-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[Support] Add mapped_file_region::sync(), equivalent to msync #153632
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Support] Add mapped_file_region::sync(), equivalent to msync #153632
Conversation
Created using spr 1.3.6
|
@llvm/pr-subscribers-platform-windows @llvm/pr-subscribers-llvm-support Author: Steven Wu (cachemeifyoucan) ChangesAdd mapped_file_region::sync(), equivalent to POSIX msync, This brings back D95494 originally authored by @dexonsmith. Full diff: https://github.com/llvm/llvm-project/pull/153632.diff 4 Files Affected:
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<const char *, const char *, const char *>;
|
|
Link to old review: https://reviews.llvm.org/D95494 |
|
I did some simplification of the original PR. Will be good to have some windows expert to comment.
Some comments from origin PR:
|
I think that it might be a good idea to call |
I agree with Saleem. If we absolutely want to mimic |
Created using spr 1.3.6
|
If we simply want the mmap to be flushed back to the file, which would be mostly likely to the OS cache in RAM, we can just use |
It is going to be used as part of CAS implementation I try to upstream (downstream example: https://github.com/swiftlang/llvm-project/blob/next/llvm/lib/CAS/MappedFileRegionBumpPtr.cpp#L232). It will not be used frequently, just to flush the file if all the users closes the database, to prevent data lost if there is a power lost afterwards. If we don't |
I guess |
|
Hmm, the test is failing on Windows. Can you read the file through IO before memory is unmapped? |
Created using spr 1.3.6
Created using spr 1.3.6
Created using spr 1.3.6
Created using spr 1.3.6
I think this is because of the |
|
The following passes the test: |
Thanks. I don't know the deleteOnClose file will impact reading before the file is closed! I will take your example and update the test with a tweak. I think the better check is to make sure file can be read with correct content before memory region is unmapped. |
Yeah I did change my example after posting it! Your example passes the test. |
Created using spr 1.3.6
Thanks @aganea for the help! Updated. |
You're very welcome! Let me know if you need further help for Windows. |
Add mapped_file_region::sync(), equivalent to POSIX msync,
synchronizing written content to disk without unmapping the region.
This brings back D95494 originally authored by @dexonsmith.