ntdll: make msync() call asynchronous in NtFlushVirtualMemory, take 2

Mathis Beer default_357-line at yahoo.de
Mon Mar 11 20:52:51 CDT 2013


Fixes bug 33146. Path of Exile's updater runs extremely slow (factor of 1000 compared to Windows) due to frequent FlushViewOfFile calls. FlushViewOfFile calls NtFlushVirtualMemory, which calls msync with MS_SYNC. FlushViewOfFile is the only function that calls NtFlushVirtualMemory in Wine, and is specified in the MSDN as asynchronous (http://msdn.microsoft.com/en-us/library/windows/desktop/aa366563%28v=vs.85%29.aspx ).

> The FlushViewOfFile function does not flush the file metadata, and it does not wait to return until the changes are flushed from the underlying hardware disk cache and physically written to disk.

As such, this patch changes msync to be called asynchronously. It also avoids redefining a preexisting header constant to a different value, instead checking for the presence of the header that contains it and calling msync with zero otherwise.

---
 dlls/ntdll/virtual.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index a99bca4..e66dcae 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -58,10 +58,6 @@
 WINE_DEFAULT_DEBUG_CHANNEL(virtual);
 WINE_DECLARE_DEBUG_CHANNEL(module);
 
-#ifndef MS_SYNC
-#define MS_SYNC 0
-#endif
-
 #ifndef MAP_NORESERVE
 #define MAP_NORESERVE 0
 #endif
@@ -2752,6 +2748,7 @@ NTSTATUS WINAPI NtFlushVirtualMemory( HANDLE process, LPCVOID *addr_ptr,
     NTSTATUS status = STATUS_SUCCESS;
     sigset_t sigset;
     void *addr = ROUND_ADDR( *addr_ptr, page_mask );
+    int msync_flags = 0;
 
     if (process != NtCurrentProcess())
     {
@@ -2780,7 +2777,10 @@ NTSTATUS WINAPI NtFlushVirtualMemory( HANDLE process, LPCVOID *addr_ptr,
     {
         if (!*size_ptr) *size_ptr = view->size;
         *addr_ptr = addr;
-        if (msync( addr, *size_ptr, MS_SYNC )) status = STATUS_NOT_MAPPED_DATA;
+#ifdef HAVE_SYS_MMAN_H
+        msync_flags |= MS_ASYNC;
+#endif
+        if (msync( addr, *size_ptr, msync_flags )) status = STATUS_NOT_MAPPED_DATA;
     }
     server_leave_uninterrupted_section( &csVirtual, &sigset );
     return status;
-- 
1.7.12


-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-Fix-bug-33146.-Call-msync-with-MS_ASYNC-not-MS_SYNC-.patch
Type: text/x-patch
Size: 1502 bytes
Desc: not available
URL: <http://www.winehq.org/pipermail/wine-patches/attachments/20130312/43d1495c/attachment.bin>


More information about the wine-patches mailing list