0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-03-03 09:31:22 -05:00

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 <dhairysrivastava5@gmail.com>
This commit is contained in:
Divy Srivastava 2023-01-15 04:56:30 -08:00 committed by GitHub
parent 90c0381272
commit a4c98e3472
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -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 =
@ -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;
}
}
}