From 31a738ee49832a4be11b6dc87c936764eecdbe81 Mon Sep 17 00:00:00 2001 From: Steven Wu Date: Thu, 14 Aug 2025 10:45:08 -0700 Subject: [PATCH 1/2] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20in?= =?UTF-8?q?itial=20version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created using spr 1.3.6 --- llvm/include/llvm/Support/FileSystem.h | 3 +++ llvm/lib/Support/Unix/Path.inc | 6 ++++++ llvm/lib/Support/Windows/Path.inc | 6 ++++++ llvm/unittests/Support/Path.cpp | 26 ++++++++++++++++++++++++++ 4 files changed, 41 insertions(+) diff --git a/llvm/include/llvm/Support/FileSystem.h b/llvm/include/llvm/Support/FileSystem.h index 31fedc37bf776..b66b3e66018ef 100644 --- a/llvm/include/llvm/Support/FileSystem.h +++ b/llvm/include/llvm/Support/FileSystem.h @@ -1342,6 +1342,9 @@ class mapped_file_region { LLVM_ABI size_t size() const; LLVM_ABI char *data() const; + /// Write changes to disk and synchronize. Equivalent to POSIX msync. + LLVM_ABI std::error_code sync() const; + /// Get a const view of the data. Modifying this memory has undefined /// behavior. LLVM_ABI const char *const_data() const; diff --git a/llvm/lib/Support/Unix/Path.inc b/llvm/lib/Support/Unix/Path.inc index cc02cae40ec76..31fb1e8fe9b75 100644 --- a/llvm/lib/Support/Unix/Path.inc +++ b/llvm/lib/Support/Unix/Path.inc @@ -876,6 +876,12 @@ void mapped_file_region::unmapImpl() { ::munmap(Mapping, Size); } +std::error_code mapped_file_region::sync() const { + if (int Res = ::msync(Mapping, Size, MS_SYNC)) + return std::error_code(Res, std::generic_category()); + return std::error_code(); +} + void mapped_file_region::dontNeedImpl() { assert(Mode == mapped_file_region::readonly); if (!Mapping) diff --git a/llvm/lib/Support/Windows/Path.inc b/llvm/lib/Support/Windows/Path.inc index fdf9d540a6488..f3db7196ffdb8 100644 --- a/llvm/lib/Support/Windows/Path.inc +++ b/llvm/lib/Support/Windows/Path.inc @@ -1006,6 +1006,12 @@ void mapped_file_region::unmapImpl() { void mapped_file_region::dontNeedImpl() {} +std::error_code mapped_file_region::sync() const { + if (::FlushViewOfFile(Mapping, 0)) + return std::error_code(); + return mapWindowsError(::GetLastError()); +} + 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 355aa6b9ade06..552c9f339166d 100644 --- a/llvm/unittests/Support/Path.cpp +++ b/llvm/unittests/Support/Path.cpp @@ -1471,6 +1471,32 @@ TEST_F(FileSystemTest, FileMapping) { ASSERT_NO_ERROR(fs::remove(TempPath)); } +TEST_F(FileSystemTest, FileMappingSync) { + // Create a temp file. + auto TempFileOrError = fs::TempFile::create(TestDirectory + "/test-%%%%"); + ASSERT_TRUE((bool)TempFileOrError); + fs::TempFile File = std::move(*TempFileOrError); + StringRef Content("hello there"); + ASSERT_NO_ERROR( + fs::resize_file_before_mapping_readwrite(File.FD, Content.size())); + { + // Map in the file and write some content. + std::error_code EC; + fs::mapped_file_region MFR(fs::convertFDToNativeFile(File.FD), + fs::mapped_file_region::readwrite, + Content.size(), 0, EC); + ASSERT_NO_ERROR(EC); + std::copy(Content.begin(), Content.end(), MFR.data()); + + // Synchronize and check the contents before unmapping. + MFR.sync(); + auto Buffer = MemoryBuffer::getFile(File.TmpName); + ASSERT_TRUE((bool)Buffer); + ASSERT_EQ(Content, Buffer->get()->getBuffer()); + } + ASSERT_FALSE((bool)File.discard()); +} + TEST(Support, NormalizePath) { // Input, Expected Win, Expected Posix using TestTuple = std::tuple; From a03db21b154703451558f15b57173c44f7a6dd12 Mon Sep 17 00:00:00 2001 From: Steven Wu Date: Thu, 14 Aug 2025 11:38:35 -0700 Subject: [PATCH 2/2] address review feedback Created using spr 1.3.6 --- llvm/lib/Support/Windows/Path.inc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Support/Windows/Path.inc b/llvm/lib/Support/Windows/Path.inc index f3db7196ffdb8..9001c19c057cf 100644 --- a/llvm/lib/Support/Windows/Path.inc +++ b/llvm/lib/Support/Windows/Path.inc @@ -1007,9 +1007,11 @@ void mapped_file_region::unmapImpl() { void mapped_file_region::dontNeedImpl() {} std::error_code mapped_file_region::sync() const { - if (::FlushViewOfFile(Mapping, 0)) - return std::error_code(); - return mapWindowsError(::GetLastError()); + if (!::FlushViewOfFile(Mapping, Size)) + return mapWindowsError(GetLastError()); + if (!::FlushFileBuffers(FileHandle)) + return mapWindowsError(GetLastError()); + return std::error_code(); } int mapped_file_region::alignment() {