1
Fork 0
mirror of https://github.com/RGBCube/superfreq synced 2025-07-27 17:07:44 +00:00

cpu: store frequency

This commit is contained in:
RGBCube 2025-05-21 17:47:13 +03:00
parent 230967832b
commit d87237165b
Signed by: RGBCube
SSH key fingerprint: SHA256:CzqbPcfwt+GxFYNnFVCqoN5Itn4YFrshg1TrnACpA5M
4 changed files with 57 additions and 32 deletions

View file

@ -50,7 +50,7 @@ pub struct CpuDelta {
impl CpuDelta { impl CpuDelta {
pub fn apply(&self) -> anyhow::Result<()> { pub fn apply(&self) -> anyhow::Result<()> {
let cpus = match &self.for_ { let mut cpus = match &self.for_ {
Some(numbers) => { Some(numbers) => {
let mut cpus = Vec::with_capacity(numbers.len()); 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")?, 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() { if let Some(governor) = self.governor.as_ref() {
cpu.set_governor(governor)?; cpu.set_governor(governor)?;
} }
@ -77,11 +77,11 @@ impl CpuDelta {
} }
if let Some(mhz_minimum) = self.frequency_mhz_minimum { 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 { if let Some(mhz_maximum) = self.frequency_mhz_maximum {
cpu.set_frequency_maximum(mhz_maximum)?; cpu.set_frequency_mhz_maximum(mhz_maximum)?;
} }
} }

View file

@ -6,9 +6,6 @@ pub struct SystemInfo {
pub struct CpuCoreInfo { pub struct CpuCoreInfo {
// Per-core data // Per-core data
pub core_id: u32, pub core_id: u32,
pub current_frequency_mhz: Option<u32>,
pub min_frequency_mhz: Option<u32>,
pub max_frequency_mhz: Option<u32>,
pub usage_percent: Option<f32>, pub usage_percent: Option<f32>,
pub temperature_celsius: Option<f32>, pub temperature_celsius: Option<f32>,
} }

View file

@ -11,6 +11,10 @@ pub struct Cpu {
pub has_cpufreq: bool, pub has_cpufreq: bool,
pub frequency_mhz: u64,
pub frequency_mhz_minimum: u64,
pub frequency_mhz_maximum: u64,
pub time_user: u64, pub time_user: u64,
pub time_nice: u64, pub time_nice: u64,
pub time_system: u64, pub time_system: u64,
@ -52,6 +56,10 @@ impl Cpu {
number, number,
has_cpufreq: false, has_cpufreq: false,
frequency_mhz: 0,
frequency_mhz_minimum: 0,
frequency_mhz_maximum: 0,
time_user: 0, time_user: 0,
time_nice: 0, time_nice: 0,
time_system: 0, time_system: 0,
@ -115,6 +123,7 @@ impl Cpu {
self.has_cpufreq = fs::exists(format!("/sys/devices/system/cpu/cpu{number}/cpufreq")); self.has_cpufreq = fs::exists(format!("/sys/devices/system/cpu/cpu{number}/cpufreq"));
self.rescan_times()?; self.rescan_times()?;
self.rescan_frequency()?;
Ok(()) Ok(())
} }
@ -180,6 +189,32 @@ impl Cpu {
Ok(()) 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<String> { pub fn get_available_governors(&self) -> Vec<String> {
let Self { number, .. } = self; let Self { number, .. } = self;
@ -308,10 +343,10 @@ impl Cpu {
}) })
} }
pub fn set_frequency_minimum(&self, frequency_mhz: u64) -> anyhow::Result<()> { pub fn set_frequency_mhz_minimum(&mut self, frequency_mhz: u64) -> anyhow::Result<()> {
let Self { number, .. } = self; 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 // We use u64 for the intermediate calculation to prevent overflow
let frequency_khz = frequency_mhz * 1000; let frequency_khz = frequency_mhz * 1000;
@ -323,10 +358,14 @@ impl Cpu {
) )
.with_context(|| { .with_context(|| {
format!("this probably means that {self} doesn't exist or doesn't support changing minimum frequency") 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 Self { number, .. } = self;
let Some(Ok(minimum_frequency_khz)) = fs::read_u64(format!( let Some(Ok(minimum_frequency_khz)) = fs::read_u64(format!(
@ -346,10 +385,10 @@ impl Cpu {
Ok(()) Ok(())
} }
pub fn set_frequency_maximum(&self, frequency_mhz: u64) -> anyhow::Result<()> { pub fn set_frequency_mhz_maximum(&mut self, frequency_mhz: u64) -> anyhow::Result<()> {
let Self { number, .. } = self; 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 // We use u64 for the intermediate calculation to prevent overflow
let frequency_khz = frequency_mhz * 1000; let frequency_khz = frequency_mhz * 1000;
@ -361,10 +400,14 @@ impl Cpu {
) )
.with_context(|| { .with_context(|| {
format!("this probably means that {self} doesn't exist or doesn't support changing maximum frequency") 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 Self { number, .. } = self;
let Some(Ok(maximum_frequency_khz)) = fs::read_u64(format!( let Some(Ok(maximum_frequency_khz)) = fs::read_u64(format!(

View file

@ -21,18 +21,6 @@ pub fn get_cpu_core_info(
prev_times: &CpuTimes, prev_times: &CpuTimes,
current_times: &CpuTimes, current_times: &CpuTimes,
) -> anyhow::Result<CpuCoreInfo> { ) -> anyhow::Result<CpuCoreInfo> {
let cpufreq_path = PathBuf::from(format!("/sys/devices/system/cpu/cpu{core_id}/cpufreq/"));
let current_frequency_mhz = read_sysfs_value::<u32>(cpufreq_path.join("scaling_cur_freq"))
.map(|khz| khz / 1000)
.ok();
let min_frequency_mhz = read_sysfs_value::<u32>(cpufreq_path.join("scaling_min_freq"))
.map(|khz| khz / 1000)
.ok();
let max_frequency_mhz = read_sysfs_value::<u32>(cpufreq_path.join("scaling_max_freq"))
.map(|khz| khz / 1000)
.ok();
// Temperature detection. // Temperature detection.
// Should be generic enough to be able to support for multiple hardware sensors // Should be generic enough to be able to support for multiple hardware sensors
// with the possibility of extending later down the road. // with the possibility of extending later down the road.
@ -144,9 +132,6 @@ pub fn get_cpu_core_info(
Ok(CpuCoreInfo { Ok(CpuCoreInfo {
core_id, core_id,
current_frequency_mhz,
min_frequency_mhz,
max_frequency_mhz,
usage_percent, usage_percent,
temperature_celsius, temperature_celsius,
}) })