From: Akihiro Sagawa Subject: [PATCH 3/4] ntdll: Use our virtual memory counters when using a process handle. Message-Id: <20170604223629.861C.375B48EC@gmail.com> Date: Sun, 04 Jun 2017 22:37:37 +0900 Signed-off-by: Akihiro Sagawa --- dlls/ntdll/process.c | 21 +++++++++++++++++++-- dlls/ntdll/server.c | 10 ++++++++++ include/wine/server_protocol.h | 16 +++++++++++++--- server/process.c | 6 +----- server/protocol.def | 14 ++++++++++++-- server/request.h | 12 +++++------- server/thread.c | 3 +++ server/trace.c | 13 ++++++++++--- 8 files changed, 73 insertions(+), 22 deletions(-) diff --git a/dlls/ntdll/process.c b/dlls/ntdll/process.c index 1d0a703..23b752d 100644 --- a/dlls/ntdll/process.c +++ b/dlls/ntdll/process.c @@ -302,13 +302,30 @@ NTSTATUS WINAPI NtQueryInformationProcess( } else { + apc_call_t call; + apc_result_t result; + + memset( &call, 0, sizeof(call) ); + call.vm_counters.type = APC_VM_COUNTERS; + ret = server_queue_process_apc( ProcessHandle, &call, &result ); + if (ret != STATUS_SUCCESS) break; + + if (result.vm_counters.status == STATUS_SUCCESS) + { + pvmi.PeakVirtualSize = result.vm_counters.peak_virtual_size; + pvmi.VirtualSize = result.vm_counters.virtual_size; + } + else + { + ret = result.vm_counters.status; + break; + } + SERVER_START_REQ(get_process_vm_counters) { req->handle = wine_server_obj_handle( ProcessHandle ); if (!(ret = wine_server_call( req ))) { - pvmi.PeakVirtualSize = reply->peak_virtual_size; - pvmi.VirtualSize = reply->virtual_size; pvmi.PeakWorkingSetSize = reply->peak_working_set_size; pvmi.WorkingSetSize = reply->working_set_size; pvmi.PagefileUsage = reply->pagefile_usage; diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c index c02a12a..0833600 100644 --- a/dlls/ntdll/server.c +++ b/dlls/ntdll/server.c @@ -515,6 +515,16 @@ static BOOL invoke_apc( const apc_call_t *call, apc_result_t *result ) } else result->virtual_unlock.status = STATUS_INVALID_PARAMETER; break; + case APC_VM_COUNTERS: + { + SIZE_T current, peak; + virtual_get_memory_counters( ¤t, &peak ); + result->vm_counters.type = call->type; + result->vm_counters.status = STATUS_SUCCESS; + result->vm_counters.virtual_size = current; + result->vm_counters.peak_virtual_size = peak; + break; + } case APC_MAP_VIEW: result->type = call->type; addr = wine_server_get_ptr( call->map_view.addr ); diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 0d7a7cd..29b2313 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -436,6 +436,7 @@ enum apc_type APC_VIRTUAL_FLUSH, APC_VIRTUAL_LOCK, APC_VIRTUAL_UNLOCK, + APC_VM_COUNTERS, APC_MAP_VIEW, APC_UNMAP_VIEW, APC_CREATE_THREAD @@ -519,6 +520,10 @@ typedef union struct { enum apc_type type; + } vm_counters; + struct + { + enum apc_type type; obj_handle_t handle; client_ptr_t addr; mem_size_t size; @@ -612,6 +617,13 @@ typedef union { enum apc_type type; unsigned int status; + mem_size_t peak_virtual_size; + mem_size_t virtual_size; + } vm_counters; + struct + { + enum apc_type type; + unsigned int status; client_ptr_t addr; mem_size_t size; } map_view; @@ -893,8 +905,6 @@ struct get_process_vm_counters_request struct get_process_vm_counters_reply { struct reply_header __header; - mem_size_t peak_virtual_size; - mem_size_t virtual_size; mem_size_t peak_working_set_size; mem_size_t working_set_size; mem_size_t pagefile_usage; @@ -6418,6 +6428,6 @@ union generic_reply struct terminate_job_reply terminate_job_reply; }; -#define SERVER_PROTOCOL_VERSION 532 +#define SERVER_PROTOCOL_VERSION 533 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/process.c b/server/process.c index 5eabbbe..ac5abe5 100644 --- a/server/process.c +++ b/server/process.c @@ -1389,11 +1389,7 @@ DECL_HANDLER(get_process_vm_counters) { while (fgets( line, sizeof(line), f )) { - if (sscanf( line, "VmPeak: %lu", &value )) - reply->peak_virtual_size = (mem_size_t)value * 1024; - else if (sscanf( line, "VmSize: %lu", &value )) - reply->virtual_size = (mem_size_t)value * 1024; - else if (sscanf( line, "VmHWM: %lu", &value )) + if (sscanf( line, "VmHWM: %lu", &value )) reply->peak_working_set_size = (mem_size_t)value * 1024; else if (sscanf( line, "VmRSS: %lu", &value )) reply->working_set_size = (mem_size_t)value * 1024; diff --git a/server/protocol.def b/server/protocol.def index 7eaaec2..ea5f237 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -452,6 +452,7 @@ enum apc_type APC_VIRTUAL_FLUSH, APC_VIRTUAL_LOCK, APC_VIRTUAL_UNLOCK, + APC_VM_COUNTERS, APC_MAP_VIEW, APC_UNMAP_VIEW, APC_CREATE_THREAD @@ -534,6 +535,10 @@ typedef union } virtual_unlock; struct { + enum apc_type type; /* APC_VM_COUNTERS */ + } vm_counters; + struct + { enum apc_type type; /* APC_MAP_VIEW */ obj_handle_t handle; /* mapping handle */ client_ptr_t addr; /* requested address */ @@ -626,6 +631,13 @@ typedef union } virtual_unlock; struct { + enum apc_type type; /* APC_VM_COUNTERS */ + unsigned int status; /* status returned by call */ + mem_size_t peak_virtual_size; /* peak virtual memory in bytes */ + mem_size_t virtual_size; /* virtual memory in bytes */ + } vm_counters; + struct + { enum apc_type type; /* APC_MAP_VIEW */ unsigned int status; /* status returned by call */ client_ptr_t addr; /* resulting address */ @@ -849,8 +861,6 @@ struct rawinput_device @REQ(get_process_vm_counters) obj_handle_t handle; /* process handle */ @REPLY - mem_size_t peak_virtual_size; /* peak virtual memory in bytes */ - mem_size_t virtual_size; /* virtual memory in bytes */ mem_size_t peak_working_set_size; /* peak real memory in bytes */ mem_size_t working_set_size; /* real memory in bytes */ mem_size_t pagefile_usage; /* commit charge in bytes */ diff --git a/server/request.h b/server/request.h index ad89f30..c21834c 100644 --- a/server/request.h +++ b/server/request.h @@ -800,13 +800,11 @@ C_ASSERT( FIELD_OFFSET(struct get_process_info_reply, debug_children) == 62 ); C_ASSERT( sizeof(struct get_process_info_reply) == 64 ); C_ASSERT( FIELD_OFFSET(struct get_process_vm_counters_request, handle) == 12 ); C_ASSERT( sizeof(struct get_process_vm_counters_request) == 16 ); -C_ASSERT( FIELD_OFFSET(struct get_process_vm_counters_reply, peak_virtual_size) == 8 ); -C_ASSERT( FIELD_OFFSET(struct get_process_vm_counters_reply, virtual_size) == 16 ); -C_ASSERT( FIELD_OFFSET(struct get_process_vm_counters_reply, peak_working_set_size) == 24 ); -C_ASSERT( FIELD_OFFSET(struct get_process_vm_counters_reply, working_set_size) == 32 ); -C_ASSERT( FIELD_OFFSET(struct get_process_vm_counters_reply, pagefile_usage) == 40 ); -C_ASSERT( FIELD_OFFSET(struct get_process_vm_counters_reply, peak_pagefile_usage) == 48 ); -C_ASSERT( sizeof(struct get_process_vm_counters_reply) == 56 ); +C_ASSERT( FIELD_OFFSET(struct get_process_vm_counters_reply, peak_working_set_size) == 8 ); +C_ASSERT( FIELD_OFFSET(struct get_process_vm_counters_reply, working_set_size) == 16 ); +C_ASSERT( FIELD_OFFSET(struct get_process_vm_counters_reply, pagefile_usage) == 24 ); +C_ASSERT( FIELD_OFFSET(struct get_process_vm_counters_reply, peak_pagefile_usage) == 32 ); +C_ASSERT( sizeof(struct get_process_vm_counters_reply) == 40 ); C_ASSERT( FIELD_OFFSET(struct set_process_info_request, handle) == 12 ); C_ASSERT( FIELD_OFFSET(struct set_process_info_request, mask) == 16 ); C_ASSERT( FIELD_OFFSET(struct set_process_info_request, priority) == 20 ); diff --git a/server/thread.c b/server/thread.c index 10a5bf1..0508ec6 100644 --- a/server/thread.c +++ b/server/thread.c @@ -1561,6 +1561,9 @@ DECL_HANDLER(queue_apc) case APC_CREATE_THREAD: process = get_process_from_handle( req->handle, PROCESS_CREATE_THREAD ); break; + case APC_VM_COUNTERS: + process = get_process_from_handle( req->handle, PROCESS_QUERY_LIMITED_INFORMATION ); + break; default: set_error( STATUS_INVALID_PARAMETER ); break; diff --git a/server/trace.c b/server/trace.c index 6e23184..013b06e 100644 --- a/server/trace.c +++ b/server/trace.c @@ -200,6 +200,9 @@ static void dump_apc_call( const char *prefix, const apc_call_t *call ) dump_uint64( "APC_VIRTUAL_UNLOCK,addr=", &call->virtual_unlock.addr ); dump_uint64( ",size=", &call->virtual_unlock.size ); break; + case APC_VM_COUNTERS: + fprintf( stderr, "APC_VM_COUNTERS" ); + break; case APC_MAP_VIEW: fprintf( stderr, "APC_MAP_VIEW,handle=%04x", call->map_view.handle ); dump_uint64( ",addr=", &call->map_view.addr ); @@ -283,6 +286,12 @@ static void dump_apc_result( const char *prefix, const apc_result_t *result ) dump_uint64( ",addr=", &result->virtual_unlock.addr ); dump_uint64( ",size=", &result->virtual_unlock.size ); break; + case APC_VM_COUNTERS: + fprintf( stderr, "APC_VM_COUNTERS,status=%s", + get_status_name( result->vm_counters.status )); + dump_uint64( ",peak_virtual_size=", &result->vm_counters.peak_virtual_size); + dump_uint64( ",virtual_size=", &result->vm_counters.virtual_size); + break; case APC_MAP_VIEW: fprintf( stderr, "APC_MAP_VIEW,status=%s", get_status_name( result->map_view.status )); @@ -1353,9 +1362,7 @@ static void dump_get_process_vm_counters_request( const struct get_process_vm_co static void dump_get_process_vm_counters_reply( const struct get_process_vm_counters_reply *req ) { - dump_uint64( " peak_virtual_size=", &req->peak_virtual_size ); - dump_uint64( ", virtual_size=", &req->virtual_size ); - dump_uint64( ", peak_working_set_size=", &req->peak_working_set_size ); + dump_uint64( " peak_working_set_size=", &req->peak_working_set_size ); dump_uint64( ", working_set_size=", &req->working_set_size ); dump_uint64( ", pagefile_usage=", &req->pagefile_usage ); dump_uint64( ", peak_pagefile_usage=", &req->peak_pagefile_usage ); -- 2.7.4