cbtop/frequency_control/
lock.rs1use std::path::PathBuf;
4
5use super::controller::FrequencyController;
6use super::governor::CpuGovernor;
7use super::sysfs::governor_path;
8
9#[derive(Debug)]
11pub struct FrequencyLock {
12 original_governors: Vec<(usize, CpuGovernor)>,
14 original_frequencies: Vec<(usize, u64)>,
16 sysfs_path: PathBuf,
18 locked: bool,
20 mock_mode: bool,
22}
23
24impl FrequencyLock {
25 pub fn try_lock(controller: &FrequencyController) -> Self {
27 let reading = controller.read_all_frequencies();
28
29 let (original_governors, original_frequencies): (Vec<_>, Vec<_>) = reading
30 .cpus
31 .iter()
32 .map(|c| ((c.cpu_id, c.governor), (c.cpu_id, c.current_khz)))
33 .unzip();
34
35 let mut lock = Self {
36 original_governors,
37 original_frequencies,
38 sysfs_path: controller.sysfs_path.clone(),
39 locked: false,
40 mock_mode: controller.mock_mode,
41 };
42
43 if controller.mock_mode {
44 lock.locked = true;
45 } else {
46 lock.locked = lock.try_set_performance();
47 }
48
49 lock
50 }
51
52 fn try_set_performance(&self) -> bool {
54 for (cpu_id, _) in &self.original_governors {
55 if std::fs::write(governor_path(&self.sysfs_path, *cpu_id), "performance").is_err() {
56 return false;
57 }
58 }
59 true
60 }
61
62 pub fn is_locked(&self) -> bool {
64 self.locked
65 }
66}
67
68impl Drop for FrequencyLock {
69 fn drop(&mut self) {
70 if !self.locked || self.mock_mode {
71 return;
72 }
73
74 for (cpu_id, governor) in &self.original_governors {
76 let _ = std::fs::write(governor_path(&self.sysfs_path, *cpu_id), governor.name());
77 }
78 }
79}