Skip to content

Instantly share code, notes, and snippets.

@baryluk
Last active August 26, 2025 15:40
Show Gist options
  • Save baryluk/943cfafc8e3dc8d8a9c882e2e42d17fb to your computer and use it in GitHub Desktop.
Save baryluk/943cfafc8e3dc8d8a9c882e2e42d17fb to your computer and use it in GitHub Desktop.
Remove support for NtQueryVirtualMemory(MemoryWorkingSetExInformation) to help with Apex Legends / EAC stutter every 30 seconds. wine 7.x
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
index 550d7f41dec..e9c2f974c1f 100644
--- a/dlls/ntdll/unix/virtual.c
+++ b/dlls/ntdll/unix/virtual.c
@@ -32,6 +32,7 @@
#include <string.h>
#include <stdlib.h>
#include <signal.h>
+#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
@@ -4397,9 +4398,20 @@ static NTSTATUS get_working_set_ex( HANDLE process, LPCVOID addr,
MEMORY_WORKING_SET_EX_INFORMATION *info,
SIZE_T len, SIZE_T *res_len )
{
- FILE *f = NULL;
MEMORY_WORKING_SET_EX_INFORMATION *p;
+#if defined(HAVE_LIBPROCSTAT)
sigset_t sigset;
+#else
+ FILE *f = NULL;
+#endif
+#if defined(WITEK_DEBUG)
+ struct timespec tp_prestart;
+ struct timespec tp_start;
+ struct timespec tp_end;
+ struct timespec tp_lock_start;
+ struct timespec tp_lock_end;
+ int loop_count = 0;
+#endif
if (process != NtCurrentProcess())
{
@@ -4458,7 +4470,12 @@ static NTSTATUS get_working_set_ex( HANDLE process, LPCVOID addr,
if (pstat)
procstat_close( pstat );
}
-#else
+#elif defined(USE_REAL_PAGEMAP)
+#if defined(WITEK_DEBUG)
+ clock_gettime(CLOCK_MONOTONIC, &tp_prestart);
+ fprintf(stderr, "%d.%09d get_working_set_ex: start len=%d\n", tp_prestart.tv_sec, tp_prestart.tv_nsec, len);
+ clock_gettime(CLOCK_MONOTONIC, &tp_start);
+#endif
f = fopen( "/proc/self/pagemap", "rb" );
if (!f)
{
@@ -4466,12 +4483,17 @@ static NTSTATUS get_working_set_ex( HANDLE process, LPCVOID addr,
if (!once++) WARN( "unable to open /proc/self/pagemap\n" );
}
+ clock_gettime(CLOCK_MONOTONIC, &tp_lock_start);
server_enter_uninterrupted_section( &virtual_mutex, &sigset );
+ clock_gettime(CLOCK_MONOTONIC, &tp_lock_end);
for (p = info; (UINT_PTR)(p + 1) <= (UINT_PTR)info + len; p++)
{
BYTE vprot;
UINT64 pagemap;
struct file_view *view;
+#if defined(WITEK_DEBUG)
+ loop_count++;
+#endif
memset( &p->VirtualAttributes, 0, sizeof(p->VirtualAttributes) );
@@ -4495,12 +4517,24 @@ static NTSTATUS get_working_set_ex( HANDLE process, LPCVOID addr,
}
}
server_leave_uninterrupted_section( &virtual_mutex, &sigset );
+
+ fclose( f );
+#if defined(WITEK_DEBUG)
+ clock_gettime(CLOCK_MONOTONIC, &tp_end);
+ fprintf(stderr, "%d.%09d get_working_set_ex: finished in %.3f ms it took %.3f ms to enter uninterrupted section , loop_count %d\n",
+ tp_end.tv_sec, tp_end.tv_nsec,
+ ((tp_end.tv_sec - tp_start.tv_sec)*1.0 + (tp_end.tv_nsec - tp_start.tv_nsec)*1.0e-9)*1.0e3,
+ ((tp_lock_end.tv_sec - tp_lock_start.tv_sec)*1.0 + (tp_lock_end.tv_nsec - tp_lock_start.tv_nsec)*1.0e-9)*1.0e3,
+ loop_count);
+#endif
+#else
+ /* fake */
+ p = info;
#endif
- if (f)
- fclose( f );
if (res_len)
*res_len = (UINT_PTR)p - (UINT_PTR)info;
+
return STATUS_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment