tuwunel_core/utils/sys/
usage.rs1use nix::sys::resource::Usage;
2#[cfg(unix)]
3use nix::sys::resource::{UsageWho, getrusage};
4
5use crate::{Result, expected};
6
7pub fn virt() -> Result<usize> {
8 Ok(statm_bytes()?
9 .next()
10 .expect("incomplete statm contents"))
11}
12
13pub fn res() -> Result<usize> {
14 Ok(statm_bytes()?
15 .nth(1)
16 .expect("incomplete statm contents"))
17}
18
19pub fn shm() -> Result<usize> {
20 Ok(statm_bytes()?
21 .nth(2)
22 .expect("incomplete statm contents"))
23}
24
25pub fn code() -> Result<usize> {
26 Ok(statm_bytes()?
27 .nth(3)
28 .expect("incomplete statm contents"))
29}
30
31pub fn data() -> Result<usize> {
32 Ok(statm_bytes()?
33 .nth(5)
34 .expect("incomplete statm contents"))
35}
36
37#[inline]
38pub fn statm_bytes() -> Result<impl Iterator<Item = usize>> {
39 let page_size = super::page_size()?;
40
41 Ok(statm()?.map(move |pages| expected!(pages * page_size)))
42}
43
44#[cfg(target_os = "linux")]
45#[inline]
46pub fn statm() -> Result<impl Iterator<Item = usize>> {
47 use std::{fs::File, io::Read, str};
48
49 use crate::{Error, arrayvec::ArrayVec};
50
51 File::open("/proc/self/statm")
52 .map_err(Error::from)
53 .and_then(|mut fp| {
54 let mut buf = [0; 96];
55 let len = fp.read(&mut buf)?;
56 let vals = str::from_utf8(&buf[0..len])
57 .expect("non-utf8 content in statm")
58 .split_ascii_whitespace()
59 .map(|val| {
60 val.parse()
61 .expect("non-integer value in statm contents")
62 })
63 .collect::<ArrayVec<usize, 12>>();
64
65 Ok(vals.into_iter())
66 })
67}
68
69#[cfg(not(target_os = "linux"))]
70#[inline]
71pub fn statm() -> Result<impl Iterator<Item = usize>> { Ok([0, 0, 0, 0, 0, 0].into_iter()) }
72
73#[cfg(unix)]
74pub fn usage() -> Result<Usage> { getrusage(UsageWho::RUSAGE_SELF).map_err(Into::into) }
75
76#[cfg(not(unix))]
77pub fn usage() -> Result<Usage> { Ok(Usage::default()) }
78
79#[cfg(any(
80 target_os = "linux",
81 target_os = "freebsd",
82 target_os = "openbsd"
83))]
84pub fn thread_usage() -> Result<Usage> { getrusage(UsageWho::RUSAGE_THREAD).map_err(Into::into) }
85
86#[cfg(not(any(
87 target_os = "linux",
88 target_os = "freebsd",
89 target_os = "openbsd"
90)))]
91pub fn thread_usage() -> Result<Usage> {
92 unimplemented!("RUSAGE_THREAD available on this platform")
93}