From 57d4ae243a92253d48021483fc58e27d42299b5a Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Mon, 2 Mar 2026 06:45:25 +0000 Subject: [PATCH] Add sys util to get rss from statm on linux. Signed-off-by: Jason Volk --- src/core/utils/sys.rs | 6 +++- src/core/utils/sys/usage.rs | 66 ++++++++++++++++++++++++++++++++++++- 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/src/core/utils/sys.rs b/src/core/utils/sys.rs index 43712487..efa9925f 100644 --- a/src/core/utils/sys.rs +++ b/src/core/utils/sys.rs @@ -5,7 +5,11 @@ pub mod usage; use std::path::PathBuf; -pub use self::{compute::available_parallelism, limits::*, usage::*}; +pub use self::{ + compute::available_parallelism, + limits::*, + usage::{statm, thread_usage, usage}, +}; use crate::{Result, at}; /// Return a possibly corrected std::env::current_exe() even if the path is diff --git a/src/core/utils/sys/usage.rs b/src/core/utils/sys/usage.rs index 6bf6f01a..423cc8fa 100644 --- a/src/core/utils/sys/usage.rs +++ b/src/core/utils/sys/usage.rs @@ -1,8 +1,72 @@ +use std::{fs::File, io::Read, str}; + use nix::sys::resource::Usage; #[cfg(unix)] use nix::sys::resource::{UsageWho, getrusage}; -use crate::Result; +use crate::{Error, Result, arrayvec::ArrayVec, expected}; + +pub fn virt() -> Result { + Ok(statm_bytes()? + .next() + .expect("incomplete statm contents")) +} + +pub fn res() -> Result { + Ok(statm_bytes()? + .nth(1) + .expect("incomplete statm contents")) +} + +pub fn shm() -> Result { + Ok(statm_bytes()? + .nth(2) + .expect("incomplete statm contents")) +} + +pub fn code() -> Result { + Ok(statm_bytes()? + .nth(3) + .expect("incomplete statm contents")) +} + +pub fn data() -> Result { + Ok(statm_bytes()? + .nth(5) + .expect("incomplete statm contents")) +} + +#[inline] +pub fn statm_bytes() -> Result> { + let page_size = super::page_size()?; + + Ok(statm()?.map(move |pages| expected!(pages * page_size))) +} + +#[cfg(target_os = "linux")] +#[inline] +pub fn statm() -> Result> { + File::open("/proc/self/statm") + .map_err(Error::from) + .and_then(|mut fp| { + let mut buf = [0; 96]; + let len = fp.read(&mut buf)?; + let vals = str::from_utf8(&buf[0..len]) + .expect("non-utf8 content in statm") + .split_ascii_whitespace() + .map(|val| { + val.parse() + .expect("non-integer value in statm contents") + }) + .collect::>(); + + Ok(vals.into_iter()) + }) +} + +#[cfg(not(target_os = "linux"))] +#[inline] +pub fn statm() -> Result { Err!("proc_pid_statm(5) only available on linux systems") } #[cfg(unix)] pub fn usage() -> Result { getrusage(UsageWho::RUSAGE_SELF).map_err(Into::into) }