blob: e70af170b138950d1ae5e660b3ced9ca00faa4a6 [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).
class LinuxMemFd
{
public:
LinuxMemFd() = default;
LinuxMemFd(const char *name, size_t size)
: LinuxMemFd()
{
allocate(name, size);
}
~LinuxMemFd();
// 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;
};
#endif // MEMFD_LINUX