Improve error information and update libs

This commit is contained in:
NGnius (Graham) 2023-02-23 20:55:12 -05:00
parent 37f96a5cdd
commit fb577620dd
22 changed files with 304 additions and 196 deletions

2
backend/Cargo.lock generated
View file

@ -826,7 +826,7 @@ dependencies = [
[[package]]
name = "powertools-rs"
version = "1.2.0-beta1"
version = "1.2.0-beta2"
dependencies = [
"async-trait",
"limits_core",

View file

@ -1,6 +1,6 @@
[package]
name = "powertools-rs"
version = "1.2.0-beta1"
version = "1.2.0-beta2"
edition = "2021"
authors = ["NGnius (Graham) <ngniusness@gmail.com>"]
description = "Backend (superuser) functionality for PowerTools"

View file

@ -1,4 +1,5 @@
use std::sync::mpsc::{self, Receiver, Sender};
use std::fmt::Write;
use crate::settings::{Settings, TCpus, TGpu, TBattery, TGeneral, OnSet, OnResume, MinMax};
use crate::persist::SettingsJson;
@ -216,6 +217,12 @@ pub struct ApiMessageHandler {
on_empty: Vec<Callback<()>>,
}
fn print_errors(call_name: &str, errors: Vec<crate::settings::SettingError>) {
let mut err_list = String::new();
errors.iter().for_each(|e| write!(err_list, "\t{},\n", e).unwrap_or(()));
log::error!("Settings {}() err:\n{}", call_name, err_list);
}
impl ApiMessageHandler {
pub fn process_forever(&mut self, settings: &mut Settings) {
let mut dirty_echo = true; // set everything twice, to make sure PowerTools wins on race conditions
@ -228,7 +235,7 @@ impl ApiMessageHandler {
dirty_echo = dirty; // echo only once
// run on_set
if let Err(e) = settings.on_set() {
log::error!("Settings on_set() err: {}", e);
print_errors("on_set", e);
}
// do callbacks
for func in self.on_empty.drain(..) {
@ -272,7 +279,7 @@ impl ApiMessageHandler {
ApiMessage::General(x) => x.process(settings.general.as_mut()),
ApiMessage::OnResume => {
if let Err(e) = settings.on_resume() {
log::error!("Settings on_resume() err: {}", e);
print_errors("on_resume", e);
}
false
}

View file

@ -224,7 +224,7 @@ fn main() -> Result<(), ()> {
.register("GENERAL_idk", api::general::gunter);
if let Err(e) = loaded_settings.on_set() {
log::error!("Startup Settings.on_set() error: {}", e);
e.iter().for_each(|e| log::error!("Startup Settings.on_set() error: {}", e));
} else {
log::info!("Startup Settings.on_set() success");
}

View file

@ -37,13 +37,13 @@ pub struct General {
}
impl OnSet for General {
fn on_set(&mut self) -> Result<(), SettingError> {
fn on_set(&mut self) -> Result<(), Vec<SettingError>> {
Ok(())
}
}
impl OnResume for General {
fn on_resume(&self) -> Result<(), SettingError> {
fn on_resume(&self) -> Result<(), Vec<SettingError>> {
Ok(())
}
}
@ -91,7 +91,7 @@ pub struct Settings {
}
impl OnSet for Settings {
fn on_set(&mut self) -> Result<(), SettingError> {
fn on_set(&mut self) -> Result<(), Vec<SettingError>> {
self.battery.on_set()?;
self.cpus.on_set()?;
self.gpu.on_set()?;
@ -224,7 +224,7 @@ impl Settings {
}
impl OnResume for Settings {
fn on_resume(&self) -> Result<(), SettingError> {
fn on_resume(&self) -> Result<(), Vec<SettingError>> {
log::debug!("Applying settings for on_resume");
self.battery.on_resume()?;
log::debug!("Resumed battery");

View file

@ -52,13 +52,15 @@ impl Battery {
}
impl OnSet for Battery {
fn on_set(&mut self) -> Result<(), SettingError> {
fn on_set(&mut self) -> Result<(), Vec<SettingError>> {
// TODO
Ok(())
}
}
impl OnResume for Battery {
fn on_resume(&self) -> Result<(), SettingError> {
fn on_resume(&self) -> Result<(), Vec<SettingError>> {
// TODO
Ok(())
}
}

View file

@ -19,7 +19,8 @@ pub struct Cpus<C: AsMut<Cpu> + AsRef<Cpu> + TCpu> {
}
impl<C: AsMut<Cpu> + AsRef<Cpu> + TCpu + OnSet> OnSet for Cpus<C> {
fn on_set(&mut self) -> Result<(), SettingError> {
fn on_set(&mut self) -> Result<(), Vec<SettingError>> {
let mut errors = Vec::new();
if self.smt_capable {
// toggle SMT
if self.smt {
@ -31,7 +32,7 @@ impl<C: AsMut<Cpu> + AsRef<Cpu> + TCpu + OnSet> OnSet for Cpus<C> {
),
setting: crate::settings::SettingVariant::Cpu,
}
})?;
}).unwrap_or_else(|e| errors.push(e));
} else {
usdpl_back::api::files::write_single(CPU_SMT_PATH, "off").map_err(|e| {
SettingError {
@ -41,23 +42,32 @@ impl<C: AsMut<Cpu> + AsRef<Cpu> + TCpu + OnSet> OnSet for Cpus<C> {
),
setting: crate::settings::SettingVariant::Cpu,
}
})?;
}).unwrap_or_else(|e| errors.push(e));
}
}
for (i, cpu) in self.cpus.as_mut_slice().iter_mut().enumerate() {
cpu.as_mut().state.do_set_online = self.smt || i % 2 == 0 || !self.smt_capable;
cpu.on_set()?;
cpu.on_set().unwrap_or_else(|mut e| errors.append(&mut e));
}
if errors.is_empty() {
Ok(())
} else {
Err(errors)
}
Ok(())
}
}
impl<C: AsMut<Cpu> + AsRef<Cpu> + TCpu + OnResume> OnResume for Cpus<C> {
fn on_resume(&self) -> Result<(), SettingError> {
fn on_resume(&self) -> Result<(), Vec<SettingError>> {
let mut errors = Vec::new();
for cpu in &self.cpus {
cpu.on_resume()?;
cpu.on_resume().unwrap_or_else(|mut e| errors.append(&mut e));
}
if errors.is_empty() {
Ok(())
} else {
Err(errors)
}
Ok(())
}
}
@ -232,7 +242,8 @@ impl FromGenericCpuInfo for Cpu {
}
impl Cpu {
fn set_all(&mut self) -> Result<(), SettingError> {
fn set_all(&mut self) -> Result<(), Vec<SettingError>> {
let mut errors = Vec::new();
// set cpu online/offline
if self.index != 0 && self.state.do_set_online { // cpu0 cannot be disabled
let online_path = cpu_online_path(self.index);
@ -241,7 +252,7 @@ impl Cpu {
msg: format!("Failed to write to `{}`: {}", &online_path, e),
setting: crate::settings::SettingVariant::Cpu,
}
})?;
}).unwrap_or_else(|e| errors.push(e));
}
// set governor
@ -255,9 +266,13 @@ impl Cpu {
),
setting: crate::settings::SettingVariant::Cpu,
}
})?;
}).unwrap_or_else(|e| errors.push(e));
}
if errors.is_empty() {
Ok(())
} else {
Err(errors)
}
Ok(())
}
/*fn from_sys(cpu_index: usize) -> Self {
@ -304,14 +319,14 @@ impl Into<CpuJson> for Cpu {
}
impl OnSet for Cpu {
fn on_set(&mut self) -> Result<(), SettingError> {
fn on_set(&mut self) -> Result<(), Vec<SettingError>> {
//self.clamp_all();
self.set_all()
}
}
impl OnResume for Cpu {
fn on_resume(&self) -> Result<(), SettingError> {
fn on_resume(&self) -> Result<(), Vec<SettingError>> {
let mut copy = self.clone();
copy.state.is_resuming = true;
copy.set_all()

View file

@ -69,13 +69,13 @@ impl Into<GpuJson> for Gpu {
}
impl OnSet for Gpu {
fn on_set(&mut self) -> Result<(), SettingError> {
fn on_set(&mut self) -> Result<(), Vec<SettingError>> {
Ok(())
}
}
impl OnResume for Gpu {
fn on_resume(&self) -> Result<(), SettingError> {
fn on_resume(&self) -> Result<(), Vec<SettingError>> {
Ok(())
}
}

View file

@ -24,14 +24,14 @@ impl Cpus {
}
impl OnResume for Cpus {
fn on_resume(&self) -> Result<(), SettingError> {
fn on_resume(&self) -> Result<(), Vec<SettingError>> {
self.generic.on_resume()
// TODO
}
}
impl OnSet for Cpus {
fn on_set(&mut self) -> Result<(), SettingError> {
fn on_set(&mut self) -> Result<(), Vec<SettingError>> {
self.generic.on_set()
// TODO
}
@ -97,14 +97,14 @@ impl AsMut<GenericCpu> for Cpu {
}
impl OnResume for Cpu {
fn on_resume(&self) -> Result<(), SettingError> {
fn on_resume(&self) -> Result<(), Vec<SettingError>> {
self.generic.on_resume()
// TODO
}
}
impl OnSet for Cpu {
fn on_set(&mut self) -> Result<(), SettingError> {
fn on_set(&mut self) -> Result<(), Vec<SettingError>> {
self.generic.on_set()
// TODO
}

View file

@ -41,25 +41,26 @@ impl Gpu {
}
}
fn set_all(&mut self) -> Result<(), SettingError> {
fn set_all(&mut self) -> Result<(), Vec<SettingError>> {
let mutex = match &self.implementor {
Some(x) => x,
None => {
return Err(SettingError {
return Err(vec![SettingError {
msg: "RyzenAdj unavailable".to_owned(),
setting: SettingVariant::Gpu,
});
}]);
}
};
let lock = match mutex.lock() {
Ok(x) => x,
Err(e) => {
return Err(SettingError {
return Err(vec![SettingError {
msg: format!("RyzenAdj lock acquire failed: {}", e),
setting: SettingVariant::Gpu,
});
}]);
}
};
let mut errors = Vec::new();
if let Some(fast_ppt) = &self.generic.fast_ppt {
if self.state.old_fast_ppt.is_none() {
self.state.old_fast_ppt = Some(lock.get_fast_value() as _);
@ -67,12 +68,12 @@ impl Gpu {
lock.set_fast_limit(*fast_ppt as _).map_err(|e| SettingError {
msg: format!("RyzenAdj set_fast_limit({}) err: {}", *fast_ppt, e),
setting: SettingVariant::Gpu,
})?;
}).unwrap_or_else(|e| errors.push(e));
} else if let Some(fast_ppt) = &self.state.old_fast_ppt {
lock.set_fast_limit(*fast_ppt as _).map_err(|e| SettingError {
msg: format!("RyzenAdj set_fast_limit({}) err: {}", *fast_ppt, e),
setting: SettingVariant::Gpu,
})?;
}).unwrap_or_else(|e| errors.push(e));
self.state.old_fast_ppt = None;
}
if let Some(slow_ppt) = &self.generic.slow_ppt {
@ -82,12 +83,12 @@ impl Gpu {
lock.set_slow_limit(*slow_ppt as _).map_err(|e| SettingError {
msg: format!("RyzenAdj set_slow_limit({}) err: {}", *slow_ppt, e),
setting: SettingVariant::Gpu,
})?;
}).unwrap_or_else(|e| errors.push(e));
} else if let Some(slow_ppt) = &self.state.old_slow_ppt {
lock.set_slow_limit(*slow_ppt as _).map_err(|e| SettingError {
msg: format!("RyzenAdj set_slow_limit({}) err: {}", *slow_ppt, e),
setting: SettingVariant::Gpu,
})?;
}).unwrap_or_else(|e| errors.push(e));
self.state.old_slow_ppt = None;
}
if let Some(clock_limits) = &self.generic.clock_limits {
@ -95,11 +96,11 @@ impl Gpu {
lock.set_max_gfxclk_freq(clock_limits.max as _).map_err(|e| SettingError {
msg: format!("RyzenAdj set_max_gfxclk_freq({}) err: {}", clock_limits.max, e),
setting: SettingVariant::Gpu,
})?;
}).unwrap_or_else(|e| errors.push(e));
lock.set_min_gfxclk_freq(clock_limits.min as _).map_err(|e| SettingError {
msg: format!("RyzenAdj set_min_gfxclk_freq({}) err: {}", clock_limits.min, e),
setting: SettingVariant::Gpu,
})?;
}).unwrap_or_else(|e| errors.push(e));
} else if self.state.clock_limits_set {
self.state.clock_limits_set = false;
let limits = self.generic.limits();
@ -108,73 +109,78 @@ impl Gpu {
lock.set_max_gfxclk_freq(max_limits.max as _).map_err(|e| SettingError {
msg: format!("RyzenAdj set_max_gfxclk_freq({}) err: {}", max_limits.max, e),
setting: SettingVariant::Gpu,
})?;
}).unwrap_or_else(|e| errors.push(e));
lock.set_min_gfxclk_freq(min_limits.min as _).map_err(|e| SettingError {
msg: format!("RyzenAdj set_min_gfxclk_freq({}) err: {}", min_limits.min, e),
setting: SettingVariant::Gpu,
})?;
}).unwrap_or_else(|e| errors.push(e));
}
}
}
Ok(())
if errors.is_empty() {
Ok(())
} else {
Err(errors)
}
}
fn resume_all(&self) -> Result<(), SettingError> {
fn resume_all(&self) -> Result<(), Vec<SettingError>> {
// like set_all() but without updating state
// -- assumption: state is already up to date
let mutex = match &self.implementor {
Some(x) => x,
None => {
return Err(SettingError {
return Err(vec![SettingError {
msg: "RyzenAdj unavailable".to_owned(),
setting: SettingVariant::Gpu,
});
}]);
}
};
let lock = match mutex.lock() {
Ok(x) => x,
Err(e) => {
return Err(SettingError {
return Err(vec![SettingError {
msg: format!("RyzenAdj lock acquire failed: {}", e),
setting: SettingVariant::Gpu,
});
}]);
}
};
let mut errors = Vec::new();
if let Some(fast_ppt) = &self.generic.fast_ppt {
lock.set_fast_limit(*fast_ppt as _).map_err(|e| SettingError {
msg: format!("RyzenAdj set_fast_limit({}) err: {}", *fast_ppt, e),
setting: SettingVariant::Gpu,
})?;
}).unwrap_or_else(|e| errors.push(e));
}
if let Some(slow_ppt) = &self.generic.slow_ppt {
lock.set_slow_limit(*slow_ppt as _).map_err(|e| SettingError {
msg: format!("RyzenAdj set_slow_limit({}) err: {}", *slow_ppt, e),
setting: SettingVariant::Gpu,
})?;
}).unwrap_or_else(|e| errors.push(e));
}
if let Some(clock_limits) = &self.generic.clock_limits {
lock.set_max_gfxclk_freq(clock_limits.max as _).map_err(|e| SettingError {
msg: format!("RyzenAdj set_max_gfxclk_freq({}) err: {}", clock_limits.max, e),
setting: SettingVariant::Gpu,
})?;
}).unwrap_or_else(|e| errors.push(e));
lock.set_min_gfxclk_freq(clock_limits.min as _).map_err(|e| SettingError {
msg: format!("RyzenAdj set_min_gfxclk_freq({}) err: {}", clock_limits.min, e),
setting: SettingVariant::Gpu,
})?;
}).unwrap_or_else(|e| errors.push(e));
}
Ok(())
}
}
impl OnResume for Gpu {
fn on_resume(&self) -> Result<(), SettingError> {
fn on_resume(&self) -> Result<(), Vec<SettingError>> {
self.generic.on_resume()?;
self.resume_all()
}
}
impl OnSet for Gpu {
fn on_set(&mut self) -> Result<(), SettingError> {
fn on_set(&mut self) -> Result<(), Vec<SettingError>> {
self.generic.on_set()?;
self.set_all()
}

View file

@ -67,7 +67,8 @@ impl Battery {
}
}
fn set_all(&mut self) -> Result<(), SettingError> {
fn set_all(&mut self) -> Result<(), Vec<SettingError>> {
let mut errors = Vec::new();
if let Some(charge_rate) = self.charge_rate {
self.state.charge_rate_set = true;
usdpl_back::api::files::write_single(BATTERY_CHARGE_RATE_PATH, charge_rate).map_err(
@ -75,7 +76,7 @@ impl Battery {
msg: format!("Failed to write to `{}`: {}", BATTERY_CHARGE_RATE_PATH, e),
setting: crate::settings::SettingVariant::Battery,
},
)?;
).unwrap_or_else(|e| errors.push(e));
} else if self.state.charge_rate_set {
self.state.charge_rate_set = false;
usdpl_back::api::files::write_single(BATTERY_CHARGE_RATE_PATH, self.limits.charge_rate.max).map_err(
@ -83,7 +84,7 @@ impl Battery {
msg: format!("Failed to write to `{}`: {}", BATTERY_CHARGE_RATE_PATH, e),
setting: crate::settings::SettingVariant::Battery,
},
)?;
).unwrap_or_else(|e| errors.push(e));
}
if let Some(charge_mode) = self.charge_mode {
self.state.charge_mode_set = true;
@ -92,7 +93,7 @@ impl Battery {
msg: format!("Failed to set charge mode: {}", e),
setting: crate::settings::SettingVariant::Battery,
},
)?;
).unwrap_or_else(|e| {errors.push(e); 0});
} else if self.state.charge_mode_set {
self.state.charge_mode_set = false;
super::util::set(super::util::Setting::ChargeMode, ChargeMode::Normal as _).map_err(
@ -100,9 +101,13 @@ impl Battery {
msg: format!("Failed to set charge mode: {}", e),
setting: crate::settings::SettingVariant::Battery,
},
)?;
).unwrap_or_else(|e| {errors.push(e); 0});
}
if errors.is_empty() {
Ok(())
} else {
Err(errors)
}
Ok(())
}
fn clamp_all(&mut self) {
@ -181,14 +186,14 @@ impl Into<BatteryJson> for Battery {
}
impl OnSet for Battery {
fn on_set(&mut self) -> Result<(), SettingError> {
fn on_set(&mut self) -> Result<(), Vec<SettingError>> {
self.clamp_all();
self.set_all()
}
}
impl OnResume for Battery {
fn on_resume(&self) -> Result<(), SettingError> {
fn on_resume(&self) -> Result<(), Vec<SettingError>> {
self.clone().set_all()
}
}

View file

@ -20,7 +20,8 @@ pub struct Cpus {
}
impl OnSet for Cpus {
fn on_set(&mut self) -> Result<(), SettingError> {
fn on_set(&mut self) -> Result<(), Vec<SettingError>> {
let mut errors = Vec::new();
if self.smt_capable {
// toggle SMT
if self.smt {
@ -32,7 +33,7 @@ impl OnSet for Cpus {
),
setting: crate::settings::SettingVariant::Cpu,
}
})?;
}).unwrap_or_else(|e| errors.push(e));
} else {
usdpl_back::api::files::write_single(CPU_SMT_PATH, "off").map_err(|e| {
SettingError {
@ -42,23 +43,32 @@ impl OnSet for Cpus {
),
setting: crate::settings::SettingVariant::Cpu,
}
})?;
}).unwrap_or_else(|e| errors.push(e));
}
}
for (i, cpu) in self.cpus.as_mut_slice().iter_mut().enumerate() {
cpu.state.do_set_online = self.smt || i % 2 == 0;
cpu.on_set()?;
cpu.on_set().unwrap_or_else(|mut e| errors.append(&mut e));
}
if errors.is_empty() {
Ok(())
} else {
Err(errors)
}
Ok(())
}
}
impl OnResume for Cpus {
fn on_resume(&self) -> Result<(), SettingError> {
fn on_resume(&self) -> Result<(), Vec<SettingError>> {
let mut errors = Vec::new();
for cpu in &self.cpus {
cpu.on_resume()?;
cpu.on_resume().unwrap_or_else(|mut e| errors.append(&mut e));
}
if errors.is_empty() {
Ok(())
} else {
Err(errors)
}
Ok(())
}
}
@ -221,30 +231,22 @@ impl Cpu {
}
}
fn set_all(&mut self) -> Result<(), SettingError> {
// set cpu online/offline
if self.index != 0 && self.state.do_set_online { // cpu0 cannot be disabled
let online_path = cpu_online_path(self.index);
usdpl_back::api::files::write_single(&online_path, self.online as u8).map_err(|e| {
SettingError {
msg: format!("Failed to write to `{}`: {}", &online_path, e),
setting: crate::settings::SettingVariant::Cpu,
}
})?;
}
fn set_force_performance_related(&mut self) -> Result<(), Vec<SettingError>> {
let mut errors = Vec::new();
// set clock limits
log::debug!("Setting {} to manual", CPU_FORCE_LIMITS_PATH);
let mode: String = usdpl_back::api::files::read_single(CPU_FORCE_LIMITS_PATH.to_owned()).unwrap();
if mode != "manual" {
// set manual control
usdpl_back::api::files::write_single(CPU_FORCE_LIMITS_PATH, "manual").map_err(|e| {
SettingError {
vec![SettingError {
msg: format!(
"Failed to write `manual` to `{}`: {}",
CPU_FORCE_LIMITS_PATH, e
),
setting: crate::settings::SettingVariant::Cpu,
}
}]
})?;
}
if let Some(clock_limits) = &self.clock_limits {
@ -260,7 +262,7 @@ impl Cpu {
),
setting: crate::settings::SettingVariant::Cpu,
},
)?;
).unwrap_or_else(|e| errors.push(e));
// min clock
let valid_min = if clock_limits.min < self.limits.clock_min.min {self.limits.clock_min.min} else {clock_limits.min};
let payload_min = format!("p {} 0 {}\n", self.index / 2, valid_min);
@ -272,7 +274,7 @@ impl Cpu {
),
setting: crate::settings::SettingVariant::Cpu,
},
)?;
).unwrap_or_else(|e| errors.push(e));
} else if self.state.clock_limits_set || (self.state.is_resuming && !self.limits.skip_resume_reclock) {
self.state.clock_limits_set = false;
// disable manual clock limits
@ -287,7 +289,7 @@ impl Cpu {
),
setting: crate::settings::SettingVariant::Cpu,
},
)?;
).unwrap_or_else(|e| errors.push(e));
// min clock
let payload_min = format!("p {} 0 {}\n", self.index / 2, self.limits.clock_min.min);
usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, &payload_min).map_err(
@ -298,15 +300,39 @@ impl Cpu {
),
setting: crate::settings::SettingVariant::Cpu,
},
)?;
).unwrap_or_else(|e| errors.push(e));
}
// commit changes
usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, "c\n").map_err(|e| {
SettingError {
msg: format!("Failed to write `c` to `{}`: {}", CPU_CLOCK_LIMITS_PATH, e),
setting: crate::settings::SettingVariant::Cpu,
}
})?;
usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, "c\n")
.unwrap_or_else(|e| {
errors.push(SettingError {
msg: format!("Failed to write `c` to `{}`: {}", CPU_CLOCK_LIMITS_PATH, e),
setting: crate::settings::SettingVariant::Cpu,
});
});
if errors.is_empty() {
Ok(())
} else {
Err(errors)
}
}
fn set_all(&mut self) -> Result<(), Vec<SettingError>> {
let mut errors = Vec::new();
// set cpu online/offline
if self.index != 0 && self.state.do_set_online { // cpu0 cannot be disabled
let online_path = cpu_online_path(self.index);
usdpl_back::api::files::write_single(&online_path, self.online as u8).map_err(|e| {
SettingError {
msg: format!("Failed to write to `{}`: {}", &online_path, e),
setting: crate::settings::SettingVariant::Cpu,
}
}).unwrap_or_else(|e| errors.push(e));
}
self.set_force_performance_related()
.unwrap_or_else(|mut e| errors.append(&mut e));
// set governor
if self.index == 0 || self.online {
@ -319,9 +345,13 @@ impl Cpu {
),
setting: crate::settings::SettingVariant::Cpu,
}
})?;
}).unwrap_or_else(|e| errors.push(e));
}
if errors.is_empty() {
Ok(())
} else {
Err(errors)
}
Ok(())
}
fn clamp_all(&mut self) {
@ -394,14 +424,14 @@ impl Into<CpuJson> for Cpu {
}
impl OnSet for Cpu {
fn on_set(&mut self) -> Result<(), SettingError> {
fn on_set(&mut self) -> Result<(), Vec<SettingError>> {
self.clamp_all();
self.set_all()
}
}
impl OnResume for Cpu {
fn on_resume(&self) -> Result<(), SettingError> {
fn on_resume(&self) -> Result<(), Vec<SettingError>> {
let mut copy = self.clone();
copy.state.is_resuming = true;
copy.set_all()

View file

@ -53,53 +53,8 @@ impl Gpu {
}
}
fn set_all(&mut self) -> Result<(), SettingError> {
// set fast PPT
if let Some(fast_ppt) = &self.fast_ppt {
let fast_ppt_path = gpu_power_path(FAST_PPT);
usdpl_back::api::files::write_single(&fast_ppt_path, fast_ppt).map_err(|e| {
SettingError {
msg: format!(
"Failed to write `{}` to `{}`: {}",
fast_ppt, &fast_ppt_path, e
),
setting: crate::settings::SettingVariant::Gpu,
}
})?;
}
// set slow PPT
if let Some(slow_ppt) = &self.slow_ppt {
let slow_ppt_path = gpu_power_path(SLOW_PPT);
usdpl_back::api::files::write_single(&slow_ppt_path, slow_ppt).map_err(|e| {
SettingError {
msg: format!(
"Failed to write `{}` to `{}`: {}",
slow_ppt, &slow_ppt_path, e
),
setting: crate::settings::SettingVariant::Gpu,
}
})?;
}
// settings using force_performance_level
let mode: String = usdpl_back::api::files::read_single(GPU_FORCE_LIMITS_PATH.to_owned()).unwrap();
if mode != "manual" {
// set manual control
usdpl_back::api::files::write_single(GPU_FORCE_LIMITS_PATH, "manual").map_err(|e| {
SettingError {
msg: format!(
"Failed to write `manual` to `{}`: {}",
GPU_FORCE_LIMITS_PATH, e
),
setting: crate::settings::SettingVariant::Gpu,
}
})?;
}
// enable/disable downclock of GPU memory (to 400Mhz?)
usdpl_back::api::files::write_single(GPU_MEMORY_DOWNCLOCK_PATH, self.slow_memory as u8)
.map_err(|e| SettingError {
msg: format!("Failed to write to `{}`: {}", GPU_MEMORY_DOWNCLOCK_PATH, e),
setting: crate::settings::SettingVariant::Gpu,
})?;
fn set_clocks(&mut self) -> Result<(), Vec<SettingError>> {
let mut errors = Vec::new();
if let Some(clock_limits) = &self.clock_limits {
// set clock limits
self.state.clock_limits_set = true;
@ -113,7 +68,7 @@ impl Gpu {
),
setting: crate::settings::SettingVariant::Gpu,
},
)?;
).unwrap_or_else(|e| errors.push(e));
// min clock
let payload_min = format!("s 0 {}\n", clock_limits.min);
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, &payload_min).map_err(
@ -124,7 +79,7 @@ impl Gpu {
),
setting: crate::settings::SettingVariant::Gpu,
},
)?;
).unwrap_or_else(|e| errors.push(e));
} else if self.state.clock_limits_set || (self.state.is_resuming && !self.limits.skip_resume_reclock) {
self.state.clock_limits_set = false;
// disable manual clock limits
@ -138,7 +93,7 @@ impl Gpu {
),
setting: crate::settings::SettingVariant::Gpu,
},
)?;
).unwrap_or_else(|e| errors.push(e));
// min clock
let payload_min = format!("s 0 {}\n", self.limits.clock_min.min);
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, &payload_min).map_err(
@ -149,17 +104,90 @@ impl Gpu {
),
setting: crate::settings::SettingVariant::Gpu,
},
)?;
).unwrap_or_else(|e| errors.push(e));
}
if errors.is_empty() {
Ok(())
} else {
Err(errors)
}
}
fn set_force_performance_related(&mut self) -> Result<(), Vec<SettingError>> {
let mut errors = Vec::new();
// settings using force_performance_level
let mode: String = usdpl_back::api::files::read_single(GPU_FORCE_LIMITS_PATH.to_owned()).unwrap();
if mode != "manual" {
// set manual control
usdpl_back::api::files::write_single(GPU_FORCE_LIMITS_PATH, "manual").map_err(|e| {
vec![SettingError {
msg: format!(
"Failed to write `manual` to `{}`: {}",
GPU_FORCE_LIMITS_PATH, e
),
setting: crate::settings::SettingVariant::Gpu,
}]
})?;
}
// enable/disable downclock of GPU memory (to 400Mhz?)
usdpl_back::api::files::write_single(GPU_MEMORY_DOWNCLOCK_PATH, self.slow_memory as u8)
.unwrap_or_else(|e| {
errors.push(SettingError {
msg: format!("Failed to write to `{}`: {}", GPU_MEMORY_DOWNCLOCK_PATH, e),
setting: crate::settings::SettingVariant::Gpu,
});
});
self.set_clocks()
.unwrap_or_else(|mut e| errors.append(&mut e));
// commit changes
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, "c\n").map_err(|e| {
SettingError {
msg: format!("Failed to write `c` to `{}`: {}", GPU_CLOCK_LIMITS_PATH, e),
setting: crate::settings::SettingVariant::Gpu,
}
})?;
}).unwrap_or_else(|e| errors.push(e));
if errors.is_empty() {
Ok(())
} else {
Err(errors)
}
}
Ok(())
fn set_all(&mut self) -> Result<(), Vec<SettingError>> {
let mut errors = Vec::new();
// set fast PPT
if let Some(fast_ppt) = &self.fast_ppt {
let fast_ppt_path = gpu_power_path(FAST_PPT);
usdpl_back::api::files::write_single(&fast_ppt_path, fast_ppt).map_err(|e| {
SettingError {
msg: format!(
"Failed to write `{}` to `{}`: {}",
fast_ppt, &fast_ppt_path, e
),
setting: crate::settings::SettingVariant::Gpu,
}
}).unwrap_or_else(|e| {errors.push(e);});
}
// set slow PPT
if let Some(slow_ppt) = &self.slow_ppt {
let slow_ppt_path = gpu_power_path(SLOW_PPT);
usdpl_back::api::files::write_single(&slow_ppt_path, slow_ppt).map_err(|e| {
SettingError {
msg: format!(
"Failed to write `{}` to `{}`: {}",
slow_ppt, &slow_ppt_path, e
),
setting: crate::settings::SettingVariant::Gpu,
}
}).unwrap_or_else(|e| {errors.push(e);});
}
self.set_force_performance_related()
.unwrap_or_else(|mut e| errors.append(&mut e));
if errors.is_empty() {
Ok(())
} else {
Err(errors)
}
}
fn clamp_all(&mut self) {
@ -208,14 +236,14 @@ impl Into<GpuJson> for Gpu {
}
impl OnSet for Gpu {
fn on_set(&mut self) -> Result<(), SettingError> {
fn on_set(&mut self) -> Result<(), Vec<SettingError>> {
self.clamp_all();
self.set_all()
}
}
impl OnResume for Gpu {
fn on_resume(&self) -> Result<(), SettingError> {
fn on_resume(&self) -> Result<(), Vec<SettingError>> {
let mut copy = self.clone();
copy.state.is_resuming = true;
copy.set_all()

View file

@ -3,11 +3,11 @@ use super::SettingError;
use super::MinMax;
pub trait OnSet {
fn on_set(&mut self) -> Result<(), SettingError>;
fn on_set(&mut self) -> Result<(), Vec<SettingError>>;
}
pub trait OnResume {
fn on_resume(&self) -> Result<(), SettingError>;
fn on_resume(&self) -> Result<(), Vec<SettingError>>;
}
pub trait SettingsRange {

View file

@ -18,13 +18,13 @@ impl Into<BatteryJson> for Battery {
}
impl OnSet for Battery {
fn on_set(&mut self) -> Result<(), SettingError> {
fn on_set(&mut self) -> Result<(), Vec<SettingError>> {
Ok(())
}
}
impl OnResume for Battery {
fn on_resume(&self) -> Result<(), SettingError> {
fn on_resume(&self) -> Result<(), Vec<SettingError>> {
Ok(())
}
}

View file

@ -16,7 +16,8 @@ pub struct Cpus {
}
impl OnSet for Cpus {
fn on_set(&mut self) -> Result<(), SettingError> {
fn on_set(&mut self) -> Result<(), Vec<SettingError>> {
let mut errors = Vec::new();
if self.smt_capable {
// toggle SMT
if self.smt {
@ -28,7 +29,7 @@ impl OnSet for Cpus {
),
setting: crate::settings::SettingVariant::Cpu,
}
})?;
}).unwrap_or_else(|e| {errors.push(e);});
} else {
usdpl_back::api::files::write_single(CPU_SMT_PATH, "off").map_err(|e| {
SettingError {
@ -38,23 +39,32 @@ impl OnSet for Cpus {
),
setting: crate::settings::SettingVariant::Cpu,
}
})?;
}).unwrap_or_else(|e| {errors.push(e);});
}
}
for (i, cpu) in self.cpus.as_mut_slice().iter_mut().enumerate() {
cpu.state.do_set_online = self.smt || i % 2 == 0;
cpu.on_set()?;
cpu.state.do_set_online = self.smt || i % 2 == 0 || !self.smt_capable;
cpu.on_set().unwrap_or_else(|mut e| errors.append(&mut e));
}
if errors.is_empty() {
Ok(())
} else {
Err(errors)
}
Ok(())
}
}
impl OnResume for Cpus {
fn on_resume(&self) -> Result<(), SettingError> {
fn on_resume(&self) -> Result<(), Vec<SettingError>> {
let mut errors = Vec::new();
for cpu in &self.cpus {
cpu.on_resume()?;
cpu.on_resume().unwrap_or_else(|mut e| errors.append(&mut e));
}
if errors.is_empty() {
Ok(())
} else {
Err(errors)
}
Ok(())
}
}
@ -191,7 +201,8 @@ impl Cpu {
}
}
fn set_all(&mut self) -> Result<(), SettingError> {
fn set_all(&mut self) -> Result<(), Vec<SettingError>> {
let mut errors = Vec::new();
// set cpu online/offline
if self.index != 0 && self.state.do_set_online { // cpu0 cannot be disabled
let online_path = cpu_online_path(self.index);
@ -200,7 +211,7 @@ impl Cpu {
msg: format!("Failed to write to `{}`: {}", &online_path, e),
setting: crate::settings::SettingVariant::Cpu,
}
})?;
}).unwrap_or_else(|e| errors.push(e));
}
// set governor
@ -214,9 +225,13 @@ impl Cpu {
),
setting: crate::settings::SettingVariant::Cpu,
}
})?;
}).unwrap_or_else(|e| errors.push(e));
}
if errors.is_empty() {
Ok(())
} else {
Err(errors)
}
Ok(())
}
fn from_sys(cpu_index: usize) -> Self {
@ -251,14 +266,14 @@ impl Into<CpuJson> for Cpu {
}
impl OnSet for Cpu {
fn on_set(&mut self) -> Result<(), SettingError> {
fn on_set(&mut self) -> Result<(), Vec<SettingError>> {
//self.clamp_all();
self.set_all()
}
}
impl OnResume for Cpu {
fn on_resume(&self) -> Result<(), SettingError> {
fn on_resume(&self) -> Result<(), Vec<SettingError>> {
let mut copy = self.clone();
copy.state.is_resuming = true;
copy.set_all()

View file

@ -38,13 +38,13 @@ impl Into<GpuJson> for Gpu {
}
impl OnSet for Gpu {
fn on_set(&mut self) -> Result<(), SettingError> {
fn on_set(&mut self) -> Result<(), Vec<SettingError>> {
Ok(())
}
}
impl OnResume for Gpu {
fn on_resume(&self) -> Result<(), SettingError> {
fn on_resume(&self) -> Result<(), Vec<SettingError>> {
Ok(())
}
}

View file

@ -44,10 +44,10 @@ pub fn chown_settings_dir() -> std::io::Result<()> {
.output()?;
let uid: u32 = String::from_utf8_lossy(&output.stdout).parse().unwrap_or(1000);
log::info!("chmod/chown ~/.config/powertools for user `{}` ({})", deck_user, uid);
let permissions = PermissionsExt::from_mode(0o655);
let permissions = PermissionsExt::from_mode(0o755);
std::fs::set_permissions(&dir, permissions)?;
// FIXME once merged into stable https://github.com/rust-lang/rust/issues/88989
//std::os::unix::fs::chown(&dir, Some(uid), None)
//std::os::unix::fs::chown(&dir, Some(uid), Some(uid))
std::process::Command::new("chown")
.args(["-R", &format!("{}:{}", deck_user, deck_user), &dir.to_str().unwrap_or(".")])
.output()?;

View file

@ -1,6 +1,6 @@
{
"name": "PowerTools",
"version": "1.2.0-beta1",
"version": "1.2.0-beta2",
"description": "Power tweaks for power users",
"scripts": {
"build": "shx rm -rf dist && rollup -c",
@ -39,7 +39,7 @@
"typescript": "^4.9.5"
},
"dependencies": {
"decky-frontend-lib": "~3.18.11",
"decky-frontend-lib": "~3.19.1",
"react-icons": "^4.7.1",
"usdpl-front": "file:src/usdpl_front"
}

View file

@ -8,7 +8,7 @@ specifiers:
'@rollup/plugin-typescript': ^8.5.0
'@types/react': 16.14.0
'@types/webpack': ^5.28.0
decky-frontend-lib: ~3.18.11
decky-frontend-lib: ~3.19.1
react-icons: ^4.7.1
rollup: ^2.79.1
rollup-plugin-import-assets: ^1.1.1
@ -18,7 +18,7 @@ specifiers:
usdpl-front: file:src/usdpl_front
dependencies:
decky-frontend-lib: 3.18.11
decky-frontend-lib: 3.19.1
react-icons: 4.7.1
usdpl-front: file:src/usdpl_front
@ -185,8 +185,8 @@ packages:
resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==}
dev: true
/@types/node/18.14.0:
resolution: {integrity: sha512-5EWrvLmglK+imbCJY0+INViFWUHg1AHel1sq4ZVSfdcNqGy9Edv3UB9IIzzg+xPaUcAgZYcfVs2fBcwDeZzU0A==}
/@types/node/18.14.1:
resolution: {integrity: sha512-QH+37Qds3E0eDlReeboBxfHbX9omAcBCXEzswCu6jySP642jiM3cYSIkU/REqwhCUqXdonHFuBfJDiAJxMNhaQ==}
dev: true
/@types/prop-types/15.7.5:
@ -203,13 +203,13 @@ packages:
/@types/resolve/1.17.1:
resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==}
dependencies:
'@types/node': 18.14.0
'@types/node': 18.14.1
dev: true
/@types/webpack/5.28.0:
resolution: {integrity: sha512-8cP0CzcxUiFuA9xGJkfeVpqmWTk9nx6CWwamRGCj95ph1SmlRRk9KlCZ6avhCbZd4L68LvYT6l1kpdEnQXrF8w==}
dependencies:
'@types/node': 18.14.0
'@types/node': 18.14.1
tapable: 2.2.1
webpack: 5.75.0
transitivePeerDependencies:
@ -381,7 +381,7 @@ packages:
hasBin: true
dependencies:
caniuse-lite: 1.0.30001457
electron-to-chromium: 1.4.305
electron-to-chromium: 1.4.309
node-releases: 2.0.10
update-browserslist-db: 1.0.10_browserslist@4.21.5
dev: true
@ -420,8 +420,8 @@ packages:
resolution: {integrity: sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==}
dev: true
/decky-frontend-lib/3.18.11:
resolution: {integrity: sha512-SLb3qWJc6CLNRqcbNyJsA8D6sXf7aix8/h6VqQTWjVmel6c3SkOR6b9KMvgFRzXumfRt7XGasBnZJmyCwH4BCQ==}
/decky-frontend-lib/3.19.1:
resolution: {integrity: sha512-hU4+EFs74MGzUCv8l1AO2+EBj9RRbnpU19Crm4u+3lbLu6d63U2GsUeQ9ssmNRcOMY1OuVZkRoZBE58soOBJ3A==}
dev: false
/deepmerge/4.3.0:
@ -429,8 +429,8 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
/electron-to-chromium/1.4.305:
resolution: {integrity: sha512-WETy6tG0CT5gm1O+xCbyapWNsCcmIvrn4NHViIGYo2AT8FV2qUCXdaB+WqYxSv/vS5mFqhBYnfZAAkVArjBmUg==}
/electron-to-chromium/1.4.309:
resolution: {integrity: sha512-U7DTiKe4h+irqBG6h4EZ0XXaZuJj4md3xIXXaGSYhwiumPZ4BSc6rgf9UD0hVUMaeP/jB0q5pKWCPxvhO8fvZA==}
dev: true
/enhanced-resolve/5.12.0:
@ -590,7 +590,7 @@ packages:
resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==}
engines: {node: '>= 10.13.0'}
dependencies:
'@types/node': 18.14.0
'@types/node': 18.14.1
merge-stream: 2.0.0
supports-color: 8.1.1
dev: true
@ -821,12 +821,12 @@ packages:
jest-worker: 27.5.1
schema-utils: 3.1.1
serialize-javascript: 6.0.1
terser: 5.16.4
terser: 5.16.5
webpack: 5.75.0
dev: true
/terser/5.16.4:
resolution: {integrity: sha512-5yEGuZ3DZradbogeYQ1NaGz7rXVBDWujWlx1PT8efXO6Txn+eWbfKqB2bTDVmFXmePFkoLU6XI8UektMIEA0ug==}
/terser/5.16.5:
resolution: {integrity: sha512-qcwfg4+RZa3YvlFh0qjifnzBHjKGNbtDo9yivMqMFDy9Q6FSaQWSB/j1xKhsoUFJIqDOM3TsN6D5xbrMrFcHbg==}
engines: {node: '>=10'}
hasBin: true
dependencies:

View file

@ -29,7 +29,7 @@ export async function initBackend() {
// init usdpl
await init_embedded();
init_usdpl(USDPL_PORT);
console.log("USDPL started for framework: " + target_usdpl());
console.log("POWERTOOLS: USDPL started for framework: " + target_usdpl());
const user_locale =
navigator.languages && navigator.languages.length
? navigator.languages[0]

View file

@ -35,7 +35,7 @@ function buildDebug() {
if (eggCount % 10 == 9) {
// you know you're bored and/or conceited when you spend time adding an easter egg
// that just sends people to your own project's repo
Router.NavigateToExternalWeb("https://github.com/NGnius/PowerTools");
Router.NavigateToExternalWeb("https://github.com/NGnius/PowerTools/releases");
}
eggCount++;
}}>