#![deny(missing_copy_implementations, missing_debug_implementations)]
#![deny(rustdoc::broken_intra_doc_links)]
#![deny(clippy::cast_possible_truncation)]
#![warn(missing_docs)]
#![no_std]
#![cfg_attr(all(doc, CHANNEL_NIGHTLY), feature(doc_cfg))]
#[cfg(windows)]
pub mod windows;
#[cfg(any(target_os = "macos", target_os = "ios"))]
pub mod macos;
#[cfg(target_os = "linux")]
pub mod linux;
#[derive(Debug, Clone, Copy)]
pub struct Snapshot {
pub total: u64,
pub available: u64,
}
impl Snapshot {
#[cfg(any(windows, target_os = "linux", target_os = "macos", target_os = "ios"))]
#[allow(unreachable_code)]
pub fn get() -> Result<Self, Option<errno::Errno>> {
#[cfg(windows)] {
let mem_status = windows::populate_mem_status()?;
return Ok(Self {
total: mem_status.ullTotalPhys,
available: mem_status.ullAvailPhys,
});
}
#[cfg(target_os = "linux")] {
let sysinfo = linux::populate_sysinfo()?;
let total = sysinfo.totalram as _;
let available = sysinfo.freeram as _;
return Ok(Self {
total,
available
});
}
#[cfg(any(target_os = "macos", target_os = "ios"))] {
let total_memory = macos::try_get_total_physical_memory()?;
let page_size = macos::page_size()?;
let vm_stats = macos::vm_statistics()
.map_err(|errno| if errno.0 == 0 { None } else { Some(errno) })?;
return Ok(Self {
total: total_memory,
available: (vm_stats.active_count + vm_stats.free_count) as u64 * page_size,
});
}
unreachable!("This function should have already hit a CFG and returned");
}
pub fn in_use(&self) -> u64 {
self.total - self.available
}
}
#[cfg(any(windows, target_os = "linux", target_os = "macos", target_os = "ios"))]
#[inline]
fn get_snapshot() -> Snapshot {
Snapshot::get().expect("failed to query system for memory stats")
}
#[cfg(any(windows, target_os = "linux", target_os = "macos", target_os = "ios"))]
pub fn total() -> u64 {
get_snapshot().total
}
#[cfg(any(windows, target_os = "linux", target_os = "macos", target_os = "ios"))]
pub fn available() -> u64 {
get_snapshot().available
}
#[cfg(any(windows, target_os = "linux", target_os = "macos", target_os = "ios"))]
pub fn used() -> u64 {
get_snapshot().in_use()
}
#[cfg(test)]
mod tests {
extern crate std;
use std::println;
#[test]
fn get_total_system_memory() {
println!(
"Total system memory: {:.2} GiB",
super::total() as f64 / 1024f64 / 1024f64 / 1024f64
);
println!(
"Available system memory: {:.2} GiB",
super::available() as f64 / 1024f64 / 1024f64 / 1024f64
);
assert_eq!(super::used(), super::total() - super::available());
}
}