blob: 8b88473f8bd795b99da371a39ae3cb019c156e70 [file] [log] [blame]
// Copyright 2019 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef MEMFD_LINUX
#define MEMFD_LINUX
#include <cstddef>
// Implementation of shared-memory regions backed by memfd_create(), which
// unfortunately is not exported by older GLibc versions, though it has been
// supported by the Linux kernel since 3.17 (good enough for Android and desktop
// Linux).
namespace linux
{
class MemFd {
public:
MemFd() = default;
MemFd(const char* name, size_t size) : MemFd() {
allocate(name, size);
}
~MemFd();
// Return true iff the region is valid/allocated.
bool isValid() const { return fd_ >= 0; }
// Return region's internal file descriptor value. Useful for mapping.
int fd() const { return fd_; }
// Set the internal handle to |fd|.
void importFd(int fd);
// Return a copy of this instance's file descriptor (with CLO_EXEC set).
int exportFd() const;
// Implement memfd_create() through direct syscalls if possible.
// On success, return true and sets |fd| accordingly. On failure, return
// false and sets errno.
bool allocate(const char* name, size_t size);
// Map a segment of |size| bytes from |offset| from the region.
// Both |offset| and |size| should be page-aligned. Returns nullptr/errno
// on failure.
void* mapReadWrite(size_t offset, size_t size);
// Unmap a region segment starting at |addr| of |size| bytes.
// Both |addr| and |size| should be page-aligned. Returns true on success
// or false/errno on failure.
bool unmap(void* addr, size_t size);
void close();
private:
int fd_ = -1;
};
} // namespace linux
#endif // MEMFD_LINUX