/*
- * Copyright 2015 Facebook, Inc.
+ * 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.
#include <utility>
#include <folly/Format.h>
+#include <folly/portability/GFlags.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>
DEFINE_int64(mlock_chunk_size, 1 << 20, // 1MB
"Maximum bytes to mlock/munlock/munmap at once "
bool memOpInChunks(std::function<int(void*, size_t)> op,
void* mem, size_t bufSize, off_t pageSize,
size_t& amountSucceeded) {
+#ifdef _MSC_VER
+ // MSVC doesn't have this problem, and calling munmap many times
+ // with the same address is a bad idea with the windows implementation.
+ int ret = op(mem, bufSize);
+ if (ret == 0) {
+ amountSucceeded = bufSize;
+ }
+ return ret == 0;
+#else
// unmap/mlock/munlock take a kernel semaphore and block other threads from
// doing other memory operations. If the size of the buffer is big the
// semaphore can be down for seconds (for benchmarks see
}
return true;
+#endif
}
} // anonymous namespace
PLOG(FATAL) << msg;
}
+#ifndef _MSC_VER
// only part of the buffer was mlocked, unlock it back
if (!memOpInChunks(::munlock, mapStart_, amountSucceeded, options_.pageSize,
amountSucceeded)) {
PLOG(WARNING) << "munlock()";
}
+#endif
return false;
}
<< " length: " << length
<< " mapLength_: " << mapLength_;
- if (length == 0) {
- return;
- }
+ // Include the entire start page: round down to page boundary.
+ const auto offMisalign = offset % options_.pageSize;
+ offset -= offMisalign;
+ length += offMisalign;
- auto offMisalign = offset % options_.pageSize;
- if (offMisalign != 0) {
- offset -= offMisalign;
- length += offMisalign;
+ // Round the last page down to page boundary.
+ if (offset + length != size_t(mapLength_)) {
+ length -= length % options_.pageSize;
}
- length = (length + options_.pageSize - 1) & ~(options_.pageSize - 1);
- length = std::min(length, mapLength_ - offset);
+ if (length == 0) {
+ return;
+ }
char* mapStart = static_cast<char*>(mapStart_) + offset;
PLOG_IF(WARNING, ::madvise(mapStart, length, advice)) << "madvise";