[llvm] 142f51f - Support: Add mapped_file_region::sync(), equivalent to msync

via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 6 13:47:02 PDT 2022


Author: raghavmedicherla
Date: 2022-09-06T16:46:37-04:00
New Revision: 142f51fc2f448845f6a32e767ffaa2b665eea11f

URL: https://github.com/llvm/llvm-project/commit/142f51fc2f448845f6a32e767ffaa2b665eea11f
DIFF: https://github.com/llvm/llvm-project/commit/142f51fc2f448845f6a32e767ffaa2b665eea11f.diff

LOG: Support: Add mapped_file_region::sync(), equivalent to msync

Add mapped_file_region::sync(), equivalent to POSIX msync,
synchronizing written content to disk without unmapping the region.
Asserts if the mode is not mapped_file_region::readwrite.

Note that I don't have access to a Windows machine, so I can't
easily run those unit tests.

Change by dexonsmith

Differential Revision: https://reviews.llvm.org/D95494

Added: 
    

Modified: 
    llvm/include/llvm/Support/FileSystem.h
    llvm/lib/Support/Unix/Path.inc
    llvm/lib/Support/Windows/Path.inc
    llvm/unittests/Support/Path.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Support/FileSystem.h b/llvm/include/llvm/Support/FileSystem.h
index 033482977a105..8521aa8af5f89 100644
--- a/llvm/include/llvm/Support/FileSystem.h
+++ b/llvm/include/llvm/Support/FileSystem.h
@@ -1337,6 +1337,9 @@ class mapped_file_region {
   /// behavior.
   const char *const_data() const;
 
+  /// Write changes to disk and synchronize. Equivalent to POSIX msync.
+  std::error_code sync() const;
+
   /// \returns The minimum alignment offset must be.
   static int alignment();
 };

diff  --git a/llvm/lib/Support/Unix/Path.inc b/llvm/lib/Support/Unix/Path.inc
index 3ecc5c971b79f..17c8069cac9b5 100644
--- a/llvm/lib/Support/Unix/Path.inc
+++ b/llvm/lib/Support/Unix/Path.inc
@@ -885,6 +885,14 @@ void mapped_file_region::dontNeedImpl() {
 #endif
 }
 
+std::error_code mapped_file_region::sync() const {
+  assert(Mapping && "Mapping failed but used anyway!");
+  assert(Mode == readwrite && "sync only valid for readwrite regions!");
+  if (::msync(Mapping, Size, MS_SYNC))
+    return std::error_code(errno, std::generic_category());
+  return std::error_code();
+}
+
 int mapped_file_region::alignment() {
   return Process::getPageSizeEstimate();
 }

diff  --git a/llvm/lib/Support/Windows/Path.inc b/llvm/lib/Support/Windows/Path.inc
index 433c62900a3f6..1e9788a137267 100644
--- a/llvm/lib/Support/Windows/Path.inc
+++ b/llvm/lib/Support/Windows/Path.inc
@@ -963,6 +963,16 @@ void mapped_file_region::unmapImpl() {
 
 void mapped_file_region::dontNeedImpl() {}
 
+std::error_code mapped_file_region::sync() const {
+  assert(Mapping && "Mapping failed but used anyway!");
+  assert(Mode == readwrite && "sync only valid for readwrite regions!");
+  if (!::FlushViewOfFile(Mapping, Size))
+    return mapWindowsError(GetLastError());
+  if (!::FlushFileBuffers(FileHandle))
+    return mapWindowsError(GetLastError());
+  return std::error_code();
+}
+
 int mapped_file_region::alignment() {
   SYSTEM_INFO SysInfo;
   ::GetSystemInfo(&SysInfo);

diff  --git a/llvm/unittests/Support/Path.cpp b/llvm/unittests/Support/Path.cpp
index 3b8ffd8fee94a..4457577edbf36 100644
--- a/llvm/unittests/Support/Path.cpp
+++ b/llvm/unittests/Support/Path.cpp
@@ -1463,6 +1463,33 @@ TEST_F(FileSystemTest, FileMapping) {
   ASSERT_NO_ERROR(fs::remove(TempPath));
 }
 
+TEST_F(FileSystemTest, FileMappingSync) {
+  // Create a temp file.
+  int FD;
+  SmallString<64> TempPath;
+  ASSERT_NO_ERROR(fs::createTemporaryFile("prefix", "temp", FD, TempPath));
+  StringRef Content("hello there");
+  ASSERT_NO_ERROR(fs::resize_file_before_mapping_readwrite(FD, Content.size()));
+
+  {
+    // Map in the file and write some content.
+    std::error_code EC;
+    fs::mapped_file_region mfr(fs::convertFDToNativeFile(FD),
+                               fs::mapped_file_region::readwrite,
+                               Content.size(), 0, EC);
+    ASSERT_NO_ERROR(EC);
+    ASSERT_EQ(close(FD), 0);
+    std::copy(Content.begin(), Content.end(), mfr.data());
+
+    // Synchronize and check the contents before unmapping.
+    mfr.sync();
+    auto Buffer = MemoryBuffer::getFile(TempPath);
+    ASSERT_TRUE((bool)Buffer);
+    ASSERT_EQ(Content, Buffer->get()->getBuffer());
+  }
+  ASSERT_NO_ERROR(fs::remove(TempPath));
+}
+
 TEST(Support, NormalizePath) {
   //                           Input,        Expected Win, Expected Posix
   using TestTuple = std::tuple<const char *, const char *, const char *>;


        


More information about the llvm-commits mailing list