Merge branch 'dev' for v1.2.0

This commit is contained in:
NGnius (Graham) 2023-03-04 10:35:17 -05:00
commit 33cd064667
37 changed files with 869 additions and 495 deletions

201
backend/Cargo.lock generated
View file

@ -81,9 +81,9 @@ dependencies = [
[[package]]
name = "async-trait"
version = "0.1.64"
version = "0.1.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cd7fce9ba8c3c042128ce72d8b2ddbf3a05747efb67ea0313c635e10bda47a2"
checksum = "095183a3539c7c7649b2beb87c2d3f0591f3a7fed07761cc546d244e27e0238c"
dependencies = [
"proc-macro2",
"quote",
@ -171,6 +171,12 @@ version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be"
[[package]]
name = "cc"
version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
[[package]]
name = "cexpr"
version = "0.6.0"
@ -197,9 +203,9 @@ dependencies = [
[[package]]
name = "clang-sys"
version = "1.4.0"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa2e27ae6ab525c3d369ded447057bca5438d86dc3a68f6faafb8269ba82ebf3"
checksum = "77ed9a53e5d4d9c573ae844bfac6872b159cb1d1585a83b29e7a64b7eef7332a"
dependencies = [
"glob",
"libc",
@ -333,10 +339,31 @@ dependencies = [
]
[[package]]
name = "fastrand"
version = "1.8.0"
name = "errno"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499"
checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1"
dependencies = [
"errno-dragonfly",
"libc",
"winapi",
]
[[package]]
name = "errno-dragonfly"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
dependencies = [
"cc",
"libc",
]
[[package]]
name = "fastrand"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be"
dependencies = [
"instant",
]
@ -447,9 +474,9 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
[[package]]
name = "h2"
version = "0.3.15"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4"
checksum = "5be7b54589b581f624f566bf5d8eb2bab1db736c51528720b6bd36b96b55924d"
dependencies = [
"bytes",
"fnv",
@ -512,9 +539,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
name = "http"
version = "0.2.8"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399"
checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482"
dependencies = [
"bytes",
"fnv",
@ -598,10 +625,20 @@ dependencies = [
]
[[package]]
name = "itoa"
name = "io-lifetimes"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440"
checksum = "1abeb7a0dd0f8181267ff8adc397075586500b81b28a73e8a0208b00fc170fb3"
dependencies = [
"libc",
"windows-sys 0.45.0",
]
[[package]]
name = "itoa"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
[[package]]
name = "lazy_static"
@ -639,6 +676,12 @@ dependencies = [
"serde_json",
]
[[package]]
name = "linux-raw-sys"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4"
[[package]]
name = "log"
version = "0.4.17"
@ -687,14 +730,14 @@ dependencies = [
[[package]]
name = "mio"
version = "0.8.5"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de"
checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9"
dependencies = [
"libc",
"log",
"wasi",
"windows-sys",
"windows-sys 0.45.0",
]
[[package]]
@ -752,9 +795,9 @@ checksum = "7b2b2cbbfd8defa51ff24450a61d73b3ff3e158484ddd274a883e886e6fbaa78"
[[package]]
name = "once_cell"
version = "1.17.0"
version = "1.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66"
checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
[[package]]
name = "opaque-debug"
@ -819,8 +862,8 @@ dependencies = [
]
[[package]]
name = "powertools-rs"
version = "1.1.0"
name = "powertools"
version = "1.2.0"
dependencies = [
"async-trait",
"limits_core",
@ -843,9 +886,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "proc-macro2"
version = "1.0.50"
version = "1.0.51"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2"
checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6"
dependencies = [
"unicode-ident",
]
@ -921,21 +964,26 @@ version = "0.6.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
[[package]]
name = "remove_dir_all"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
dependencies = [
"winapi",
]
[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "rustix"
version = "0.36.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd5c6ff11fecd55b40746d1995a02f2eb375bf8c00d192d521ee09f42bef37bc"
dependencies = [
"bitflags",
"errno",
"io-lifetimes",
"libc",
"linux-raw-sys",
"windows-sys 0.45.0",
]
[[package]]
name = "rustls-pemfile"
version = "0.2.1"
@ -947,9 +995,9 @@ dependencies = [
[[package]]
name = "ryu"
version = "1.0.12"
version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde"
checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
[[package]]
name = "ryzenadj-rs"
@ -994,9 +1042,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.91"
version = "1.0.93"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883"
checksum = "cad406b69c91885b5107daf2c29572f6c8cdb3c66826821e286c533490c0bc76"
dependencies = [
"itoa",
"ryu",
@ -1045,9 +1093,9 @@ checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
[[package]]
name = "simplelog"
version = "0.12.0"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48dfff04aade74dd495b007c831cd6f4e0cee19c344dd9dc0884c0289b70a786"
checksum = "acee08041c5de3d5048c8b3f6f13fafb3026b24ba43c6a695a0c76179b844369"
dependencies = [
"log",
"termcolor",
@ -1056,18 +1104,18 @@ dependencies = [
[[package]]
name = "slab"
version = "0.4.7"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef"
checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d"
dependencies = [
"autocfg",
]
[[package]]
name = "socket2"
version = "0.4.7"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd"
checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662"
dependencies = [
"libc",
"winapi",
@ -1081,9 +1129,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
[[package]]
name = "syn"
version = "1.0.107"
version = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [
"proc-macro2",
"quote",
@ -1092,16 +1140,15 @@ dependencies = [
[[package]]
name = "tempfile"
version = "3.3.0"
version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4"
checksum = "af18f7ae1acd354b992402e9ec5864359d693cd8a79dcbef59f76891701c1e95"
dependencies = [
"cfg-if",
"fastrand",
"libc",
"redox_syscall",
"remove_dir_all",
"winapi",
"rustix",
"windows-sys 0.42.0",
]
[[package]]
@ -1135,9 +1182,9 @@ dependencies = [
[[package]]
name = "time"
version = "0.3.17"
version = "0.3.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376"
checksum = "cd0cbfecb4d19b5ea75bb31ad904eb5b9fa13f21079c3b92017ebdf4999a5890"
dependencies = [
"itoa",
"libc",
@ -1155,9 +1202,9 @@ checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd"
[[package]]
name = "time-macros"
version = "0.2.6"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2"
checksum = "fd80a657e71da814b8e5d60d3374fc6d35045062245d80224748ae522dd76f36"
dependencies = [
"time-core",
]
@ -1179,9 +1226,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
version = "1.25.0"
version = "1.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8e00990ebabbe4c14c08aca901caed183ecd5c09562a12c824bb53d3c3fd3af"
checksum = "03201d01c3c27a29c8a5cee5b55a93ddae1ccf6f08f65365c2c918f8c1b76f64"
dependencies = [
"autocfg",
"bytes",
@ -1191,14 +1238,14 @@ dependencies = [
"num_cpus",
"pin-project-lite",
"socket2",
"windows-sys",
"windows-sys 0.45.0",
]
[[package]]
name = "tokio-stream"
version = "0.1.11"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d660770404473ccd7bc9f8b28494a811bc18542b915c0855c51e8f419d5223ce"
checksum = "8fb52b74f05dbf495a8fba459fdc331812b96aa086d9eb78101fa0d4569c3313"
dependencies = [
"futures-core",
"pin-project-lite",
@ -1219,9 +1266,9 @@ dependencies = [
[[package]]
name = "tokio-util"
version = "0.7.4"
version = "0.7.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740"
checksum = "5427d89453009325de0d8f342c9490009f76e999cb7672d77e46267448f7e6b2"
dependencies = [
"bytes",
"futures-core",
@ -1315,9 +1362,9 @@ checksum = "d54675592c1dbefd78cbd98db9bacd89886e1ca50692a0692baefffdeb92dd58"
[[package]]
name = "unicode-ident"
version = "1.0.6"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
checksum = "775c11906edafc97bc378816b94585fbd9a054eabaf86fdd0ced94af449efab7"
[[package]]
name = "unicode-normalization"
@ -1368,9 +1415,9 @@ dependencies = [
[[package]]
name = "usdpl-back"
version = "0.9.1"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2938cb40ba84ebea44658ebb1e4e0045fca54a562873bacab2ae094abab61ff"
checksum = "2d185cc6e3f5d305e6e97f1b5cadf1da78bac6b62ea3457802d250708c315306"
dependencies = [
"async-recursion",
"async-trait",
@ -1386,9 +1433,9 @@ dependencies = [
[[package]]
name = "usdpl-core"
version = "0.9.0"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3904ca38aca189c68a6bc876cf73de7cc60003476b4e118012ae7eb783c1700"
checksum = "bd73bec3df5bed5862cab15aaa645d76c388e00128a14c372806907e2f331960"
dependencies = [
"aes-gcm-siv",
"base64",
@ -1510,6 +1557,30 @@ dependencies = [
"windows_x86_64_msvc",
]
[[package]]
name = "windows-sys"
version = "0.45.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.42.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.42.1"

View file

@ -1,6 +1,6 @@
[package]
name = "powertools-rs"
version = "1.1.1"
name = "powertools"
version = "1.2.0"
edition = "2021"
authors = ["NGnius (Graham) <ngniusness@gmail.com>"]
description = "Backend (superuser) functionality for PowerTools"
@ -12,7 +12,7 @@ readme = "../README.md"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
usdpl-back = { version = "0.9.1", features = ["blocking"] }#, path = "../../usdpl-rs/usdpl-back"}
usdpl-back = { version = "0.10.1", features = ["blocking"] }#, path = "../../usdpl-rs/usdpl-back"}
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
@ -32,11 +32,12 @@ ryzenadj-rs = { version = "0.1" }
ureq = { version = "2.5", features = ["json", "gzip", "brotli", "charset"], default-features = false, optional = true }
[features]
default = ["online"]
default = ["online", "decky"]
decky = ["usdpl-back/decky"]
crankshaft = ["usdpl-back/crankshaft"]
encrypt = ["usdpl-back/encrypt"]
online = ["ureq"]
dev_stuff = []
[profile.release]
debug = false

View file

@ -8,7 +8,7 @@ cargo --version
echo "--- Building plugin backend ---"
cargo build --profile docker
mkdir -p out
cp target/release/powertools-rs out/backend
cp target/release/powertools out/backend
echo " --- Cleaning up ---"
# remove root-owned target folder

View file

@ -1,10 +1,10 @@
#!/bin/bash
cargo build --release --target x86_64-unknown-linux-musl
#cargo build --target x86_64-unknown-linux-musl
#cargo build --release --target x86_64-unknown-linux-musl
cargo build --target x86_64-unknown-linux-musl
#cross build --release
mkdir -p ../bin
cp ./target/x86_64-unknown-linux-musl/release/powertools-rs ../bin/backend
#cp ./target/x86_64-unknown-linux-musl/debug/powertools-rs ../bin/backend
#cp ./target/release/powertools-rs ../bin/backend
#cp ./target/x86_64-unknown-linux-musl/release/powertools ../bin/backend
cp ./target/x86_64-unknown-linux-musl/debug/powertools ../bin/backend
#cp ./target/release/powertools ../bin/backend

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(..) {
@ -244,6 +251,9 @@ impl ApiMessageHandler {
let save_json: SettingsJson = settings_clone.into();
unwrap_maybe_fatal(save_json.save(&save_path), "Failed to save settings");
log::debug!("Saved settings to {}", save_path.display());
if let Err(e) = crate::utility::chown_settings_dir() {
log::error!("Failed to change config dir permissions: {}", e);
}
} else {
if save_path.exists() {
if let Err(e) = std::fs::remove_file(&save_path) {
@ -269,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

@ -18,7 +18,6 @@ use usdpl_back::core::serdes::Primitive;
use usdpl_back::Instance;
fn main() -> Result<(), ()> {
#[cfg(debug_assertions)]
let log_filepath = usdpl_back::api::dirs::home()
.unwrap_or_else(|| "/tmp/".into())
@ -46,6 +45,7 @@ fn main() -> Result<(), ()> {
},
Default::default(),
std::fs::File::create(&log_filepath).unwrap(),
//std::fs::File::create("/home/deck/powertools-rs.log").unwrap(),
)
.unwrap();
log::debug!("Logging to: {:?}.", log_filepath);
@ -55,6 +55,8 @@ fn main() -> Result<(), ()> {
log::info!("Current dir `{}`", std::env::current_dir().unwrap().display());
println!("Current dir `{}`", std::env::current_dir().unwrap().display());
log::info!("home dir: {:?}", usdpl_back::api::dirs::home());
let _limits_handle = crate::settings::limits_worker_spawn();
log::info!("Detected device automatically, starting with driver: {:?} (This can be overriden)", crate::settings::auto_detect_provider());
@ -71,7 +73,13 @@ fn main() -> Result<(), ()> {
let instance = Instance::new(PORT)
.register("V_INFO", |_: Vec<Primitive>| {
vec![format!("{} v{}", PACKAGE_NAME, PACKAGE_VERSION).into()]
#[cfg(debug_assertions)]
{vec![format!("v{}-dbg", PACKAGE_VERSION).into()]}
#[cfg(not(debug_assertions))]
{vec![format!("v{}-rls", PACKAGE_VERSION).into()]}
})
.register("NAME", |_: Vec<Primitive>| {
vec![PACKAGE_NAME.into()]
})
.register("LOG", api::general::log_it())
// battery API functions
@ -222,11 +230,15 @@ 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");
}
if let Err(e) = utility::chown_settings_dir() {
log::warn!("Failed to change config dir permissions: {}", e);
}
api_worker::spawn(loaded_settings, api_handler);
instance

View file

@ -1,29 +0,0 @@
use std::sync::mpsc::{self, Receiver, Sender};
use std::thread::{self, JoinHandle};
use crate::persist::SettingsJson;
use crate::settings::Settings;
use crate::utility::{unwrap_lock, unwrap_maybe_fatal};
pub fn spawn(settings: Settings) -> (JoinHandle<()>, Sender<()>) {
let (sender, receiver): (Sender<()>, Receiver<()>) = mpsc::channel();
let worker = thread::spawn(move || {
log::info!("save_worker starting...");
for _ in receiver.iter() {
log::debug!("save_worker is saving...");
let is_persistent = unwrap_lock(settings.general.lock(), "general").persistent.clone();
if is_persistent {
let save_path = crate::utility::settings_dir()
.join(unwrap_lock(settings.general.lock(), "general").path.clone());
let settings_clone = settings.clone();
let save_json: SettingsJson = settings_clone.into();
unwrap_maybe_fatal(save_json.save(&save_path), "Failed to save settings");
log::debug!("Saved settings to {}", save_path.display());
} else {
log::debug!("Ignored save request for non-persistent settings");
}
}
log::warn!("save_worker completed!");
});
(worker, sender)
}

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

@ -23,7 +23,7 @@ pub use traits::{OnResume, OnSet, SettingsRange, TGeneral, TGpu, TCpus, TBattery
mod tests {
#[test]
fn system_defaults_test() {
let settings = super::Settings::system_default("idc".into());
let settings = super::Settings::system_default("idc".into(), "Cool name".into());
println!("Loaded system settings: {:?}", settings);
}
}

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(())
}
}
@ -176,6 +186,7 @@ impl TCpus for Cpus {
}
fn smt(&mut self) -> &'_ mut bool {
log::debug!("CPU driver thinks SMT is {}", self.smt);
&mut self.smt
}
@ -220,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 {
@ -259,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);
@ -271,8 +274,8 @@ impl Cpu {
),
setting: crate::settings::SettingVariant::Cpu,
},
)?;
} else if self.state.clock_limits_set || self.state.is_resuming {
).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
log::debug!("Setting CPU {} to default clockspeed", self.index);
@ -286,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(
@ -297,15 +300,44 @@ 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,
});
});
// commit changes (if no errors have already occured)
if errors.is_empty() {
usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, "c\n").map_err(|e| {
vec![SettingError {
msg: format!("Failed to write `c` to `{}`: {}", CPU_CLOCK_LIMITS_PATH, e),
setting: crate::settings::SettingVariant::Cpu,
}]
})
} 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 {
@ -318,9 +350,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) {
@ -393,14 +429,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,8 +79,8 @@ impl Gpu {
),
setting: crate::settings::SettingVariant::Gpu,
},
)?;
} else if self.state.clock_limits_set || self.state.is_resuming {
).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
// max clock
@ -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,89 @@ impl Gpu {
),
setting: crate::settings::SettingVariant::Gpu,
},
)?;
).unwrap_or_else(|e| errors.push(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,
}
})?;
if errors.is_empty() {
Ok(())
} else {
Err(errors)
}
}
Ok(())
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 (if no errors have already occured)
if errors.is_empty() {
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, "c\n").map_err(|e| {
vec![SettingError {
msg: format!("Failed to write `c` to `{}`: {}", GPU_CLOCK_LIMITS_PATH, e),
setting: crate::settings::SettingVariant::Gpu,
}]
})
} else {
Err(errors)
}
}
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 +235,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

@ -73,7 +73,7 @@ impl Default for CpusLimits {
fn default() -> Self {
Self {
cpus: [(); 8].iter().map(|_| CpuLimits::default()).collect(),
global_governors: false,
global_governors: true,
}
}
}
@ -83,6 +83,7 @@ pub(super) struct CpuLimits {
pub clock_min: MinMax<u64>,
pub clock_max: MinMax<u64>,
pub clock_step: u64,
pub skip_resume_reclock: bool,
}
impl Default for CpuLimits {
@ -91,6 +92,7 @@ impl Default for CpuLimits {
clock_min: MinMax { min: 1400, max: 3500 },
clock_max: MinMax { min: 400, max: 3500 },
clock_step: 100,
skip_resume_reclock: false,
}
}
}
@ -104,6 +106,7 @@ pub(super) struct GpuLimits {
pub clock_min: MinMax<u64>,
pub clock_max: MinMax<u64>,
pub clock_step: u64,
pub skip_resume_reclock: bool,
}
impl Default for GpuLimits {
@ -113,9 +116,10 @@ impl Default for GpuLimits {
slow_ppt: MinMax { min: 1000000, max: 29_000_000 },
ppt_divisor: 1_000_000,
ppt_step: 1,
clock_min: MinMax { min: 200, max: 1600 },
clock_max: MinMax { min: 200, max: 1600 },
clock_min: MinMax { min: 400, max: 1600 },
clock_max: MinMax { min: 400, max: 1600 },
clock_step: 100,
skip_resume_reclock: false,
}
}
}
@ -123,3 +127,22 @@ impl Default for GpuLimits {
fn oc_limits_filepath() -> std::path::PathBuf {
crate::utility::settings_dir().join(OC_LIMITS_FILEPATH)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn load_pt_oc() {
let mut file = std::fs::File::open("../pt_oc.json").unwrap();
let settings: OverclockLimits = serde_json::from_reader(&mut file).unwrap();
assert!(settings.cpus.cpus.len() == 8);
}
#[cfg(feature = "dev_stuff")]
#[test]
fn emit_default_pt_oc() {
let mut file = std::fs::File::create("../pt_oc.json").unwrap();
serde_json::to_writer_pretty(&mut file, &OverclockLimits::default()).unwrap();
}
}

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

@ -5,3 +5,45 @@ pub fn guess_smt(cpus: &Vec<crate::persist::CpuJson>) -> bool {
}
guess
}
#[cfg(test)]
mod test {
use super::*;
use crate::persist::CpuJson;
#[test]
fn smt_guess_test() {
let input = vec![
cpu_with_online(true),
cpu_with_online(true),
cpu_with_online(true),
cpu_with_online(true),
cpu_with_online(true),
cpu_with_online(true),
cpu_with_online(true),
cpu_with_online(true),
];
assert_eq!(guess_smt(&input), true);
let input = vec![
cpu_with_online(true),
cpu_with_online(false),
cpu_with_online(true),
cpu_with_online(false),
cpu_with_online(true),
cpu_with_online(false),
cpu_with_online(true),
cpu_with_online(false),
];
assert_eq!(guess_smt(&input), false);
}
fn cpu_with_online(status: bool) -> CpuJson {
CpuJson {
online: status,
clock_limits: None,
governor: "schedutil".to_owned(),
}
}
}

View file

@ -1,5 +1,7 @@
use std::fmt::Display;
//use std::sync::{LockResult, MutexGuard};
//use std::fs::{Permissions, metadata};
use std::os::unix::fs::PermissionsExt;
pub fn unwrap_maybe_fatal<T: Sized, E: Display>(result: Result<T, E>, message: &str) -> T {
match result {
@ -29,3 +31,25 @@ pub fn settings_dir() -> std::path::PathBuf {
.unwrap_or_else(|| "/tmp/".into())
.join(".config/powertools/")
}
pub fn chown_settings_dir() -> std::io::Result<()> {
let dir = settings_dir();
#[cfg(feature = "decky")]
let deck_user = usdpl_back::api::decky::user().map_err(|_| std::io::Error::new(std::io::ErrorKind::NotFound, "Decky missing deck user's username"))?;
#[cfg(not(feature = "decky"))]
let deck_user = "deck".to_owned();
// FIXME this shouldn't need to invoke a command
let output = std::process::Command::new("id")
.args(["-u", &deck_user])
.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(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), Some(uid))
std::process::Command::new("chown")
.args(["-R", &format!("{}:{}", deck_user, deck_user), &dir.to_str().unwrap_or(".")])
.output()?;
Ok(())
}

View file

@ -12,9 +12,14 @@ class Plugin:
async def _main(self):
# startup
print("PowerTools starting...")
env_proc = dict(os.environ)
if "LD_LIBRARY_PATH" in env_proc:
env_proc["LD_LIBRARY_PATH"] += ":"+PARENT_DIR+"/bin"
else:
env_proc["LD_LIBRARY_PATH"] = ":"+PARENT_DIR+"/bin"
self.backend_proc = subprocess.Popen(
[PARENT_DIR + "/bin/backend"],
env = {"LD_LIBRARY_PATH": ":"+PARENT_DIR+"/bin"})
env = env_proc)
while True:
await asyncio.sleep(1)

View file

@ -1,6 +1,6 @@
{
"name": "PowerTools",
"version": "1.1.1",
"version": "1.2.0",
"description": "Power tweaks for power users",
"scripts": {
"build": "shx rm -rf dist && rollup -c",
@ -35,12 +35,12 @@
"rollup": "^2.79.1",
"rollup-plugin-import-assets": "^1.1.1",
"shx": "^0.3.4",
"tslib": "^2.4.1",
"typescript": "^4.9.4"
"tslib": "^2.5.0",
"typescript": "^4.9.5"
},
"dependencies": {
"decky-frontend-lib": "~3.18.10",
"react-icons": "^4.7.1",
"decky-frontend-lib": "~3.19.1",
"react-icons": "^4.8.0",
"usdpl-front": "file:src/usdpl_front"
}
}

View file

@ -8,18 +8,18 @@ specifiers:
'@rollup/plugin-typescript': ^8.5.0
'@types/react': 16.14.0
'@types/webpack': ^5.28.0
decky-frontend-lib: ~3.18.10
react-icons: ^4.7.1
decky-frontend-lib: ~3.19.1
react-icons: ^4.8.0
rollup: ^2.79.1
rollup-plugin-import-assets: ^1.1.1
shx: ^0.3.4
tslib: ^2.4.1
typescript: ^4.9.4
tslib: ^2.5.0
typescript: ^4.9.5
usdpl-front: file:src/usdpl_front
dependencies:
decky-frontend-lib: 3.18.10
react-icons: 4.7.1
decky-frontend-lib: 3.19.1
react-icons: 4.8.0
usdpl-front: file:src/usdpl_front
devDependencies:
@ -158,12 +158,12 @@ packages:
/@types/eslint-scope/3.7.4:
resolution: {integrity: sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==}
dependencies:
'@types/eslint': 8.21.0
'@types/eslint': 8.21.1
'@types/estree': 0.0.51
dev: true
/@types/eslint/8.21.0:
resolution: {integrity: sha512-35EhHNOXgxnUgh4XCJsGhE7zdlDhYDN/aMG6UbkByCFFNgQ7b3U+uVoqBpicFydR8JEfgdjCF7SJ7MiJfzuiTA==}
/@types/eslint/8.21.1:
resolution: {integrity: sha512-rc9K8ZpVjNcLs8Fp0dkozd5Pt2Apk1glO4Vgz8ix1u6yFByxfqo5Yavpy65o+93TAe24jr7v+eSBtFLvOQtCRQ==}
dependencies:
'@types/estree': 0.0.51
'@types/json-schema': 7.0.11
@ -185,8 +185,8 @@ packages:
resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==}
dev: true
/@types/node/18.11.18:
resolution: {integrity: sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==}
/@types/node/18.14.6:
resolution: {integrity: sha512-93+VvleD3mXwlLI/xASjw0FzKcwzl3OdTCzm1LaRfqgS21gfFtK3zDXM5Op9TeeMsJVOaJ2VRDpT9q4Y3d0AvA==}
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.11.18
'@types/node': 18.14.6
dev: true
/@types/webpack/5.28.0:
resolution: {integrity: sha512-8cP0CzcxUiFuA9xGJkfeVpqmWTk9nx6CWwamRGCj95ph1SmlRRk9KlCZ6avhCbZd4L68LvYT6l1kpdEnQXrF8w==}
dependencies:
'@types/node': 18.11.18
'@types/node': 18.14.6
tapable: 2.2.1
webpack: 5.75.0
transitivePeerDependencies:
@ -380,9 +380,9 @@ packages:
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
hasBin: true
dependencies:
caniuse-lite: 1.0.30001450
electron-to-chromium: 1.4.286
node-releases: 2.0.9
caniuse-lite: 1.0.30001460
electron-to-chromium: 1.4.320
node-releases: 2.0.10
update-browserslist-db: 1.0.10_browserslist@4.21.5
dev: true
@ -395,8 +395,8 @@ packages:
engines: {node: '>=6'}
dev: true
/caniuse-lite/1.0.30001450:
resolution: {integrity: sha512-qMBmvmQmFXaSxexkjjfMvD5rnDL0+m+dUMZKoDYsGG8iZN29RuYh9eRoMvKsT6uMAWlyUUGDEQGJJYjzCIO9ew==}
/caniuse-lite/1.0.30001460:
resolution: {integrity: sha512-Bud7abqjvEjipUkpLs4D7gR0l8hBYBHoa+tGtKJHvT2AYzLp1z7EmVkUT4ERpVUfca8S2HGIVs883D8pUH1ZzQ==}
dev: true
/chrome-trace-event/1.0.3:
@ -420,8 +420,8 @@ packages:
resolution: {integrity: sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==}
dev: true
/decky-frontend-lib/3.18.10:
resolution: {integrity: sha512-2mgbA3sSkuwQR/FnmhXVrcW6LyTS95IuL6muJAmQCruhBvXapDtjk1TcgxqMZxFZwGD1IPnemPYxHZll6IgnZw==}
/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.286:
resolution: {integrity: sha512-Vp3CVhmYpgf4iXNKAucoQUDcCrBQX3XLBtwgFqP9BUXuucgvAV9zWp1kYU7LL9j4++s9O+12cb3wMtN4SJy6UQ==}
/electron-to-chromium/1.4.320:
resolution: {integrity: sha512-h70iRscrNluMZPVICXYl5SSB+rBKo22XfuIS1ER0OQxQZpKTnFpuS6coj7wY9M/3trv7OR88rRMOlKmRvDty7Q==}
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.11.18
'@types/node': 18.14.6
merge-stream: 2.0.0
supports-color: 8.1.1
dev: true
@ -636,16 +636,16 @@ packages:
brace-expansion: 1.1.11
dev: true
/minimist/1.2.7:
resolution: {integrity: sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==}
/minimist/1.2.8:
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
dev: true
/neo-async/2.6.2:
resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==}
dev: true
/node-releases/2.0.9:
resolution: {integrity: sha512-2xfmOrRkGogbTK9R6Leda0DGiXeY3p2NJpy4+gNCffdUvV6mdEJnaDEic1i3Ec2djAo8jWYoJMR5PB0MSMpxUA==}
/node-releases/2.0.10:
resolution: {integrity: sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==}
dev: true
/once/1.4.0:
@ -683,8 +683,8 @@ packages:
safe-buffer: 5.2.1
dev: true
/react-icons/4.7.1:
resolution: {integrity: sha512-yHd3oKGMgm7zxo3EA7H2n7vxSoiGmHk5t6Ou4bXsfcgWyhfDKMpyKfhHR6Bjnn63c+YXBLBPUql9H4wPJM6sXw==}
/react-icons/4.8.0:
resolution: {integrity: sha512-N6+kOLcihDiAnj5Czu637waJqSnwlMNROzVZMhfX68V/9bu9qHaMIJC4UdozWoOk57gahFCNHwVvWzm0MTzRjg==}
peerDependencies:
react: '*'
dev: false
@ -763,7 +763,7 @@ packages:
engines: {node: '>=6'}
hasBin: true
dependencies:
minimist: 1.2.7
minimist: 1.2.8
shelljs: 0.8.5
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.3
terser: 5.16.5
webpack: 5.75.0
dev: true
/terser/5.16.3:
resolution: {integrity: sha512-v8wWLaS/xt3nE9dgKEWhNUFP6q4kngO5B8eYFUuebsu7Dw/UNAnpUod6UHo04jSSkv8TzKHjZDSd7EXdDQAl8Q==}
/terser/5.16.5:
resolution: {integrity: sha512-qcwfg4+RZa3YvlFh0qjifnzBHjKGNbtDo9yivMqMFDy9Q6FSaQWSB/j1xKhsoUFJIqDOM3TsN6D5xbrMrFcHbg==}
engines: {node: '>=10'}
hasBin: true
dependencies:
@ -927,5 +927,5 @@ packages:
file:src/usdpl_front:
resolution: {directory: src/usdpl_front, type: directory}
name: usdpl-front
version: 0.9.1
version: 0.10.0
dev: false

View file

@ -1,59 +1,131 @@
{
"battery": {
"charge_rate": {"min": 250, "max": 2500}
},
"cpus": {
"cpus": [
{
"clock_min": {"min": 1400, "max": 3500},
"clock_max": {"min": 500, "max": 3500},
"clock_step": 100
},
{
"clock_min": {"min": 1400, "max": 3500},
"clock_max": {"min": 500, "max": 3500},
"clock_step": 100
},
{
"clock_min": {"min": 1400, "max": 3500},
"clock_max": {"min": 500, "max": 3500},
"clock_step": 100
},
{
"clock_min": {"min": 1400, "max": 3500},
"clock_max": {"min": 500, "max": 3500},
"clock_step": 100
},
{
"clock_min": {"min": 1400, "max": 3500},
"clock_max": {"min": 500, "max": 3500},
"clock_step": 100
},
{
"clock_min": {"min": 1400, "max": 3500},
"clock_max": {"min": 500, "max": 3500},
"clock_step": 100
},
{
"clock_min": {"min": 1400, "max": 3500},
"clock_max": {"min": 500, "max": 3500},
"clock_step": 100
},
{
"clock_min": {"min": 1400, "max": 3500},
"clock_max": {"min": 500, "max": 3500},
"clock_step": 100
}
],
"global_governors": false
},
"gpu": {
"fast_ppt": {"min": 1000000, "max": 30000000},
"slow_ppt": {"min": 1000000, "max": 29000000},
"ppt_divisor": 1000000,
"ppt_step": 1,
"clock_min": {"min": 200, "max": 1600},
"clock_max": {"min": 200, "max": 1600},
"clock_step": 100
"battery": {
"charge_rate": {
"min": 250,
"max": 2500
}
}
},
"cpus": {
"cpus": [
{
"clock_min": {
"min": 1400,
"max": 3500
},
"clock_max": {
"min": 400,
"max": 3500
},
"clock_step": 100,
"skip_resume_reclock": false
},
{
"clock_min": {
"min": 1400,
"max": 3500
},
"clock_max": {
"min": 400,
"max": 3500
},
"clock_step": 100,
"skip_resume_reclock": false
},
{
"clock_min": {
"min": 1400,
"max": 3500
},
"clock_max": {
"min": 400,
"max": 3500
},
"clock_step": 100,
"skip_resume_reclock": false
},
{
"clock_min": {
"min": 1400,
"max": 3500
},
"clock_max": {
"min": 400,
"max": 3500
},
"clock_step": 100,
"skip_resume_reclock": false
},
{
"clock_min": {
"min": 1400,
"max": 3500
},
"clock_max": {
"min": 400,
"max": 3500
},
"clock_step": 100,
"skip_resume_reclock": false
},
{
"clock_min": {
"min": 1400,
"max": 3500
},
"clock_max": {
"min": 400,
"max": 3500
},
"clock_step": 100,
"skip_resume_reclock": false
},
{
"clock_min": {
"min": 1400,
"max": 3500
},
"clock_max": {
"min": 400,
"max": 3500
},
"clock_step": 100,
"skip_resume_reclock": false
},
{
"clock_min": {
"min": 1400,
"max": 3500
},
"clock_max": {
"min": 400,
"max": 3500
},
"clock_step": 100,
"skip_resume_reclock": false
}
],
"global_governors": true
},
"gpu": {
"fast_ppt": {
"min": 1000000,
"max": 30000000
},
"slow_ppt": {
"min": 1000000,
"max": 29000000
},
"ppt_divisor": 1000000,
"ppt_step": 1,
"clock_min": {
"min": 400,
"max": 1600
},
"clock_max": {
"min": 400,
"max": 1600
},
"clock_step": 100,
"skip_resume_reclock": false
}
}

View file

@ -29,14 +29,14 @@ 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]
: navigator.language;
console.log("POWERTOOLS: locale", user_locale);
let mo_path = "../plugins/PowerTools/translations/" + user_locale.toString() + ".mo";
await init_tr(mo_path);
//let mo_path = "../plugins/PowerTools/translations/" + user_locale.toString() + ".mo";
await init_tr(user_locale);
//await init_tr("../plugins/PowerTools/translations/test.mo");
//setReady(true);
}
@ -146,7 +146,7 @@ export async function setCpuSmt(status: boolean): Promise<boolean[]> {
}
export async function getCpuSmt(): Promise<boolean> {
return await call_backend("CPU_get_smt", []);
return (await call_backend("CPU_get_smt", []))[0];
}
/*export async function getCpuCount(): Promise<number> {

View file

@ -175,9 +175,9 @@ export class Cpus extends Component<backend.IdcProps, CpuState> {
set_value(CLOCK_MIN_CPU, freq);
for (let i = 0; i < total_cpus; i++) {
backend.resolve(backend.setCpuClockLimits(i, freq, get_value(CLOCK_MAX_CPU)),
(limits: number[]) => {
set_value(CLOCK_MIN_CPU, limits[0]);
set_value(CLOCK_MAX_CPU, limits[1]);
(_limits: number[]) => {
//set_value(CLOCK_MIN_CPU, limits[0]);
//set_value(CLOCK_MAX_CPU, limits[1]);
syncPlebClockToAdvanced();
});
}
@ -206,9 +206,9 @@ export class Cpus extends Component<backend.IdcProps, CpuState> {
set_value(CLOCK_MAX_CPU, freq);
for (let i = 0; i < total_cpus; i++) {
backend.resolve(backend.setCpuClockLimits(i, get_value(CLOCK_MIN_CPU), freq),
(limits: number[]) => {
set_value(CLOCK_MIN_CPU, limits[0]);
set_value(CLOCK_MAX_CPU, limits[1]);
(_limits: number[]) => {
//set_value(CLOCK_MIN_CPU, limits[0]);
//set_value(CLOCK_MAX_CPU, limits[1]);
syncPlebClockToAdvanced();
});
}
@ -238,7 +238,7 @@ export class Cpus extends Component<backend.IdcProps, CpuState> {
const governors = get_value(GOVERNOR_CPU);
for (let i = 0; i < total_cpus; i++) {
governors[i] = elem.data as string;
backend.resolve(backend.setCpuGovernor(i, elem.data as string), (_: string) => {});
backend.resolve(backend.setCpuGovernor(i, governors[i]), (_: string) => {});
}
set_value(GOVERNOR_CPU, governors);
reloadGUI("CPUGlobalGovernor");
@ -273,14 +273,14 @@ export class Cpus extends Component<backend.IdcProps, CpuState> {
onChange={(status: boolean) => {
backend.log(backend.LogLevel.Debug, "CPU " + advancedCpu.toString() + " is now " + status.toString());
if (!get_value(SMT_CPU)) {
backend.resolve(backend.setCpuSmt(true), (_newVal: boolean[]) => {
set_value(SMT_CPU, true);
});
backend.resolve(backend.setCpuSmt(true), (_newVal: boolean[]) => {
set_value(SMT_CPU, true);
});
}
backend.resolve(backend.setCpuOnline(advancedCpuIndex, status), (newVal: boolean) => {
const onlines = get_value(ONLINE_STATUS_CPUS);
onlines[advancedCpuIndex] = newVal;
set_value(ONLINE_STATUS_CPUS, onlines);
const onlines = get_value(ONLINE_STATUS_CPUS);
onlines[advancedCpuIndex] = newVal;
set_value(ONLINE_STATUS_CPUS, onlines);
});
}}
/>
@ -292,24 +292,24 @@ export class Cpus extends Component<backend.IdcProps, CpuState> {
description={tr("Set bounds on clock speed")}
onChange={(value: boolean) => {
if (value) {
const clocks = get_value(CLOCK_MIN_MAX_CPU) as MinMax[];
if ((get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[advancedCpuIndex].clock_min_limits != null) {
clocks[advancedCpuIndex].min = (get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[advancedCpuIndex].clock_min_limits!.min;
}
const clocks = get_value(CLOCK_MIN_MAX_CPU) as MinMax[];
if ((get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[advancedCpuIndex].clock_min_limits != null) {
clocks[advancedCpuIndex].min = (get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[advancedCpuIndex].clock_min_limits!.min;
}
if ((get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[advancedCpuIndex].clock_max_limits != null) {
clocks[advancedCpuIndex].max = (get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[advancedCpuIndex].clock_max_limits!.max;
}
set_value(CLOCK_MIN_MAX_CPU, clocks);
reloadGUI("CPUFreqToggle");
if ((get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[advancedCpuIndex].clock_max_limits != null) {
clocks[advancedCpuIndex].max = (get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[advancedCpuIndex].clock_max_limits!.max;
}
set_value(CLOCK_MIN_MAX_CPU, clocks);
reloadGUI("CPUFreqToggle");
} else {
const clocks = get_value(CLOCK_MIN_MAX_CPU) as MinMax[];
clocks[advancedCpuIndex].min = null;
clocks[advancedCpuIndex].max = null;
set_value(CLOCK_MIN_MAX_CPU, clocks);
backend.resolve(backend.unsetCpuClockLimits(advancedCpuIndex), (_idc: any[]) => {
reloadGUI("CPUUnsetFreq");
});
const clocks = get_value(CLOCK_MIN_MAX_CPU) as MinMax[];
clocks[advancedCpuIndex].min = null;
clocks[advancedCpuIndex].max = null;
set_value(CLOCK_MIN_MAX_CPU, clocks);
backend.resolve(backend.unsetCpuClockLimits(advancedCpuIndex), (_idc: any[]) => {
reloadGUI("CPUUnsetFreq");
});
}
}}
/>

View file

@ -16,6 +16,8 @@ import {
import { get_value, target_usdpl, version_usdpl} from "usdpl-front";
let eggCount = 0;
let now = new Date();
let isSpecialDay = now.getDate() == 1 && now.getMonth() == 3;
export class Debug extends Component<backend.IdcProps> {
render() {
@ -35,7 +37,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++;
}}>
@ -70,7 +72,7 @@ function buildDebug() {
v{version_usdpl()}
</Field>
</PanelSectionRow>
{eggCount % 10 == 9 && <PanelSectionRow>
{(eggCount % 10 == 9 || isSpecialDay) && <PanelSectionRow>
<ButtonItem
layout="below"
onClick={(_: MouseEvent) => {

View file

@ -40,20 +40,20 @@ export class Gpu extends Component<backend.IdcProps> {
description={tr("Override APU TDP settings")}
onChange={(value: boolean) => {
if (value) {
if ((get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.slow_ppt_limits != null) {
set_value(SLOW_PPT_GPU, (get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.slow_ppt_limits!.max);
}
if ((get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.slow_ppt_limits != null) {
set_value(SLOW_PPT_GPU, (get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.slow_ppt_limits!.max);
}
if ((get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.fast_ppt_limits != null) {
set_value(FAST_PPT_GPU, (get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.fast_ppt_limits!.max);
}
reloadGUI("GPUPPTToggle");
if ((get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.fast_ppt_limits != null) {
set_value(FAST_PPT_GPU, (get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.fast_ppt_limits!.max);
}
reloadGUI("GPUPPTToggle");
} else {
set_value(SLOW_PPT_GPU, null);
set_value(FAST_PPT_GPU, null);
backend.resolve(backend.unsetGpuPpt(), (_: any[]) => {
reloadGUI("GPUUnsetPPT");
});
set_value(SLOW_PPT_GPU, null);
set_value(FAST_PPT_GPU, null);
backend.resolve(backend.unsetGpuPpt(), (_: any[]) => {
reloadGUI("GPUUnsetPPT");
});
}
}}
/>
@ -113,15 +113,15 @@ export class Gpu extends Component<backend.IdcProps> {
description={tr("Set bounds on clock speed")}
onChange={(value: boolean) => {
if (value) {
let clock_min_limits = (get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.clock_min_limits;
let clock_max_limits = (get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.clock_max_limits;
if (clock_min_limits != null) {
set_value(CLOCK_MIN_GPU, clock_min_limits.min);
}
if (clock_max_limits != null) {
set_value(CLOCK_MAX_GPU, clock_max_limits.max);
}
reloadGUI("GPUFreqToggle");
let clock_min_limits = (get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.clock_min_limits;
let clock_max_limits = (get_value(LIMITS_INFO) as backend.SettingsLimits).gpu.clock_max_limits;
if (clock_min_limits != null) {
set_value(CLOCK_MIN_GPU, clock_min_limits.min);
}
if (clock_max_limits != null) {
set_value(CLOCK_MAX_GPU, clock_max_limits.max);
}
reloadGUI("GPUFreqToggle");
} else {
set_value(CLOCK_MIN_GPU, null);
set_value(CLOCK_MAX_GPU, null);
@ -187,8 +187,8 @@ export class Gpu extends Component<backend.IdcProps> {
description={tr("Force RAM into low-power mode")}
onChange={(value: boolean) => {
backend.resolve(backend.setGpuSlowMemory(value), (val: boolean) => {
set_value(SLOW_MEMORY_GPU, val);
reloadGUI("GPUSlowMemory");
set_value(SLOW_MEMORY_GPU, val);
reloadGUI("GPUSlowMemory");
})
}}
/>

View file

@ -20,7 +20,7 @@ import {
//joinClassNames,
} from "decky-frontend-lib";
import { VFC, useState } from "react";
import { GiDrill } from "react-icons/gi";
import { GiDrill, GiTimeBomb, GiTimeTrap, GiDynamite } from "react-icons/gi";
//import * as python from "./python";
import * as backend from "./backend";
@ -210,6 +210,24 @@ const Content: VFC<{ serverAPI: ServerAPI }> = ({}) => {
reloadGUI("periodic" + (new Date()).getTime().toString());
}, 1000);
if (!usdplReady || !get_value(LIMITS_INFO)) {
// Not translated on purpose (to avoid USDPL issues)
return (
<PanelSection>
USDPL or PowerTools's backend did not start correctly!
<ButtonItem
layout="below"
onClick={(_: MouseEvent) => {
console.log("POWERTOOLS: manual reload after startup failure");
reload();
}}
>
Reload
</ButtonItem>
</PanelSection>
)
}
return (
<PanelSection>
<Cpus idc={idc}/>
@ -271,17 +289,22 @@ const Content: VFC<{ serverAPI: ServerAPI }> = ({}) => {
};
export default definePlugin((serverApi: ServerAPI) => {
let ico = <GiDrill />;
let now = new Date();
if (now.getDate() == 1 && now.getMonth() == 3) {
ico = <span><GiDynamite /><GiTimeTrap /><GiTimeBomb /></span>;
}
return {
title: <div className={staticClasses.Title}>PowerTools</div>,
title: <div className={staticClasses.Title}>I'm a tool</div>,
content: <Content serverAPI={serverApi} />,
icon: <GiDrill />,
icon: ico,
onDismount() {
backend.log(backend.LogLevel.Debug, "PowerTools shutting down");
clearInterval(periodicHook!);
periodicHook = null;
lifetimeHook!.unregister();
startHook!.unregister();
serverApi.routerHook.removeRoute("/decky-plugin-test");
//serverApi.routerHook.removeRoute("/decky-plugin-test");
backend.log(backend.LogLevel.Debug, "Unregistered PowerTools callbacks, so long and thanks for all the fish.");
},
};

View file

@ -4,7 +4,7 @@
"NGnius (Graham) <ngniusness@gmail.com>"
],
"description": "Universal Steam Deck Plugin Library front-end designed for WASM",
"version": "0.9.1",
"version": "0.10.0",
"license": "GPL-3.0-only",
"repository": {
"type": "git",

13
src/usdpl_front/rebuild.sh Executable file
View file

@ -0,0 +1,13 @@
#!/bin/bash
git clone https://github.com/NGnius/usdpl-rs usdpl-rs
cd usdpl-rs/usdpl-front/
./build.sh $1 $2
cd ../..
cp -f ./usdpl-rs/usdpl-front/pkg/* ./
#rm ./.gitignore
rm -rf ./usdpl-rs

File diff suppressed because one or more lines are too long

Binary file not shown.