proxygen
folly::MemoryMapping Class Reference

#include <MemoryMapping.h>

Inheritance diagram for folly::MemoryMapping:

Classes

struct  Options
 

Public Types

enum  LockMode { LockMode::TRY_LOCK, LockMode::MUST_LOCK }
 
enum  AnonymousType { kAnonymous }
 

Public Member Functions

 MemoryMapping (AnonymousType, off_t length, Options options=Options())
 
 MemoryMapping (File file, off_t offset=0, off_t length=-1, Options options=Options())
 
 MemoryMapping (const char *name, off_t offset=0, off_t length=-1, Options options=Options())
 
 MemoryMapping (int fd, off_t offset=0, off_t length=-1, Options options=Options())
 
 MemoryMapping (MemoryMapping &&) noexcept
 
 ~MemoryMapping ()
 
MemoryMappingoperator= (MemoryMapping)
 
void swap (MemoryMapping &other) noexcept
 
bool mlock (LockMode lock)
 
void munlock (bool dontneed=false)
 
void hintLinearScan ()
 
void advise (int advice) const
 
void advise (int advice, size_t offset, size_t length) const
 
template<class T >
Range< const T * > asRange () const
 
ByteRange range () const
 
template<class T >
Range< T * > asWritableRange () const
 
MutableByteRange writableRange () const
 
StringPiece data () const
 
bool mlocked () const
 
int fd () const
 

Static Public Member Functions

static Options writable ()
 

Private Types

enum  InitFlags { kGrow = 1 << 0, kAnon = 1 << 1 }
 

Private Member Functions

 MemoryMapping ()
 
void init (off_t offset, off_t length)
 

Private Attributes

File file_
 
void * mapStart_ = nullptr
 
off_t mapLength_ = 0
 
Options options_
 
bool locked_ = false
 
MutableByteRange data_
 

Detailed Description

Maps files in memory (read-only).

Author
Tudor Bosman (tudor.nosp@m.b@fb.nosp@m..com)

Definition at line 32 of file MemoryMapping.h.

Member Enumeration Documentation

Enumerator
kAnonymous 

Definition at line 123 of file MemoryMapping.h.

Enumerator
kGrow 
kAnon 

Definition at line 238 of file MemoryMapping.h.

238  {
239  kGrow = 1 << 0,
240  kAnon = 1 << 1,
241  };

Lock the pages in memory? TRY_LOCK = try to lock, log warning if permission denied MUST_LOCK = lock, fail assertion if permission denied.

Enumerator
TRY_LOCK 
MUST_LOCK 

Definition at line 39 of file MemoryMapping.h.

39  {
40  TRY_LOCK,
41  MUST_LOCK,
42  };

Constructor & Destructor Documentation

folly::MemoryMapping::MemoryMapping ( AnonymousType  ,
off_t  length,
Options  options = Options() 
)

Create an anonymous mapping.

Definition at line 92 of file MemoryMapping.cpp.

References folly::getHugePageSizeForDevice(), and init().

