std::move-able MemoryMapping
authorTom Jackson <tjackson@fb.com>
Wed, 23 Apr 2014 00:22:09 +0000 (17:22 -0700)
committerDave Watson <davejwatson@fb.com>
Tue, 20 May 2014 19:53:56 +0000 (12:53 -0700)
Test Plan: unit tests

Reviewed By: lucian@fb.com

FB internal diff: D1290632

folly/MemoryMapping.cpp
folly/MemoryMapping.h
folly/test/MemoryMappingTest.cpp

index 8240f097f9d88042748a720d7d18dc107be4671a..fbc144d93b6cfad0bd8feca32419f2b8aacfb121 100644 (file)
@@ -37,6 +37,14 @@ MemoryMapping::MemoryMapping()
   , locked_(false) {
 }
 
+MemoryMapping::MemoryMapping(MemoryMapping&& other)
+  : mapStart_(nullptr)
+  , mapLength_(0)
+  , pageSize_(0)
+  , locked_(false) {
+  swap(other);
+}
+
 MemoryMapping::MemoryMapping(File file, off_t offset, off_t length,
                              off_t pageSize)
   : mapStart_(nullptr)
@@ -229,9 +237,26 @@ void MemoryMapping::advise(int advice) const {
   }
 }
 
+MemoryMapping& MemoryMapping::operator=(MemoryMapping other) {
+  swap(other);
+  return *this;
+}
+
+void MemoryMapping::swap(MemoryMapping& other) {
+  using std::swap;
+  swap(this->file_, other.file_);
+  swap(this->mapStart_, other.mapStart_);
+  swap(this->mapLength_, other.mapLength_);
+  swap(this->pageSize_, other.pageSize_);
+  swap(this->locked_, other.locked_);
+  swap(this->data_, other.data_);
+}
+
 WritableMemoryMapping::WritableMemoryMapping(
     File file, off_t offset, off_t length, off_t pageSize) {
   init(std::move(file), offset, length, pageSize, PROT_READ | PROT_WRITE, true);
 }
 
+void swap(MemoryMapping& a, MemoryMapping& b) { a.swap(b); }
+
 }  // namespace folly
index 9607ba293b2b74682106925d3380a027e46fdd0a..7b09dc980abba09f0cc992d8dafc913ce184f55f 100644 (file)
@@ -67,8 +67,14 @@ class MemoryMapping : boost::noncopyable {
                          off_t length=-1,
                          off_t pageSize=0);
 
+  MemoryMapping(MemoryMapping&&);
+
   virtual ~MemoryMapping();
 
+  MemoryMapping& operator=(MemoryMapping);
+
+  void swap(MemoryMapping& other);
+
   /**
    * Lock the pages in memory
    */
@@ -79,7 +85,7 @@ class MemoryMapping : boost::noncopyable {
    * If dontneed is true, the kernel is instructed to release these pages
    * (per madvise(MADV_DONTNEED)).
    */
-  void munlock(bool dontneed=false);
+  void munlock(bool dontneed = false);
 
   /**
    * Hint that these pages will be scanned linearly.
@@ -172,6 +178,8 @@ class WritableMemoryMapping : public MemoryMapping {
   }
 };
 
+void swap(MemoryMapping&, MemoryMapping&);
+
 }  // namespace folly
 
 #endif /* FOLLY_MEMORYMAPPING_H_ */
index c111073a716ec3ff6040da349f94f150a4edd674..d7ee607c501e216a2d0431b25fa32f0591f99364 100644 (file)
@@ -38,6 +38,26 @@ TEST(MemoryMapping, Basic) {
   }
 }
 
+TEST(MemoryMapping, Move) {
+  File f = File::temporary();
+  {
+    WritableMemoryMapping m(File(f.fd()), 0, sizeof(double) * 2);
+    double volatile* d = m.asWritableRange<double>().data();
+    d[0] = 37 * M_PI;
+    WritableMemoryMapping m2(std::move(m));
+    double volatile* d2 = m2.asWritableRange<double>().data();
+    d2[1] = 39 * M_PI;
+  }
+  {
+    MemoryMapping m(File(f.fd()), 0, sizeof(double));
+    const double volatile* d = m.asRange<double>().data();
+    EXPECT_EQ(d[0], 37 * M_PI);
+    MemoryMapping m2(std::move(m));
+    const double volatile* d2 = m2.asRange<double>().data();
+    EXPECT_EQ(d2[1], 39 * M_PI);
+  }
+}
+
 TEST(MemoryMapping, DoublyMapped) {
   File f = File::temporary();
   // two mappings of the same memory, different addresses.