Commit 51026ab6 authored by Lucian Grijincu's avatar Lucian Grijincu Committed by Viswanath Sivakumar

folly: MemoryMapping: add offset/size params to advise

Test Plan: ran it

Reviewed By: philipp@fb.com

Subscribers: folly-diffs@, yfeldblum, chalfant

FB internal diff: D1974936

Signature: t1:1974936:1428453023:1a83ed8336f75b745bffc633b8471231423b0fb0
parent d2eda017
......@@ -15,8 +15,12 @@
*/
#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>
......@@ -240,9 +244,8 @@ bool MemoryMapping::mlock(LockMode lock) {
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;
......@@ -283,17 +286,35 @@ MemoryMapping::~MemoryMapping() {
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) {
......
......@@ -157,6 +157,7 @@ class MemoryMapping : boost::noncopyable {
* Advise the kernel about memory access.
*/
void advise(int advice) const;
void advise(int advice, size_t offset, size_t length) const;
/**
* A bitwise cast of the mapped bytes as range of values. Only intended for
......
......@@ -14,9 +14,11 @@
* 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 {
......@@ -145,4 +147,29 @@ TEST(MemoryMapping, ZeroLength) {
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
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