93  : options_(std::move(options)) {
94  init(0, length);
95 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
void init(off_t offset, off_t length)
folly::MemoryMapping::MemoryMapping ( File  file,
off_t  offset = 0,
off_t  length = -1,
Options  options = Options() 
)
explicit

Definition at line 64 of file MemoryMapping.cpp.

References file_, and init().

69  : file_(std::move(file)), options_(std::move(options)) {
70  CHECK(file_);
71  init(offset, length);
72 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
void init(off_t offset, off_t length)
folly::MemoryMapping::MemoryMapping ( const char *  name,
off_t  offset = 0,
off_t  length = -1,
Options  options = Options() 
)
explicit

Definition at line 74 of file MemoryMapping.cpp.

79  : MemoryMapping(
80  File(name, options.writable ? O_RDWR : O_RDONLY),
81  offset,
82  length,
83  options) {}
const char * name
Definition: http_parser.c:437
folly::MemoryMapping::MemoryMapping ( int  fd,
off_t  offset = 0,
off_t  length = -1,
Options  options = Options() 
)
explicit

Definition at line 85 of file MemoryMapping.cpp.

90  : MemoryMapping(File(fd), offset, length, options) {}
folly::MemoryMapping::MemoryMapping ( MemoryMapping &&  other)
noexcept

Definition at line 60 of file MemoryMapping.cpp.

References swap().

60  {
61  swap(other);
62 }
void swap(MemoryMapping &other) noexcept
folly::MemoryMapping::~MemoryMapping ( )

Definition at line 329 of file MemoryMapping.cpp.

References folly::FATAL, folly::format(), mapLength_, mapStart_, options_, and folly::MemoryMapping::Options::pageSize.

329  {
330  if (mapLength_) {
331  size_t amountSucceeded = 0;
332  if (!memOpInChunks(
333  ::munmap,
334  mapStart_,
335  size_t(mapLength_),
337  amountSucceeded)) {
338  PLOG(FATAL) << folly::format(
339  "munmap({}) failed at {}", mapLength_, amountSucceeded);
340  }
341  }
342 }
Formatter< false, Args... > format(StringPiece fmt, Args &&...args)
Definition: Format.h:271
folly::MemoryMapping::MemoryMapping ( )
private

Referenced by fd().

Member Function Documentation

void folly::MemoryMapping::advise ( int  advice) const

Advise the kernel about memory access.

Definition at line 344 of file MemoryMapping.cpp.

References mapLength_.

Referenced by hintLinearScan(), and folly::TEST().

344  {
345  advise(advice, 0, size_t(mapLength_));
346 }
void advise(int advice) const
void folly::MemoryMapping::advise ( int  advice,
size_t  offset,
size_t  length 
) const

Definition at line 348 of file MemoryMapping.cpp.

References mapLength_, mapStart_, options_, folly::MemoryMapping::Options::pageSize, and folly::WARNING.

348  {
349  CHECK_LE(offset + length, size_t(mapLength_))
350  << " offset: " << offset << " length: " << length
351  << " mapLength_: " << mapLength_;
352 
353  // Include the entire start page: round down to page boundary.
354  const auto offMisalign = offset % options_.pageSize;
355  offset -= offMisalign;
356  length += offMisalign;
357 
358  // Round the last page down to page boundary.
359  if (offset + length != size_t(mapLength_)) {
360  length -= length % options_.pageSize;
361  }
362 
363  if (length == 0) {
364  return;
365  }
366 
367  char* mapStart = static_cast<char*>(mapStart_) + offset;
368  PLOG_IF(WARNING, ::madvise(mapStart, length, advice)) << "madvise";
369 }
template<class T >
Range<const T*> folly::MemoryMapping::asRange ( ) const
inline

A bitwise cast of the mapped bytes as range of values. Only intended for use with POD or in-place usable types.

Definition at line 187 of file MemoryMapping.h.

References count, folly::Range< Iter >::data(), data_, folly::Range< Iter >::size(), and folly::T.

Referenced by folly::TEST().

187  {
188  size_t count = data_.size() / sizeof(T);
189  return Range<const T*>(
190  static_cast<const T*>(static_cast<const void*>(data_.data())), count);
191  }
constexpr size_type size() const
Definition: Range.h:431
folly::std T
MutableByteRange data_
constexpr Iter data() const
Definition: Range.h:446
int * count
template<class T >
Range<T*> folly::MemoryMapping::asWritableRange ( ) const
inline

A bitwise cast of the mapped bytes as range of mutable values. Only intended for use with POD or in-place usable types.

Definition at line 205 of file MemoryMapping.h.

References count, folly::Range< Iter >::data(), data_, options_, folly::Range< Iter >::size(), folly::T, and folly::MemoryMapping::Options::writable.

Referenced by folly::TEST().

205  {
206  DCHECK(options_.writable); // you'll segfault anyway...
207  size_t count = data_.size() / sizeof(T);
208  return Range<T*>(static_cast<T*>(static_cast<void*>(data_.data())), count);
209  }
constexpr size_type size() const
Definition: Range.h:431
folly::std T
MutableByteRange data_
constexpr Iter data() const
Definition: Range.h:446
int * count
StringPiece folly::MemoryMapping::data ( ) const
inline

Return the memory area where the file was mapped. Deprecated; use range() instead.

Definition at line 223 of file MemoryMapping.h.

Referenced by folly::TEST().

223  {
224  return asRange<const char>();
225  }
int folly::MemoryMapping::fd ( ) const
inline

Definition at line 231 of file MemoryMapping.h.

References folly::File::fd(), file_, and MemoryMapping().

231  {
232  return file_.fd();
233  }
int fd() const
Definition: File.h:85
void folly::MemoryMapping::hintLinearScan ( )

Hint that these pages will be scanned linearly. madvise(MADV_SEQUENTIAL)

Definition at line 325 of file MemoryMapping.cpp.

References advise().

Referenced by folly::mmapFileCopy().

325  {
326  advise(MADV_SEQUENTIAL);
327 }
void advise(int advice) const
void folly::MemoryMapping::init ( off_t  offset,
off_t  length 
)
private

Definition at line 113 of file MemoryMapping.cpp.

References addr, folly::MemoryMapping::Options::address, data_, folly::File::fd(), file_, folly::MemoryMapping::Options::grow, MAP_POPULATE, mapLength_, mapStart_, min, options_, folly::MemoryMapping::Options::pageSize, folly::MemoryMapping::Options::prefault, folly::MemoryMapping::Options::readable, folly::Range< Iter >::reset(), folly::MemoryMapping::Options::shared, folly::size(), start, and folly::MemoryMapping::Options::writable.

Referenced by MemoryMapping().

113  {
114  const bool grow = options_.grow;
115  const bool anon = !file_;
116  CHECK(!(grow && anon));
117 
118  off_t& pageSize = options_.pageSize;
119 
120  struct stat st;
121 
122  // On Linux, hugetlbfs file systems don't require ftruncate() to grow the
123  // file, and (on kernels before 2.6.24) don't even allow it. Also, the file
124  // size is always a multiple of the page size.
125  bool autoExtend = false;
126 
127  if (!anon) {
128  // Stat the file
129  CHECK_ERR(fstat(file_.fd(), &st));
130 
131  if (pageSize == 0) {
132  getDeviceOptions(st.st_dev, pageSize, autoExtend);
133  }
134  } else {
135  DCHECK(!file_);
136  DCHECK_EQ(offset, 0);
137  CHECK_EQ(pageSize, 0);
138  CHECK_GE(length, 0);
139  }
140 
141  if (pageSize == 0) {
142  pageSize = off_t(sysconf(_SC_PAGESIZE));
143  }
144 
145  CHECK_GT(pageSize, 0);
146  CHECK_EQ(pageSize & (pageSize - 1), 0); // power of two
147  CHECK_GE(offset, 0);
148 
149  // Round down the start of the mapped region
150  off_t skipStart = offset % pageSize;
151  offset -= skipStart;
152 
153  mapLength_ = length;
154  if (mapLength_ != -1) {
155  mapLength_ += skipStart;
156 
157  // Round up the end of the mapped region
158  mapLength_ = (mapLength_ + pageSize - 1) / pageSize * pageSize;
159  }
160 
161  off_t remaining = anon ? length : st.st_size - offset;
162 
163  if (mapLength_ == -1) {
164  length = mapLength_ = remaining;
165  } else {
166  if (length > remaining) {
167  if (grow) {
168  if (!autoExtend) {
169  PCHECK(0 == ftruncate(file_.fd(), offset + length))
170  << "ftruncate() failed, couldn't grow file to "
171  << offset + length;
172  remaining = length;
173  } else {
174  // Extend mapping to multiple of page size, don't use ftruncate
175  remaining = mapLength_;
176  }
177  } else {
178  length = remaining;
179  }
180  }
181  if (mapLength_ > remaining) {
182  mapLength_ = remaining;
183  }
184  }
185 
186  if (length == 0) {
187  mapLength_ = 0;
188  mapStart_ = nullptr;
189  } else {
190  int flags = options_.shared ? MAP_SHARED : MAP_PRIVATE;
191  if (anon) {
192  flags |= MAP_ANONYMOUS;
193  }
194  if (options_.prefault) {
195  flags |= MAP_POPULATE;
196  }
197 
198  // The standard doesn't actually require PROT_NONE to be zero...
199  int prot = PROT_NONE;
201  prot =
202  ((options_.readable ? PROT_READ : 0) |
203  (options_.writable ? PROT_WRITE : 0));
204  }
205 
206  unsigned char* start = static_cast<unsigned char*>(mmap(
207  options_.address, size_t(mapLength_), prot, flags, file_.fd(), offset));
208  PCHECK(start != MAP_FAILED)
209  << " offset=" << offset << " length=" << mapLength_;
210  mapStart_ = start;
211  data_.reset(start + skipStart, size_t(length));
212  }
213 }
flags
Definition: http_parser.h:127
int fd() const
Definition: File.h:85
MutableByteRange data_
#define MAP_POPULATE
auto start
void reset(Iter start, size_type size)
Definition: Range.h:421
bool folly::MemoryMapping::mlock ( LockMode  lock)

Lock the pages in memory

Definition at line 269 of file MemoryMapping.cpp.

References folly::FATAL, folly::format(), locked_, mapLength_, mapStart_, munlock(), options_, folly::MemoryMapping::Options::pageSize, TRY_LOCK, and folly::WARNING.

Referenced by folly::TEST().

269  {
270  size_t amountSucceeded = 0;
271  locked_ = memOpInChunks(
272  ::mlock,
273  mapStart_,
274  size_t(mapLength_),
276  amountSucceeded);
277  if (locked_) {
278  return true;
279  }
280 
281  auto msg =
282  folly::format("mlock({}) failed at {}", mapLength_, amountSucceeded);
283  if (lock == LockMode::TRY_LOCK && errno == EPERM) {
284  PLOG(WARNING) << msg;
285  } else if (lock == LockMode::TRY_LOCK && errno == ENOMEM) {
286  VLOG(1) << msg;
287  } else {
288  PLOG(FATAL) << msg;
289  }
290 
291  // only part of the buffer was mlocked, unlock it back
292  if (!memOpInChunks(
293  ::munlock,
294  mapStart_,
295  amountSucceeded,
297  amountSucceeded)) {
298  PLOG(WARNING) << "munlock()";
299  }
300 
301  return false;
302 }
bool mlock(LockMode lock)
auto lock(Synchronized< D, M > &synchronized, Args &&...args)
void munlock(bool dontneed=false)
Formatter< false, Args... > format(StringPiece fmt, Args &&...args)
Definition: Format.h:271
bool folly::MemoryMapping::mlocked ( ) const
inline

Definition at line 227 of file MemoryMapping.h.

References locked_.

Referenced by folly::TEST().

227  {
228  return locked_;
229  }
void folly::MemoryMapping::munlock ( bool  dontneed = false)

Unlock the pages. If dontneed is true, the kernel is instructed to release these pages (per madvise(MADV_DONTNEED)).

Definition at line 304 of file MemoryMapping.cpp.

References locked_, mapLength_, mapStart_, options_, folly::MemoryMapping::Options::pageSize, and folly::WARNING.

Referenced by mlock().

304  {
305  if (!locked_) {
306  return;
307  }
308 
309  size_t amountSucceeded = 0;
310  if (!memOpInChunks(
311  ::munlock,
312  mapStart_,
313  size_t(mapLength_),
315  amountSucceeded)) {
316  PLOG(WARNING) << "munlock()";
317  }
318  if (mapLength_ && dontneed &&
319  ::madvise(mapStart_, size_t(mapLength_), MADV_DONTNEED)) {
320  PLOG(WARNING) << "madvise()";
321  }
322  locked_ = false;
323 }
void munlock(bool dontneed=false)
MemoryMapping & folly::MemoryMapping::operator= ( MemoryMapping  other)

Definition at line 371 of file MemoryMapping.cpp.

References swap().

371  {
372  swap(other);
373  return *this;
374 }
void swap(MemoryMapping &other) noexcept
ByteRange folly::MemoryMapping::range ( ) const
inline

A range of bytes mapped by this mapping.

Definition at line 196 of file MemoryMapping.h.

References data_.

Referenced by folly::mmapFileCopy(), and folly::RecordIOReader::seek().

196  {
197  return data_;
198  }
MutableByteRange data_
void folly::MemoryMapping::swap ( MemoryMapping other)
noexcept

Definition at line 376 of file MemoryMapping.cpp.

References data_, file_, locked_, mapLength_, mapStart_, options_, and folly::swap().

Referenced by MemoryMapping(), and operator=().

376  {
377  using std::swap;
378  swap(this->file_, other.file_);
379  swap(this->mapStart_, other.mapStart_);
380  swap(this->mapLength_, other.mapLength_);
381  swap(this->options_, other.options_);
382  swap(this->locked_, other.locked_);
383  swap(this->data_, other.data_);
384 }
void swap(MemoryMapping &other) noexcept
void swap(MemoryMapping &a, MemoryMapping &b) noexcept
MutableByteRange data_
static Options folly::MemoryMapping::writable ( )
inlinestatic

Definition at line 119 of file MemoryMapping.h.

References folly::MemoryMapping::Options::setGrow(), and folly::MemoryMapping::Options::setWritable().

Referenced by folly::mmapFileCopy(), folly::MemoryMapping::Options::setWritable(), and folly::TEST().

119  {
120  return Options().setWritable(true).setGrow(true);
121  }
MutableByteRange folly::MemoryMapping::writableRange ( ) const
inline

A range of mutable bytes mapped by this mapping.

Definition at line 214 of file MemoryMapping.h.

References data_, options_, and folly::MemoryMapping::Options::writable.

214  {
215  DCHECK(options_.writable); // you'll segfault anyway...
216  return data_;
217  }
MutableByteRange data_

Member Data Documentation

MutableByteRange folly::MemoryMapping::data_
private

Definition at line 249 of file MemoryMapping.h.

Referenced by asRange(), asWritableRange(), init(), range(), swap(), and writableRange().

File folly::MemoryMapping::file_
private

Definition at line 244 of file MemoryMapping.h.

Referenced by fd(), init(), MemoryMapping(), and swap().

bool folly::MemoryMapping::locked_ = false
private

Definition at line 248 of file MemoryMapping.h.

Referenced by mlock(), mlocked(), munlock(), and swap().

off_t folly::MemoryMapping::mapLength_ = 0
private

Definition at line 246 of file MemoryMapping.h.

Referenced by advise(), init(), mlock(), munlock(), swap(), and ~MemoryMapping().

void* folly::MemoryMapping::mapStart_ = nullptr
private

Definition at line 245 of file MemoryMapping.h.

Referenced by advise(), init(), mlock(), munlock(), swap(), and ~MemoryMapping().

Options folly::MemoryMapping::options_
private

The documentation for this class was generated from the following files: