[PATCH 2/4] ntdll: Provide more accurate virtual memory counters.
Akihiro Sagawa
sagawa.aki at gmail.com
Sun Jun 4 08:37:36 CDT 2017
Current approach is less accurate because VmSize from /proc/self/status
contains Wine's reserved area by mmap(2). Thus, the counter doesn't reflect
VirtualAlloc()/VirtualFree() simultaneously.
This approach is keeping process own VM counters inside ntdll.dll. So, we can
provide more accurate values for Windows applications. To avoid wineserver
round-trip overheads when allocating, it is implemented as variables in
dlls/ntdll/virtual.c.
Signed-off-by: Akihiro Sagawa <sagawa.aki at gmail.com>
---
dlls/ntdll/ntdll_misc.h | 1 +
dlls/ntdll/process.c | 18 ++++++++++++------
dlls/ntdll/tests/info.c | 2 +-
dlls/ntdll/virtual.c | 41 ++++++++++++++++++++++++++++++++++++++++-
4 files changed, 54 insertions(+), 8 deletions(-)
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index 5e4c39e..aa385af 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -162,6 +162,7 @@ extern NTSTATUS nt_to_unix_file_name_attr( const OBJECT_ATTRIBUTES *attr, ANSI_S
/* virtual memory */
extern void virtual_get_system_info( SYSTEM_BASIC_INFORMATION *info ) DECLSPEC_HIDDEN;
+extern void virtual_get_memory_counters( SIZE_T *current, SIZE_T *peak ) DECLSPEC_HIDDEN;
extern NTSTATUS virtual_create_builtin_view( void *base ) DECLSPEC_HIDDEN;
extern NTSTATUS virtual_alloc_thread_stack( TEB *teb, SIZE_T reserve_size, SIZE_T commit_size ) DECLSPEC_HIDDEN;
extern void virtual_clear_thread_stack(void) DECLSPEC_HIDDEN;
diff --git a/dlls/ntdll/process.c b/dlls/ntdll/process.c
index f615ce2..1d0a703 100644
--- a/dlls/ntdll/process.c
+++ b/dlls/ntdll/process.c
@@ -123,7 +123,6 @@ static void fill_VM_COUNTERS(VM_COUNTERS* pvmi)
mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT;
if(task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)&info, &infoCount) == KERN_SUCCESS)
{
- pvmi->VirtualSize = info.resident_size + info.virtual_size;
pvmi->PagefileUsage = info.virtual_size;
pvmi->WorkingSetSize = info.resident_size;
pvmi->PeakWorkingSetSize = info.resident_size_max;
@@ -144,11 +143,7 @@ static void fill_VM_COUNTERS(VM_COUNTERS* pvmi)
while (fgets(line, sizeof(line), f))
{
- if (sscanf(line, "VmPeak: %lu", &value))
- pvmi->PeakVirtualSize = (ULONG64)value * 1024;
- else if (sscanf(line, "VmSize: %lu", &value))
- pvmi->VirtualSize = (ULONG64)value * 1024;
- else if (sscanf(line, "VmHWM: %lu", &value))
+ if (sscanf(line, "VmHWM: %lu", &value))
pvmi->PeakWorkingSetSize = (ULONG64)value * 1024;
else if (sscanf(line, "VmRSS: %lu", &value))
pvmi->WorkingSetSize = (ULONG64)value * 1024;
@@ -301,7 +296,10 @@ NTSTATUS WINAPI NtQueryInformationProcess(
{
memset(&pvmi, 0 , sizeof(VM_COUNTERS));
if (ProcessHandle == GetCurrentProcess())
+ {
+ virtual_get_memory_counters(&pvmi.VirtualSize, &pvmi.PeakVirtualSize);
fill_VM_COUNTERS(&pvmi);
+ }
else
{
SERVER_START_REQ(get_process_vm_counters)
@@ -320,6 +318,14 @@ NTSTATUS WINAPI NtQueryInformationProcess(
SERVER_END_REQ;
if (ret) break;
}
+ if (pvmi.PeakWorkingSetSize > pvmi.PeakVirtualSize)
+ pvmi.PeakWorkingSetSize = pvmi.PeakVirtualSize;
+ if (pvmi.WorkingSetSize > pvmi.VirtualSize)
+ pvmi.WorkingSetSize = pvmi.VirtualSize;
+ if (pvmi.PagefileUsage > pvmi.VirtualSize)
+ pvmi.PagefileUsage = pvmi.VirtualSize;
+ if (pvmi.PeakPagefileUsage > pvmi.PeakVirtualSize)
+ pvmi.PeakPagefileUsage = pvmi.PeakVirtualSize;
len = ProcessInformationLength;
if (len != FIELD_OFFSET(VM_COUNTERS,PrivatePageCount)) len = sizeof(VM_COUNTERS);
diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c
index 4198d9c..5e42045 100644
--- a/dlls/ntdll/tests/info.c
+++ b/dlls/ntdll/tests/info.c
@@ -1135,7 +1135,7 @@ static void test_query_process_vm(void)
ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
if (winetest_debug > 1)
dump_vm_counters("VM counters after VirtualAlloc", &pvi);
- todo_wine ok( pvi.VirtualSize >= prev_size + alloc_size,
+ ok( pvi.VirtualSize >= prev_size + alloc_size,
"Expected to be greater than %lu, got %lu\n", prev_size + alloc_size, pvi.VirtualSize);
VirtualFree( ptr, 0, MEM_RELEASE);
}
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index e826fa0..d19d31b 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -108,6 +108,10 @@ static RTL_CRITICAL_SECTION_DEBUG critsect_debug =
0, 0, { (DWORD_PTR)(__FILE__ ": csVirtual") }
};
static RTL_CRITICAL_SECTION csVirtual = { &critsect_debug, -1, 0, 0, 0, 0 };
+static struct {
+ SIZE_T size;
+ SIZE_T peak;
+} vm_counters;
#ifdef __i386__
static const UINT page_shift = 12;
@@ -438,7 +442,13 @@ static inline void unmap_area( void *addr, size_t size )
*/
static void delete_view( struct file_view *view ) /* [in] View */
{
- if (!(view->protect & VPROT_SYSTEM)) unmap_area( view->base, view->size );
+ if (!(view->protect & VPROT_SYSTEM))
+ {
+ unmap_area( view->base, view->size );
+
+ /* Decrement VM counters */
+ vm_counters.size -= view->size;
+ }
list_remove( &view->entry );
if (view->mapping) close_handle( view->mapping );
RtlFreeHeap( virtual_heap, 0, view );
@@ -512,6 +522,15 @@ static NTSTATUS create_view( struct file_view **view_ret, void *base, size_t siz
}
}
+ /* Increment VM counters */
+
+ if (!(vprot & VPROT_SYSTEM))
+ {
+ vm_counters.size += size;
+ if (vm_counters.peak < vm_counters.size)
+ vm_counters.peak = vm_counters.size;
+ }
+
*view_ret = view;
VIRTUAL_DEBUG_DUMP_VIEW( view );
@@ -1385,6 +1404,26 @@ void virtual_get_system_info( SYSTEM_BASIC_INFORMATION *info )
/***********************************************************************
+ * virtual_get_memory_counters
+ */
+void virtual_get_memory_counters( SIZE_T *current, SIZE_T *peak )
+{
+ sigset_t sigset;
+ server_enter_uninterrupted_section( &csVirtual, &sigset );
+
+ *current = min(vm_counters.size, (SIZE_T)user_space_limit);
+ *peak = min(vm_counters.peak, (SIZE_T)user_space_limit);
+
+ server_leave_uninterrupted_section( &csVirtual, &sigset );
+
+ TRACE("current=%s, peak=%s\n",
+ wine_dbgstr_longlong((ULONGLONG)*current),
+ wine_dbgstr_longlong((ULONGLONG)*peak));
+
+}
+
+
+/***********************************************************************
* virtual_create_builtin_view
*/
NTSTATUS virtual_create_builtin_view( void *module )
--
2.7.4
More information about the wine-patches
mailing list