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

View file

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

View file

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

View file

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

View file

@ -1,4 +1,5 @@
use std::sync::mpsc::{self, Receiver, Sender}; use std::sync::mpsc::{self, Receiver, Sender};
use std::fmt::Write;
use crate::settings::{Settings, TCpus, TGpu, TBattery, TGeneral, OnSet, OnResume, MinMax}; use crate::settings::{Settings, TCpus, TGpu, TBattery, TGeneral, OnSet, OnResume, MinMax};
use crate::persist::SettingsJson; use crate::persist::SettingsJson;
@ -216,6 +217,12 @@ pub struct ApiMessageHandler {
on_empty: Vec<Callback<()>>, 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 { impl ApiMessageHandler {
pub fn process_forever(&mut self, settings: &mut Settings) { 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 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 dirty_echo = dirty; // echo only once
// run on_set // run on_set
if let Err(e) = settings.on_set() { if let Err(e) = settings.on_set() {
log::error!("Settings on_set() err: {}", e); print_errors("on_set", e);
} }
// do callbacks // do callbacks
for func in self.on_empty.drain(..) { for func in self.on_empty.drain(..) {
@ -244,6 +251,9 @@ impl ApiMessageHandler {
let save_json: SettingsJson = settings_clone.into(); let save_json: SettingsJson = settings_clone.into();
unwrap_maybe_fatal(save_json.save(&save_path), "Failed to save settings"); unwrap_maybe_fatal(save_json.save(&save_path), "Failed to save settings");
log::debug!("Saved settings to {}", save_path.display()); 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 { } else {
if save_path.exists() { if save_path.exists() {
if let Err(e) = std::fs::remove_file(&save_path) { 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::General(x) => x.process(settings.general.as_mut()),
ApiMessage::OnResume => { ApiMessage::OnResume => {
if let Err(e) = settings.on_resume() { if let Err(e) = settings.on_resume() {
log::error!("Settings on_resume() err: {}", e); print_errors("on_resume", e);
} }
false false
} }

View file

@ -18,7 +18,6 @@ use usdpl_back::core::serdes::Primitive;
use usdpl_back::Instance; use usdpl_back::Instance;
fn main() -> Result<(), ()> { fn main() -> Result<(), ()> {
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
let log_filepath = usdpl_back::api::dirs::home() let log_filepath = usdpl_back::api::dirs::home()
.unwrap_or_else(|| "/tmp/".into()) .unwrap_or_else(|| "/tmp/".into())
@ -46,6 +45,7 @@ fn main() -> Result<(), ()> {
}, },
Default::default(), Default::default(),
std::fs::File::create(&log_filepath).unwrap(), std::fs::File::create(&log_filepath).unwrap(),
//std::fs::File::create("/home/deck/powertools-rs.log").unwrap(),
) )
.unwrap(); .unwrap();
log::debug!("Logging to: {:?}.", log_filepath); log::debug!("Logging to: {:?}.", log_filepath);
@ -55,6 +55,8 @@ fn main() -> Result<(), ()> {
log::info!("Current dir `{}`", std::env::current_dir().unwrap().display()); log::info!("Current dir `{}`", std::env::current_dir().unwrap().display());
println!("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(); 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()); 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) let instance = Instance::new(PORT)
.register("V_INFO", |_: Vec<Primitive>| { .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()) .register("LOG", api::general::log_it())
// battery API functions // battery API functions
@ -222,11 +230,15 @@ fn main() -> Result<(), ()> {
.register("GENERAL_idk", api::general::gunter); .register("GENERAL_idk", api::general::gunter);
if let Err(e) = loaded_settings.on_set() { 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 { } else {
log::info!("Startup Settings.on_set() success"); 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); api_worker::spawn(loaded_settings, api_handler);
instance 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 { impl OnSet for General {
fn on_set(&mut self) -> Result<(), SettingError> { fn on_set(&mut self) -> Result<(), Vec<SettingError>> {
Ok(()) Ok(())
} }
} }
impl OnResume for General { impl OnResume for General {
fn on_resume(&self) -> Result<(), SettingError> { fn on_resume(&self) -> Result<(), Vec<SettingError>> {
Ok(()) Ok(())
} }
} }
@ -91,7 +91,7 @@ pub struct Settings {
} }
impl OnSet for 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.battery.on_set()?;
self.cpus.on_set()?; self.cpus.on_set()?;
self.gpu.on_set()?; self.gpu.on_set()?;
@ -224,7 +224,7 @@ impl Settings {
} }
impl OnResume for 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"); log::debug!("Applying settings for on_resume");
self.battery.on_resume()?; self.battery.on_resume()?;
log::debug!("Resumed battery"); log::debug!("Resumed battery");

View file

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

View file

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

View file

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

View file

@ -23,7 +23,7 @@ pub use traits::{OnResume, OnSet, SettingsRange, TGeneral, TGpu, TCpus, TBattery
mod tests { mod tests {
#[test] #[test]
fn system_defaults_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); 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 { if let Some(charge_rate) = self.charge_rate {
self.state.charge_rate_set = true; self.state.charge_rate_set = true;
usdpl_back::api::files::write_single(BATTERY_CHARGE_RATE_PATH, charge_rate).map_err( 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), msg: format!("Failed to write to `{}`: {}", BATTERY_CHARGE_RATE_PATH, e),
setting: crate::settings::SettingVariant::Battery, setting: crate::settings::SettingVariant::Battery,
}, },
)?; ).unwrap_or_else(|e| errors.push(e));
} else if self.state.charge_rate_set { } else if self.state.charge_rate_set {
self.state.charge_rate_set = false; self.state.charge_rate_set = false;
usdpl_back::api::files::write_single(BATTERY_CHARGE_RATE_PATH, self.limits.charge_rate.max).map_err( 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), msg: format!("Failed to write to `{}`: {}", BATTERY_CHARGE_RATE_PATH, e),
setting: crate::settings::SettingVariant::Battery, setting: crate::settings::SettingVariant::Battery,
}, },
)?; ).unwrap_or_else(|e| errors.push(e));
} }
if let Some(charge_mode) = self.charge_mode { if let Some(charge_mode) = self.charge_mode {
self.state.charge_mode_set = true; self.state.charge_mode_set = true;
@ -92,7 +93,7 @@ impl Battery {
msg: format!("Failed to set charge mode: {}", e), msg: format!("Failed to set charge mode: {}", e),
setting: crate::settings::SettingVariant::Battery, setting: crate::settings::SettingVariant::Battery,
}, },
)?; ).unwrap_or_else(|e| {errors.push(e); 0});
} else if self.state.charge_mode_set { } else if self.state.charge_mode_set {
self.state.charge_mode_set = false; self.state.charge_mode_set = false;
super::util::set(super::util::Setting::ChargeMode, ChargeMode::Normal as _).map_err( 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), msg: format!("Failed to set charge mode: {}", e),
setting: crate::settings::SettingVariant::Battery, 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) { fn clamp_all(&mut self) {
@ -181,14 +186,14 @@ impl Into<BatteryJson> for Battery {
} }
impl OnSet 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.clamp_all();
self.set_all() self.set_all()
} }
} }
impl OnResume for Battery { impl OnResume for Battery {
fn on_resume(&self) -> Result<(), SettingError> { fn on_resume(&self) -> Result<(), Vec<SettingError>> {
self.clone().set_all() self.clone().set_all()
} }
} }

View file

@ -20,7 +20,8 @@ pub struct Cpus {
} }
impl OnSet for 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 { if self.smt_capable {
// toggle SMT // toggle SMT
if self.smt { if self.smt {
@ -32,7 +33,7 @@ impl OnSet for Cpus {
), ),
setting: crate::settings::SettingVariant::Cpu, setting: crate::settings::SettingVariant::Cpu,
} }
})?; }).unwrap_or_else(|e| errors.push(e));
} else { } else {
usdpl_back::api::files::write_single(CPU_SMT_PATH, "off").map_err(|e| { usdpl_back::api::files::write_single(CPU_SMT_PATH, "off").map_err(|e| {
SettingError { SettingError {
@ -42,23 +43,32 @@ impl OnSet for Cpus {
), ),
setting: crate::settings::SettingVariant::Cpu, setting: crate::settings::SettingVariant::Cpu,
} }
})?; }).unwrap_or_else(|e| errors.push(e));
} }
} }
for (i, cpu) in self.cpus.as_mut_slice().iter_mut().enumerate() { for (i, cpu) in self.cpus.as_mut_slice().iter_mut().enumerate() {
cpu.state.do_set_online = self.smt || i % 2 == 0; 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 { 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 { 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 { fn smt(&mut self) -> &'_ mut bool {
log::debug!("CPU driver thinks SMT is {}", self.smt);
&mut self.smt &mut self.smt
} }
@ -220,30 +231,22 @@ impl Cpu {
} }
} }
fn set_all(&mut self) -> Result<(), SettingError> { fn set_force_performance_related(&mut self) -> Result<(), Vec<SettingError>> {
// set cpu online/offline let mut errors = Vec::new();
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,
}
})?;
}
// set clock limits // set clock limits
log::debug!("Setting {} to manual", CPU_FORCE_LIMITS_PATH); 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(); let mode: String = usdpl_back::api::files::read_single(CPU_FORCE_LIMITS_PATH.to_owned()).unwrap();
if mode != "manual" { if mode != "manual" {
// set manual control // set manual control
usdpl_back::api::files::write_single(CPU_FORCE_LIMITS_PATH, "manual").map_err(|e| { usdpl_back::api::files::write_single(CPU_FORCE_LIMITS_PATH, "manual").map_err(|e| {
SettingError { vec![SettingError {
msg: format!( msg: format!(
"Failed to write `manual` to `{}`: {}", "Failed to write `manual` to `{}`: {}",
CPU_FORCE_LIMITS_PATH, e CPU_FORCE_LIMITS_PATH, e
), ),
setting: crate::settings::SettingVariant::Cpu, setting: crate::settings::SettingVariant::Cpu,
} }]
})?; })?;
} }
if let Some(clock_limits) = &self.clock_limits { if let Some(clock_limits) = &self.clock_limits {
@ -259,7 +262,7 @@ impl Cpu {
), ),
setting: crate::settings::SettingVariant::Cpu, setting: crate::settings::SettingVariant::Cpu,
}, },
)?; ).unwrap_or_else(|e| errors.push(e));
// min clock // min clock
let valid_min = if clock_limits.min < self.limits.clock_min.min {self.limits.clock_min.min} else {clock_limits.min}; 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); let payload_min = format!("p {} 0 {}\n", self.index / 2, valid_min);
@ -271,8 +274,8 @@ impl Cpu {
), ),
setting: crate::settings::SettingVariant::Cpu, setting: crate::settings::SettingVariant::Cpu,
}, },
)?; ).unwrap_or_else(|e| errors.push(e));
} else if self.state.clock_limits_set || self.state.is_resuming { } else if self.state.clock_limits_set || (self.state.is_resuming && !self.limits.skip_resume_reclock) {
self.state.clock_limits_set = false; self.state.clock_limits_set = false;
// disable manual clock limits // disable manual clock limits
log::debug!("Setting CPU {} to default clockspeed", self.index); log::debug!("Setting CPU {} to default clockspeed", self.index);
@ -286,7 +289,7 @@ impl Cpu {
), ),
setting: crate::settings::SettingVariant::Cpu, setting: crate::settings::SettingVariant::Cpu,
}, },
)?; ).unwrap_or_else(|e| errors.push(e));
// min clock // min clock
let payload_min = format!("p {} 0 {}\n", self.index / 2, self.limits.clock_min.min); 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( 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, 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| { usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, "c\n")
SettingError { .unwrap_or_else(|e| {
msg: format!("Failed to write `c` to `{}`: {}", CPU_CLOCK_LIMITS_PATH, e), errors.push(SettingError {
setting: crate::settings::SettingVariant::Cpu, 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 // set governor
if self.index == 0 || self.online { if self.index == 0 || self.online {
@ -318,9 +350,13 @@ impl Cpu {
), ),
setting: crate::settings::SettingVariant::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) { fn clamp_all(&mut self) {
@ -393,14 +429,14 @@ impl Into<CpuJson> for Cpu {
} }
impl OnSet 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.clamp_all();
self.set_all() self.set_all()
} }
} }
impl OnResume for Cpu { impl OnResume for Cpu {
fn on_resume(&self) -> Result<(), SettingError> { fn on_resume(&self) -> Result<(), Vec<SettingError>> {
let mut copy = self.clone(); let mut copy = self.clone();
copy.state.is_resuming = true; copy.state.is_resuming = true;
copy.set_all() copy.set_all()

View file

@ -53,53 +53,8 @@ impl Gpu {
} }
} }
fn set_all(&mut self) -> Result<(), SettingError> { fn set_clocks(&mut self) -> Result<(), Vec<SettingError>> {
// set fast PPT let mut errors = Vec::new();
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,
})?;
if let Some(clock_limits) = &self.clock_limits { if let Some(clock_limits) = &self.clock_limits {
// set clock limits // set clock limits
self.state.clock_limits_set = true; self.state.clock_limits_set = true;
@ -113,7 +68,7 @@ impl Gpu {
), ),
setting: crate::settings::SettingVariant::Gpu, setting: crate::settings::SettingVariant::Gpu,
}, },
)?; ).unwrap_or_else(|e| errors.push(e));
// min clock // min clock
let payload_min = format!("s 0 {}\n", clock_limits.min); let payload_min = format!("s 0 {}\n", clock_limits.min);
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, &payload_min).map_err( 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, setting: crate::settings::SettingVariant::Gpu,
}, },
)?; ).unwrap_or_else(|e| errors.push(e));
} else if self.state.clock_limits_set || self.state.is_resuming { } else if self.state.clock_limits_set || (self.state.is_resuming && !self.limits.skip_resume_reclock) {
self.state.clock_limits_set = false; self.state.clock_limits_set = false;
// disable manual clock limits // disable manual clock limits
// max clock // max clock
@ -138,7 +93,7 @@ impl Gpu {
), ),
setting: crate::settings::SettingVariant::Gpu, setting: crate::settings::SettingVariant::Gpu,
}, },
)?; ).unwrap_or_else(|e| errors.push(e));
// min clock // min clock
let payload_min = format!("s 0 {}\n", self.limits.clock_min.min); 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( 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, setting: crate::settings::SettingVariant::Gpu,
}, },
)?; ).unwrap_or_else(|e| errors.push(e));
} }
// commit changes if errors.is_empty() {
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, "c\n").map_err(|e| { Ok(())
SettingError { } else {
msg: format!("Failed to write `c` to `{}`: {}", GPU_CLOCK_LIMITS_PATH, e), Err(errors)
setting: crate::settings::SettingVariant::Gpu, }
} }
})?;
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) { fn clamp_all(&mut self) {
@ -208,14 +235,14 @@ impl Into<GpuJson> for Gpu {
} }
impl OnSet 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.clamp_all();
self.set_all() self.set_all()
} }
} }
impl OnResume for Gpu { impl OnResume for Gpu {
fn on_resume(&self) -> Result<(), SettingError> { fn on_resume(&self) -> Result<(), Vec<SettingError>> {
let mut copy = self.clone(); let mut copy = self.clone();
copy.state.is_resuming = true; copy.state.is_resuming = true;
copy.set_all() copy.set_all()

View file

@ -73,7 +73,7 @@ impl Default for CpusLimits {
fn default() -> Self { fn default() -> Self {
Self { Self {
cpus: [(); 8].iter().map(|_| CpuLimits::default()).collect(), 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_min: MinMax<u64>,
pub clock_max: MinMax<u64>, pub clock_max: MinMax<u64>,
pub clock_step: u64, pub clock_step: u64,
pub skip_resume_reclock: bool,
} }
impl Default for CpuLimits { impl Default for CpuLimits {
@ -91,6 +92,7 @@ impl Default for CpuLimits {
clock_min: MinMax { min: 1400, max: 3500 }, clock_min: MinMax { min: 1400, max: 3500 },
clock_max: MinMax { min: 400, max: 3500 }, clock_max: MinMax { min: 400, max: 3500 },
clock_step: 100, clock_step: 100,
skip_resume_reclock: false,
} }
} }
} }
@ -104,6 +106,7 @@ pub(super) struct GpuLimits {
pub clock_min: MinMax<u64>, pub clock_min: MinMax<u64>,
pub clock_max: MinMax<u64>, pub clock_max: MinMax<u64>,
pub clock_step: u64, pub clock_step: u64,
pub skip_resume_reclock: bool,
} }
impl Default for GpuLimits { impl Default for GpuLimits {
@ -113,9 +116,10 @@ impl Default for GpuLimits {
slow_ppt: MinMax { min: 1000000, max: 29_000_000 }, slow_ppt: MinMax { min: 1000000, max: 29_000_000 },
ppt_divisor: 1_000_000, ppt_divisor: 1_000_000,
ppt_step: 1, ppt_step: 1,
clock_min: MinMax { min: 200, max: 1600 }, clock_min: MinMax { min: 400, max: 1600 },
clock_max: MinMax { min: 200, max: 1600 }, clock_max: MinMax { min: 400, max: 1600 },
clock_step: 100, clock_step: 100,
skip_resume_reclock: false,
} }
} }
} }
@ -123,3 +127,22 @@ impl Default for GpuLimits {
fn oc_limits_filepath() -> std::path::PathBuf { fn oc_limits_filepath() -> std::path::PathBuf {
crate::utility::settings_dir().join(OC_LIMITS_FILEPATH) 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; use super::MinMax;
pub trait OnSet { pub trait OnSet {
fn on_set(&mut self) -> Result<(), SettingError>; fn on_set(&mut self) -> Result<(), Vec<SettingError>>;
} }
pub trait OnResume { pub trait OnResume {
fn on_resume(&self) -> Result<(), SettingError>; fn on_resume(&self) -> Result<(), Vec<SettingError>>;
} }
pub trait SettingsRange { pub trait SettingsRange {

View file

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

View file

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

View file

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

View file

@ -5,3 +5,45 @@ pub fn guess_smt(cpus: &Vec<crate::persist::CpuJson>) -> bool {
} }
guess 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::fmt::Display;
//use std::sync::{LockResult, MutexGuard}; //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 { pub fn unwrap_maybe_fatal<T: Sized, E: Display>(result: Result<T, E>, message: &str) -> T {
match result { match result {
@ -29,3 +31,25 @@ pub fn settings_dir() -> std::path::PathBuf {
.unwrap_or_else(|| "/tmp/".into()) .unwrap_or_else(|| "/tmp/".into())
.join(".config/powertools/") .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): async def _main(self):
# startup # startup
print("PowerTools starting...") 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( self.backend_proc = subprocess.Popen(
[PARENT_DIR + "/bin/backend"], [PARENT_DIR + "/bin/backend"],
env = {"LD_LIBRARY_PATH": ":"+PARENT_DIR+"/bin"}) env = env_proc)
while True: while True:
await asyncio.sleep(1) await asyncio.sleep(1)

View file

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

View file

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

View file

@ -1,59 +1,131 @@
{ {
"battery": { "battery": {
"charge_rate": {"min": 250, "max": 2500} "charge_rate": {
}, "min": 250,
"cpus": { "max": 2500
"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
} }
} },
"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 // init usdpl
await init_embedded(); await init_embedded();
init_usdpl(USDPL_PORT); init_usdpl(USDPL_PORT);
console.log("USDPL started for framework: " + target_usdpl()); console.log("POWERTOOLS: USDPL started for framework: " + target_usdpl());
const user_locale = const user_locale =
navigator.languages && navigator.languages.length navigator.languages && navigator.languages.length
? navigator.languages[0] ? navigator.languages[0]
: navigator.language; : navigator.language;
console.log("POWERTOOLS: locale", user_locale); console.log("POWERTOOLS: locale", user_locale);
let mo_path = "../plugins/PowerTools/translations/" + user_locale.toString() + ".mo"; //let mo_path = "../plugins/PowerTools/translations/" + user_locale.toString() + ".mo";
await init_tr(mo_path); await init_tr(user_locale);
//await init_tr("../plugins/PowerTools/translations/test.mo"); //await init_tr("../plugins/PowerTools/translations/test.mo");
//setReady(true); //setReady(true);
} }
@ -146,7 +146,7 @@ export async function setCpuSmt(status: boolean): Promise<boolean[]> {
} }
export async function getCpuSmt(): 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> { /*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); set_value(CLOCK_MIN_CPU, freq);
for (let i = 0; i < total_cpus; i++) { for (let i = 0; i < total_cpus; i++) {
backend.resolve(backend.setCpuClockLimits(i, freq, get_value(CLOCK_MAX_CPU)), backend.resolve(backend.setCpuClockLimits(i, freq, get_value(CLOCK_MAX_CPU)),
(limits: number[]) => { (_limits: number[]) => {
set_value(CLOCK_MIN_CPU, limits[0]); //set_value(CLOCK_MIN_CPU, limits[0]);
set_value(CLOCK_MAX_CPU, limits[1]); //set_value(CLOCK_MAX_CPU, limits[1]);
syncPlebClockToAdvanced(); syncPlebClockToAdvanced();
}); });
} }
@ -206,9 +206,9 @@ export class Cpus extends Component<backend.IdcProps, CpuState> {
set_value(CLOCK_MAX_CPU, freq); set_value(CLOCK_MAX_CPU, freq);
for (let i = 0; i < total_cpus; i++) { for (let i = 0; i < total_cpus; i++) {
backend.resolve(backend.setCpuClockLimits(i, get_value(CLOCK_MIN_CPU), freq), backend.resolve(backend.setCpuClockLimits(i, get_value(CLOCK_MIN_CPU), freq),
(limits: number[]) => { (_limits: number[]) => {
set_value(CLOCK_MIN_CPU, limits[0]); //set_value(CLOCK_MIN_CPU, limits[0]);
set_value(CLOCK_MAX_CPU, limits[1]); //set_value(CLOCK_MAX_CPU, limits[1]);
syncPlebClockToAdvanced(); syncPlebClockToAdvanced();
}); });
} }
@ -238,7 +238,7 @@ export class Cpus extends Component<backend.IdcProps, CpuState> {
const governors = get_value(GOVERNOR_CPU); const governors = get_value(GOVERNOR_CPU);
for (let i = 0; i < total_cpus; i++) { for (let i = 0; i < total_cpus; i++) {
governors[i] = elem.data as string; 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); set_value(GOVERNOR_CPU, governors);
reloadGUI("CPUGlobalGovernor"); reloadGUI("CPUGlobalGovernor");
@ -273,14 +273,14 @@ export class Cpus extends Component<backend.IdcProps, CpuState> {
onChange={(status: boolean) => { onChange={(status: boolean) => {
backend.log(backend.LogLevel.Debug, "CPU " + advancedCpu.toString() + " is now " + status.toString()); backend.log(backend.LogLevel.Debug, "CPU " + advancedCpu.toString() + " is now " + status.toString());
if (!get_value(SMT_CPU)) { if (!get_value(SMT_CPU)) {
backend.resolve(backend.setCpuSmt(true), (_newVal: boolean[]) => { backend.resolve(backend.setCpuSmt(true), (_newVal: boolean[]) => {
set_value(SMT_CPU, true); set_value(SMT_CPU, true);
}); });
} }
backend.resolve(backend.setCpuOnline(advancedCpuIndex, status), (newVal: boolean) => { backend.resolve(backend.setCpuOnline(advancedCpuIndex, status), (newVal: boolean) => {
const onlines = get_value(ONLINE_STATUS_CPUS); const onlines = get_value(ONLINE_STATUS_CPUS);
onlines[advancedCpuIndex] = newVal; onlines[advancedCpuIndex] = newVal;
set_value(ONLINE_STATUS_CPUS, onlines); 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")} description={tr("Set bounds on clock speed")}
onChange={(value: boolean) => { onChange={(value: boolean) => {
if (value) { if (value) {
const clocks = get_value(CLOCK_MIN_MAX_CPU) as MinMax[]; 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) { 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; 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) { 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; clocks[advancedCpuIndex].max = (get_value(LIMITS_INFO) as backend.SettingsLimits).cpu.cpus[advancedCpuIndex].clock_max_limits!.max;
} }
set_value(CLOCK_MIN_MAX_CPU, clocks); set_value(CLOCK_MIN_MAX_CPU, clocks);
reloadGUI("CPUFreqToggle"); reloadGUI("CPUFreqToggle");
} else { } else {
const clocks = get_value(CLOCK_MIN_MAX_CPU) as MinMax[]; const clocks = get_value(CLOCK_MIN_MAX_CPU) as MinMax[];
clocks[advancedCpuIndex].min = null; clocks[advancedCpuIndex].min = null;
clocks[advancedCpuIndex].max = null; clocks[advancedCpuIndex].max = null;
set_value(CLOCK_MIN_MAX_CPU, clocks); set_value(CLOCK_MIN_MAX_CPU, clocks);
backend.resolve(backend.unsetCpuClockLimits(advancedCpuIndex), (_idc: any[]) => { backend.resolve(backend.unsetCpuClockLimits(advancedCpuIndex), (_idc: any[]) => {
reloadGUI("CPUUnsetFreq"); reloadGUI("CPUUnsetFreq");
}); });
} }
}} }}
/> />

View file

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

View file

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

View file

@ -20,7 +20,7 @@ import {
//joinClassNames, //joinClassNames,
} from "decky-frontend-lib"; } from "decky-frontend-lib";
import { VFC, useState } from "react"; 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 python from "./python";
import * as backend from "./backend"; import * as backend from "./backend";
@ -210,6 +210,24 @@ const Content: VFC<{ serverAPI: ServerAPI }> = ({}) => {
reloadGUI("periodic" + (new Date()).getTime().toString()); reloadGUI("periodic" + (new Date()).getTime().toString());
}, 1000); }, 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 ( return (
<PanelSection> <PanelSection>
<Cpus idc={idc}/> <Cpus idc={idc}/>
@ -271,17 +289,22 @@ const Content: VFC<{ serverAPI: ServerAPI }> = ({}) => {
}; };
export default definePlugin((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 { return {
title: <div className={staticClasses.Title}>PowerTools</div>, title: <div className={staticClasses.Title}>I'm a tool</div>,
content: <Content serverAPI={serverApi} />, content: <Content serverAPI={serverApi} />,
icon: <GiDrill />, icon: ico,
onDismount() { onDismount() {
backend.log(backend.LogLevel.Debug, "PowerTools shutting down"); backend.log(backend.LogLevel.Debug, "PowerTools shutting down");
clearInterval(periodicHook!); clearInterval(periodicHook!);
periodicHook = null; periodicHook = null;
lifetimeHook!.unregister(); lifetimeHook!.unregister();
startHook!.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."); 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>" "NGnius (Graham) <ngniusness@gmail.com>"
], ],
"description": "Universal Steam Deck Plugin Library front-end designed for WASM", "description": "Universal Steam Deck Plugin Library front-end designed for WASM",
"version": "0.9.1", "version": "0.10.0",
"license": "GPL-3.0-only", "license": "GPL-3.0-only",
"repository": { "repository": {
"type": "git", "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.