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:
parent
d87237165b
commit
961d1dfcd7
4 changed files with 61 additions and 56 deletions
|
@ -12,8 +12,6 @@ pub struct CpuCoreInfo {
|
||||||
|
|
||||||
pub struct CpuGlobalInfo {
|
pub struct CpuGlobalInfo {
|
||||||
// System-wide CPU settings
|
// 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 turbo_status: Option<bool>, // true for enabled, false for disabled
|
||||||
pub epp: Option<String>, // Energy Performance Preference
|
pub epp: Option<String>, // Energy Performance Preference
|
||||||
pub epb: Option<String>, // Energy Performance Bias
|
pub epb: Option<String>, // Energy Performance Bias
|
||||||
|
|
90
src/cpu.rs
90
src/cpu.rs
|
@ -11,9 +11,12 @@ pub struct Cpu {
|
||||||
|
|
||||||
pub has_cpufreq: bool,
|
pub has_cpufreq: bool,
|
||||||
|
|
||||||
pub frequency_mhz: u64,
|
pub available_governors: Vec<String>,
|
||||||
pub frequency_mhz_minimum: u64,
|
pub governor: Option<String>,
|
||||||
pub frequency_mhz_maximum: u64,
|
|
||||||
|
pub frequency_mhz: Option<u64>,
|
||||||
|
pub frequency_mhz_minimum: Option<u64>,
|
||||||
|
pub frequency_mhz_maximum: Option<u64>,
|
||||||
|
|
||||||
pub time_user: u64,
|
pub time_user: u64,
|
||||||
pub time_nice: u64,
|
pub time_nice: u64,
|
||||||
|
@ -56,9 +59,12 @@ impl Cpu {
|
||||||
number,
|
number,
|
||||||
has_cpufreq: false,
|
has_cpufreq: false,
|
||||||
|
|
||||||
frequency_mhz: 0,
|
available_governors: Vec::new(),
|
||||||
frequency_mhz_minimum: 0,
|
governor: None,
|
||||||
frequency_mhz_maximum: 0,
|
|
||||||
|
frequency_mhz: None,
|
||||||
|
frequency_mhz_minimum: None,
|
||||||
|
frequency_mhz_maximum: None,
|
||||||
|
|
||||||
time_user: 0,
|
time_user: 0,
|
||||||
time_nice: 0,
|
time_nice: 0,
|
||||||
|
@ -123,7 +129,11 @@ 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()?;
|
||||||
|
|
||||||
|
if self.has_cpufreq {
|
||||||
|
self.rescan_governor()?;
|
||||||
self.rescan_frequency()?;
|
self.rescan_frequency()?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -189,6 +199,33 @@ impl Cpu {
|
||||||
Ok(())
|
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<()> {
|
fn rescan_frequency(&mut self) -> anyhow::Result<()> {
|
||||||
let Self { number, .. } = *self;
|
let Self { number, .. } = *self;
|
||||||
|
|
||||||
|
@ -208,32 +245,19 @@ impl Cpu {
|
||||||
.with_context(|| format!("failed to find {self} frequency maximum"))?
|
.with_context(|| format!("failed to find {self} frequency maximum"))?
|
||||||
.with_context(|| format!("failed to parse {self} frequency"))?;
|
.with_context(|| format!("failed to parse {self} frequency"))?;
|
||||||
|
|
||||||
self.frequency_mhz = frequency_khz / 1000;
|
self.frequency_mhz = Some(frequency_khz / 1000);
|
||||||
self.frequency_mhz_minimum = frequency_khz_minimum / 1000;
|
self.frequency_mhz_minimum = Some(frequency_khz_minimum / 1000);
|
||||||
self.frequency_mhz_maximum = frequency_khz_maximum / 1000;
|
self.frequency_mhz_maximum = Some(frequency_khz_maximum / 1000);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_available_governors(&self) -> Vec<String> {
|
pub fn set_governor(&mut self, governor: &str) -> anyhow::Result<()> {
|
||||||
let Self { number, .. } = self;
|
let Self {
|
||||||
|
number,
|
||||||
let Some(Ok(content)) = fs::read(format!(
|
available_governors: ref governors,
|
||||||
"/sys/devices/system/cpu/cpu{number}/cpufreq/scaling_available_governors"
|
..
|
||||||
)) else {
|
} = *self;
|
||||||
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();
|
|
||||||
|
|
||||||
if !governors
|
if !governors
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -253,7 +277,11 @@ impl Cpu {
|
||||||
format!(
|
format!(
|
||||||
"this probably means that {self} doesn't exist or doesn't support changing governors"
|
"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> {
|
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")
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -402,7 +430,7 @@ impl Cpu {
|
||||||
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;
|
self.frequency_mhz_maximum = Some(frequency_mhz);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ pub fn read(path: impl AsRef<Path>) -> Option<anyhow::Result<String>> {
|
||||||
let path = path.as_ref();
|
let path = path.as_ref();
|
||||||
|
|
||||||
match fs::read_to_string(path) {
|
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,
|
Err(error) if error.kind() == io::ErrorKind::NotFound => None,
|
||||||
|
|
||||||
|
|
|
@ -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 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 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() {
|
let turbo_status = if turbo_status_path.exists() {
|
||||||
// 0 means turbo enabled, 1 means disabled for intel_pstate
|
// 0 means turbo enabled, 1 means disabled for intel_pstate
|
||||||
read_sysfs_value::<u8>(turbo_status_path)
|
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
|
// Return the constructed CpuGlobalInfo
|
||||||
CpuGlobalInfo {
|
CpuGlobalInfo {
|
||||||
current_governor,
|
|
||||||
available_governors,
|
|
||||||
turbo_status,
|
turbo_status,
|
||||||
epp: energy_perf_pref,
|
epp: energy_perf_pref,
|
||||||
epb: energy_perf_bias,
|
epb: energy_perf_bias,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue