*/
#include <folly/MemoryMapping.h>
+
+#include <algorithm>
+#include <functional>
+#include <utility>
+
#include <folly/Format.h>
-#include <folly/Portability.h>
#ifdef __linux__
#include <folly/experimental/io/HugePages.h>
return true;
}
- auto msg(folly::format(
- "mlock({}) failed at {}",
- mapLength_, amountSucceeded).str());
+ auto msg =
+ folly::sformat("mlock({}) failed at {}", mapLength_, amountSucceeded);
if (lock == LockMode::TRY_LOCK && (errno == EPERM || errno == ENOMEM)) {
PLOG(WARNING) << msg;
size_t amountSucceeded = 0;
if (!memOpInChunks(::munmap, mapStart_, mapLength_, options_.pageSize,
amountSucceeded)) {
- PLOG(FATAL) << folly::format(
- "munmap({}) failed at {}",
- mapLength_, amountSucceeded).str();
+ PLOG(FATAL) << folly::format("munmap({}) failed at {}",
+ mapLength_, amountSucceeded);
}
}
}
-void MemoryMapping::advise(int advice) const {
- if (mapLength_ && ::madvise(mapStart_, mapLength_, advice)) {
- PLOG(WARNING) << "madvise()";
+void MemoryMapping::advise(int advice) const { advise(advice, 0, mapLength_); }
+
+void MemoryMapping::advise(int advice, size_t offset, size_t length) const {
+ CHECK_LE(offset + length, mapLength_)
+ << " offset: " << offset
+ << " length: " << length
+ << " mapLength_: " << mapLength_;
+
+ if (length == 0) {
+ return;
+ }
+
+ auto offMisalign = offset % options_.pageSize;
+ if (offMisalign != 0) {
+ offset -= offMisalign;
+ length += offMisalign;
}
+
+ length = (length + options_.pageSize - 1) & ~(options_.pageSize - 1);
+ length = std::min(length, mapLength_ - offset);
+
+ char* mapStart = static_cast<char*>(mapStart_) + offset;
+ PLOG_IF(WARNING, ::madvise(mapStart, length, advice)) << "madvise";
}
MemoryMapping& MemoryMapping::operator=(MemoryMapping other) {
* limitations under the License.
*/
+#include <sys/mman.h>
#include <cstdlib>
-#include <gtest/gtest.h>
+#include <folly/FileUtil.h>
#include <folly/MemoryMapping.h>
+#include <gtest/gtest.h>
namespace folly {
EXPECT_EQ(0, m.data().size());
}
+TEST(MemoryMapping, Advise) {
+ File f = File::temporary();
+ size_t kPageSize = 4096;
+ size_t size = kPageSize + 10; // unaligned file size
+ PCHECK(ftruncateNoInt(f.fd(), size) == 0) << size;
+
+ MemoryMapping m(File(f.fd()));
+
+ // NOTE: advise crashes on bad input.
+
+ m.advise(MADV_NORMAL, 0, kPageSize);
+ m.advise(MADV_NORMAL, 1, kPageSize);
+ m.advise(MADV_NORMAL, 0, 2);
+ m.advise(MADV_NORMAL, 1, 2);
+
+ m.advise(MADV_NORMAL, kPageSize, 0);
+ m.advise(MADV_NORMAL, kPageSize, 1);
+ m.advise(MADV_NORMAL, kPageSize, size - kPageSize);
+
+ auto off = kPageSize + 1;
+ m.advise(MADV_NORMAL, off, size - off);
+
+ EXPECT_DEATH(m.advise(MADV_NORMAL, off, size - off + 1), "");
+}
+
} // namespace folly