1#![deny(missing_copy_implementations, missing_debug_implementations)]
10#![deny(rustdoc::broken_intra_doc_links)]
11#![deny(clippy::cast_possible_truncation)]
12#![warn(missing_docs)]
13#![no_std]
14#![cfg_attr(all(doc, CHANNEL_NIGHTLY), feature(doc_cfg))]
19
20#[cfg(windows)]
21pub mod windows;
22
23#[cfg(any(target_os = "macos", target_os = "ios"))]
24pub mod macos;
25
26#[cfg(target_os = "linux")]
27pub mod linux;
28
29#[derive(Debug, Clone, Copy)]
31pub struct Snapshot {
32 pub total: u64,
34
35 pub available: u64,
37}
38
39impl Snapshot {
40 #[cfg(any(windows, target_os = "linux", target_os = "macos", target_os = "ios"))]
42 #[allow(unreachable_code)]
43 pub fn get() -> Result<Self, Option<errno::Errno>> {
44 #[cfg(windows)] {
45 let mem_status = windows::populate_mem_status()?;
46
47 return Ok(Self {
48 total: mem_status.ullTotalPhys,
49 available: mem_status.ullAvailPhys,
50 });
51 }
52
53 #[cfg(target_os = "linux")] {
56 let sysinfo = linux::populate_sysinfo()?;
57
58 let total = sysinfo.totalram as _;
59 let available = sysinfo.freeram as _;
60
61 return Ok(Self {
62 total,
63 available
64 });
65 }
66
67 #[cfg(any(target_os = "macos", target_os = "ios"))] {
68 let total_memory = macos::try_get_total_physical_memory()?;
69 let page_size = macos::page_size()?;
70 let vm_stats = macos::vm_statistics()
71 .map_err(|errno| if errno.0 == 0 { None } else { Some(errno) })?;
72
73 return Ok(Self {
74 total: total_memory,
75 available: (vm_stats.active_count + vm_stats.free_count) as u64 * page_size,
78 });
79 }
80
81 unreachable!("This function should have already hit a CFG and returned");
82 }
83
84 pub fn in_use(&self) -> u64 {
86 self.total - self.available
87 }
88}
89
90
91#[cfg(any(windows, target_os = "linux", target_os = "macos", target_os = "ios"))]
92#[inline]
93fn get_snapshot() -> Snapshot {
94 Snapshot::get().expect("failed to query system for memory stats")
95}
96
97#[cfg(any(windows, target_os = "linux", target_os = "macos", target_os = "ios"))]
102pub fn total() -> u64 {
103 get_snapshot().total
104}
105
106#[cfg(any(windows, target_os = "linux", target_os = "macos", target_os = "ios"))]
111pub fn available() -> u64 {
112 get_snapshot().available
113}
114
115#[cfg(any(windows, target_os = "linux", target_os = "macos", target_os = "ios"))]
120pub fn used() -> u64 {
121 get_snapshot().in_use()
122}
123
124#[cfg(test)]
125mod tests {
126 extern crate std;
127 use std::println;
128
129 #[test]
130 fn get_total_system_memory() {
131 println!(
132 "Total system memory: {:.2} GiB",
133 super::total() as f64 / 1024f64 / 1024f64 / 1024f64
134 );
135 println!(
136 "Available system memory: {:.2} GiB",
137 super::available() as f64 / 1024f64 / 1024f64 / 1024f64
138 );
139
140 assert_eq!(super::used(), super::total() - super::available());
143 }
144}