Commit fbb2e01e authored by Giuseppe Ottaviano's avatar Giuseppe Ottaviano Committed by Facebook Github Bot

Turn MemoryMapping::LockFlags into a struct of bools

Summary: `LockFlags` is a set of flags that mirrors `mlock2(..., int flags)`, but since this is not a C API we don't need a bitset, we can just use a more idiomatic struct of bools (also used for the other options in the class). Furthermore, having an entry with value 0 (`LOCK_PREFAULT`) does not make sense in a bitset.

Reviewed By: yfeldblum

Differential Revision: D16900127

fbshipit-source-id: 6477854121c0626e0f36cb7a50d50df73323bd4e
parent da621b8f
......@@ -274,13 +274,22 @@ bool memOpInChunks(
* glibc added the mlock2 wrapper in 2.27
* https://lists.gnu.org/archive/html/info-gnu/2018-02/msg00000.html
*/
int mlock2wrapper(const void* addr, size_t len, int flags) {
int mlock2wrapper(
const void* addr,
size_t len,
MemoryMapping::LockFlags flags) {
int intFlags = 0;
if (flags.lockOnFault) {
// MLOCK_ONFAULT, only available in non-portable headers.
intFlags |= 0x01;
}
#if defined(__GLIBC__) && !defined(__APPLE__)
#if __GLIBC_PREREQ(2, 27)
return mlock2(addr, len, flags);
return mlock2(addr, len, intFlags);
#elif defined(SYS_mlock2)
// SYS_mlock2 is defined in Linux headers since 4.4
return syscall(SYS_mlock2, addr, len, flags);
return syscall(SYS_mlock2, addr, len, intFlags);
#else // !__GLIBC_PREREQ(2, 27) && !defined(SYS_mlock2)
errno = ENOSYS;
return -1;
......@@ -297,10 +306,10 @@ bool MemoryMapping::mlock(LockMode mode, LockFlags flags) {
size_t amountSucceeded = 0;
locked_ = memOpInChunks(
[flags](void* addr, size_t len) -> int {
// If flags is 0, mlock2() behaves exactly the same as mlock().
// Prefer the portable variant.
return int(flags) == 0 ? ::mlock(addr, len)
: mlock2wrapper(addr, len, int(flags));
// If no flags are set, mlock2() behaves exactly the same as
// mlock(). Prefer the portable variant.
return flags == LockFlags{} ? ::mlock(addr, len)
: mlock2wrapper(addr, len, flags);
},
mapStart_,
size_t(mapLength_),
......@@ -456,10 +465,8 @@ void mmapFileCopy(const char* src, const char* dest, mode_t mode) {
srcMap.range().size());
}
MemoryMapping::LockFlags operator|(
MemoryMapping::LockFlags a,
MemoryMapping::LockFlags b) {
return MemoryMapping::LockFlags(int(a) | int(b));
bool MemoryMapping::LockFlags::operator==(const LockFlags& other) const {
return lockOnFault == other.lockOnFault;
}
} // namespace folly
......@@ -23,7 +23,6 @@
namespace folly {
/**
* Maps files in memory (read-only).
*
......@@ -41,21 +40,19 @@ class MemoryMapping {
MUST_LOCK,
};
enum class LockFlags : int {
/**
* All pages that contain a part of the specified address range are
* guaranteed to be resident in RAM when the call returns successfully; the
* pages are guaranteed to stay in RAM until later unlocked.
* Uses mlock or mlock2(flags=0). Portable.
*/
LOCK_PREFAULT = 0,
struct LockFlags {
LockFlags() {}
bool operator==(const LockFlags& other) const;
/**
* Lock pages that are currently resident and mark the entire range to have
* pages locked when they are populated by the page fault.
* Same value as MLOCK_ONFAULT which is defined in a non-portable header.
* Instead of locking all the pages in the mapping before the call returns,
* only lock those that are currently resident and mark the others to be
* locked at the time they're populated by their first page fault.
*
* Uses mlock2(flags=MLOCK_ONFAULT). Requires Linux >= 4.4.
*/
LOCK_ONFAULT = 0x01, // = np MLOCK_ONFAULT
bool lockOnFault = false;
};
/**
......@@ -178,7 +175,7 @@ class MemoryMapping {
/**
* Lock the pages in memory
*/
bool mlock(LockMode mode, LockFlags flags = LockFlags::LOCK_PREFAULT);
bool mlock(LockMode mode, LockFlags flags = {});
/**
* Unlock the pages.
......@@ -288,8 +285,4 @@ void alignedForwardMemcpy(void* dest, const void* src, size_t size);
*/
void mmapFileCopy(const char* src, const char* dest, mode_t mode = 0666);
MemoryMapping::LockFlags operator|(
MemoryMapping::LockFlags a,
MemoryMapping::LockFlags b);
} // 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