use failure::Fallible;
use libc;
use serde;
use std::convert::TryInto;
#[derive(Debug, Default, serde::Serialize, serde::Deserialize)]
pub struct Usage {
pub utime: f64,
pub stime: f64,
pub maxrss: u32,
pub ixrss: u32,
pub idrss: u32,
pub isrss: u32,
pub minflt: u32,
pub majflt: u32,
pub nswap: u32,
pub inblock: u32,
pub oublock: u32,
pub msgsnd: u32,
pub msgrcv: u32,
pub nsignals: u32,
pub nvcsw: u32,
pub nivcsw: u32,
}
impl Usage {
pub fn new() -> Fallible<Usage> {
let mut rret = Usage {
..Default::default()
};
unsafe {
let mut rout: libc::rusage = std::mem::zeroed();
libc::getrusage(libc::RUSAGE_SELF, &mut rout);
rret.utime = Usage::time2f64(rout.ru_utime)?;
rret.stime = Usage::time2f64(rout.ru_stime)?;
rret.maxrss = rout.ru_maxrss.try_into()?;
rret.ixrss = rout.ru_ixrss.try_into()?;
rret.idrss = rout.ru_idrss.try_into()?;
rret.isrss = rout.ru_isrss.try_into()?;
rret.minflt = rout.ru_minflt.try_into()?;
rret.majflt = rout.ru_majflt.try_into()?;
rret.nswap = rout.ru_nswap.try_into()?;
rret.inblock = rout.ru_inblock.try_into()?;
rret.oublock = rout.ru_oublock.try_into()?;
rret.msgsnd = rout.ru_msgsnd.try_into()?;
rret.msgrcv = rout.ru_msgrcv.try_into()?;
rret.nsignals = rout.ru_nsignals.try_into()?;
rret.nvcsw = rout.ru_nvcsw.try_into()?;
rret.nivcsw = rout.ru_nivcsw.try_into()?;
}
Ok(rret)
}
fn time2f64(tin: libc::timeval) -> Fallible<f64> {
let sec: u32 = tin.tv_sec.try_into()?;
let usec: u32 = tin.tv_usec.try_into()?;
let res: f64 = f64::from(sec) + (f64::from(usec) / 1000000.0);
Ok(res)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_usage() {
let usage = Usage::new().unwrap();
assert!(usage.utime > 0.0);
}
}