From d87237165b4cded6905c4128766b86d4b016c317 Mon Sep 17 00:00:00 2001 From: RGBCube Date: Wed, 21 May 2025 17:47:13 +0300 Subject: [PATCH] cpu: store frequency --- src/config.rs | 8 +++---- src/core.rs | 3 --- src/cpu.rs | 63 ++++++++++++++++++++++++++++++++++++++++++-------- src/monitor.rs | 15 ------------ 4 files changed, 57 insertions(+), 32 deletions(-) diff --git a/src/config.rs b/src/config.rs index 9ca0498..b68485a 100644 --- a/src/config.rs +++ b/src/config.rs @@ -50,7 +50,7 @@ pub struct CpuDelta { impl CpuDelta { pub fn apply(&self) -> anyhow::Result<()> { - let cpus = match &self.for_ { + let mut cpus = match &self.for_ { Some(numbers) => { let mut cpus = Vec::with_capacity(numbers.len()); @@ -63,7 +63,7 @@ impl CpuDelta { None => cpu::Cpu::all().context("failed to get all CPUs and their information")?, }; - for cpu in cpus { + for cpu in &mut cpus { if let Some(governor) = self.governor.as_ref() { cpu.set_governor(governor)?; } @@ -77,11 +77,11 @@ impl CpuDelta { } if let Some(mhz_minimum) = self.frequency_mhz_minimum { - cpu.set_frequency_minimum(mhz_minimum)?; + cpu.set_frequency_mhz_minimum(mhz_minimum)?; } if let Some(mhz_maximum) = self.frequency_mhz_maximum { - cpu.set_frequency_maximum(mhz_maximum)?; + cpu.set_frequency_mhz_maximum(mhz_maximum)?; } } diff --git a/src/core.rs b/src/core.rs index a3f4e33..84f1886 100644 --- a/src/core.rs +++ b/src/core.rs @@ -6,9 +6,6 @@ pub struct SystemInfo { pub struct CpuCoreInfo { // Per-core data pub core_id: u32, - pub current_frequency_mhz: Option, - pub min_frequency_mhz: Option, - pub max_frequency_mhz: Option, pub usage_percent: Option, pub temperature_celsius: Option, } diff --git a/src/cpu.rs b/src/cpu.rs index 736008a..9941020 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -11,6 +11,10 @@ pub struct Cpu { pub has_cpufreq: bool, + pub frequency_mhz: u64, + pub frequency_mhz_minimum: u64, + pub frequency_mhz_maximum: u64, + pub time_user: u64, pub time_nice: u64, pub time_system: u64, @@ -52,6 +56,10 @@ impl Cpu { number, has_cpufreq: false, + frequency_mhz: 0, + frequency_mhz_minimum: 0, + frequency_mhz_maximum: 0, + time_user: 0, time_nice: 0, time_system: 0, @@ -115,6 +123,7 @@ impl Cpu { self.has_cpufreq = fs::exists(format!("/sys/devices/system/cpu/cpu{number}/cpufreq")); self.rescan_times()?; + self.rescan_frequency()?; Ok(()) } @@ -180,6 +189,32 @@ impl Cpu { Ok(()) } + fn rescan_frequency(&mut self) -> anyhow::Result<()> { + let Self { number, .. } = *self; + + let frequency_khz = fs::read_u64(format!( + "/sys/devices/system/cpu/cpu{number}/cpufreq/scaling_cur_freq" + )) + .with_context(|| format!("failed to find {self} frequency"))? + .with_context(|| format!("failed to parse {self} frequency"))?; + let frequency_khz_minimum = fs::read_u64(format!( + "/sys/devices/system/cpu/cpu{number}/cpufreq/scaling_min_freq" + )) + .with_context(|| format!("failed to find {self} frequency minimum"))? + .with_context(|| format!("failed to parse {self} frequency"))?; + let frequency_khz_maximum = fs::read_u64(format!( + "/sys/devices/system/cpu/cpu{number}/cpufreq/scaling_max_freq" + )) + .with_context(|| format!("failed to find {self} frequency maximum"))? + .with_context(|| format!("failed to parse {self} frequency"))?; + + self.frequency_mhz = frequency_khz / 1000; + self.frequency_mhz_minimum = frequency_khz_minimum / 1000; + self.frequency_mhz_maximum = frequency_khz_maximum / 1000; + + Ok(()) + } + pub fn get_available_governors(&self) -> Vec { let Self { number, .. } = self; @@ -308,10 +343,10 @@ impl Cpu { }) } - pub fn set_frequency_minimum(&self, frequency_mhz: u64) -> anyhow::Result<()> { - let Self { number, .. } = self; + pub fn set_frequency_mhz_minimum(&mut self, frequency_mhz: u64) -> anyhow::Result<()> { + let Self { number, .. } = *self; - self.validate_frequency_minimum(frequency_mhz)?; + self.validate_frequency_mhz_minimum(frequency_mhz)?; // We use u64 for the intermediate calculation to prevent overflow let frequency_khz = frequency_mhz * 1000; @@ -323,10 +358,14 @@ impl Cpu { ) .with_context(|| { format!("this probably means that {self} doesn't exist or doesn't support changing minimum frequency") - }) + })?; + + self.frequency_mhz_minimum = frequency_mhz; + + Ok(()) } - fn validate_frequency_minimum(&self, new_frequency_mhz: u64) -> anyhow::Result<()> { + fn validate_frequency_mhz_minimum(&self, new_frequency_mhz: u64) -> anyhow::Result<()> { let Self { number, .. } = self; let Some(Ok(minimum_frequency_khz)) = fs::read_u64(format!( @@ -346,10 +385,10 @@ impl Cpu { Ok(()) } - pub fn set_frequency_maximum(&self, frequency_mhz: u64) -> anyhow::Result<()> { - let Self { number, .. } = self; + pub fn set_frequency_mhz_maximum(&mut self, frequency_mhz: u64) -> anyhow::Result<()> { + let Self { number, .. } = *self; - self.validate_frequency_maximum(frequency_mhz)?; + self.validate_frequency_mhz_maximum(frequency_mhz)?; // We use u64 for the intermediate calculation to prevent overflow let frequency_khz = frequency_mhz * 1000; @@ -361,10 +400,14 @@ impl Cpu { ) .with_context(|| { format!("this probably means that {self} doesn't exist or doesn't support changing maximum frequency") - }) + })?; + + self.frequency_mhz_maximum = frequency_mhz; + + Ok(()) } - fn validate_frequency_maximum(&self, new_frequency_mhz: u64) -> anyhow::Result<()> { + fn validate_frequency_mhz_maximum(&self, new_frequency_mhz: u64) -> anyhow::Result<()> { let Self { number, .. } = self; let Some(Ok(maximum_frequency_khz)) = fs::read_u64(format!( diff --git a/src/monitor.rs b/src/monitor.rs index 5d0468b..9f0c972 100644 --- a/src/monitor.rs +++ b/src/monitor.rs @@ -21,18 +21,6 @@ pub fn get_cpu_core_info( prev_times: &CpuTimes, current_times: &CpuTimes, ) -> anyhow::Result { - let cpufreq_path = PathBuf::from(format!("/sys/devices/system/cpu/cpu{core_id}/cpufreq/")); - - let current_frequency_mhz = read_sysfs_value::(cpufreq_path.join("scaling_cur_freq")) - .map(|khz| khz / 1000) - .ok(); - let min_frequency_mhz = read_sysfs_value::(cpufreq_path.join("scaling_min_freq")) - .map(|khz| khz / 1000) - .ok(); - let max_frequency_mhz = read_sysfs_value::(cpufreq_path.join("scaling_max_freq")) - .map(|khz| khz / 1000) - .ok(); - // Temperature detection. // Should be generic enough to be able to support for multiple hardware sensors // with the possibility of extending later down the road. @@ -144,9 +132,6 @@ pub fn get_cpu_core_info( Ok(CpuCoreInfo { core_id, - current_frequency_mhz, - min_frequency_mhz, - max_frequency_mhz, usage_percent, temperature_celsius, })