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