| author | |
| committer | |
| log | 3aa0a7ecdf3f88d0d37e20c88bf57b69355573fe |
| tree | 42324dba8b76601f7d30a5270b28fa7763873bbc |
| parent | dcdb878360045ec50fc0cc6fda0f970150567182 |
| parent | 8f4548dd69de3a1c1f5c14cdf6b2e7052ea5079f |
| signature |
Implement getMaxRss for Windows3 files changed, 108 insertions(+), 0 deletions(-)
lib/std/child_process.zig+13| ... | @@ -99,12 +99,20 @@ pub const ChildProcess = struct { | ... | @@ -99,12 +99,20 @@ pub const ChildProcess = struct { |
| 99 | return null; | 99 | return null; |
| 100 | } | 100 | } |
| 101 | }, | 101 | }, |
| 102 | .windows => { | ||
| 103 | if (rus.rusage) |ru| { | ||
| 104 | return ru.PeakWorkingSetSize; | ||
| 105 | } else { | ||
| 106 | return null; | ||
| 107 | } | ||
| 108 | }, | ||
| 102 | else => return null, | 109 | else => return null, |
| 103 | } | 110 | } |
| 104 | } | 111 | } |
| 105 | 112 | ||
| 106 | const rusage_init = switch (builtin.os.tag) { | 113 | const rusage_init = switch (builtin.os.tag) { |
| 107 | .linux => @as(?std.os.rusage, null), | 114 | .linux => @as(?std.os.rusage, null), |
| 115 | .windows => @as(?windows.VM_COUNTERS, null), | ||
| 108 | else => {}, | 116 | else => {}, |
| 109 | }; | 117 | }; |
| 110 | }; | 118 | }; |
| ... | @@ -129,6 +137,7 @@ pub const ChildProcess = struct { | ... | @@ -129,6 +137,7 @@ pub const ChildProcess = struct { |
| 129 | os.SetIdError || | 137 | os.SetIdError || |
| 130 | os.ChangeCurDirError || | 138 | os.ChangeCurDirError || |
| 131 | windows.CreateProcessError || | 139 | windows.CreateProcessError || |
| 140 | windows.GetProcessMemoryInfoError || | ||
| 132 | windows.WaitForSingleObjectError; | 141 | windows.WaitForSingleObjectError; |
| 133 | 142 | ||
| 134 | pub const Term = union(enum) { | 143 | pub const Term = union(enum) { |
| ... | @@ -364,6 +373,10 @@ pub const ChildProcess = struct { | ... | @@ -364,6 +373,10 @@ pub const ChildProcess = struct { |
| 364 | } | 373 | } |
| 365 | }); | 374 | }); |
| 366 | 375 | ||
| 376 | if (self.request_resource_usage_statistics) { | ||
| 377 | self.resource_usage_statistics.rusage = try windows.GetProcessMemoryInfo(self.id); | ||
| 378 | } | ||
| 379 | |||
| 367 | os.close(self.id); | 380 | os.close(self.id); |
| 368 | os.close(self.thread_handle); | 381 | os.close(self.thread_handle); |
| 369 | self.cleanupStreams(); | 382 | self.cleanupStreams(); |
lib/std/os/windows.zig+32| ... | @@ -3947,6 +3947,20 @@ pub const PSAPI_WS_WATCH_INFORMATION = extern struct { | ... | @@ -3947,6 +3947,20 @@ pub const PSAPI_WS_WATCH_INFORMATION = extern struct { |
| 3947 | FaultingVa: LPVOID, | 3947 | FaultingVa: LPVOID, |
| 3948 | }; | 3948 | }; |
| 3949 | 3949 | ||
| 3950 | pub const VM_COUNTERS = extern struct { | ||
| 3951 | PeakVirtualSize: SIZE_T, | ||
| 3952 | VirtualSize: SIZE_T, | ||
| 3953 | PageFaultCount: ULONG, | ||
| 3954 | PeakWorkingSetSize: SIZE_T, | ||
| 3955 | WorkingSetSize: SIZE_T, | ||
| 3956 | QuotaPeakPagedPoolUsage: SIZE_T, | ||
| 3957 | QuotaPagedPoolUsage: SIZE_T, | ||
| 3958 | QuotaPeakNonPagedPoolUsage: SIZE_T, | ||
| 3959 | QuotaNonPagedPoolUsage: SIZE_T, | ||
| 3960 | PagefileUsage: SIZE_T, | ||
| 3961 | PeakPagefileUsage: SIZE_T, | ||
| 3962 | }; | ||
| 3963 | |||
| 3950 | pub const PROCESS_MEMORY_COUNTERS = extern struct { | 3964 | pub const PROCESS_MEMORY_COUNTERS = extern struct { |
| 3951 | cb: DWORD, | 3965 | cb: DWORD, |
| 3952 | PageFaultCount: DWORD, | 3966 | PageFaultCount: DWORD, |
| ... | @@ -3974,6 +3988,24 @@ pub const PROCESS_MEMORY_COUNTERS_EX = extern struct { | ... | @@ -3974,6 +3988,24 @@ pub const PROCESS_MEMORY_COUNTERS_EX = extern struct { |
| 3974 | PrivateUsage: SIZE_T, | 3988 | PrivateUsage: SIZE_T, |
| 3975 | }; | 3989 | }; |
| 3976 | 3990 | ||
| 3991 | pub const GetProcessMemoryInfoError = error{ | ||
| 3992 | AccessDenied, | ||
| 3993 | InvalidHandle, | ||
| 3994 | Unexpected, | ||
| 3995 | }; | ||
| 3996 | |||
| 3997 | pub fn GetProcessMemoryInfo(hProcess: HANDLE) GetProcessMemoryInfoError!VM_COUNTERS { | ||
| 3998 | var vmc: VM_COUNTERS = undefined; | ||
| 3999 | const rc = ntdll.NtQueryInformationProcess(hProcess, .ProcessVmCounters, &vmc, @sizeOf(VM_COUNTERS), null); | ||
| 4000 | switch (rc) { | ||
| 4001 | .SUCCESS => return vmc, | ||
| 4002 | .ACCESS_DENIED => return error.AccessDenied, | ||
| 4003 | .INVALID_HANDLE => return error.InvalidHandle, | ||
| 4004 | .INVALID_PARAMETER => unreachable, | ||
| 4005 | else => return unexpectedStatus(rc), | ||
| 4006 | } | ||
| 4007 | } | ||
| 4008 | |||
| 3977 | pub const PERFORMANCE_INFORMATION = extern struct { | 4009 | pub const PERFORMANCE_INFORMATION = extern struct { |
| 3978 | cb: DWORD, | 4010 | cb: DWORD, |
| 3979 | CommitTotal: SIZE_T, | 4011 | CommitTotal: SIZE_T, |
lib/std/os/windows/ntdll.zig+63| ... | @@ -32,6 +32,69 @@ const RUNTIME_FUNCTION = windows.RUNTIME_FUNCTION; | ... | @@ -32,6 +32,69 @@ const RUNTIME_FUNCTION = windows.RUNTIME_FUNCTION; |
| 32 | const KNONVOLATILE_CONTEXT_POINTERS = windows.KNONVOLATILE_CONTEXT_POINTERS; | 32 | const KNONVOLATILE_CONTEXT_POINTERS = windows.KNONVOLATILE_CONTEXT_POINTERS; |
| 33 | const EXCEPTION_ROUTINE = windows.EXCEPTION_ROUTINE; | 33 | const EXCEPTION_ROUTINE = windows.EXCEPTION_ROUTINE; |
| 34 | 34 | ||
| 35 | pub const PROCESSINFOCLASS = enum(c_int) { | ||
| 36 | ProcessBasicInformation, | ||
| 37 | ProcessQuotaLimits, | ||
| 38 | ProcessIoCounters, | ||
| 39 | ProcessVmCounters, | ||
| 40 | ProcessTimes, | ||
| 41 | ProcessBasePriority, | ||
| 42 | ProcessRaisePriority, | ||
| 43 | ProcessDebugPort, | ||
| 44 | ProcessExceptionPort, | ||
| 45 | ProcessAccessToken, | ||
| 46 | ProcessLdtInformation, | ||
| 47 | ProcessLdtSize, | ||
| 48 | ProcessDefaultHardErrorMode, | ||
| 49 | ProcessIoPortHandlers, | ||
| 50 | ProcessPooledUsageAndLimits, | ||
| 51 | ProcessWorkingSetWatch, | ||
| 52 | ProcessUserModeIOPL, | ||
| 53 | ProcessEnableAlignmentFaultFixup, | ||
| 54 | ProcessPriorityClass, | ||
| 55 | ProcessWx86Information, | ||
| 56 | ProcessHandleCount, | ||
| 57 | ProcessAffinityMask, | ||
| 58 | ProcessPriorityBoost, | ||
| 59 | ProcessDeviceMap, | ||
| 60 | ProcessSessionInformation, | ||
| 61 | ProcessForegroundInformation, | ||
| 62 | ProcessWow64Information, | ||
| 63 | ProcessImageFileName, | ||
| 64 | ProcessLUIDDeviceMapsEnabled, | ||
| 65 | ProcessBreakOnTermination, | ||
| 66 | ProcessDebugObjectHandle, | ||
| 67 | ProcessDebugFlags, | ||
| 68 | ProcessHandleTracing, | ||
| 69 | ProcessIoPriority, | ||
| 70 | ProcessExecuteFlags, | ||
| 71 | ProcessTlsInformation, | ||
| 72 | ProcessCookie, | ||
| 73 | ProcessImageInformation, | ||
| 74 | ProcessCycleTime, | ||
| 75 | ProcessPagePriority, | ||
| 76 | ProcessInstrumentationCallback, | ||
| 77 | ProcessThreadStackAllocation, | ||
| 78 | ProcessWorkingSetWatchEx, | ||
| 79 | ProcessImageFileNameWin32, | ||
| 80 | ProcessImageFileMapping, | ||
| 81 | ProcessAffinityUpdateMode, | ||
| 82 | ProcessMemoryAllocationMode, | ||
| 83 | ProcessGroupInformation, | ||
| 84 | ProcessTokenVirtualizationEnabled, | ||
| 85 | ProcessConsoleHostProcess, | ||
| 86 | ProcessWindowInformation, | ||
| 87 | MaxProcessInfoClass, | ||
| 88 | }; | ||
| 89 | |||
| 90 | pub extern "ntdll" fn NtQueryInformationProcess( | ||
| 91 | ProcessHandle: HANDLE, | ||
| 92 | ProcessInformationClass: PROCESSINFOCLASS, | ||
| 93 | ProcessInformation: *anyopaque, | ||
| 94 | ProcessInformationLength: ULONG, | ||
| 95 | ReturnLength: ?*ULONG, | ||
| 96 | ) callconv(WINAPI) NTSTATUS; | ||
| 97 | |||
| 35 | pub const THREADINFOCLASS = enum(c_int) { | 98 | pub const THREADINFOCLASS = enum(c_int) { |
| 36 | ThreadBasicInformation, | 99 | ThreadBasicInformation, |
| 37 | ThreadTimes, | 100 | ThreadTimes, |