Commit 6346da0d authored by Christopher Dykes's avatar Christopher Dykes Committed by Facebook Github Bot 5

Create the sys/mman.h portability header

Summary: Something that Windows very definitely lacks. This is a fun one.

Reviewed By: yfeldblum

Differential Revision: D2979661

fb-gh-sync-id: e23c1db0cb8655b22308b874bd421a7cc1e4759e
shipit-source-id: e23c1db0cb8655b22308b874bd421a7cc1e4759e
parent 2c8de414
......@@ -21,10 +21,10 @@
#include <stdint.h>
#include <assert.h>
#include <unistd.h>
#include <sys/mman.h>
#include <boost/noncopyable.hpp>
#include <folly/AtomicStruct.h>
#include <folly/detail/CacheLocality.h>
#include <folly/portability/SysMman.h>
// Ignore shadowing warnings within this file, so includers can use -Wshadow.
#pragma GCC diagnostic push
......
......@@ -276,6 +276,7 @@ nobase_follyinclude_HEADERS = \
portability/Strings.h \
portability/Syscall.h \
portability/SysFile.h \
portability/SysMman.h \
portability/SysStat.h \
portability/SysTime.h \
portability/SysTypes.h \
......@@ -410,6 +411,7 @@ libfolly_la_SOURCES = \
portability/Environment.cpp \
portability/Strings.cpp \
portability/SysFile.cpp \
portability/SysMman.cpp \
portability/SysStat.cpp \
portability/SysTime.cpp \
portability/Time.cpp \
......
......@@ -21,13 +21,13 @@
#include <utility>
#include <folly/Format.h>
#include <folly/portability/SysMman.h>
#ifdef __linux__
#include <folly/experimental/io/HugePages.h>
#endif
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <system_error>
#include <gflags/gflags.h>
......
......@@ -46,17 +46,6 @@ constexpr bool kHasUnalignedAccess = false;
#endif
}
// A change in folly/MemoryMapping.cpp uses MAP_ANONYMOUS, which is named
// MAP_ANON on OSX/BSD.
#if defined(__APPLE__) || defined(__FreeBSD__)
#include <sys/mman.h>
#ifndef MAP_ANONYMOUS
#ifdef MAP_ANON
#define MAP_ANONYMOUS MAP_ANON
#endif
#endif
#endif
// compiler specific attribute translation
// msvc should come first, so if clang is in msvc mode it gets the right defines
......
......@@ -2,9 +2,10 @@
#include <atomic>
#include <stdint.h>
#include <sys/mman.h>
#include <unistd.h>
#include <folly/portability/SysMman.h>
namespace folly { namespace detail {
class MMapAlloc {
......
......@@ -15,13 +15,13 @@
*/
#include "GuardPageAllocator.h"
#include <sys/mman.h>
#include <unistd.h>
#include <mutex>
#include <folly/Singleton.h>
#include <folly/SpinLock.h>
#include <folly/portability/SysMman.h>
#include <glog/logging.h>
......
/*
* Copyright 2016 Facebook, Inc.
*
* 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.
*/
#include <folly/portability/SysMman.h>
#ifdef _WIN32
#include <folly/portability/Windows.h>
static bool mmap_to_page_protection(int prot, DWORD& ret) {
if (prot == PROT_NONE) {
ret = PAGE_NOACCESS;
} else if (prot == PROT_READ) {
ret = PAGE_READONLY;
} else if (prot == PROT_EXEC) {
ret = PAGE_EXECUTE;
} else if (prot == (PROT_READ | PROT_EXEC)) {
ret = PAGE_EXECUTE_READ;
} else if (prot == (PROT_READ | PROT_WRITE)) {
ret = PAGE_READWRITE;
} else if (prot == (PROT_READ | PROT_WRITE | PROT_EXEC)) {
ret = PAGE_EXECUTE_READWRITE;
} else {
return false;
}
return true;
}
extern "C" {
int madvise(const void* addr, size_t len, int advise) {
// We do nothing at all.
// Could probably implement dontneed via VirtualAlloc
// with the MEM_RESET and MEM_RESET_UNDO flags.
return 0;
}
int mlock(const void* addr, size_t len) {
if (!VirtualLock((void*)addr, len)) {
return -1;
}
return 0;
}
void* mmap(void* addr, size_t length, int prot, int flags, int fd, off_t off) {
// Make sure it's something we support first.
// No Anon shared.
if ((flags & (MAP_ANONYMOUS | MAP_SHARED)) == (MAP_ANONYMOUS | MAP_SHARED)) {
return MAP_FAILED;
}
// No private copy on write.
if ((flags & MAP_PRIVATE) == MAP_PRIVATE && fd != -1) {
return MAP_FAILED;
}
// Map isn't anon, must be file backed.
if (!(flags & MAP_ANONYMOUS) && fd == -1) {
return MAP_FAILED;
}
DWORD newProt;
if (!mmap_to_page_protection(prot, newProt)) {
return MAP_FAILED;
}
void* ret;
if (!(flags & MAP_ANONYMOUS) || (flags & MAP_SHARED)) {
HANDLE h = INVALID_HANDLE_VALUE;
if (!(flags & MAP_ANONYMOUS)) {
h = (HANDLE)_get_osfhandle(fd);
}
HANDLE fmh = CreateFileMapping(
h,
nullptr,
newProt | SEC_COMMIT | SEC_RESERVE,
(DWORD)((length >> 32) & 0xFFFFFFFF),
(DWORD)(length & 0xFFFFFFFF),
nullptr);
ret = MapViewOfFileEx(
fmh,
FILE_MAP_ALL_ACCESS,
(DWORD)((off >> 32) & 0xFFFFFFFF),
(DWORD)(off & 0xFFFFFFFF),
0,
addr);
if (ret == nullptr) {
ret = MAP_FAILED;
}
CloseHandle(fmh);
} else {
ret = VirtualAlloc(addr, length, MEM_COMMIT | MEM_RESERVE, newProt);
if (ret == nullptr) {
return MAP_FAILED;
}
}
// TODO: Could technically implement MAP_POPULATE via PrefetchVirtualMemory
// Should also see about implementing MAP_NORESERVE
return ret;
}
int mprotect(void* addr, size_t size, int prot) {
DWORD newProt;
if (!mmap_to_page_protection(prot, newProt)) {
return -1;
}
DWORD oldProt;
BOOL res = VirtualProtect(addr, size, newProt, &oldProt);
if (!res) {
return -1;
}
return 0;
}
int munlock(const void* addr, size_t length) {
if (!VirtualUnlock((void*)addr, length)) {
return -1;
}
return 0;
}
int munmap(void* addr, size_t length) {
// Try to unmap it as a file, otherwise VirtualFree.
if (!UnmapViewOfFile(addr)) {
if (!VirtualFree(addr, length, MEM_RELEASE)) {
return -1;
}
return 0;
}
return 0;
}
}
#endif
/*
* Copyright 2016 Facebook, Inc.
*
* 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.
*/
#pragma once
#ifndef _WIN32
#include <sys/mman.h>
// MAP_ANONYMOUS is named MAP_ANON on OSX/BSD.
#if defined(__APPLE__) || defined(__FreeBSD__)
# if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
# define MAP_ANONYMOUS MAP_ANON
# endif
#endif
#else
#include <cstdint>
#include <sys/types.h>
#define MAP_ANONYMOUS 1
#define MAP_ANON MAP_ANONYMOUS
#define MAP_SHARED 2
#define MAP_PRIVATE 4
#define MAP_POPULATE 8
#define MAP_NORESERVE 16
#define MAP_FIXED 32
#define MAP_FAILED ((void*)-1)
#define PROT_NONE 0
#define PROT_READ 1
#define PROT_WRITE 2
#define PROT_EXEC 4
#define MADV_DONTNEED 0
#define MADV_SEQUENTIAL 0
extern "C" {
int madvise(const void* addr, size_t len, int advise);
int mlock(const void* addr, size_t len);
void* mmap(void* addr, size_t length, int prot, int flags, int fd, off_t off);
int mprotect(void* addr, size_t size, int prot);
int munlock(const void* addr, size_t length);
int munmap(void* addr, size_t length);
}
#endif
......@@ -14,22 +14,17 @@
* limitations under the License.
*/
#include <sys/mman.h>
#include <cstddef>
#include <map>
#include <stdexcept>
#include <folly/AtomicHashArray.h>
#include <folly/Hash.h>
#include <folly/Conv.h>
#include <folly/Hash.h>
#include <folly/Memory.h>
#include <folly/portability/SysMman.h>
#include <gtest/gtest.h>
#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
#define MAP_ANONYMOUS MAP_ANON
#endif
using namespace std;
using namespace folly;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment