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 {
44764476 szExePath: [MAX_PATH]CHAR,
44774477};
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
44794507pub const THREADINFOCLASS = enum(c_int) {
44804508 ThreadBasicInformation,
44814509 ThreadTimes,
lib/std/os/windows/ntdll.zig+9
......@@ -31,6 +31,7 @@ const UNWIND_HISTORY_TABLE = windows.UNWIND_HISTORY_TABLE;
3131const RUNTIME_FUNCTION = windows.RUNTIME_FUNCTION;
3232const KNONVOLATILE_CONTEXT_POINTERS = windows.KNONVOLATILE_CONTEXT_POINTERS;
3333const EXCEPTION_ROUTINE = windows.EXCEPTION_ROUTINE;
34const SYSTEM_INFORMATION_CLASS = windows.SYSTEM_INFORMATION_CLASS;
3435const THREADINFOCLASS = windows.THREADINFOCLASS;
3536const PROCESSINFOCLASS = windows.PROCESSINFOCLASS;
3637const LPVOID = windows.LPVOID;
......@@ -51,6 +52,14 @@ pub extern "ntdll" fn NtQueryInformationThread(
5152 ThreadInformationLength: ULONG,
5253 ReturnLength: ?*ULONG,
5354) 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
5463pub extern "ntdll" fn NtSetInformationThread(
5564 ThreadHandle: HANDLE,
5665 ThreadInformationClass: THREADINFOCLASS,
lib/std/process.zig+10-3
......@@ -1163,10 +1163,17 @@ pub fn totalSystemMemory() TotalSystemMemoryError!usize {
11631163 return totalSystemMemoryLinux() catch return error.UnknownTotalSystemMemory;
11641164 },
11651165 .windows => {
1166 var kilobytes: std.os.windows.ULONGLONG = undefined;
1167 if (std.os.windows.kernel32.GetPhysicallyInstalledSystemMemory(&kilobytes) != std.os.windows.TRUE)
1166 var sbi: std.os.windows.SYSTEM_BASIC_INFORMATION = undefined;
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) {
11681174 return error.UnknownTotalSystemMemory;
1169 return kilobytes * 1024;
1175 }
1176 return @as(usize, sbi.NumberOfPhysicalPages) * sbi.PageSize;
11701177 },
11711178 else => return error.UnknownTotalSystemMemory,
11721179 }