1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
use std::io::ErrorKind;
use std::path::Path;
use crate::scanner_rust::generic_array::typenum::U96;
use crate::scanner_rust::{Scanner, ScannerError};
use crate::process::ProcessStat;
#[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)
}