heim_process/process/
cpu_usage.rs

1use std::ops;
2use std::time::Instant;
3
4use heim_common::units::{ratio, time, Ratio};
5
6use super::CpuTime;
7
8/// Process CPU usage measurement.
9///
10/// See [Process::cpu_usage](./struct.Process.html#method.cpu_usage) method for details.
11#[derive(Debug)]
12pub struct CpuUsage {
13    pub(crate) cpu_count: u64,
14    pub(crate) cpu_time: CpuTime,
15    pub(crate) at: Instant,
16}
17
18impl ops::Sub<CpuUsage> for CpuUsage {
19    type Output = Ratio;
20
21    #[allow(clippy::suspicious_arithmetic_impl, clippy::cast_lossless)]
22    fn sub(self, rhs: CpuUsage) -> Self::Output {
23        let delta_proc = (self.cpu_time.user() - rhs.cpu_time.user())
24            + (self.cpu_time.system() - rhs.cpu_time.system());
25        let delta_time = self.at - rhs.at;
26
27        // TODO: Can be replaced with a `delta_time.as_secs_f64()`
28        // as soon as https://github.com/rust-lang/rust/issues/54361 will be stable
29        const NANOS_PER_SEC: u32 = 1_000_000_000;
30        let mut delta_time_secs =
31            (delta_time.as_secs() as f64) + (delta_time.as_nanos() as f64) / (NANOS_PER_SEC as f64);
32
33        // Time should calculated across all the cores available
34        delta_time_secs *= self.cpu_count as f64;
35
36        if delta_time_secs != 0.0 {
37            let overall_cpus_ratio = delta_proc.get::<time::second>() / delta_time_secs;
38            let single_cpu_ratio = overall_cpus_ratio * self.cpu_count as f64;
39
40            Ratio::new::<ratio::ratio>(single_cpu_ratio as f32)
41        } else {
42            Ratio::new::<ratio::ratio>(0.0)
43        }
44    }
45}