Skip to main content

cbtop/frequency_control/
reading.rs

1use super::governor::CpuGovernor;
2use super::info::CpuFrequencyInfo;
3
4/// Frequency reading result
5#[derive(Debug, Clone)]
6pub struct FrequencyReading {
7    /// CPU info for each core
8    pub cpus: Vec<CpuFrequencyInfo>,
9    /// Timestamp
10    pub timestamp_ns: u64,
11}
12
13impl FrequencyReading {
14    /// Get average frequency in MHz
15    pub fn average_mhz(&self) -> f64 {
16        if self.cpus.is_empty() {
17            return 0.0;
18        }
19        let total: f64 = self.cpus.iter().map(|c| c.current_mhz()).sum();
20        total / self.cpus.len() as f64
21    }
22
23    /// Get min frequency across cores in MHz
24    pub fn min_mhz(&self) -> f64 {
25        self.extremum_mhz(f64::min)
26    }
27
28    /// Get max frequency across cores in MHz
29    pub fn max_mhz(&self) -> f64 {
30        self.extremum_mhz(f64::max)
31    }
32
33    /// Get frequency variance in MHz
34    pub fn variance_mhz(&self) -> f64 {
35        self.max_mhz() - self.min_mhz()
36    }
37
38    /// Shared extremum helper (min or max across core frequencies).
39    fn extremum_mhz(&self, cmp: fn(f64, f64) -> f64) -> f64 {
40        self.cpus
41            .iter()
42            .map(|c| c.current_mhz())
43            .reduce(cmp)
44            .unwrap_or(0.0)
45    }
46
47    /// Check if all cores have same governor
48    pub fn uniform_governor(&self) -> bool {
49        if self.cpus.is_empty() {
50            return true;
51        }
52        let first = self.cpus[0].governor;
53        self.cpus.iter().all(|c| c.governor == first)
54    }
55
56    /// Get most common governor
57    pub fn common_governor(&self) -> CpuGovernor {
58        self.cpus
59            .first()
60            .map(|c| c.governor)
61            .unwrap_or(CpuGovernor::Unknown)
62    }
63}