Skip to content

Commit 53039fc

Browse files
committed
Windows available memory support.
1 parent 5884f64 commit 53039fc

1 file changed

Lines changed: 42 additions & 3 deletions

File tree

src/sysmem.rs

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
//! System memory queries.
22
3-
/// Available system memory in bytes, from `/proc/meminfo` (Linux). Returns
4-
/// `None` on other platforms or on parse failure (callers then skip any
5-
/// memory-based heuristics).
3+
/// Available system memory in bytes, when determinable. Returns `None` on
4+
/// unsupported platforms or on failure (callers then skip memory-based
5+
/// heuristics and show "n/a").
66
pub fn available_bytes() -> Option<u64> {
7+
platform_available()
8+
}
9+
10+
/// Linux: `MemAvailable` from `/proc/meminfo`.
11+
#[cfg(target_os = "linux")]
12+
fn platform_available() -> Option<u64> {
713
let meminfo = std::fs::read_to_string("/proc/meminfo").ok()?;
814
for line in meminfo.lines() {
915
if let Some(rest) = line.strip_prefix("MemAvailable:") {
@@ -14,6 +20,39 @@ pub fn available_bytes() -> Option<u64> {
1420
None
1521
}
1622

23+
/// Windows: available physical memory via `GlobalMemoryStatusEx`.
24+
#[cfg(windows)]
25+
fn platform_available() -> Option<u64> {
26+
#[repr(C)]
27+
struct MemoryStatusEx {
28+
length: u32,
29+
memory_load: u32,
30+
total_phys: u64,
31+
avail_phys: u64,
32+
total_page_file: u64,
33+
avail_page_file: u64,
34+
total_virtual: u64,
35+
avail_virtual: u64,
36+
avail_extended_virtual: u64,
37+
}
38+
#[link(name = "kernel32")]
39+
extern "system" {
40+
fn GlobalMemoryStatusEx(buffer: *mut MemoryStatusEx) -> i32;
41+
}
42+
let mut status: MemoryStatusEx = unsafe { std::mem::zeroed() };
43+
status.length = std::mem::size_of::<MemoryStatusEx>() as u32;
44+
if unsafe { GlobalMemoryStatusEx(&mut status) } != 0 {
45+
Some(status.avail_phys)
46+
} else {
47+
None
48+
}
49+
}
50+
51+
#[cfg(not(any(target_os = "linux", windows)))]
52+
fn platform_available() -> Option<u64> {
53+
None
54+
}
55+
1756
/// Format a byte count as `GiB`/`MiB`.
1857
pub fn human_bytes(bytes: u64) -> String {
1958
let gib = bytes as f64 / (1024.0 * 1024.0 * 1024.0);

0 commit comments

Comments
 (0)