use std::{io::ErrorKind, path::Path};
use crate::{
process::ProcessStat,
scanner_rust::{generic_array::typenum::U96, Scanner, ScannerError},
};
#[derive(Default, Debug, Clone)]
pub struct ProcessTimeStat {
pub utime: u32,
pub stime: u32,
}
impl ProcessTimeStat {
#[inline]
pub fn compute_cpu_utilization_in_percentage(
&self,
process_time_stat_after_this: &ProcessTimeStat,
total_cpu_time: f64,
) -> f64 {
let d_utime = process_time_stat_after_this.utime - self.utime;
let d_stime = process_time_stat_after_this.stime - self.stime;
let d_time_f64 = (d_utime + d_stime) as f64;
if total_cpu_time < 1.0 {
0.0
} else if d_time_f64 >= total_cpu_time {
1.0
} else {
d_time_f64 / total_cpu_time
}
}
}
impl From<ProcessStat> for ProcessTimeStat {
#[inline]
fn from(process_stat: ProcessStat) -> Self {
ProcessTimeStat {
utime: process_stat.utime, stime: process_stat.stime
}
}
}
pub fn get_process_time_stat(pid: u32) -> Result<ProcessTimeStat, ScannerError> {
let stat_path = Path::new("/proc").join(pid.to_string()).join("stat");
let mut sc: Scanner<_, U96> = Scanner::scan_path2(stat_path)?;
sc.drop_next()?.ok_or(ErrorKind::UnexpectedEof)?;
loop {
let comm = sc.next_raw()?.ok_or(ErrorKind::UnexpectedEof)?;
if comm.ends_with(b")") {
break;
}
}
for _ in 0..11 {
sc.drop_next()?.ok_or(ErrorKind::UnexpectedEof)?;
}
let utime = sc.next_u32()?.ok_or(ErrorKind::UnexpectedEof)?;
let stime = sc.next_u32()?.ok_or(ErrorKind::UnexpectedEof)?;
let time_stat = ProcessTimeStat {
utime,
stime,
};
Ok(time_stat)
}