Commit 0733c8c5ca

xEgoist <egoist@egoistic.dev>
2023-04-13 01:22:07
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.
1 parent 7b908e1
Changed files (3)
lib/std/os/windows/ntdll.zig
@@ -31,6 +31,7 @@ const UNWIND_HISTORY_TABLE = windows.UNWIND_HISTORY_TABLE;
 const RUNTIME_FUNCTION = windows.RUNTIME_FUNCTION;
 const KNONVOLATILE_CONTEXT_POINTERS = windows.KNONVOLATILE_CONTEXT_POINTERS;
 const EXCEPTION_ROUTINE = windows.EXCEPTION_ROUTINE;
+const SYSTEM_INFORMATION_CLASS = windows.SYSTEM_INFORMATION_CLASS;
 const THREADINFOCLASS = windows.THREADINFOCLASS;
 const PROCESSINFOCLASS = windows.PROCESSINFOCLASS;
 const LPVOID = windows.LPVOID;
@@ -51,6 +52,14 @@ pub extern "ntdll" fn NtQueryInformationThread(
     ThreadInformationLength: ULONG,
     ReturnLength: ?*ULONG,
 ) callconv(WINAPI) NTSTATUS;
+
+pub extern "ntdll" fn NtQuerySystemInformation(
+    SystemInformationClass: SYSTEM_INFORMATION_CLASS,
+    SystemInformation: PVOID,
+    SystemInformationLength: ULONG,
+    ReturnLength: ?*ULONG,
+) callconv(WINAPI) NTSTATUS;
+
 pub extern "ntdll" fn NtSetInformationThread(
     ThreadHandle: HANDLE,
     ThreadInformationClass: THREADINFOCLASS,
lib/std/os/windows.zig
@@ -4476,6 +4476,34 @@ pub const MODULEENTRY32 = extern struct {
     szExePath: [MAX_PATH]CHAR,
 };
 
+pub const SYSTEM_INFORMATION_CLASS = enum(c_int) {
+    SystemBasicInformation = 0,
+    SystemPerformanceInformation = 2,
+    SystemTimeOfDayInformation = 3,
+    SystemProcessInformation = 5,
+    SystemProcessorPerformanceInformation = 8,
+    SystemInterruptInformation = 23,
+    SystemExceptionInformation = 33,
+    SystemRegistryQuotaInformation = 37,
+    SystemLookasideInformation = 45,
+    SystemCodeIntegrityInformation = 103,
+    SystemPolicyInformation = 134,
+};
+
+pub const SYSTEM_BASIC_INFORMATION = extern struct {
+    Reserved: ULONG,
+    TimerResolution: ULONG,
+    PageSize: ULONG,
+    NumberOfPhysicalPages: ULONG,
+    LowestPhysicalPageNumber: ULONG,
+    HighestPhysicalPageNumber: ULONG,
+    AllocationGranularity: ULONG,
+    MinimumUserModeAddress: ULONG_PTR,
+    MaximumUserModeAddress: ULONG_PTR,
+    ActiveProcessorsAffinityMask: KAFFINITY,
+    NumberOfProcessors: UCHAR,
+};
+
 pub const THREADINFOCLASS = enum(c_int) {
     ThreadBasicInformation,
     ThreadTimes,
lib/std/process.zig
@@ -1163,10 +1163,17 @@ pub fn totalSystemMemory() TotalSystemMemoryError!usize {
             return totalSystemMemoryLinux() catch return error.UnknownTotalSystemMemory;
         },
         .windows => {
-            var kilobytes: std.os.windows.ULONGLONG = undefined;
-            if (std.os.windows.kernel32.GetPhysicallyInstalledSystemMemory(&kilobytes) != std.os.windows.TRUE)
+            var sbi: std.os.windows.SYSTEM_BASIC_INFORMATION = undefined;
+            const rc = std.os.windows.ntdll.NtQuerySystemInformation(
+                .SystemBasicInformation,
+                &sbi,
+                @sizeOf(std.os.windows.SYSTEM_BASIC_INFORMATION),
+                null,
+            );
+            if (rc != .SUCCESS) {
                 return error.UnknownTotalSystemMemory;
-            return kilobytes * 1024;
+            }
+            return @as(usize, sbi.NumberOfPhysicalPages) * sbi.PageSize;
         },
         else => return error.UnknownTotalSystemMemory,
     }