use std::sync::{Mutex, PoisonError};
use cubecl_server::runtime::{DeviceUtilization, UtilizationUnavailable};
use sysinfo::System;
pub struct ProcessorTimes;
static PREVIOUS_READING: Mutex<Option<System>> = Mutex::new(None);
impl ProcessorTimes {
pub fn read_machine_wide() -> Result<DeviceUtilization, UtilizationUnavailable> {
let mut previous_reading = PREVIOUS_READING
.lock()
.unwrap_or_else(PoisonError::into_inner);
let Some(system) = previous_reading.as_mut() else {
let mut system = System::new();
system.refresh_cpu_usage();
*previous_reading = Some(system);
return Err(UtilizationUnavailable::NoPreviousReading);
};
system.refresh_cpu_usage();
Ok(DeviceUtilization::new(system.global_cpu_usage()))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn the_first_reading_measures_nothing_and_the_next_is_a_percent() {
assert_eq!(
ProcessorTimes::read_machine_wide(),
Err(UtilizationUnavailable::NoPreviousReading)
);
let next = ProcessorTimes::read_machine_wide().map(|utilization| utilization.busy_percent);
assert!(
matches!(next, Ok(busy_percent) if (0.0..=100.0).contains(&busy_percent)),
"{next:?}"
);
}
}