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";