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

cpu: store governor and available governors

This commit is contained in:
RGBCube 2025-05-21 18:27:09 +03:00
parent d87237165b
commit 961d1dfcd7
Signed by: RGBCube
SSH key fingerprint: SHA256:CzqbPcfwt+GxFYNnFVCqoN5Itn4YFrshg1TrnACpA5M
4 changed files with 61 additions and 56 deletions

View file

@ -12,8 +12,6 @@ pub struct CpuCoreInfo {
pub struct CpuGlobalInfo {
// System-wide CPU settings
pub current_governor: Option<String>,
pub available_governors: Vec<String>,
pub turbo_status: Option<bool>, // true for enabled, false for disabled
pub epp: Option<String>, // Energy Performance Preference
pub epb: Option<String>, // Energy Performance Bias

View file

@ -11,9 +11,12 @@ pub struct Cpu {
pub has_cpufreq: bool,
pub frequency_mhz: u64,
pub frequency_mhz_minimum: u64,
pub frequency_mhz_maximum: u64,
pub available_governors: Vec<String>,
pub governor: Option<String>,
pub frequency_mhz: Option<u64>,
pub frequency_mhz_minimum: Option<u64>,
pub frequency_mhz_maximum: Option<u64>,
pub time_user: u64,
pub time_nice: u64,
@ -56,9 +59,12 @@ impl Cpu {
number,
has_cpufreq: false,
frequency_mhz: 0,
frequency_mhz_minimum: 0,
frequency_mhz_maximum: 0,
available_governors: Vec::new(),
governor: None,
frequency_mhz: None,
frequency_mhz_minimum: None,
frequency_mhz_maximum: None,
time_user: 0,
time_nice: 0,
@ -123,7 +129,11 @@ impl Cpu {
self.has_cpufreq = fs::exists(format!("/sys/devices/system/cpu/cpu{number}/cpufreq"));
self.rescan_times()?;
self.rescan_frequency()?;
if self.has_cpufreq {
self.rescan_governor()?;
self.rescan_frequency()?;
}
Ok(())
}
@ -189,6 +199,33 @@ impl Cpu {
Ok(())
}
fn rescan_governor(&mut self) -> anyhow::Result<()> {
let Self { number, .. } = *self;
self.available_governors = 'available_governors: {
let Some(Ok(content)) = fs::read(format!(
"/sys/devices/system/cpu/cpu{number}/cpufreq/scaling_available_governors"
)) else {
break 'available_governors Vec::new();
};
content
.split_whitespace()
.map(ToString::to_string)
.collect()
};
self.governor = Some(
fs::read(format!(
"/sys/devices/system/cpu/cpu{number}/cpufreq/scaling_governor"
))
.with_context(|| format!("failed to find {self} scaling governor"))?
.with_context(|| format!("failed to read {self} scaling governor"))?,
);
Ok(())
}
fn rescan_frequency(&mut self) -> anyhow::Result<()> {
let Self { number, .. } = *self;
@ -208,32 +245,19 @@ impl Cpu {
.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;
self.frequency_mhz = Some(frequency_khz / 1000);
self.frequency_mhz_minimum = Some(frequency_khz_minimum / 1000);
self.frequency_mhz_maximum = Some(frequency_khz_maximum / 1000);
Ok(())
}
pub fn get_available_governors(&self) -> Vec<String> {
let Self { number, .. } = self;
let Some(Ok(content)) = fs::read(format!(
"/sys/devices/system/cpu/cpu{number}/cpufreq/scaling_available_governors"
)) else {
return Vec::new();
};
content
.split_whitespace()
.map(ToString::to_string)
.collect()
}
pub fn set_governor(&self, governor: &str) -> anyhow::Result<()> {
let Self { number, .. } = self;
let governors = self.get_available_governors();
pub fn set_governor(&mut self, governor: &str) -> anyhow::Result<()> {
let Self {
number,
available_governors: ref governors,
..
} = *self;
if !governors
.iter()
@ -253,7 +277,11 @@ impl Cpu {
format!(
"this probably means that {self} doesn't exist or doesn't support changing governors"
)
})
})?;
self.governor = Some(governor.to_owned());
Ok(())
}
pub fn get_available_epps(&self) -> Vec<String> {
@ -360,7 +388,7 @@ impl Cpu {
format!("this probably means that {self} doesn't exist or doesn't support changing minimum frequency")
})?;
self.frequency_mhz_minimum = frequency_mhz;
self.frequency_mhz_minimum = Some(frequency_mhz);
Ok(())
}
@ -402,7 +430,7 @@ impl Cpu {
format!("this probably means that {self} doesn't exist or doesn't support changing maximum frequency")
})?;
self.frequency_mhz_maximum = frequency_mhz;
self.frequency_mhz_maximum = Some(frequency_mhz);
Ok(())
}

View file

@ -19,7 +19,7 @@ pub fn read(path: impl AsRef<Path>) -> Option<anyhow::Result<String>> {
let path = path.as_ref();
match fs::read_to_string(path) {
Ok(string) => Some(Ok(string)),
Ok(string) => Some(Ok(string.trim().to_owned())),
Err(error) if error.kind() == io::ErrorKind::NotFound => None,

View file

@ -260,25 +260,6 @@ pub fn get_cpu_global_info(cpu_cores: &[CpuCoreInfo]) -> CpuGlobalInfo {
let turbo_status_path = Path::new("/sys/devices/system/cpu/intel_pstate/no_turbo");
let boost_path = Path::new("/sys/devices/system/cpu/cpufreq/boost");
let current_governor = if cpufreq_base_path_buf.join("scaling_governor").exists() {
read_sysfs_file_trimmed(cpufreq_base_path_buf.join("scaling_governor")).ok()
} else {
None
};
let available_governors = if cpufreq_base_path_buf
.join("scaling_available_governors")
.exists()
{
read_sysfs_file_trimmed(cpufreq_base_path_buf.join("scaling_available_governors"))
.map_or_else(
|_| vec![],
|s| s.split_whitespace().map(String::from).collect(),
)
} else {
vec![]
};
let turbo_status = if turbo_status_path.exists() {
// 0 means turbo enabled, 1 means disabled for intel_pstate
read_sysfs_value::<u8>(turbo_status_path)
@ -325,8 +306,6 @@ pub fn get_cpu_global_info(cpu_cores: &[CpuCoreInfo]) -> CpuGlobalInfo {
// Return the constructed CpuGlobalInfo
CpuGlobalInfo {
current_governor,
available_governors,
turbo_status,
epp: energy_perf_pref,
epb: energy_perf_bias,