diff --git a/.gitignore b/.gitignore index 71e279b..ed38553 100644 --- a/.gitignore +++ b/.gitignore @@ -41,5 +41,6 @@ __pycache__/ yalc.lock # rust -/powertools-rs/target +/backend/target /bin +/backend/out diff --git a/powertools-rs/Cargo.lock b/backend/Cargo.lock similarity index 98% rename from powertools-rs/Cargo.lock rename to backend/Cargo.lock index 850bf31..aceef7c 100644 --- a/powertools-rs/Cargo.lock +++ b/backend/Cargo.lock @@ -567,7 +567,7 @@ dependencies = [ [[package]] name = "powertools-rs" -version = "1.0.0" +version = "1.0.0-beta4" dependencies = [ "log", "serde", @@ -1054,6 +1054,8 @@ dependencies = [ [[package]] name = "usdpl-back" version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbbc0781e83ba990f8239142e33173a2d2548701775f3db66702d1af4fd0319a" dependencies = [ "bytes", "hex", @@ -1066,6 +1068,8 @@ dependencies = [ [[package]] name = "usdpl-core" version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "862153581fac266458521f49e5906a71c1eee1665cb4c7d71e9586bd34b45394" dependencies = [ "aes-gcm-siv", "base64", diff --git a/powertools-rs/Cargo.toml b/backend/Cargo.toml similarity index 71% rename from powertools-rs/Cargo.toml rename to backend/Cargo.toml index d6565f0..ddacce4 100644 --- a/powertools-rs/Cargo.toml +++ b/backend/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "powertools-rs" -version = "1.0.0" +version = "1.0.0-beta4" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -usdpl-back = { version = "0.6.0", features = ["blocking"], path = "../../usdpl-rs/usdpl-back"} +usdpl-back = { version = "0.6.0", features = ["blocking"]} serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" @@ -19,3 +19,9 @@ default = [] decky = ["usdpl-back/decky"] crankshaft = ["usdpl-back/crankshaft"] encrypt = ["usdpl-back/encrypt"] + +[profile.release] +debug = false +strip = true +lto = true +codegen-units = 4 diff --git a/powertools-rs/Cross.toml b/backend/Cross.toml similarity index 100% rename from powertools-rs/Cross.toml rename to backend/Cross.toml diff --git a/backend/Dockerfile b/backend/Dockerfile new file mode 100644 index 0000000..f1a0ed3 --- /dev/null +++ b/backend/Dockerfile @@ -0,0 +1,3 @@ +FROM ghcr.io/steamdeckhomebrew/holo-toolchain-rust:latest + +ENTRYPOINT [ "/backend/entrypoint.sh" ] \ No newline at end of file diff --git a/backend/Makefile b/backend/Makefile new file mode 100644 index 0000000..a1e5dc5 --- /dev/null +++ b/backend/Makefile @@ -0,0 +1,14 @@ +# This is the default target, which will be built when +# you invoke make +.PHONY: all +all: hello + +# This rule tells make how to build hello from hello.cpp +hello: + mkdir -p ./out + gcc -o ./out/hello ./src/main.c + +# This rule tells make to delete hello and hello.o +.PHONY: clean +clean: + rm -f hello \ No newline at end of file diff --git a/backend/build-docker.sh b/backend/build-docker.sh new file mode 100755 index 0000000..c6074a9 --- /dev/null +++ b/backend/build-docker.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +echo "--- Rust version info ---" +rustup --version +rustc --version +cargo --version + +echo "--- Building plugin backend ---" +cargo build --release +mkdir -p out +cp target/release/powertools-rs out/backend + +echo " --- Cleaning up ---" +# remove root-owned target folder +cargo clean diff --git a/powertools-rs/build.sh b/backend/build.sh similarity index 100% rename from powertools-rs/build.sh rename to backend/build.sh diff --git a/backend/create_docker_img.sh b/backend/create_docker_img.sh new file mode 100755 index 0000000..4ff3064 --- /dev/null +++ b/backend/create_docker_img.sh @@ -0,0 +1,4 @@ +#!/bin/bash +# build docker container locally (for testing) + +docker build -t powertools_backend . diff --git a/backend/entrypoint.sh b/backend/entrypoint.sh new file mode 100755 index 0000000..db4cf23 --- /dev/null +++ b/backend/entrypoint.sh @@ -0,0 +1,8 @@ +#!/bin/sh +set -e + +echo "Container's IP address: `awk 'END{print $1}' /etc/hosts`" + +cd /backend + +sudo bash build-docker.sh \ No newline at end of file diff --git a/backend/run_docker_img.sh b/backend/run_docker_img.sh new file mode 100755 index 0000000..c8d8eb9 --- /dev/null +++ b/backend/run_docker_img.sh @@ -0,0 +1,7 @@ +#!/bin/bash +# run docker container locally (for testing) +# assumes you're running in the backend/ dir of the project + +docker run -i --entrypoint /backend/entrypoint.sh -v $PWD:/backend powertools_backend +mkdir -p ../bin +cp ./out/backend ../bin diff --git a/powertools-rs/src/api/battery.rs b/backend/src/api/battery.rs similarity index 97% rename from powertools-rs/src/api/battery.rs rename to backend/src/api/battery.rs index 507ed78..6f717af 100644 --- a/powertools-rs/src/api/battery.rs +++ b/backend/src/api/battery.rs @@ -59,6 +59,6 @@ pub fn unset_charge_rate( unwrap_lock(saver.lock(), "save channel").send(()), "Failed to send on save channel", ); - vec![] + super::utility::map_empty_result(settings_lock.on_set(), true) } } diff --git a/powertools-rs/src/api/cpu.rs b/backend/src/api/cpu.rs similarity index 99% rename from powertools-rs/src/api/cpu.rs rename to backend/src/api/cpu.rs index 02d8570..a9f66bd 100644 --- a/powertools-rs/src/api/cpu.rs +++ b/backend/src/api/cpu.rs @@ -139,7 +139,7 @@ pub fn unset_clock_limits( unwrap_lock(saver.lock(), "save channel").send(()), "Failed to send on save channel", ); - vec![] + super::utility::map_empty_result(cpu.on_set(), true) } else { vec!["get_clock_limits cpu index out of bounds".into()] } diff --git a/powertools-rs/src/api/general.rs b/backend/src/api/general.rs similarity index 98% rename from powertools-rs/src/api/general.rs rename to backend/src/api/general.rs index 67dcba4..cd58e3f 100644 --- a/powertools-rs/src/api/general.rs +++ b/backend/src/api/general.rs @@ -97,7 +97,7 @@ pub fn get_name( } } -/// Generate get current settings name +/// Generate wait for all locks to be available web method pub fn lock_unlock_all( settings: Settings, ) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType { diff --git a/powertools-rs/src/api/gpu.rs b/backend/src/api/gpu.rs similarity index 98% rename from powertools-rs/src/api/gpu.rs rename to backend/src/api/gpu.rs index 008f563..bff5aa9 100644 --- a/powertools-rs/src/api/gpu.rs +++ b/backend/src/api/gpu.rs @@ -124,7 +124,7 @@ pub fn unset_clock_limits( unwrap_lock(saver.lock(), "save channel").send(()), "Failed to send on save channel", ); - vec![] + super::utility::map_empty_result(settings_lock.on_set(), true) } } diff --git a/powertools-rs/src/api/mod.rs b/backend/src/api/mod.rs similarity index 100% rename from powertools-rs/src/api/mod.rs rename to backend/src/api/mod.rs diff --git a/powertools-rs/src/api/utility.rs b/backend/src/api/utility.rs similarity index 100% rename from powertools-rs/src/api/utility.rs rename to backend/src/api/utility.rs diff --git a/powertools-rs/src/consts.rs b/backend/src/consts.rs similarity index 100% rename from powertools-rs/src/consts.rs rename to backend/src/consts.rs diff --git a/powertools-rs/src/main.rs b/backend/src/main.rs similarity index 95% rename from powertools-rs/src/main.rs rename to backend/src/main.rs index d612013..ffb887a 100644 --- a/powertools-rs/src/main.rs +++ b/backend/src/main.rs @@ -17,7 +17,13 @@ use usdpl_back::core::serdes::Primitive; use usdpl_back::Instance; fn main() -> Result<(), ()> { - let log_filepath = format!("/tmp/{}.log", PACKAGE_NAME); + let log_filepath = format!("/home/deck/{}.log", PACKAGE_NAME); + #[cfg(debug_assertions)] + { + if std::path::Path::new(&log_filepath).exists() { + std::fs::copy(&log_filepath, "/home/deck/powertools.log.old").unwrap(); + } + } WriteLogger::init( #[cfg(debug_assertions)] { diff --git a/powertools-rs/src/persist/battery.rs b/backend/src/persist/battery.rs similarity index 100% rename from powertools-rs/src/persist/battery.rs rename to backend/src/persist/battery.rs diff --git a/powertools-rs/src/persist/cpu.rs b/backend/src/persist/cpu.rs similarity index 100% rename from powertools-rs/src/persist/cpu.rs rename to backend/src/persist/cpu.rs diff --git a/powertools-rs/src/persist/error.rs b/backend/src/persist/error.rs similarity index 100% rename from powertools-rs/src/persist/error.rs rename to backend/src/persist/error.rs diff --git a/powertools-rs/src/persist/general.rs b/backend/src/persist/general.rs similarity index 100% rename from powertools-rs/src/persist/general.rs rename to backend/src/persist/general.rs diff --git a/powertools-rs/src/persist/gpu.rs b/backend/src/persist/gpu.rs similarity index 100% rename from powertools-rs/src/persist/gpu.rs rename to backend/src/persist/gpu.rs diff --git a/powertools-rs/src/persist/mod.rs b/backend/src/persist/mod.rs similarity index 100% rename from powertools-rs/src/persist/mod.rs rename to backend/src/persist/mod.rs diff --git a/powertools-rs/src/resume_worker.rs b/backend/src/resume_worker.rs similarity index 100% rename from powertools-rs/src/resume_worker.rs rename to backend/src/resume_worker.rs diff --git a/powertools-rs/src/save_worker.rs b/backend/src/save_worker.rs similarity index 100% rename from powertools-rs/src/save_worker.rs rename to backend/src/save_worker.rs diff --git a/powertools-rs/src/settings/battery.rs b/backend/src/settings/battery.rs similarity index 76% rename from powertools-rs/src/settings/battery.rs rename to backend/src/settings/battery.rs index 39d9b7d..bc32b21 100644 --- a/powertools-rs/src/settings/battery.rs +++ b/backend/src/settings/battery.rs @@ -6,6 +6,7 @@ use crate::persist::BatteryJson; #[derive(Debug, Clone)] pub struct Battery { pub charge_rate: Option, + state: crate::state::Battery, } const BATTERY_CHARGE_RATE_PATH: &str = "/sys/class/hwmon/hwmon5/maximum_battery_charge_rate"; // write-only @@ -17,21 +18,32 @@ impl Battery { match version { 0 => Self { charge_rate: other.charge_rate, + state: crate::state::Battery::default(), }, _ => Self { charge_rate: other.charge_rate, + state: crate::state::Battery::default(), }, } } - fn set_all(&self) -> Result<(), SettingError> { + fn set_all(&mut self) -> Result<(), SettingError> { 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( |e| SettingError { msg: format!("Failed to write to `{}`: {}", BATTERY_CHARGE_RATE_PATH, e), setting: super::SettingVariant::Battery, }, ) + } else if self.state.charge_rate_set { + self.state.charge_rate_set = false; + usdpl_back::api::files::write_single(BATTERY_CHARGE_RATE_PATH, Self::max().charge_rate.unwrap()).map_err( + |e| SettingError { + msg: format!("Failed to write to `{}`: {}", BATTERY_CHARGE_RATE_PATH, e), + setting: super::SettingVariant::Battery, + }, + ) } else { Ok(()) } @@ -66,7 +78,10 @@ impl Battery { } pub fn system_default() -> Self { - Self { charge_rate: None } + Self { + charge_rate: None, + state: crate::state::Battery::default(), + } } } @@ -88,7 +103,7 @@ impl OnSet for Battery { impl OnResume for Battery { fn on_resume(&self) -> Result<(), SettingError> { - self.set_all() + self.clone().set_all() } } @@ -97,6 +112,7 @@ impl SettingsRange for Battery { fn max() -> Self { Self { charge_rate: Some(2500), + state: crate::state::Battery::default(), } } @@ -104,6 +120,7 @@ impl SettingsRange for Battery { fn min() -> Self { Self { charge_rate: Some(250), + state: crate::state::Battery::default(), } } } diff --git a/powertools-rs/src/settings/cpu.rs b/backend/src/settings/cpu.rs similarity index 73% rename from powertools-rs/src/settings/cpu.rs rename to backend/src/settings/cpu.rs index 5b0ad78..70e465a 100644 --- a/powertools-rs/src/settings/cpu.rs +++ b/backend/src/settings/cpu.rs @@ -10,6 +10,7 @@ pub struct Cpu { pub clock_limits: Option>, pub governor: String, index: usize, + state: crate::state::Cpu, } const CPU_CLOCK_LIMITS_PATH: &str = "/sys/class/drm/card0/device/pp_od_clk_voltage"; @@ -26,17 +27,19 @@ impl Cpu { clock_limits: other.clock_limits.map(|x| MinMax::from_json(x, version)), governor: other.governor, index: i, + state: crate::state::Cpu::default(), }, _ => Self { online: other.online, clock_limits: other.clock_limits.map(|x| MinMax::from_json(x, version)), governor: other.governor, index: i, + state: crate::state::Cpu::default(), }, } } - fn set_all(&self) -> Result<(), SettingError> { + fn set_all(&mut self) -> Result<(), SettingError> { // set cpu online/offline if self.index != 0 { // cpu0 cannot be disabled let online_path = cpu_online_path(self.index); @@ -48,7 +51,9 @@ impl Cpu { })?; } // set clock limits - if let Some(clock_limits) = &self.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 { @@ -59,8 +64,12 @@ impl Cpu { setting: super::SettingVariant::Cpu, } })?; + } + if let Some(clock_limits) = &self.clock_limits { + log::debug!("Setting CPU {} (min, max) clockspeed to ({}, {})", self.index, clock_limits.min, clock_limits.max); + self.state.clock_limits_set = true; // max clock - let payload_max = format!("p {} 1 {}", self.index / 2, clock_limits.max); + let payload_max = format!("p {} 1 {}\n", self.index / 2, clock_limits.max); usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, &payload_max).map_err( |e| SettingError { msg: format!( @@ -71,7 +80,7 @@ impl Cpu { }, )?; // min clock - let payload_min = format!("p {} 0 {}", self.index / 2, clock_limits.min); + let payload_min = format!("p {} 0 {}\n", self.index / 2, clock_limits.min); usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, &payload_min).map_err( |e| SettingError { msg: format!( @@ -81,25 +90,41 @@ impl Cpu { setting: super::SettingVariant::Cpu, }, )?; - // commit changes - usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, "c").map_err(|e| { - SettingError { - msg: format!("Failed to write `c` to `{}`: {}", CPU_CLOCK_LIMITS_PATH, e), - setting: super::SettingVariant::Cpu, - } - })?; - } else { + } else if self.state.clock_limits_set { + self.state.clock_limits_set = false; // disable manual clock limits - usdpl_back::api::files::write_single(CPU_FORCE_LIMITS_PATH, "auto").map_err(|e| { - SettingError { + log::debug!("Setting CPU {} to default clockspeed", self.index); + // max clock + let payload_max = format!("p {} 1 {}\n", self.index / 2, Self::max().clock_limits.unwrap().max); + usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, &payload_max).map_err( + |e| SettingError { msg: format!( - "Failed to write `auto` to `{}`: {}", - CPU_FORCE_LIMITS_PATH, e + "Failed to write `{}` to `{}`: {}", + &payload_max, CPU_CLOCK_LIMITS_PATH, e ), setting: super::SettingVariant::Cpu, - } - })?; + }, + )?; + // min clock + let payload_min = format!("p {} 0 {}\n", self.index / 2, Self::min().clock_limits.unwrap().min); + usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, &payload_min).map_err( + |e| SettingError { + msg: format!( + "Failed to write `{}` to `{}`: {}", + &payload_min, CPU_CLOCK_LIMITS_PATH, e + ), + setting: super::SettingVariant::Cpu, + }, + )?; } + // 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: super::SettingVariant::Cpu, + } + })?; + // set governor if self.index == 0 || self.online { let governor_path = cpu_governor_path(self.index); @@ -134,6 +159,7 @@ impl Cpu { governor: usdpl_back::api::files::read_single(cpu_governor_path(index)) .unwrap_or("schedutil".to_owned()), index: index, + state: crate::state::Cpu::default(), } } @@ -152,8 +178,8 @@ impl Cpu { pub fn system_default() -> Vec { if let Some(max_cpu) = Self::cpu_count() { - let mut cpus = Vec::with_capacity(max_cpu + 1); - for i in 0..=max_cpu { + let mut cpus = Vec::with_capacity(max_cpu); + for i in 0..max_cpu { cpus.push(Self::from_sys(i)); } cpus @@ -183,7 +209,7 @@ impl OnSet for Cpu { impl OnResume for Cpu { fn on_resume(&self) -> Result<(), SettingError> { - self.set_all() + self.clone().set_all() } } @@ -198,6 +224,7 @@ impl SettingsRange for Cpu { }), governor: "schedutil".to_owned(), index: usize::MAX, + state: crate::state::Cpu::default(), } } @@ -207,7 +234,8 @@ impl SettingsRange for Cpu { online: false, clock_limits: Some(MinMax { max: 500, min: 1400 }), governor: "schedutil".to_owned(), - index: 0, + index: usize::MIN, + state: crate::state::Cpu::default(), } } } diff --git a/powertools-rs/src/settings/error.rs b/backend/src/settings/error.rs similarity index 100% rename from powertools-rs/src/settings/error.rs rename to backend/src/settings/error.rs diff --git a/powertools-rs/src/settings/general.rs b/backend/src/settings/general.rs similarity index 97% rename from powertools-rs/src/settings/general.rs rename to backend/src/settings/general.rs index 7956b4b..1ea88bf 100644 --- a/powertools-rs/src/settings/general.rs +++ b/backend/src/settings/general.rs @@ -120,7 +120,8 @@ impl Settings { } } - pub fn load_file(&self, json_path: PathBuf, name: String) -> Result { + pub fn load_file(&self, filename: PathBuf, name: String) -> Result { + let json_path = crate::utility::settings_dir().join(filename); let mut general_lock = unwrap_lock(self.general.lock(), "general"); if json_path.exists() { let settings_json = SettingsJson::open(&json_path).map_err(|e| SettingError { diff --git a/powertools-rs/src/settings/gpu.rs b/backend/src/settings/gpu.rs similarity index 63% rename from powertools-rs/src/settings/gpu.rs rename to backend/src/settings/gpu.rs index 147d8de..ae950e9 100644 --- a/powertools-rs/src/settings/gpu.rs +++ b/backend/src/settings/gpu.rs @@ -13,6 +13,7 @@ pub struct Gpu { pub slow_ppt: Option, pub clock_limits: Option>, pub slow_memory: bool, + state: crate::state::Gpu, } // same as CPU @@ -29,17 +30,19 @@ impl Gpu { slow_ppt: other.slow_ppt, clock_limits: other.clock_limits.map(|x| MinMax::from_json(x, version)), slow_memory: other.slow_memory, + state: crate::state::Gpu::default(), }, _ => Self { fast_ppt: other.fast_ppt, slow_ppt: other.slow_ppt, clock_limits: other.clock_limits.map(|x| MinMax::from_json(x, version)), slow_memory: other.slow_memory, + state: crate::state::Gpu::default(), }, } } - fn set_all(&self) -> Result<(), SettingError> { + 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); @@ -67,7 +70,8 @@ impl Gpu { })?; } // settings using force_performance_level - if self.clock_limits.is_some() || self.slow_memory { + 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 { @@ -78,58 +82,73 @@ impl Gpu { setting: super::SettingVariant::Gpu, } })?; - // set clock limits - if let Some(clock_limits) = &self.clock_limits { - // max clock - let payload_max = format!("s 1 {}", clock_limits.max); - usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, &payload_max).map_err( - |e| SettingError { - msg: format!( - "Failed to write `{}` to `{}`: {}", - &payload_max, GPU_CLOCK_LIMITS_PATH, e - ), - setting: super::SettingVariant::Gpu, - }, - )?; - // min clock - let payload_min = format!("s 0 {}", clock_limits.min); - usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, &payload_min).map_err( - |e| SettingError { - msg: format!( - "Failed to write `{}` to `{}`: {}", - &payload_min, GPU_CLOCK_LIMITS_PATH, e - ), - setting: super::SettingVariant::Gpu, - }, - )?; - } - // force 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: super::SettingVariant::Gpu, - })?; - // commit changes - usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, "c").map_err(|e| { - SettingError { - msg: format!("Failed to write `c` to `{}`: {}", GPU_CLOCK_LIMITS_PATH, e), - setting: super::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: super::SettingVariant::Gpu, })?; - } else { - // disable manual clock limits - usdpl_back::api::files::write_single(GPU_FORCE_LIMITS_PATH, "auto").map_err(|e| { - SettingError { + if let Some(clock_limits) = &self.clock_limits { + // set clock limits + self.state.clock_limits_set = true; + // max clock + let payload_max = format!("s 1 {}\n", clock_limits.max); + usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, &payload_max).map_err( + |e| SettingError { msg: format!( - "Failed to write `auto` to `{}`: {}", - GPU_FORCE_LIMITS_PATH, e + "Failed to write `{}` to `{}`: {}", + &payload_max, GPU_CLOCK_LIMITS_PATH, e ), setting: super::SettingVariant::Gpu, - } - })?; + }, + )?; + // 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( + |e| SettingError { + msg: format!( + "Failed to write `{}` to `{}`: {}", + &payload_min, GPU_CLOCK_LIMITS_PATH, e + ), + setting: super::SettingVariant::Gpu, + }, + )?; + } else if self.state.clock_limits_set { + self.state.clock_limits_set = false; + // disable manual clock limits + // max clock + let payload_max = format!("s 1 {}\n", Self::max().clock_limits.unwrap().max); + usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, &payload_max).map_err( + |e| SettingError { + msg: format!( + "Failed to write `{}` to `{}`: {}", + &payload_max, GPU_CLOCK_LIMITS_PATH, e + ), + setting: super::SettingVariant::Gpu, + }, + )?; + // min clock + let payload_min = format!("s 0 {}\n", Self::min().clock_limits.unwrap().min); + usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, &payload_min).map_err( + |e| SettingError { + msg: format!( + "Failed to write `{}` to `{}`: {}", + &payload_min, GPU_CLOCK_LIMITS_PATH, e + ), + setting: super::SettingVariant::Gpu, + }, + )?; } + // 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: super::SettingVariant::Gpu, + } + })?; - Ok(()) // TODO + Ok(()) } fn clamp_all(&mut self) { @@ -161,6 +180,7 @@ impl Gpu { slow_ppt: None, clock_limits: None, slow_memory: false, + state: crate::state::Gpu::default(), } } } @@ -186,7 +206,7 @@ impl OnSet for Gpu { impl OnResume for Gpu { fn on_resume(&self) -> Result<(), SettingError> { - self.set_all() + self.clone().set_all() } } @@ -201,6 +221,7 @@ impl SettingsRange for Gpu { max: 1600, }), slow_memory: false, + state: crate::state::Gpu::default(), } } @@ -211,6 +232,7 @@ impl SettingsRange for Gpu { slow_ppt: Some(1000000), clock_limits: Some(MinMax { min: 200, max: 200 }), slow_memory: true, + state: crate::state::Gpu::default(), } } } diff --git a/powertools-rs/src/settings/min_max.rs b/backend/src/settings/min_max.rs similarity index 100% rename from powertools-rs/src/settings/min_max.rs rename to backend/src/settings/min_max.rs diff --git a/powertools-rs/src/settings/mod.rs b/backend/src/settings/mod.rs similarity index 100% rename from powertools-rs/src/settings/mod.rs rename to backend/src/settings/mod.rs diff --git a/powertools-rs/src/settings/traits.rs b/backend/src/settings/traits.rs similarity index 100% rename from powertools-rs/src/settings/traits.rs rename to backend/src/settings/traits.rs diff --git a/backend/src/state/battery.rs b/backend/src/state/battery.rs new file mode 100644 index 0000000..ab4c9f0 --- /dev/null +++ b/backend/src/state/battery.rs @@ -0,0 +1,12 @@ +#[derive(Debug, Clone)] +pub struct Battery { + pub charge_rate_set: bool, +} + +impl std::default::Default for Battery { + fn default() -> Self { + Self { + charge_rate_set: false, + } + } +} diff --git a/backend/src/state/cpu.rs b/backend/src/state/cpu.rs new file mode 100644 index 0000000..8f9a083 --- /dev/null +++ b/backend/src/state/cpu.rs @@ -0,0 +1,12 @@ +#[derive(Debug, Clone)] +pub struct Cpu { + pub clock_limits_set: bool, +} + +impl std::default::Default for Cpu { + fn default() -> Self { + Self { + clock_limits_set: false, + } + } +} diff --git a/powertools-rs/src/state/error.rs b/backend/src/state/error.rs similarity index 100% rename from powertools-rs/src/state/error.rs rename to backend/src/state/error.rs diff --git a/backend/src/state/gpu.rs b/backend/src/state/gpu.rs new file mode 100644 index 0000000..ab39b11 --- /dev/null +++ b/backend/src/state/gpu.rs @@ -0,0 +1,12 @@ +#[derive(Debug, Clone)] +pub struct Gpu { + pub clock_limits_set: bool, +} + +impl std::default::Default for Gpu { + fn default() -> Self { + Self { + clock_limits_set: false, + } + } +} diff --git a/backend/src/state/mod.rs b/backend/src/state/mod.rs new file mode 100644 index 0000000..1eb1e58 --- /dev/null +++ b/backend/src/state/mod.rs @@ -0,0 +1,11 @@ +mod battery; +mod cpu; +mod error; +mod gpu; +mod traits; + +pub use battery::Battery; +pub use cpu::Cpu; +pub use error::StateError; +pub use gpu::Gpu; +pub use traits::OnPoll; diff --git a/powertools-rs/src/state/traits.rs b/backend/src/state/traits.rs similarity index 100% rename from powertools-rs/src/state/traits.rs rename to backend/src/state/traits.rs diff --git a/powertools-rs/src/utility.rs b/backend/src/utility.rs similarity index 100% rename from powertools-rs/src/utility.rs rename to backend/src/utility.rs diff --git a/main.py b/main.py index 3e7acb9..6c1ab39 100644 --- a/main.py +++ b/main.py @@ -11,6 +11,6 @@ class Plugin: # Asyncio-compatible long-running code, executed in a task when the plugin is loaded async def _main(self): # startup - self.backend_proc = subprocess.Popen([PARENT_DIR + "/bin/backend"]) + #self.backend_proc = subprocess.Popen([PARENT_DIR + "/bin/backend"]) while True: await asyncio.sleep(1) diff --git a/powertools-rs/src/state/mod.rs b/powertools-rs/src/state/mod.rs deleted file mode 100644 index 2a8befe..0000000 --- a/powertools-rs/src/state/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -mod error; -mod traits; - -pub use error::StateError; -pub use traits::OnPoll; diff --git a/src/index.tsx b/src/index.tsx index b03ea92..50205c6 100755 --- a/src/index.tsx +++ b/src/index.tsx @@ -173,16 +173,21 @@ const Content: VFC<{ serverAPI: ServerAPI }> = ({}) => { onChange={(smt: boolean) => { console.debug("SMT is now " + smt.toString()); const cpus = get_value(ONLINE_CPUS); - set_value(ONLINE_CPUS, 0); smtGlobal = smt && smtAllowed; for (let i = 0; i < total_cpus; i++) { const online = (smtGlobal? i < cpus : (i % 2 == 0) && (i < cpus * 2)) || (!smtGlobal && cpus == 4); - backend.resolve(backend.setCpuOnline(i, online), (value: boolean) => { - if (value) {set_value(ONLINE_CPUS, get_value(ONLINE_CPUS) + 1)} - }) + backend.resolve(backend.setCpuOnline(i, online), (_value: boolean) => {}); } - backend.resolve(backend.waitForComplete(), (_: boolean[]) => { + backend.resolve(backend.getCpusOnline(), (statii: boolean[]) => { + // TODO: allow for per-core control of online status + let count = 0; + for (let i = 0; i < statii.length; i++) { + if (statii[i]) { + count += 1; + } + } + set_value(ONLINE_CPUS, count); reloadGUI("SMT"); }); }} @@ -200,14 +205,21 @@ const Content: VFC<{ serverAPI: ServerAPI }> = ({}) => { console.debug("CPU slider is now " + cpus.toString()); const onlines = get_value(ONLINE_CPUS); if (cpus != onlines) { - set_value(ONLINE_CPUS, 0); for (let i = 0; i < total_cpus; i++) { const online = smtGlobal? i < cpus : (i % 2 == 0) && (i < cpus * 2); backend.resolve(backend.setCpuOnline(i, online), (value: boolean) => { if (value) {set_value(ONLINE_CPUS, get_value(ONLINE_CPUS) + 1)} }) } - backend.resolve(backend.waitForComplete(), (_: boolean[]) => { + backend.resolve(backend.getCpusOnline(), (statii: boolean[]) => { + // TODO: allow for per-core control of online status + let count = 0; + for (let i = 0; i < statii.length; i++) { + if (statii[i]) { + count += 1; + } + } + set_value(ONLINE_CPUS, count); reloadGUI("CPUs"); }); } @@ -218,6 +230,7 @@ const Content: VFC<{ serverAPI: ServerAPI }> = ({}) => { { if (value) { set_value(CLOCK_MIN_CPU, 1400); @@ -365,6 +378,7 @@ const Content: VFC<{ serverAPI: ServerAPI }> = ({}) => { { if (value) { set_value(CLOCK_MIN_GPU, 200);