blob: f4b82798f79bd5f88a1152d53d1d9fdf8208f19a [file] [log] [blame]
Andrew Walbran12f61402020-10-14 11:10:53 +01001use libc::{self, SI_LOAD_SHIFT};
2use std::{cmp, mem};
3use std::time::Duration;
4
5use crate::Result;
6use crate::errno::Errno;
7
8/// System info structure returned by `sysinfo`.
9#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
10#[repr(transparent)]
11pub struct SysInfo(libc::sysinfo);
12
13impl SysInfo {
14 /// Returns the load average tuple.
15 ///
16 /// The returned values represent the load average over time intervals of
17 /// 1, 5, and 15 minutes, respectively.
18 pub fn load_average(&self) -> (f64, f64, f64) {
19 (
20 self.0.loads[0] as f64 / (1 << SI_LOAD_SHIFT) as f64,
21 self.0.loads[1] as f64 / (1 << SI_LOAD_SHIFT) as f64,
22 self.0.loads[2] as f64 / (1 << SI_LOAD_SHIFT) as f64,
23 )
24 }
25
26 /// Returns the time since system boot.
27 pub fn uptime(&self) -> Duration {
28 // Truncate negative values to 0
29 Duration::from_secs(cmp::max(self.0.uptime, 0) as u64)
30 }
31
32 /// Current number of processes.
33 pub fn process_count(&self) -> u16 {
34 self.0.procs
35 }
36
37 /// Returns the amount of swap memory in Bytes.
38 pub fn swap_total(&self) -> u64 {
39 self.scale_mem(self.0.totalswap)
40 }
41
42 /// Returns the amount of unused swap memory in Bytes.
43 pub fn swap_free(&self) -> u64 {
44 self.scale_mem(self.0.freeswap)
45 }
46
47 /// Returns the total amount of installed RAM in Bytes.
48 pub fn ram_total(&self) -> u64 {
49 self.scale_mem(self.0.totalram)
50 }
51
52 /// Returns the amount of completely unused RAM in Bytes.
53 ///
54 /// "Unused" in this context means that the RAM in neither actively used by
55 /// programs, nor by the operating system as disk cache or buffer. It is
56 /// "wasted" RAM since it currently serves no purpose.
57 pub fn ram_unused(&self) -> u64 {
58 self.scale_mem(self.0.freeram)
59 }
60
61 fn scale_mem(&self, units: libc::c_ulong) -> u64 {
62 units as u64 * self.0.mem_unit as u64
63 }
64}
65
66/// Returns system information.
67///
68/// [See `sysinfo(2)`](http://man7.org/linux/man-pages/man2/sysinfo.2.html).
69pub fn sysinfo() -> Result<SysInfo> {
70 let mut info = mem::MaybeUninit::uninit();
71 let res = unsafe { libc::sysinfo(info.as_mut_ptr()) };
72 Errno::result(res).map(|_| unsafe{ SysInfo(info.assume_init()) })
73}