summaryrefslogtreecommitdiff
path: root/runtime/ops/os/sys_info.rs
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/ops/os/sys_info.rs')
-rw-r--r--runtime/ops/os/sys_info.rs30
1 files changed, 26 insertions, 4 deletions
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<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;
}
}
}