authorgravatar for egoist@egoistic.devxEgoist <egoist@egoistic.dev> 2023-04-12 18:22:07-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-04-14 13:43:03-04:00
log0733c8c5ca03f55fe8f65f74cea89dfccf6079b4
tree1d941f7b9845f860304cfd4a9fd12be59e7b880a
parent7b908e173fa6034dc92e6b73c4264dc44706bd32

windows: replace GetPhysicallyInstalledSystemMemory with ntdll.

`GetPhysicallyInstalledSystemMemory` uses SMBios to grab the physical memory size which can lead to unecessary allocation and inacurate representation of the total memory. Using `System_Basic_Information` help to retrieve the physical memory which is not reserved for the kernel/tables. This aligns better with the linux side as `/proc/meminfo` does the same thing.

3 files changed, 47 insertions(+), 3 deletions(-)

lib/std/os/windows.zig+28
...@@ -4476,6 +4476,34 @@ pub const MODULEENTRY32 = extern struct {...@@ -4476,6 +4476,34 @@ pub const MODULEENTRY32 = extern struct {
4476 szExePath: [MAX_PATH]CHAR,4476 szExePath: [MAX_PATH]CHAR,
4477};4477};
44784478
4479pub const SYSTEM_INFORMATION_CLASS = enum(c_int) {
4480 SystemBasicInformation = 0,
4481 SystemPerformanceInformation = 2,
4482 SystemTimeOfDayInformation = 3,
4483 SystemProcessInformation = 5,
4484 SystemProcessorPerformanceInformation = 8,
4485 SystemInterruptInformation = 23,
4486 SystemExceptionInformation = 33,
4487 SystemRegistryQuotaInformation = 37,
4488 SystemLookasideInformation = 45,
4489 SystemCodeIntegrityInformation = 103,
4490 SystemPolicyInformation = 134,
4491};
4492
4493pub const SYSTEM_BASIC_INFORMATION = extern struct {
4494 Reserved: ULONG,
4495 TimerResolution: ULONG,
4496 PageSize: ULONG,
4497 NumberOfPhysicalPages: ULONG,
4498 LowestPhysicalPageNumber: ULONG,
4499 HighestPhysicalPageNumber: ULONG,
4500 AllocationGranularity: ULONG,
4501 MinimumUserModeAddress: ULONG_PTR,
4502 MaximumUserModeAddress: ULONG_PTR,
4503 ActiveProcessorsAffinityMask: KAFFINITY,
4504 NumberOfProcessors: UCHAR,
4505};
4506
4479pub const THREADINFOCLASS = enum(c_int) {4507pub const THREADINFOCLASS = enum(c_int) {
4480 ThreadBasicInformation,4508 ThreadBasicInformation,
4481 ThreadTimes,4509 ThreadTimes,
lib/std/os/windows/ntdll.zig+9
...@@ -31,6 +31,7 @@ const UNWIND_HISTORY_TABLE = windows.UNWIND_HISTORY_TABLE;...@@ -31,6 +31,7 @@ const UNWIND_HISTORY_TABLE = windows.UNWIND_HISTORY_TABLE;
31const RUNTIME_FUNCTION = windows.RUNTIME_FUNCTION;31const RUNTIME_FUNCTION = windows.RUNTIME_FUNCTION;
32const KNONVOLATILE_CONTEXT_POINTERS = windows.KNONVOLATILE_CONTEXT_POINTERS;32const KNONVOLATILE_CONTEXT_POINTERS = windows.KNONVOLATILE_CONTEXT_POINTERS;
33const EXCEPTION_ROUTINE = windows.EXCEPTION_ROUTINE;33const EXCEPTION_ROUTINE = windows.EXCEPTION_ROUTINE;
34const SYSTEM_INFORMATION_CLASS = windows.SYSTEM_INFORMATION_CLASS;
34const THREADINFOCLASS = windows.THREADINFOCLASS;35const THREADINFOCLASS = windows.THREADINFOCLASS;
35const PROCESSINFOCLASS = windows.PROCESSINFOCLASS;36const PROCESSINFOCLASS = windows.PROCESSINFOCLASS;
36const LPVOID = windows.LPVOID;37const LPVOID = windows.LPVOID;
...@@ -51,6 +52,14 @@ pub extern "ntdll" fn NtQueryInformationThread(...@@ -51,6 +52,14 @@ pub extern "ntdll" fn NtQueryInformationThread(
51 ThreadInformationLength: ULONG,52 ThreadInformationLength: ULONG,
52 ReturnLength: ?*ULONG,53 ReturnLength: ?*ULONG,
53) callconv(WINAPI) NTSTATUS;54) callconv(WINAPI) NTSTATUS;
55
56pub extern "ntdll" fn NtQuerySystemInformation(
57 SystemInformationClass: SYSTEM_INFORMATION_CLASS,
58 SystemInformation: PVOID,
59 SystemInformationLength: ULONG,
60 ReturnLength: ?*ULONG,
61) callconv(WINAPI) NTSTATUS;
62
54pub extern "ntdll" fn NtSetInformationThread(63pub extern "ntdll" fn NtSetInformationThread(
55 ThreadHandle: HANDLE,64 ThreadHandle: HANDLE,
56 ThreadInformationClass: THREADINFOCLASS,65 ThreadInformationClass: THREADINFOCLASS,
lib/std/process.zig+10-3
...@@ -1163,10 +1163,17 @@ pub fn totalSystemMemory() TotalSystemMemoryError!usize {...@@ -1163,10 +1163,17 @@ pub fn totalSystemMemory() TotalSystemMemoryError!usize {
1163 return totalSystemMemoryLinux() catch return error.UnknownTotalSystemMemory;1163 return totalSystemMemoryLinux() catch return error.UnknownTotalSystemMemory;
1164 },1164 },
1165 .windows => {1165 .windows => {
1166 var kilobytes: std.os.windows.ULONGLONG = undefined;1166 var sbi: std.os.windows.SYSTEM_BASIC_INFORMATION = undefined;
1167 if (std.os.windows.kernel32.GetPhysicallyInstalledSystemMemory(&kilobytes) != std.os.windows.TRUE)1167 const rc = std.os.windows.ntdll.NtQuerySystemInformation(
1168 .SystemBasicInformation,
1169 &sbi,
1170 @sizeOf(std.os.windows.SYSTEM_BASIC_INFORMATION),
1171 null,
1172 );
1173 if (rc != .SUCCESS) {
1168 return error.UnknownTotalSystemMemory;1174 return error.UnknownTotalSystemMemory;
1169 return kilobytes * 1024;1175 }
1176 return @as(usize, sbi.NumberOfPhysicalPages) * sbi.PageSize;
1170 },1177 },
1171 else => return error.UnknownTotalSystemMemory,1178 else => return error.UnknownTotalSystemMemory,
1172 }1179 }