#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[derive(Deserialize, Serialize)]
#[serde(deny_unknown_fields)]
pub struct StatM
{
pub total_program_size: NumberOfPages,
pub resident_set_memory_size: NumberOfPages,
pub resident_shared_pages: NumberOfPages,
pub text_segment_size: NumberOfPages,
pub data: NumberOfPages,
}
impl StatM
{
#[inline(always)]
pub fn self_statm(proc_path: &ProcPath) -> Result<Self, StatMParseError>
{
Self::process_statm(proc_path, ProcessIdentifierChoice::Current)
}
#[inline(always)]
pub fn process_statm(proc_path: &ProcPath, process_identifier: ProcessIdentifierChoice) -> Result<Self, StatMParseError>
{
let file_path = proc_path.process_file_path(process_identifier, "statm");
let line = file_path.read_raw_without_line_feed()?;
let mut columns = line.split_bytes_n(7, b' ');
#[inline(always)]
fn parse_field<'a>(columns: &mut impl Iterator<Item=&'a [u8]>, index: u8, name: &'static str) -> Result<NumberOfPages, StatMParseError>
{
use self::StatMParseError::*;
let field = match columns.next()
{
None => return Err(MissingField { index: new_non_zero_u8(index), name }),
Some(bytes) => NumberOfPages::from_bytes(bytes).map_err(|cause| ParseNumber { index: new_non_zero_u8(index), name, cause})?,
};
Ok(field)
}
#[inline(always)]
fn parse_always_zero_field<'a>(columns: &mut impl Iterator<Item=&'a [u8]>, index: u8, name: &'static str) -> Result<(), StatMParseError>
{
let value = parse_field(columns, index, name)?;
if likely!(value == 0)
{
Ok(())
}
else
{
Err(StatMParseError::FieldWasNotZero { index: new_non_zero_u8(index), name })
}
}
Ok
(
Self
{
total_program_size: parse_field(&mut columns, 1, "size")?,
resident_set_memory_size: parse_field(&mut columns, 2, "resident")?,
resident_shared_pages: parse_field(&mut columns, 3, "shared")?,
text_segment_size: parse_field(&mut columns, 4, "text")?,
data:
{
parse_always_zero_field(&mut columns, 1, "lib")?;
let data = parse_field(&mut columns, 1, "data")?;
parse_always_zero_field(&mut columns, 1, "dt")?;
data
},
}
)
}
}