Skip to content

Commit

Permalink
fix(runtime/os): use GetPerformanceInfo for swap info on Windows (den…
Browse files Browse the repository at this point in the history
…oland#17433)

Fixes denoland#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 GuillaumeGomez/sysinfo#534

Co-authored-by: Nightly <[email protected]>
  • Loading branch information
littledivy and nightlyistaken committed Jan 15, 2023
1 parent 90c0381 commit a4c98e3
Showing 1 changed file with 26 additions and 4 deletions.
30 changes: 26 additions & 4 deletions runtime/ops/os/sys_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,8 @@ pub fn mem_info() -> Option<MemInfo> {
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 =
Expand All @@ -290,10 +292,30 @@ pub fn mem_info() -> Option<MemInfo> {
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::<PERFORMANCE_INFORMATION>::uninit();
let result = GetPerformanceInfo(
perf_info.as_mut_ptr(),
mem::size_of::<PERFORMANCE_INFORMATION>() 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;
}
}
}
Expand Down

0 comments on commit a4c98e3

Please sign in to comment.