mod stat;
mod cmd_line;
use std::fmt;
use super::Result;
use linux::{Jiffies, Ratio, PAGESIZE};
pub use self::stat::{Stat, State};
pub use self::cmd_line::CmdLine;
#[derive(Clone, Debug, Default)]
pub struct Process {
pub stat: Stat,
pub cmdline: CmdLine,
}
impl Process {
pub fn from_pid<P: fmt::Display + Copy>(p: P) -> Result<Process> {
Ok(Process {
stat: try!(Stat::from_pid(p)),
cmdline: try!(CmdLine::from_pid(p)),
})
}
pub fn useful_cmdline(&self) -> String {
let cmd = self.cmdline.display();
if cmd.is_empty() {
self.stat.comm.clone()
} else {
cmd
}
}
pub fn percent_ram(&self, of_bytes: usize) -> f64 {
pages_to_bytes(self.stat.rss) as f64 / of_bytes as f64 * 100.0
}
pub fn cpu_utilization_since<'a>(
&'a self,
start_process: &'a Process,
total_cpu: Jiffies,
) -> ProcessCpuUsage<'a> {
let (start_ps, end_ps) = (&start_process.stat, &self.stat);
if end_ps.utime < start_ps.utime || end_ps.stime < start_ps.stime {
panic!("End process is before start process (arguments called in wrong order)");
}
let user = 100.0
* (end_ps.utime - start_ps.utime)
.duration()
.ratio(&total_cpu.duration());
let sys = 100.0
* (end_ps.stime - start_ps.stime)
.duration()
.ratio(&total_cpu.duration());
ProcessCpuUsage {
process: &start_process,
upercent: user,
spercent: sys,
total: user + sys,
}
}
}
pub struct ProcessCpuUsage<'a> {
pub process: &'a Process,
pub upercent: f64,
pub spercent: f64,
pub total: f64,
}
fn pages_to_bytes(pages: u64) -> u64 {
pages * (*PAGESIZE)
}