From 274fe74055f1c753d880ca1a5b52a2455eb32db5 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Tue, 3 Mar 2015 19:22:17 +0100 Subject: [PATCH] Added patches to improve performance by reusing old async IO structure if possible. --- debian/changelog | 1 + ...-async-fileio-structures-if-possible.patch | 62 ++++++++++++++++++ patches/patchinstall.sh | 64 ++++++++++++++----- ...-async-ws2_async_io-structures-if-po.patch | 61 ++++++++++++++++++ 4 files changed, 172 insertions(+), 16 deletions(-) create mode 100644 patches/ntdll-APC_Performance/0001-ntdll-Reuse-old-async-fileio-structures-if-possible.patch create mode 100644 patches/ws2_32-APC_Performance/0001-ws2_32-Reuse-old-async-ws2_async_io-structures-if-po.patch diff --git a/debian/changelog b/debian/changelog index 7b0d556f..ea1a40c2 100644 --- a/debian/changelog +++ b/debian/changelog @@ -33,6 +33,7 @@ wine-staging (1.7.38) UNRELEASED; urgency=low * Added patch to avoid unloading msctf library while textservices are activated. * Added patch to correct DDSCAPS2 and DDSURFACEDESC2 structure (by Amine Khaldi, wine-patched/pull/7). * Added patch to fix crash when trying to switch back to a 16-bit stack. + * Added patches to improve performance by reusing old async IO structure if possible. * Removed patch to properly call DriverUnload when unloading device drivers (accepted upstream). * Removed patch to allow Accept-Encoding for HTTP/1.0 in wininet (accepted upstream). * Removed patch to declare pDirectInputCreateEx in a MSVC compatible way (accepted upstream). diff --git a/patches/ntdll-APC_Performance/0001-ntdll-Reuse-old-async-fileio-structures-if-possible.patch b/patches/ntdll-APC_Performance/0001-ntdll-Reuse-old-async-fileio-structures-if-possible.patch new file mode 100644 index 00000000..8a47aed9 --- /dev/null +++ b/patches/ntdll-APC_Performance/0001-ntdll-Reuse-old-async-fileio-structures-if-possible.patch @@ -0,0 +1,62 @@ +From e9f0a1256a3e1850f5a19bf33f44fafb05caa4e2 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Tue, 3 Mar 2015 03:39:12 +0100 +Subject: ntdll: Reuse old async fileio structures if possible. + +This should speed up apps which heavily rely on async io stuff. Some +tests (using the kernel and ntdll wine tests) show that it is very +often possible to reuse old fileio structures. +--- + dlls/ntdll/file.c | 24 ++++++++++++++++++------ + 1 file changed, 18 insertions(+), 6 deletions(-) + +diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c +index b07e5f9..7b6c2b9 100644 +--- a/dlls/ntdll/file.c ++++ b/dlls/ntdll/file.c +@@ -332,6 +332,7 @@ NTSTATUS WINAPI NtCreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATTRIB + struct async_fileio + { + struct async_fileio *next; ++ DWORD size; + HANDLE handle; + PIO_APC_ROUTINE apc; + void *apc_arg; +@@ -370,17 +371,28 @@ static struct async_fileio *alloc_fileio( DWORD size, HANDLE handle, PIO_APC_ROU + { + /* first free remaining previous fileinfos */ + +- struct async_fileio *io = interlocked_xchg_ptr( (void **)&fileio_freelist, NULL ); ++ struct async_fileio *old_io = interlocked_xchg_ptr( (void **)&fileio_freelist, NULL ); ++ struct async_fileio *io = NULL; + +- while (io) ++ while (old_io) + { +- struct async_fileio *next = io->next; +- RtlFreeHeap( GetProcessHeap(), 0, io ); +- io = next; ++ if (!io && old_io->size >= size && old_io->size <= max(4096, 4 * size)) ++ { ++ io = old_io; ++ size = old_io->size; ++ old_io = old_io->next; ++ } ++ else ++ { ++ struct async_fileio *next = old_io->next; ++ RtlFreeHeap( GetProcessHeap(), 0, old_io ); ++ old_io = next; ++ } + } + +- if ((io = RtlAllocateHeap( GetProcessHeap(), 0, size ))) ++ if (io || (io = RtlAllocateHeap( GetProcessHeap(), 0, size ))) + { ++ io->size = size; + io->handle = handle; + io->apc = apc; + io->apc_arg = arg; +-- +2.3.0 + diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 93a4763a..92fcbaea 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -121,6 +121,7 @@ patch_enable_all () enable_msvcrt_atof_strtod="$1" enable_msvfw32_Image_Size="$1" enable_netprofm_IConnectionPoint="$1" + enable_ntdll_APC_Performance="$1" enable_ntdll_DOS_Attributes="$1" enable_ntdll_DVD_Read_Size="$1" enable_ntdll_DllRedirects="$1" @@ -216,6 +217,7 @@ patch_enable_all () enable_winex11_wglShareLists="$1" enable_winmm_Delay_Import_Depends="$1" enable_wpcap_Dynamic_Linking="$1" + enable_ws2_32_APC_Performance="$1" enable_ws2_32_Connect_Time="$1" enable_ws2_32_WriteWatches="$1" enable_ws2_32_getaddrinfo="$1" @@ -403,6 +405,9 @@ patch_enable () netprofm-IConnectionPoint) enable_netprofm_IConnectionPoint="$2" ;; + ntdll-APC_Performance) + enable_ntdll_APC_Performance="$2" + ;; ntdll-DOS_Attributes) enable_ntdll_DOS_Attributes="$2" ;; @@ -688,6 +693,9 @@ patch_enable () wpcap-Dynamic_Linking) enable_wpcap_Dynamic_Linking="$2" ;; + ws2_32-APC_Performance) + enable_ws2_32_APC_Performance="$2" + ;; ws2_32-Connect_Time) enable_ws2_32_Connect_Time="$2" ;; @@ -2280,6 +2288,22 @@ if test "$enable_kernel32_Console_Handles" -eq 1; then ) >> "$patchlist" fi +# Patchset kernel32-SetFileInformationByHandle +# | +# | Modified files: +# | * dlls/kernel32/file.c, dlls/ntdll/file.c, include/winbase.h, include/winternl.h +# | +if test "$enable_kernel32_SetFileInformationByHandle" -eq 1; then + patch_apply kernel32-SetFileInformationByHandle/0001-ntdll-Define-a-couple-more-information-classes.patch + patch_apply kernel32-SetFileInformationByHandle/0002-include-Declare-a-couple-more-file-information-class.patch + patch_apply kernel32-SetFileInformationByHandle/0003-kernel32-Implement-SetFileInformationByHandle.patch + ( + echo '+ { "Michael Müller", "ntdll: Define a couple more information classes.", 1 },'; + echo '+ { "Michael Müller", "include: Declare a couple more file information class structures.", 1 },'; + echo '+ { "Michael Müller", "kernel32: Implement SetFileInformationByHandle.", 1 },'; + ) >> "$patchlist" +fi + # Patchset ntdll-FileDispositionInformation # | # | This patchset fixes the following Wine bugs: @@ -2299,22 +2323,6 @@ if test "$enable_ntdll_FileDispositionInformation" -eq 1; then ) >> "$patchlist" fi -# Patchset kernel32-SetFileInformationByHandle -# | -# | Modified files: -# | * dlls/kernel32/file.c, dlls/ntdll/file.c, include/winbase.h, include/winternl.h -# | -if test "$enable_kernel32_SetFileInformationByHandle" -eq 1; then - patch_apply kernel32-SetFileInformationByHandle/0001-ntdll-Define-a-couple-more-information-classes.patch - patch_apply kernel32-SetFileInformationByHandle/0002-include-Declare-a-couple-more-file-information-class.patch - patch_apply kernel32-SetFileInformationByHandle/0003-kernel32-Implement-SetFileInformationByHandle.patch - ( - echo '+ { "Michael Müller", "ntdll: Define a couple more information classes.", 1 },'; - echo '+ { "Michael Müller", "include: Declare a couple more file information class structures.", 1 },'; - echo '+ { "Michael Müller", "kernel32: Implement SetFileInformationByHandle.", 1 },'; - ) >> "$patchlist" -fi - # Patchset kernel32-CopyFileEx # | # | This patchset fixes the following Wine bugs: @@ -2640,6 +2648,18 @@ if test "$enable_netprofm_IConnectionPoint" -eq 1; then ) >> "$patchlist" fi +# Patchset ntdll-APC_Performance +# | +# | Modified files: +# | * dlls/ntdll/file.c +# | +if test "$enable_ntdll_APC_Performance" -eq 1; then + patch_apply ntdll-APC_Performance/0001-ntdll-Reuse-old-async-fileio-structures-if-possible.patch + ( + echo '+ { "Sebastian Lackner", "ntdll: Reuse old async fileio structures if possible.", 1 },'; + ) >> "$patchlist" +fi + # Patchset ntdll-DOS_Attributes # | # | This patchset fixes the following Wine bugs: @@ -4205,6 +4225,18 @@ if test "$enable_wpcap_Dynamic_Linking" -eq 1; then ) >> "$patchlist" fi +# Patchset ws2_32-APC_Performance +# | +# | Modified files: +# | * dlls/ws2_32/socket.c +# | +if test "$enable_ws2_32_APC_Performance" -eq 1; then + patch_apply ws2_32-APC_Performance/0001-ws2_32-Reuse-old-async-ws2_async_io-structures-if-po.patch + ( + echo '+ { "Sebastian Lackner", "ws2_32: Reuse old async ws2_async_io structures if possible.", 1 },'; + ) >> "$patchlist" +fi + # Patchset ws2_32-Connect_Time # | # | Modified files: diff --git a/patches/ws2_32-APC_Performance/0001-ws2_32-Reuse-old-async-ws2_async_io-structures-if-po.patch b/patches/ws2_32-APC_Performance/0001-ws2_32-Reuse-old-async-ws2_async_io-structures-if-po.patch new file mode 100644 index 00000000..4ac1086c --- /dev/null +++ b/patches/ws2_32-APC_Performance/0001-ws2_32-Reuse-old-async-ws2_async_io-structures-if-po.patch @@ -0,0 +1,61 @@ +From 1c8b23cabb6ae115226a5adf3e88bdda4ab84776 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Tue, 3 Mar 2015 19:20:40 +0100 +Subject: ws2_32: Reuse old async ws2_async_io structures if possible. + +--- + dlls/ws2_32/socket.c | 27 +++++++++++++++++++++------ + 1 file changed, 21 insertions(+), 6 deletions(-) + +diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c +index 5bfdecf..4538948 100644 +--- a/dlls/ws2_32/socket.c ++++ b/dlls/ws2_32/socket.c +@@ -333,6 +333,7 @@ static inline const char *debugstr_sockaddr( const struct WS_sockaddr *a ) + struct ws2_async_io + { + struct ws2_async_io *next; ++ DWORD size; + }; + + struct ws2_async_shutdown +@@ -394,16 +395,30 @@ static struct ws2_async_io *alloc_async_io( DWORD size ) + { + /* first free remaining previous fileinfos */ + +- struct ws2_async_io *io = interlocked_xchg_ptr( (void **)&async_io_freelist, NULL ); ++ struct ws2_async_io *old_io = interlocked_xchg_ptr( (void **)&async_io_freelist, NULL ); ++ struct ws2_async_io *io = NULL; + +- while (io) ++ while (old_io) + { +- struct ws2_async_io *next = io->next; +- HeapFree( GetProcessHeap(), 0, io ); +- io = next; ++ if (!io && old_io->size >= size && old_io->size <= max(4096, 4 * size)) ++ { ++ io = old_io; ++ size = old_io->size; ++ old_io = old_io->next; ++ } ++ else ++ { ++ struct ws2_async_io *next = old_io->next; ++ HeapFree( GetProcessHeap(), 0, old_io ); ++ old_io = next; ++ } + } + +- return HeapAlloc( GetProcessHeap(), 0, size ); ++ if (io || (io = HeapAlloc( GetProcessHeap(), 0, size ))) ++ { ++ io->size = size; ++ } ++ return io; + } + + /****************************************************************/ +-- +2.3.0 +