From 2c73945cae93e33935f0c9730117ba78387cd987 Mon Sep 17 00:00:00 2001 From: Tom Jackson Date: Tue, 22 Apr 2014 17:22:09 -0700 Subject: [PATCH] std::move-able MemoryMapping Test Plan: unit tests Reviewed By: lucian@fb.com FB internal diff: D1290632 --- folly/MemoryMapping.cpp | 25 +++++++++++++++++++++++++ folly/MemoryMapping.h | 10 +++++++++- folly/test/MemoryMappingTest.cpp | 20 ++++++++++++++++++++ 3 files changed, 54 insertions(+), 1 deletion(-) diff --git a/folly/MemoryMapping.cpp b/folly/MemoryMapping.cpp index 8240f097..fbc144d9 100644 --- a/folly/MemoryMapping.cpp +++ b/folly/MemoryMapping.cpp @@ -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 diff --git a/folly/MemoryMapping.h b/folly/MemoryMapping.h index 9607ba29..7b09dc98 100644 --- a/folly/MemoryMapping.h +++ b/folly/MemoryMapping.h @@ -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_ */ diff --git a/folly/test/MemoryMappingTest.cpp b/folly/test/MemoryMappingTest.cpp index c111073a..d7ee607c 100644 --- a/folly/test/MemoryMappingTest.cpp +++ b/folly/test/MemoryMappingTest.cpp @@ -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().data(); + d[0] = 37 * M_PI; + WritableMemoryMapping m2(std::move(m)); + double volatile* d2 = m2.asWritableRange().data(); + d2[1] = 39 * M_PI; + } + { + MemoryMapping m(File(f.fd()), 0, sizeof(double)); + const double volatile* d = m.asRange().data(); + EXPECT_EQ(d[0], 37 * M_PI); + MemoryMapping m2(std::move(m)); + const double volatile* d2 = m2.asRange().data(); + EXPECT_EQ(d2[1], 39 * M_PI); + } +} + TEST(MemoryMapping, DoublyMapped) { File f = File::temporary(); // two mappings of the same memory, different addresses. -- 2.34.1