1#[derive(Clone, Debug)]
14pub struct CpuFreqs {
17 pub min: Option<f32>,
18 pub max: Option<f32>,
19 pub cur: Option<f32>,
20}
21
22pub fn get() -> Vec<CpuFreqs> {
24 get_cpu_freqs()
25}
26
27#[cfg(target_os = "linux")]
28fn get_cpu_freqs() -> Vec<CpuFreqs> {
30 use std::fs;
31 use std::path::Path;
32
33 fn get_path(num: usize) -> Option<String> {
34 let policy_path = format!("/sys/devices/system/cpu/cpufreq/policy{}", num);
35 let cpu_path = format!("/sys/devices/system/cpu/cpu{}/cpufreq", num);
36 let base_path = match (
37 Path::new(&policy_path).exists(),
38 Path::new(&cpu_path).exists(),
39 ) {
40 (true, true) => Some(cpu_path),
41 (true, false) => Some(policy_path),
42 (false, true) => Some(cpu_path),
43 (false, false) => None,
44 };
45 base_path
46 }
47
48 fn get_measurement(cpu: usize, measurement_file: &str) -> Option<f32> {
49 let base_path = get_path(cpu);
50 match base_path {
51 Some(path) => {
52 let val_ = fs::read_to_string(Path::new(&path).join(measurement_file));
53 let val = match val_ {
54 Ok(val) => Some(val.trim().parse::<f32>().unwrap() / 1000.0),
55 Err(_) => None,
56 };
57 val
58 }
59 None => None,
60 }
61 }
62
63 let mut res: Vec<CpuFreqs> = vec![];
64 let num_cpus = num_cpus::get();
65 if Path::new("/sys/devices/system/cpu/cpufreq").exists()
66 || Path::new("/sys/devices/system/cpu/cpu0/cpufreq").exists()
67 {
68 for cpu in 0..num_cpus {
69 let min = get_measurement(cpu, "scaling_min_freq");
70 let max = get_measurement(cpu, "scaling_max_freq");
71 let cur = get_measurement(cpu, "scaling_cur_freq");
72 let r = CpuFreqs {
73 min: min,
74 max: max,
75 cur: cur,
76 };
77 res.push(r);
78 }
79 } else {
80 let data = fs::read_to_string("/proc/cpuinfo");
82 match data {
83 Ok(data) => {
84 for line in data.lines() {
85 if line.to_lowercase().starts_with("cpu mhz") {
86 let fields: Vec<&str> = line.split_whitespace().collect();
87 let cur = Some(fields[3].parse::<f32>().unwrap());
89 res.push(CpuFreqs {
90 cur: cur,
91 min: None,
92 max: None,
93 })
94 }
95 }
96 }
97 Err(_) => (),
98 }
99 }
100 res
101}
102
103#[cfg(not(target_os = "linux"))]
104fn get_cpu_freqs() -> Vec<CpuFreqs> {
105 unimplemented!("cpu-freq is not yet supported on this system")
106}
107
108#[cfg(test)]
109mod tests {
110 use super::get;
111
112 #[test]
113 fn test_cpu_freq() {
114 get().iter().for_each(|x| assert!(x.cur > Some(0.0)));
115 }
116}