From a4c98e347215528d20e4891e4f0e54b2d8523c89 Mon Sep 17 00:00:00 2001 From: Divy Srivastava Date: Sun, 15 Jan 2023 04:56:30 -0800 Subject: fix(runtime/os): use GetPerformanceInfo for swap info on Windows (#17433) Fixes https://github.com/denoland/deno/issues/17417 According to https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/ns-sysinfoapi-memorystatusex , `stat.ullTotalPageFile` value is reliable only from GetPerformanceInfo() Also see https://github.com/GuillaumeGomez/sysinfo/issues/534 Co-authored-by: Nightly --- runtime/ops/os/sys_info.rs | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) (limited to 'runtime/ops/os') diff --git a/runtime/ops/os/sys_info.rs b/runtime/ops/os/sys_info.rs index 366864f46..1a9358dc0 100644 --- a/runtime/ops/os/sys_info.rs +++ b/runtime/ops/os/sys_info.rs @@ -274,6 +274,8 @@ pub fn mem_info() -> Option { unsafe { use std::mem; use winapi::shared::minwindef; + use winapi::um::psapi::GetPerformanceInfo; + use winapi::um::psapi::PERFORMANCE_INFORMATION; use winapi::um::sysinfoapi; let mut mem_status = @@ -290,10 +292,30 @@ pub fn mem_info() -> Option { mem_info.free = stat.ullAvailPhys / 1024; mem_info.cached = 0; mem_info.buffers = 0; - mem_info.swap_total = (stat.ullTotalPageFile - stat.ullTotalPhys) / 1024; - mem_info.swap_free = (stat.ullAvailPageFile - stat.ullAvailPhys) / 1024; - if mem_info.swap_free > mem_info.swap_total { - mem_info.swap_free = mem_info.swap_total; + + // `stat.ullTotalPageFile` is reliable only from GetPerformanceInfo() + // + // See https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/ns-sysinfoapi-memorystatusex + // and https://github.com/GuillaumeGomez/sysinfo/issues/534 + + let mut perf_info = mem::MaybeUninit::::uninit(); + let result = GetPerformanceInfo( + perf_info.as_mut_ptr(), + mem::size_of::() as minwindef::DWORD, + ); + if result == minwindef::TRUE { + let perf_info = perf_info.assume_init(); + let swap_total = perf_info.PageSize + * perf_info + .CommitLimit + .saturating_sub(perf_info.PhysicalTotal); + let swap_free = perf_info.PageSize + * perf_info + .CommitLimit + .saturating_sub(perf_info.PhysicalTotal) + .saturating_sub(perf_info.PhysicalAvailable); + mem_info.swap_total = (swap_total / 1000) as u64; + mem_info.swap_free = (swap_free / 1000) as u64; } } } -- cgit v1.2.3