forked from NG-SD-Plugins/PowerTools
Cargo fmt
This commit is contained in:
parent
2c0cac125c
commit
54393cd0cb
38 changed files with 1725 additions and 1023 deletions
|
@ -9,7 +9,10 @@ pub struct RangeLimit<T> {
|
|||
impl<T> From<limits_core::json::RangeLimit<T>> for RangeLimit<T> {
|
||||
#[inline]
|
||||
fn from(other: limits_core::json::RangeLimit<T>) -> Self {
|
||||
RangeLimit { min: other.min, max: other.max }
|
||||
RangeLimit {
|
||||
min: other.min,
|
||||
max: other.max,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,8 +50,7 @@ pub struct CpuLimits {
|
|||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct GeneralLimits {
|
||||
}
|
||||
pub struct GeneralLimits {}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct GpuLimits {
|
||||
|
|
|
@ -1,29 +1,33 @@
|
|||
//use usdpl_back::core::serdes::Primitive;
|
||||
use usdpl_back::AsyncCallable;
|
||||
|
||||
pub struct AsyncIsh<In: Send + 'static,
|
||||
pub struct AsyncIsh<
|
||||
In: Send + 'static,
|
||||
Out: Send + 'static,
|
||||
TS: (Fn(super::ApiParameterType) -> Result<In, String>) + Send + Sync,
|
||||
Gen: (Fn() -> SG) + Send + Sync,
|
||||
SG: (Fn(In) -> Out) + Send + Sync + 'static,
|
||||
TG: (Fn(Out) -> super::ApiParameterType) + Send + Sync> {
|
||||
TG: (Fn(Out) -> super::ApiParameterType) + Send + Sync,
|
||||
> {
|
||||
pub trans_setter: TS, // assumed to be pretty fast
|
||||
pub set_get: Gen, // probably has locks (i.e. slow)
|
||||
pub set_get: Gen, // probably has locks (i.e. slow)
|
||||
pub trans_getter: TG, // assumed to be pretty fast
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl <In: Send + 'static,
|
||||
Out: Send + 'static,
|
||||
TS: (Fn(super::ApiParameterType) -> Result<In, String>) + Send + Sync,
|
||||
Gen: (Fn() -> SG) + Send + Sync,
|
||||
SG: (Fn(In) -> Out) + Send + Sync + 'static,
|
||||
TG: (Fn(Out) -> super::ApiParameterType) + Send + Sync>
|
||||
AsyncCallable for AsyncIsh<In, Out, TS, Gen, SG, TG> {
|
||||
impl<
|
||||
In: Send + 'static,
|
||||
Out: Send + 'static,
|
||||
TS: (Fn(super::ApiParameterType) -> Result<In, String>) + Send + Sync,
|
||||
Gen: (Fn() -> SG) + Send + Sync,
|
||||
SG: (Fn(In) -> Out) + Send + Sync + 'static,
|
||||
TG: (Fn(Out) -> super::ApiParameterType) + Send + Sync,
|
||||
> AsyncCallable for AsyncIsh<In, Out, TS, Gen, SG, TG>
|
||||
{
|
||||
async fn call(&self, params: super::ApiParameterType) -> super::ApiParameterType {
|
||||
let t_to_set = match (self.trans_setter)(params) {
|
||||
Ok(t) => t,
|
||||
Err(e) => return vec![e.into()]
|
||||
Err(e) => return vec![e.into()],
|
||||
};
|
||||
let setter = (self.set_get)();
|
||||
let t_got = match tokio::task::spawn_blocking(move || setter(t_to_set)).await {
|
||||
|
@ -34,20 +38,24 @@ impl <In: Send + 'static,
|
|||
}
|
||||
}
|
||||
|
||||
pub struct AsyncIshGetter<T: Send + 'static,
|
||||
pub struct AsyncIshGetter<
|
||||
T: Send + 'static,
|
||||
Gen: (Fn() -> G) + Send + Sync,
|
||||
G: (Fn() -> T) + Send + Sync + 'static,
|
||||
TG: (Fn(T) -> super::ApiParameterType) + Send + Sync> {
|
||||
pub set_get: Gen, // probably has locks (i.e. slow)
|
||||
TG: (Fn(T) -> super::ApiParameterType) + Send + Sync,
|
||||
> {
|
||||
pub set_get: Gen, // probably has locks (i.e. slow)
|
||||
pub trans_getter: TG, // assumed to be pretty fast
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl <T: Send + 'static,
|
||||
Gen: (Fn() -> G) + Send + Sync,
|
||||
G: (Fn() -> T) + Send + Sync + 'static,
|
||||
TG: (Fn(T) -> super::ApiParameterType) + Send + Sync>
|
||||
AsyncCallable for AsyncIshGetter<T, Gen, G, TG> {
|
||||
impl<
|
||||
T: Send + 'static,
|
||||
Gen: (Fn() -> G) + Send + Sync,
|
||||
G: (Fn() -> T) + Send + Sync + 'static,
|
||||
TG: (Fn(T) -> super::ApiParameterType) + Send + Sync,
|
||||
> AsyncCallable for AsyncIshGetter<T, Gen, G, TG>
|
||||
{
|
||||
async fn call(&self, _params: super::ApiParameterType) -> super::ApiParameterType {
|
||||
let getter = (self.set_get)();
|
||||
let t_got = match tokio::task::spawn_blocking(move || getter()).await {
|
||||
|
@ -63,7 +71,9 @@ pub struct Blocking<F: (Fn(super::ApiParameterType) -> super::ApiParameterType)
|
|||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl <F: (Fn(super::ApiParameterType) -> super::ApiParameterType) + Send + Sync> AsyncCallable for Blocking<F> {
|
||||
impl<F: (Fn(super::ApiParameterType) -> super::ApiParameterType) + Send + Sync> AsyncCallable
|
||||
for Blocking<F>
|
||||
{
|
||||
async fn call(&self, params: super::ApiParameterType) -> super::ApiParameterType {
|
||||
(self.func)(params)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use std::sync::mpsc::{Sender, self};
|
||||
use std::sync::mpsc::{self, Sender};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use usdpl_back::core::serdes::Primitive;
|
||||
use usdpl_back::AsyncCallable;
|
||||
|
@ -6,24 +6,27 @@ use usdpl_back::AsyncCallable;
|
|||
use super::handler::{ApiMessage, BatteryMessage};
|
||||
|
||||
/// Current current (ha!) web method
|
||||
pub fn current_now(
|
||||
sender: Sender<ApiMessage>,
|
||||
) -> impl AsyncCallable {
|
||||
pub fn current_now(sender: Sender<ApiMessage>) -> impl AsyncCallable {
|
||||
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
||||
let getter = move || {
|
||||
let sender2 = sender.clone();
|
||||
move || {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
let callback = move |val: Option<f64>| tx.send(val).expect("current_now callback send failed");
|
||||
sender2.lock().unwrap().send(ApiMessage::Battery(BatteryMessage::ReadCurrentNow(Box::new(callback)))).expect("current_now send failed");
|
||||
let callback =
|
||||
move |val: Option<f64>| tx.send(val).expect("current_now callback send failed");
|
||||
sender2
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::Battery(BatteryMessage::ReadCurrentNow(
|
||||
Box::new(callback),
|
||||
)))
|
||||
.expect("current_now send failed");
|
||||
rx.recv().expect("current_now callback recv failed")
|
||||
}
|
||||
};
|
||||
super::async_utils::AsyncIshGetter {
|
||||
set_get: getter,
|
||||
trans_getter: |result| {
|
||||
super::utility::map_optional_result(Ok(result))
|
||||
}
|
||||
trans_getter: |result| super::utility::map_optional_result(Ok(result)),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,68 +36,77 @@ pub fn current_now(
|
|||
}*/
|
||||
|
||||
/// Charge now web method
|
||||
pub fn charge_now(
|
||||
sender: Sender<ApiMessage>,
|
||||
) -> impl AsyncCallable {
|
||||
pub fn charge_now(sender: Sender<ApiMessage>) -> impl AsyncCallable {
|
||||
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
||||
let getter = move || {
|
||||
let sender2 = sender.clone();
|
||||
move || {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
let callback = move |val: Option<f64>| tx.send(val).expect("charge_now callback send failed");
|
||||
sender2.lock().unwrap().send(ApiMessage::Battery(BatteryMessage::ReadChargeNow(Box::new(callback)))).expect("charge_now send failed");
|
||||
let callback =
|
||||
move |val: Option<f64>| tx.send(val).expect("charge_now callback send failed");
|
||||
sender2
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::Battery(BatteryMessage::ReadChargeNow(
|
||||
Box::new(callback),
|
||||
)))
|
||||
.expect("charge_now send failed");
|
||||
rx.recv().expect("charge_now callback recv failed")
|
||||
}
|
||||
};
|
||||
super::async_utils::AsyncIshGetter {
|
||||
set_get: getter,
|
||||
trans_getter: |result| {
|
||||
super::utility::map_optional_result(Ok(result))
|
||||
}
|
||||
trans_getter: |result| super::utility::map_optional_result(Ok(result)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Charge full web method
|
||||
pub fn charge_full(
|
||||
sender: Sender<ApiMessage>,
|
||||
) -> impl AsyncCallable {
|
||||
pub fn charge_full(sender: Sender<ApiMessage>) -> impl AsyncCallable {
|
||||
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
||||
let getter = move || {
|
||||
let sender2 = sender.clone();
|
||||
move || {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
let callback = move |val: Option<f64>| tx.send(val).expect("charge_full callback send failed");
|
||||
sender2.lock().unwrap().send(ApiMessage::Battery(BatteryMessage::ReadChargeFull(Box::new(callback)))).expect("charge_full send failed");
|
||||
let callback =
|
||||
move |val: Option<f64>| tx.send(val).expect("charge_full callback send failed");
|
||||
sender2
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::Battery(BatteryMessage::ReadChargeFull(
|
||||
Box::new(callback),
|
||||
)))
|
||||
.expect("charge_full send failed");
|
||||
rx.recv().expect("charge_full callback recv failed")
|
||||
}
|
||||
};
|
||||
super::async_utils::AsyncIshGetter {
|
||||
set_get: getter,
|
||||
trans_getter: |result| {
|
||||
super::utility::map_optional_result(Ok(result))
|
||||
}
|
||||
trans_getter: |result| super::utility::map_optional_result(Ok(result)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Charge design web method
|
||||
pub fn charge_design(
|
||||
sender: Sender<ApiMessage>,
|
||||
) -> impl AsyncCallable {
|
||||
pub fn charge_design(sender: Sender<ApiMessage>) -> impl AsyncCallable {
|
||||
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
||||
let getter = move || {
|
||||
let sender2 = sender.clone();
|
||||
move || {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
let callback = move |val: Option<f64>| tx.send(val).expect("charge_design callback send failed");
|
||||
sender2.lock().unwrap().send(ApiMessage::Battery(BatteryMessage::ReadChargeDesign(Box::new(callback)))).expect("charge_design send failed");
|
||||
let callback =
|
||||
move |val: Option<f64>| tx.send(val).expect("charge_design callback send failed");
|
||||
sender2
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::Battery(BatteryMessage::ReadChargeDesign(
|
||||
Box::new(callback),
|
||||
)))
|
||||
.expect("charge_design send failed");
|
||||
rx.recv().expect("charge_design callback recv failed")
|
||||
}
|
||||
};
|
||||
super::async_utils::AsyncIshGetter {
|
||||
set_get: getter,
|
||||
trans_getter: |result| {
|
||||
super::utility::map_optional_result(Ok(result))
|
||||
}
|
||||
trans_getter: |result| super::utility::map_optional_result(Ok(result)),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -103,11 +115,15 @@ pub fn set_charge_rate(
|
|||
sender: Sender<ApiMessage>,
|
||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||
let setter = move |rate: f64|
|
||||
sender.lock()
|
||||
let setter = move |rate: f64| {
|
||||
sender
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::Battery(BatteryMessage::SetChargeRate(Some(rate as u64))))
|
||||
.expect("set_charge_rate send failed");
|
||||
.send(ApiMessage::Battery(BatteryMessage::SetChargeRate(Some(
|
||||
rate as u64,
|
||||
))))
|
||||
.expect("set_charge_rate send failed")
|
||||
};
|
||||
move |params_in: super::ApiParameterType| {
|
||||
if let Some(&Primitive::F64(new_val)) = params_in.get(0) {
|
||||
setter(new_val);
|
||||
|
@ -125,13 +141,18 @@ pub fn get_charge_rate(
|
|||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||
let getter = move || {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
let callback = move |rate: Option<u64>| tx.send(rate).expect("get_charge_rate callback send failed");
|
||||
sender.lock().unwrap().send(ApiMessage::Battery(BatteryMessage::GetChargeRate(Box::new(callback)))).expect("get_charge_rate send failed");
|
||||
let callback =
|
||||
move |rate: Option<u64>| tx.send(rate).expect("get_charge_rate callback send failed");
|
||||
sender
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::Battery(BatteryMessage::GetChargeRate(
|
||||
Box::new(callback),
|
||||
)))
|
||||
.expect("get_charge_rate send failed");
|
||||
rx.recv().expect("get_charge_rate callback recv failed")
|
||||
};
|
||||
move |_: super::ApiParameterType| {
|
||||
vec![getter().map(|x| x.into()).unwrap_or(Primitive::Empty)]
|
||||
}
|
||||
move |_: super::ApiParameterType| vec![getter().map(|x| x.into()).unwrap_or(Primitive::Empty)]
|
||||
}
|
||||
|
||||
/// Generate unset battery charge rate web method
|
||||
|
@ -139,7 +160,13 @@ pub fn unset_charge_rate(
|
|||
sender: Sender<ApiMessage>,
|
||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||
let setter = move || sender.lock().unwrap().send(ApiMessage::Battery(BatteryMessage::SetChargeRate(None))).expect("unset_charge_rate send failed");
|
||||
let setter = move || {
|
||||
sender
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::Battery(BatteryMessage::SetChargeRate(None)))
|
||||
.expect("unset_charge_rate send failed")
|
||||
};
|
||||
move |_params_in: super::ApiParameterType| {
|
||||
setter();
|
||||
vec![true.into()]
|
||||
|
@ -151,11 +178,15 @@ pub fn set_charge_mode(
|
|||
sender: Sender<ApiMessage>,
|
||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||
let setter = move |mode: String|
|
||||
sender.lock()
|
||||
let setter = move |mode: String| {
|
||||
sender
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::Battery(BatteryMessage::SetChargeMode(Some(mode))))
|
||||
.expect("set_charge_mode send failed");
|
||||
.send(ApiMessage::Battery(BatteryMessage::SetChargeMode(Some(
|
||||
mode,
|
||||
))))
|
||||
.expect("set_charge_mode send failed")
|
||||
};
|
||||
move |params_in: super::ApiParameterType| {
|
||||
if let Some(Primitive::String(new_val)) = params_in.get(0) {
|
||||
setter(new_val.to_owned());
|
||||
|
@ -173,13 +204,19 @@ pub fn get_charge_mode(
|
|||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||
let getter = move || {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
let callback = move |mode: Option<String>| tx.send(mode).expect("get_charge_mode callback send failed");
|
||||
sender.lock().unwrap().send(ApiMessage::Battery(BatteryMessage::GetChargeMode(Box::new(callback)))).expect("get_charge_mode send failed");
|
||||
let callback = move |mode: Option<String>| {
|
||||
tx.send(mode).expect("get_charge_mode callback send failed")
|
||||
};
|
||||
sender
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::Battery(BatteryMessage::GetChargeMode(
|
||||
Box::new(callback),
|
||||
)))
|
||||
.expect("get_charge_mode send failed");
|
||||
rx.recv().expect("get_charge_mode callback recv failed")
|
||||
};
|
||||
move |_: super::ApiParameterType| {
|
||||
vec![getter().map(|x| x.into()).unwrap_or(Primitive::Empty)]
|
||||
}
|
||||
move |_: super::ApiParameterType| vec![getter().map(|x| x.into()).unwrap_or(Primitive::Empty)]
|
||||
}
|
||||
|
||||
/// Generate unset battery charge mode web method
|
||||
|
@ -187,7 +224,13 @@ pub fn unset_charge_mode(
|
|||
sender: Sender<ApiMessage>,
|
||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||
let setter = move || sender.lock().unwrap().send(ApiMessage::Battery(BatteryMessage::SetChargeMode(None))).expect("unset_charge_mode send failed");
|
||||
let setter = move || {
|
||||
sender
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::Battery(BatteryMessage::SetChargeMode(None)))
|
||||
.expect("unset_charge_mode send failed")
|
||||
};
|
||||
move |_params_in: super::ApiParameterType| {
|
||||
setter();
|
||||
vec![true.into()]
|
||||
|
@ -200,7 +243,11 @@ pub fn on_unplugged(
|
|||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||
move |_| {
|
||||
sender.lock().unwrap().send(ApiMessage::OnUnplugged).expect("on_unplugged send failed");
|
||||
sender
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::OnUnplugged)
|
||||
.expect("on_unplugged send failed");
|
||||
vec![true.into()]
|
||||
}
|
||||
}
|
||||
|
@ -211,7 +258,11 @@ pub fn on_plugged(
|
|||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||
move |_| {
|
||||
sender.lock().unwrap().send(ApiMessage::OnPluggedIn).expect("on_plugged send failed");
|
||||
sender
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::OnPluggedIn)
|
||||
.expect("on_plugged send failed");
|
||||
vec![true.into()]
|
||||
}
|
||||
}
|
||||
|
@ -221,11 +272,15 @@ pub fn set_charge_limit(
|
|||
sender: Sender<ApiMessage>,
|
||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||
let setter = move |limit: f64|
|
||||
sender.lock()
|
||||
let setter = move |limit: f64| {
|
||||
sender
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::Battery(BatteryMessage::SetChargeLimit(Some(limit))))
|
||||
.expect("set_charge_limit send failed");
|
||||
.send(ApiMessage::Battery(BatteryMessage::SetChargeLimit(Some(
|
||||
limit,
|
||||
))))
|
||||
.expect("set_charge_limit send failed")
|
||||
};
|
||||
move |params_in: super::ApiParameterType| {
|
||||
if let Some(&Primitive::F64(new_val)) = params_in.get(0) {
|
||||
setter(new_val);
|
||||
|
@ -241,11 +296,13 @@ pub fn unset_charge_limit(
|
|||
sender: Sender<ApiMessage>,
|
||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||
let unsetter = move ||
|
||||
sender.lock()
|
||||
let unsetter = move || {
|
||||
sender
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::Battery(BatteryMessage::SetChargeLimit(None)))
|
||||
.expect("unset_charge_limit send failed");
|
||||
.expect("unset_charge_limit send failed")
|
||||
};
|
||||
move |_: super::ApiParameterType| {
|
||||
unsetter();
|
||||
vec![true.into()]
|
||||
|
@ -253,23 +310,27 @@ pub fn unset_charge_limit(
|
|||
}
|
||||
|
||||
/// Charge design web method
|
||||
pub fn get_charge_limit(
|
||||
sender: Sender<ApiMessage>,
|
||||
) -> impl AsyncCallable {
|
||||
pub fn get_charge_limit(sender: Sender<ApiMessage>) -> impl AsyncCallable {
|
||||
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
||||
let getter = move || {
|
||||
let sender2 = sender.clone();
|
||||
move || {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
let callback = move |val: Option<f64>| tx.send(val).expect("get_charge_limit callback send failed");
|
||||
sender2.lock().unwrap().send(ApiMessage::Battery(BatteryMessage::GetChargeLimit(Box::new(callback)))).expect("get_charge_limit send failed");
|
||||
let callback = move |val: Option<f64>| {
|
||||
tx.send(val).expect("get_charge_limit callback send failed")
|
||||
};
|
||||
sender2
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::Battery(BatteryMessage::GetChargeLimit(
|
||||
Box::new(callback),
|
||||
)))
|
||||
.expect("get_charge_limit send failed");
|
||||
rx.recv().expect("get_charge_limit callback recv failed")
|
||||
}
|
||||
};
|
||||
super::async_utils::AsyncIshGetter {
|
||||
set_get: getter,
|
||||
trans_getter: |result| {
|
||||
super::utility::map_optional_result(Ok(result))
|
||||
}
|
||||
trans_getter: |result| super::utility::map_optional_result(Ok(result)),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use std::sync::mpsc::{Sender, self};
|
||||
use std::sync::mpsc::{self, Sender};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use usdpl_back::core::serdes::Primitive;
|
||||
use usdpl_back::AsyncCallable;
|
||||
|
||||
use crate::settings::{SettingError, SettingVariant, MinMax};
|
||||
use crate::settings::{MinMax, SettingError, SettingVariant};
|
||||
//use crate::utility::{unwrap_lock, unwrap_maybe_fatal};
|
||||
use super::handler::{ApiMessage, CpuMessage};
|
||||
|
||||
|
@ -12,13 +12,11 @@ pub fn max_cpus(_: super::ApiParameterType) -> super::ApiParameterType {
|
|||
super::utility::map_result(
|
||||
crate::settings::steam_deck::Cpus::cpu_count()
|
||||
.map(|x| x as u64)
|
||||
.ok_or_else(
|
||||
|| SettingError {
|
||||
msg: "Failed to parse CPU count".to_owned(),
|
||||
setting: SettingVariant::Cpu,
|
||||
}
|
||||
)
|
||||
)
|
||||
.ok_or_else(|| SettingError {
|
||||
msg: "Failed to parse CPU count".to_owned(),
|
||||
setting: SettingVariant::Cpu,
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
/// Generate set CPU online web method
|
||||
|
@ -26,10 +24,13 @@ pub fn set_cpu_online(
|
|||
sender: Sender<ApiMessage>,
|
||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||
let setter = move |index: usize, value: bool|
|
||||
sender.lock()
|
||||
let setter = move |index: usize, value: bool| {
|
||||
sender
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::Cpu(CpuMessage::SetCpuOnline(index, value))).expect("set_cpu_online send failed");
|
||||
.send(ApiMessage::Cpu(CpuMessage::SetCpuOnline(index, value)))
|
||||
.expect("set_cpu_online send failed")
|
||||
};
|
||||
move |params_in: super::ApiParameterType| {
|
||||
if let Some(&Primitive::F64(index)) = params_in.get(0) {
|
||||
//let mut settings_lock = unwrap_lock(settings.lock(), "cpu");
|
||||
|
@ -49,10 +50,13 @@ pub fn set_cpus_online(
|
|||
sender: Sender<ApiMessage>,
|
||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||
let setter = move |values: Vec<bool>|
|
||||
sender.lock()
|
||||
let setter = move |values: Vec<bool>| {
|
||||
sender
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::Cpu(CpuMessage::SetCpusOnline(values))).expect("set_cpus_online send failed");
|
||||
.send(ApiMessage::Cpu(CpuMessage::SetCpusOnline(values)))
|
||||
.expect("set_cpus_online send failed")
|
||||
};
|
||||
move |params_in: super::ApiParameterType| {
|
||||
let mut result = Vec::with_capacity(params_in.len());
|
||||
let mut values = Vec::with_capacity(params_in.len());
|
||||
|
@ -90,16 +94,19 @@ pub fn set_cpus_online(
|
|||
}
|
||||
}*/
|
||||
|
||||
pub fn set_smt(
|
||||
sender: Sender<ApiMessage>,
|
||||
) -> impl AsyncCallable {
|
||||
pub fn set_smt(sender: Sender<ApiMessage>) -> impl AsyncCallable {
|
||||
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
||||
let getter = move || {
|
||||
let sender2 = sender.clone();
|
||||
move |smt: bool| {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
let callback = move |values: Vec<bool>| tx.send(values).expect("set_smt callback send failed");
|
||||
sender2.lock().unwrap().send(ApiMessage::Cpu(CpuMessage::SetSmt(smt, Box::new(callback)))).expect("set_smt send failed");
|
||||
let callback =
|
||||
move |values: Vec<bool>| tx.send(values).expect("set_smt callback send failed");
|
||||
sender2
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::Cpu(CpuMessage::SetSmt(smt, Box::new(callback))))
|
||||
.expect("set_smt send failed");
|
||||
rx.recv().expect("set_smt callback recv failed")
|
||||
}
|
||||
};
|
||||
|
@ -118,41 +125,48 @@ pub fn set_smt(
|
|||
output.push(status.into());
|
||||
}
|
||||
output
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_smt(
|
||||
sender: Sender<ApiMessage>,
|
||||
) -> impl AsyncCallable {
|
||||
pub fn get_smt(sender: Sender<ApiMessage>) -> impl AsyncCallable {
|
||||
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
||||
let getter = move || {
|
||||
let sender2 = sender.clone();
|
||||
move || {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
let callback = move |value: bool| tx.send(value).expect("get_smt callback send failed");
|
||||
sender2.lock().unwrap().send(ApiMessage::Cpu(CpuMessage::GetSmt(Box::new(callback)))).expect("get_smt send failed");
|
||||
sender2
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::Cpu(CpuMessage::GetSmt(Box::new(callback))))
|
||||
.expect("get_smt send failed");
|
||||
rx.recv().expect("get_smt callback recv failed")
|
||||
}
|
||||
};
|
||||
super::async_utils::AsyncIshGetter {
|
||||
set_get: getter,
|
||||
trans_getter: |result| {
|
||||
vec![result.into()]
|
||||
}
|
||||
trans_getter: |result| vec![result.into()],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_cpus_online(
|
||||
sender: Sender<ApiMessage>,
|
||||
) -> impl AsyncCallable {
|
||||
pub fn get_cpus_online(sender: Sender<ApiMessage>) -> impl AsyncCallable {
|
||||
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
||||
let getter = move || {
|
||||
let sender2 = sender.clone();
|
||||
move || {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
let callback = move |values: Vec<bool>| tx.send(values).expect("get_cpus_online callback send failed");
|
||||
sender2.lock().unwrap().send(ApiMessage::Cpu(CpuMessage::GetCpusOnline(Box::new(callback)))).expect("get_cpus_online send failed");
|
||||
let callback = move |values: Vec<bool>| {
|
||||
tx.send(values)
|
||||
.expect("get_cpus_online callback send failed")
|
||||
};
|
||||
sender2
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::Cpu(CpuMessage::GetCpusOnline(Box::new(
|
||||
callback,
|
||||
))))
|
||||
.expect("get_cpus_online send failed");
|
||||
rx.recv().expect("get_cpus_online callback recv failed")
|
||||
}
|
||||
};
|
||||
|
@ -164,7 +178,7 @@ pub fn get_cpus_online(
|
|||
output.push(status.into());
|
||||
}
|
||||
output
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -172,25 +186,29 @@ pub fn set_clock_limits(
|
|||
sender: Sender<ApiMessage>,
|
||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||
let setter = move |index: usize, value: MinMax<u64>|
|
||||
sender.lock()
|
||||
let setter = move |index: usize, value: MinMax<u64>| {
|
||||
sender
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::Cpu(CpuMessage::SetClockLimits(index, Some(value)))).expect("set_clock_limits send failed");
|
||||
.send(ApiMessage::Cpu(CpuMessage::SetClockLimits(
|
||||
index,
|
||||
Some(value),
|
||||
)))
|
||||
.expect("set_clock_limits send failed")
|
||||
};
|
||||
move |params_in: super::ApiParameterType| {
|
||||
if let Some(&Primitive::F64(index)) = params_in.get(0) {
|
||||
if let Some(&Primitive::F64(min)) = params_in.get(1) {
|
||||
if let Some(&Primitive::F64(max)) = params_in.get(2) {
|
||||
let safe_max = if max < min {
|
||||
min
|
||||
} else {
|
||||
max
|
||||
};
|
||||
let safe_min = if min > max {
|
||||
max
|
||||
} else {
|
||||
min
|
||||
};
|
||||
setter(index as usize, MinMax {min: safe_min as u64, max: safe_max as u64});
|
||||
let safe_max = if max < min { min } else { max };
|
||||
let safe_min = if min > max { max } else { min };
|
||||
setter(
|
||||
index as usize,
|
||||
MinMax {
|
||||
min: safe_min as u64,
|
||||
max: safe_max as u64,
|
||||
},
|
||||
);
|
||||
vec![safe_min.into(), safe_max.into()]
|
||||
} else {
|
||||
vec!["set_clock_limits missing parameter 2".into()]
|
||||
|
@ -210,8 +228,18 @@ pub fn get_clock_limits(
|
|||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||
let getter = move |index: usize| {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
let callback = move |values: Option<MinMax<u64>>| tx.send(values).expect("get_clock_limits callback send failed");
|
||||
sender.lock().unwrap().send(ApiMessage::Cpu(CpuMessage::GetClockLimits(index, Box::new(callback)))).expect("get_clock_limits send failed");
|
||||
let callback = move |values: Option<MinMax<u64>>| {
|
||||
tx.send(values)
|
||||
.expect("get_clock_limits callback send failed")
|
||||
};
|
||||
sender
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::Cpu(CpuMessage::GetClockLimits(
|
||||
index,
|
||||
Box::new(callback),
|
||||
)))
|
||||
.expect("get_clock_limits send failed");
|
||||
rx.recv().expect("get_clock_limits callback recv failed")
|
||||
};
|
||||
move |params_in: super::ApiParameterType| {
|
||||
|
@ -231,10 +259,13 @@ pub fn unset_clock_limits(
|
|||
sender: Sender<ApiMessage>,
|
||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||
let setter = move |index: usize|
|
||||
sender.lock()
|
||||
let setter = move |index: usize| {
|
||||
sender
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::Cpu(CpuMessage::SetClockLimits(index, None))).expect("unset_clock_limits send failed");
|
||||
.send(ApiMessage::Cpu(CpuMessage::SetClockLimits(index, None)))
|
||||
.expect("unset_clock_limits send failed")
|
||||
};
|
||||
move |params_in: super::ApiParameterType| {
|
||||
if let Some(&Primitive::F64(index)) = params_in.get(0) {
|
||||
setter(index as usize);
|
||||
|
@ -249,10 +280,13 @@ pub fn set_cpu_governor(
|
|||
sender: Sender<ApiMessage>,
|
||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||
let setter = move |index: usize, governor: String|
|
||||
sender.lock()
|
||||
let setter = move |index: usize, governor: String| {
|
||||
sender
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::Cpu(CpuMessage::SetCpuGovernor(index, governor))).expect("set_cpu_governor send failed");
|
||||
.send(ApiMessage::Cpu(CpuMessage::SetCpuGovernor(index, governor)))
|
||||
.expect("set_cpu_governor send failed")
|
||||
};
|
||||
move |params_in: super::ApiParameterType| {
|
||||
if let Some(&Primitive::F64(index)) = params_in.get(0) {
|
||||
if let Some(Primitive::String(governor)) = params_in.get(1) {
|
||||
|
@ -271,10 +305,13 @@ pub fn set_cpus_governors(
|
|||
sender: Sender<ApiMessage>,
|
||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||
let setter = move |governors: Vec<String>|
|
||||
sender.lock()
|
||||
let setter = move |governors: Vec<String>| {
|
||||
sender
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::Cpu(CpuMessage::SetCpusGovernor(governors))).expect("set_cpus_governor send failed");
|
||||
.send(ApiMessage::Cpu(CpuMessage::SetCpusGovernor(governors)))
|
||||
.expect("set_cpus_governor send failed")
|
||||
};
|
||||
move |params_in: super::ApiParameterType| {
|
||||
let mut result = Vec::with_capacity(params_in.len());
|
||||
let mut values = Vec::with_capacity(params_in.len());
|
||||
|
@ -298,8 +335,17 @@ pub fn get_cpu_governors(
|
|||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||
let getter = move || {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
let callback = move |values: Vec<String>| tx.send(values).expect("get_cpu_governors callback send failed");
|
||||
sender.lock().unwrap().send(ApiMessage::Cpu(CpuMessage::GetCpusGovernor(Box::new(callback)))).expect("get_cpu_governors send failed");
|
||||
let callback = move |values: Vec<String>| {
|
||||
tx.send(values)
|
||||
.expect("get_cpu_governors callback send failed")
|
||||
};
|
||||
sender
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::Cpu(CpuMessage::GetCpusGovernor(Box::new(
|
||||
callback,
|
||||
))))
|
||||
.expect("get_cpu_governors send failed");
|
||||
rx.recv().expect("get_cpu_governors callback recv failed")
|
||||
};
|
||||
move |_: super::ApiParameterType| {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use std::sync::mpsc::{Sender, self};
|
||||
use std::sync::mpsc::{self, Sender};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use usdpl_back::core::serdes::Primitive;
|
||||
use usdpl_back::AsyncCallable;
|
||||
|
@ -11,10 +11,13 @@ pub fn set_persistent(
|
|||
sender: Sender<ApiMessage>,
|
||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||
let setter = move |pers: bool|
|
||||
sender.lock()
|
||||
let setter = move |pers: bool| {
|
||||
sender
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::General(GeneralMessage::SetPersistent(pers))).expect("set_persistent send failed");
|
||||
.send(ApiMessage::General(GeneralMessage::SetPersistent(pers)))
|
||||
.expect("set_persistent send failed")
|
||||
};
|
||||
move |params_in: super::ApiParameterType| {
|
||||
if let Some(&Primitive::Bool(new_val)) = params_in.get(0) {
|
||||
setter(new_val);
|
||||
|
@ -33,13 +36,18 @@ pub fn get_persistent(
|
|||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||
let getter = move || {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
let callback = move |value: bool| tx.send(value).expect("get_persistent callback send failed");
|
||||
sender.lock().unwrap().send(ApiMessage::General(GeneralMessage::GetPersistent(Box::new(callback)))).expect("get_persistent send failed");
|
||||
let callback =
|
||||
move |value: bool| tx.send(value).expect("get_persistent callback send failed");
|
||||
sender
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::General(GeneralMessage::GetPersistent(
|
||||
Box::new(callback),
|
||||
)))
|
||||
.expect("get_persistent send failed");
|
||||
rx.recv().expect("get_persistent callback recv failed")
|
||||
};
|
||||
move |_: super::ApiParameterType| {
|
||||
vec![getter().into()]
|
||||
}
|
||||
move |_: super::ApiParameterType| vec![getter().into()]
|
||||
}
|
||||
|
||||
/// Generate load app settings from file web method
|
||||
|
@ -47,10 +55,13 @@ pub fn load_settings(
|
|||
sender: Sender<ApiMessage>,
|
||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||
let setter = move |path: i64, name: String|
|
||||
sender.lock()
|
||||
let setter = move |path: i64, name: String| {
|
||||
sender
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::LoadSettings(path, name)).expect("load_settings send failed");
|
||||
.send(ApiMessage::LoadSettings(path, name))
|
||||
.expect("load_settings send failed")
|
||||
};
|
||||
move |params_in: super::ApiParameterType| {
|
||||
if let Some(Primitive::F64(id)) = params_in.get(0) {
|
||||
if let Some(Primitive::String(name)) = params_in.get(1) {
|
||||
|
@ -73,10 +84,13 @@ pub fn load_default_settings(
|
|||
sender: Sender<ApiMessage>,
|
||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||
let setter = move ||
|
||||
sender.lock()
|
||||
let setter = move || {
|
||||
sender
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::LoadMainSettings).expect("load_default_settings send failed");
|
||||
.send(ApiMessage::LoadMainSettings)
|
||||
.expect("load_default_settings send failed")
|
||||
};
|
||||
move |_: super::ApiParameterType| {
|
||||
setter();
|
||||
vec![true.into()]
|
||||
|
@ -99,10 +113,13 @@ pub fn load_system_settings(
|
|||
sender: Sender<ApiMessage>,
|
||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||
let setter = move ||
|
||||
sender.lock()
|
||||
let setter = move || {
|
||||
sender
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::LoadSystemSettings).expect("load_default_settings send failed");
|
||||
.send(ApiMessage::LoadSystemSettings)
|
||||
.expect("load_default_settings send failed")
|
||||
};
|
||||
move |_: super::ApiParameterType| {
|
||||
setter();
|
||||
vec![true.into()]
|
||||
|
@ -121,68 +138,75 @@ pub fn load_system_settings(
|
|||
}
|
||||
|
||||
/// Generate get current settings name
|
||||
pub fn get_name(
|
||||
sender: Sender<ApiMessage>,
|
||||
) -> impl AsyncCallable {
|
||||
pub fn get_name(sender: Sender<ApiMessage>) -> impl AsyncCallable {
|
||||
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
||||
let getter = move || {
|
||||
let sender2 = sender.clone();
|
||||
move || {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
let callback = move |name: String| tx.send(name).expect("get_name callback send failed");
|
||||
sender2.lock().unwrap().send(ApiMessage::General(GeneralMessage::GetCurrentProfileName(Box::new(callback)))).expect("get_name send failed");
|
||||
let callback =
|
||||
move |name: String| tx.send(name).expect("get_name callback send failed");
|
||||
sender2
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::General(GeneralMessage::GetCurrentProfileName(
|
||||
Box::new(callback),
|
||||
)))
|
||||
.expect("get_name send failed");
|
||||
rx.recv().expect("get_name callback recv failed")
|
||||
}
|
||||
};
|
||||
super::async_utils::AsyncIshGetter {
|
||||
set_get: getter,
|
||||
trans_getter: |result| {
|
||||
vec![result.into()]
|
||||
}
|
||||
trans_getter: |result| vec![result.into()],
|
||||
}
|
||||
}
|
||||
|
||||
/// Generate get current settings name
|
||||
pub fn get_path(
|
||||
sender: Sender<ApiMessage>,
|
||||
) -> impl AsyncCallable {
|
||||
pub fn get_path(sender: Sender<ApiMessage>) -> impl AsyncCallable {
|
||||
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
||||
let getter = move || {
|
||||
let sender2 = sender.clone();
|
||||
move || {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
let callback = move |name: std::path::PathBuf| tx.send(name).expect("get_path callback send failed");
|
||||
sender2.lock().unwrap().send(ApiMessage::General(GeneralMessage::GetPath(Box::new(callback)))).expect("get_name send failed");
|
||||
let callback = move |name: std::path::PathBuf| {
|
||||
tx.send(name).expect("get_path callback send failed")
|
||||
};
|
||||
sender2
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::General(GeneralMessage::GetPath(Box::new(
|
||||
callback,
|
||||
))))
|
||||
.expect("get_name send failed");
|
||||
rx.recv().expect("get_path callback recv failed")
|
||||
}
|
||||
};
|
||||
super::async_utils::AsyncIshGetter {
|
||||
set_get: getter,
|
||||
trans_getter: |result| {
|
||||
vec![result.to_string_lossy().to_string().into()]
|
||||
}
|
||||
trans_getter: |result| vec![result.to_string_lossy().to_string().into()],
|
||||
}
|
||||
}
|
||||
|
||||
/// Generate wait for all locks to be available web method
|
||||
pub fn lock_unlock_all(
|
||||
sender: Sender<ApiMessage>,
|
||||
) -> impl AsyncCallable {
|
||||
pub fn lock_unlock_all(sender: Sender<ApiMessage>) -> impl AsyncCallable {
|
||||
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
||||
let getter = move || {
|
||||
let sender2 = sender.clone();
|
||||
move || {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
let callback = move |x| tx.send(x).expect("lock_unlock_all callback send failed");
|
||||
sender2.lock().unwrap().send(ApiMessage::WaitForEmptyQueue(Box::new(callback))).expect("lock_unlock_all send failed");
|
||||
sender2
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::WaitForEmptyQueue(Box::new(callback)))
|
||||
.expect("lock_unlock_all send failed");
|
||||
rx.recv().expect("lock_unlock_all callback recv failed")
|
||||
}
|
||||
};
|
||||
super::async_utils::AsyncIshGetter {
|
||||
set_get: getter,
|
||||
trans_getter: |_| {
|
||||
vec![true.into()]
|
||||
}
|
||||
trans_getter: |_| vec![true.into()],
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -193,8 +217,14 @@ pub fn get_limits(
|
|||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||
let getter = move || {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
let callback = move |value: super::SettingsLimits| tx.send(value).expect("get_limits callback send failed");
|
||||
sender.lock().unwrap().send(ApiMessage::GetLimits(Box::new(callback))).expect("get_limits send failed");
|
||||
let callback = move |value: super::SettingsLimits| {
|
||||
tx.send(value).expect("get_limits callback send failed")
|
||||
};
|
||||
sender
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::GetLimits(Box::new(callback)))
|
||||
.expect("get_limits send failed");
|
||||
rx.recv().expect("get_limits callback recv failed")
|
||||
};
|
||||
move |_: super::ApiParameterType| {
|
||||
|
@ -203,16 +233,20 @@ pub fn get_limits(
|
|||
}
|
||||
|
||||
/// Generate get current driver name
|
||||
pub fn get_provider(
|
||||
sender: Sender<ApiMessage>,
|
||||
) -> impl AsyncCallable {
|
||||
pub fn get_provider(sender: Sender<ApiMessage>) -> impl AsyncCallable {
|
||||
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
||||
let getter = move || {
|
||||
let sender2 = sender.clone();
|
||||
move |provider_name: String| {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
let callback = move |name: crate::persist::DriverJson| tx.send(name).expect("get_provider callback send failed");
|
||||
sender2.lock().unwrap().send(ApiMessage::GetProvider(provider_name, Box::new(callback))).expect("get_provider send failed");
|
||||
let callback = move |name: crate::persist::DriverJson| {
|
||||
tx.send(name).expect("get_provider callback send failed")
|
||||
};
|
||||
sender2
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::GetProvider(provider_name, Box::new(callback)))
|
||||
.expect("get_provider send failed");
|
||||
rx.recv().expect("get_provider callback recv failed")
|
||||
}
|
||||
};
|
||||
|
@ -225,9 +259,7 @@ pub fn get_provider(
|
|||
}
|
||||
},
|
||||
set_get: getter,
|
||||
trans_getter: |result| {
|
||||
vec![format!("{:?}", result).into()]
|
||||
}
|
||||
trans_getter: |result| vec![format!("{:?}", result).into()],
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -277,14 +309,15 @@ pub fn force_apply(
|
|||
sender: Sender<ApiMessage>,
|
||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||
let setter = move |_: ()|
|
||||
sender.lock()
|
||||
let setter = move |_: ()| {
|
||||
sender
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::General(GeneralMessage::ApplyNow))
|
||||
.expect("force_apply send failed");
|
||||
.expect("force_apply send failed")
|
||||
};
|
||||
move |_params_in: super::ApiParameterType| {
|
||||
setter(());
|
||||
vec![true.into()]
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use std::sync::mpsc::{Sender, self};
|
||||
use std::sync::{Mutex, Arc};
|
||||
use std::sync::mpsc::{self, Sender};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use usdpl_back::core::serdes::Primitive;
|
||||
use usdpl_back::AsyncCallable;
|
||||
|
||||
|
@ -11,10 +11,13 @@ pub fn set_ppt(
|
|||
sender: Sender<ApiMessage>,
|
||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||
let setter = move |fast: u64, slow: u64|
|
||||
sender.lock()
|
||||
let setter = move |fast: u64, slow: u64| {
|
||||
sender
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::Gpu(GpuMessage::SetPpt(Some(fast), Some(slow)))).expect("set_ppt send failed");
|
||||
.send(ApiMessage::Gpu(GpuMessage::SetPpt(Some(fast), Some(slow))))
|
||||
.expect("set_ppt send failed")
|
||||
};
|
||||
move |params_in: super::ApiParameterType| {
|
||||
if let Some(&Primitive::F64(fast_ppt)) = params_in.get(0) {
|
||||
if let Some(&Primitive::F64(slow_ppt)) = params_in.get(1) {
|
||||
|
@ -29,16 +32,20 @@ pub fn set_ppt(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_ppt(
|
||||
sender: Sender<ApiMessage>,
|
||||
) -> impl AsyncCallable {
|
||||
pub fn get_ppt(sender: Sender<ApiMessage>) -> impl AsyncCallable {
|
||||
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
||||
let getter = move || {
|
||||
let sender2 = sender.clone();
|
||||
move || {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
let callback = move |ppt: (Option<u64>, Option<u64>)| tx.send(ppt).expect("get_ppt callback send failed");
|
||||
sender2.lock().unwrap().send(ApiMessage::Gpu(GpuMessage::GetPpt(Box::new(callback)))).expect("get_ppt send failed");
|
||||
let callback = move |ppt: (Option<u64>, Option<u64>)| {
|
||||
tx.send(ppt).expect("get_ppt callback send failed")
|
||||
};
|
||||
sender2
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::Gpu(GpuMessage::GetPpt(Box::new(callback))))
|
||||
.expect("get_ppt send failed");
|
||||
rx.recv().expect("get_ppt callback recv failed")
|
||||
}
|
||||
};
|
||||
|
@ -49,7 +56,7 @@ pub fn get_ppt(
|
|||
fast.map(|x| x.into()).unwrap_or(Primitive::Empty),
|
||||
slow.map(|x| x.into()).unwrap_or(Primitive::Empty),
|
||||
]
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,10 +64,13 @@ pub fn unset_ppt(
|
|||
sender: Sender<ApiMessage>,
|
||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||
let setter = move ||
|
||||
sender.lock()
|
||||
let setter = move || {
|
||||
sender
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::Gpu(GpuMessage::SetPpt(None, None))).expect("set_ppt send failed");
|
||||
.send(ApiMessage::Gpu(GpuMessage::SetPpt(None, None)))
|
||||
.expect("set_ppt send failed")
|
||||
};
|
||||
move |_: super::ApiParameterType| {
|
||||
setter();
|
||||
vec![true.into()]
|
||||
|
@ -71,23 +81,18 @@ pub fn set_clock_limits(
|
|||
sender: Sender<ApiMessage>,
|
||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||
let setter = move |value: MinMax<u64>|
|
||||
sender.lock()
|
||||
let setter = move |value: MinMax<u64>| {
|
||||
sender
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::Gpu(GpuMessage::SetClockLimits(Some(value)))).expect("set_clock_limits send failed");
|
||||
.send(ApiMessage::Gpu(GpuMessage::SetClockLimits(Some(value))))
|
||||
.expect("set_clock_limits send failed")
|
||||
};
|
||||
move |params_in: super::ApiParameterType| {
|
||||
if let Some(&Primitive::F64(min)) = params_in.get(0) {
|
||||
if let Some(&Primitive::F64(max)) = params_in.get(1) {
|
||||
let safe_max = if max < min {
|
||||
min
|
||||
} else {
|
||||
max
|
||||
};
|
||||
let safe_min = if min > max {
|
||||
max
|
||||
} else {
|
||||
min
|
||||
};
|
||||
let safe_max = if max < min { min } else { max };
|
||||
let safe_min = if min > max { max } else { min };
|
||||
setter(MinMax {
|
||||
min: safe_min as _,
|
||||
max: safe_max as _,
|
||||
|
@ -102,26 +107,33 @@ pub fn set_clock_limits(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_clock_limits(
|
||||
sender: Sender<ApiMessage>,
|
||||
) -> impl AsyncCallable {
|
||||
pub fn get_clock_limits(sender: Sender<ApiMessage>) -> impl AsyncCallable {
|
||||
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
||||
let getter = move|| {
|
||||
let getter = move || {
|
||||
let sender2 = sender.clone();
|
||||
move || {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
let callback = move |clocks: Option<MinMax<u64>>| tx.send(clocks).expect("get_clock_limits callback send failed");
|
||||
sender2.lock().unwrap().send(ApiMessage::Gpu(GpuMessage::GetClockLimits(Box::new(callback)))).expect("get_clock_limits send failed");
|
||||
let callback = move |clocks: Option<MinMax<u64>>| {
|
||||
tx.send(clocks)
|
||||
.expect("get_clock_limits callback send failed")
|
||||
};
|
||||
sender2
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::Gpu(GpuMessage::GetClockLimits(Box::new(
|
||||
callback,
|
||||
))))
|
||||
.expect("get_clock_limits send failed");
|
||||
rx.recv().expect("get_clock_limits callback recv failed")
|
||||
}
|
||||
};
|
||||
super::async_utils::AsyncIshGetter {
|
||||
set_get: getter,
|
||||
trans_getter: |clocks: Option<MinMax<u64>>| {
|
||||
clocks.map(|x| vec![
|
||||
x.min.into(), x.max.into()
|
||||
]).unwrap_or_else(|| vec![Primitive::Empty, Primitive::Empty])
|
||||
}
|
||||
clocks
|
||||
.map(|x| vec![x.min.into(), x.max.into()])
|
||||
.unwrap_or_else(|| vec![Primitive::Empty, Primitive::Empty])
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -129,10 +141,13 @@ pub fn unset_clock_limits(
|
|||
sender: Sender<ApiMessage>,
|
||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||
let setter = move ||
|
||||
sender.lock()
|
||||
let setter = move || {
|
||||
sender
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::Gpu(GpuMessage::SetClockLimits(None))).expect("unset_clock_limits send failed");
|
||||
.send(ApiMessage::Gpu(GpuMessage::SetClockLimits(None)))
|
||||
.expect("unset_clock_limits send failed")
|
||||
};
|
||||
move |_: super::ApiParameterType| {
|
||||
setter();
|
||||
vec![true.into()]
|
||||
|
@ -143,10 +158,13 @@ pub fn set_slow_memory(
|
|||
sender: Sender<ApiMessage>,
|
||||
) -> impl Fn(super::ApiParameterType) -> super::ApiParameterType {
|
||||
let sender = Mutex::new(sender); // Sender is not Sync; this is required for safety
|
||||
let setter = move |value: bool|
|
||||
sender.lock()
|
||||
let setter = move |value: bool| {
|
||||
sender
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::Gpu(GpuMessage::SetSlowMemory(value))).expect("unset_clock_limits send failed");
|
||||
.send(ApiMessage::Gpu(GpuMessage::SetSlowMemory(value)))
|
||||
.expect("unset_clock_limits send failed")
|
||||
};
|
||||
move |params_in: super::ApiParameterType| {
|
||||
if let Some(&Primitive::Bool(memory_is_slow)) = params_in.get(0) {
|
||||
setter(memory_is_slow);
|
||||
|
@ -157,23 +175,28 @@ pub fn set_slow_memory(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_slow_memory(
|
||||
sender: Sender<ApiMessage>,
|
||||
) -> impl AsyncCallable {
|
||||
pub fn get_slow_memory(sender: Sender<ApiMessage>) -> impl AsyncCallable {
|
||||
let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety
|
||||
let getter = move || {
|
||||
let sender2 = sender.clone();
|
||||
move || {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
let callback = move |value: bool| tx.send(value).expect("get_slow_memory callback send failed");
|
||||
sender2.lock().unwrap().send(ApiMessage::Gpu(GpuMessage::GetSlowMemory(Box::new(callback)))).expect("get_slow_memory send failed");
|
||||
let callback = move |value: bool| {
|
||||
tx.send(value)
|
||||
.expect("get_slow_memory callback send failed")
|
||||
};
|
||||
sender2
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(ApiMessage::Gpu(GpuMessage::GetSlowMemory(Box::new(
|
||||
callback,
|
||||
))))
|
||||
.expect("get_slow_memory send failed");
|
||||
rx.recv().expect("get_slow_memory callback recv failed")
|
||||
}
|
||||
};
|
||||
super::async_utils::AsyncIshGetter {
|
||||
set_get: getter,
|
||||
trans_getter: |value: bool| {
|
||||
vec![value.into()]
|
||||
}
|
||||
trans_getter: |value: bool| vec![value.into()],
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
use std::sync::mpsc::{self, Receiver, Sender};
|
||||
use std::fmt::Write;
|
||||
use std::sync::mpsc::{self, Receiver, Sender};
|
||||
|
||||
use crate::settings::{Settings, TCpus, TGpu, TBattery, TGeneral, OnSet, OnResume, MinMax, OnPowerEvent, PowerMode};
|
||||
use crate::persist::SettingsJson;
|
||||
use crate::settings::{
|
||||
MinMax, OnPowerEvent, OnResume, OnSet, PowerMode, Settings, TBattery, TCpus, TGeneral, TGpu,
|
||||
};
|
||||
use crate::utility::unwrap_maybe_fatal;
|
||||
|
||||
type Callback<T> = Box<dyn FnOnce(T) + Send>;
|
||||
|
@ -84,12 +86,14 @@ impl CpuMessage {
|
|||
// NOTE: "cpu" refers to the Linux kernel definition of a CPU, which is actually a hardware thread
|
||||
// not to be confused with a CPU chip, which usually has multiple hardware threads (cpu cores/threads) in the chip
|
||||
match self {
|
||||
Self::SetCpuOnline(index, status) => {settings.cpus().get_mut(index).map(|c| *c.online() = status);},
|
||||
Self::SetCpuOnline(index, status) => {
|
||||
settings.cpus().get_mut(index).map(|c| *c.online() = status);
|
||||
}
|
||||
Self::SetCpusOnline(cpus) => {
|
||||
for i in 0..cpus.len() {
|
||||
settings.cpus().get_mut(i).map(|c| *c.online() = cpus[i]);
|
||||
}
|
||||
},
|
||||
}
|
||||
Self::SetSmt(status, cb) => {
|
||||
if *settings.smt() == status {
|
||||
// already set, do nothing
|
||||
|
@ -105,8 +109,8 @@ impl CpuMessage {
|
|||
// for 1c:2t configs (i.e. anything with SMT2), the highest cpu core is always odd
|
||||
// (e.g. 4c8t has CPUs 0-7, inclusive)
|
||||
// this enables the """fake""" (i.e. odd) cpu which is disabled when SMT is set off
|
||||
if i % 2 == 0 && i+1 != cpu_count {
|
||||
*(settings.cpus()[i+1].online()) = true;
|
||||
if i % 2 == 0 && i + 1 != cpu_count {
|
||||
*(settings.cpus()[i + 1].online()) = true;
|
||||
}
|
||||
} else {
|
||||
*settings.cpus()[i].online() = should_be_online;
|
||||
|
@ -118,7 +122,8 @@ impl CpuMessage {
|
|||
for i in 0..settings.len() {
|
||||
// this disables the """fake""" (odd) cpu for appearances' sake
|
||||
// the kernel will automatically disable that same cpu when SMT is changed
|
||||
*settings.cpus()[i].online() = *settings.cpus()[i].online() && (status || i % 2 == 0);
|
||||
*settings.cpus()[i].online() =
|
||||
*settings.cpus()[i].online() && (status || i % 2 == 0);
|
||||
}
|
||||
}
|
||||
let mut result = Vec::with_capacity(settings.len());
|
||||
|
@ -126,25 +131,40 @@ impl CpuMessage {
|
|||
result.push(*settings.cpus()[i].online());
|
||||
}
|
||||
cb(result);
|
||||
},
|
||||
}
|
||||
Self::GetSmt(cb) => {
|
||||
cb(*settings.smt());
|
||||
},
|
||||
}
|
||||
Self::GetCpusOnline(cb) => {
|
||||
let mut result = Vec::with_capacity(settings.len());
|
||||
for cpu in settings.cpus() {
|
||||
result.push(*cpu.online());
|
||||
}
|
||||
cb(result);
|
||||
},
|
||||
Self::SetClockLimits(index, clocks) => {settings.cpus().get_mut(index).map(|c| c.clock_limits(clocks));},
|
||||
Self::GetClockLimits(index, cb) => {settings.cpus().get(index).map(|c| cb(c.get_clock_limits().map(|x| x.to_owned())));},
|
||||
Self::SetCpuGovernor(index, gov) => {settings.cpus().get_mut(index).map(|c| c.governor(gov));},
|
||||
}
|
||||
Self::SetClockLimits(index, clocks) => {
|
||||
settings
|
||||
.cpus()
|
||||
.get_mut(index)
|
||||
.map(|c| c.clock_limits(clocks));
|
||||
}
|
||||
Self::GetClockLimits(index, cb) => {
|
||||
settings
|
||||
.cpus()
|
||||
.get(index)
|
||||
.map(|c| cb(c.get_clock_limits().map(|x| x.to_owned())));
|
||||
}
|
||||
Self::SetCpuGovernor(index, gov) => {
|
||||
settings.cpus().get_mut(index).map(|c| c.governor(gov));
|
||||
}
|
||||
Self::SetCpusGovernor(govs) => {
|
||||
for i in 0..govs.len() {
|
||||
settings.cpus().get_mut(i).map(|c| c.governor(govs[i].clone()));
|
||||
settings
|
||||
.cpus()
|
||||
.get_mut(i)
|
||||
.map(|c| c.governor(govs[i].clone()));
|
||||
}
|
||||
},
|
||||
}
|
||||
Self::GetCpusGovernor(cb) => {
|
||||
let mut result = Vec::with_capacity(settings.len());
|
||||
for cpu in settings.cpus() {
|
||||
|
@ -158,13 +178,14 @@ impl CpuMessage {
|
|||
|
||||
/// Message instructs the driver to modify settings
|
||||
fn is_modify(&self) -> bool {
|
||||
matches!(self,
|
||||
matches!(
|
||||
self,
|
||||
Self::SetCpuOnline(_, _)
|
||||
| Self::SetCpusOnline(_)
|
||||
| Self::SetSmt(_, _)
|
||||
| Self::SetClockLimits(_, _)
|
||||
| Self::SetCpuGovernor(_, _)
|
||||
| Self::SetCpusGovernor(_)
|
||||
| Self::SetCpusOnline(_)
|
||||
| Self::SetSmt(_, _)
|
||||
| Self::SetClockLimits(_, _)
|
||||
| Self::SetCpuGovernor(_, _)
|
||||
| Self::SetCpusGovernor(_)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -193,10 +214,9 @@ impl GpuMessage {
|
|||
}
|
||||
|
||||
fn is_modify(&self) -> bool {
|
||||
matches!(self,
|
||||
Self::SetPpt(_, _)
|
||||
| Self::SetClockLimits(_)
|
||||
| Self::SetSlowMemory(_)
|
||||
matches!(
|
||||
self,
|
||||
Self::SetPpt(_, _) | Self::SetClockLimits(_) | Self::SetSlowMemory(_)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -217,7 +237,7 @@ impl GeneralMessage {
|
|||
Self::GetPersistent(cb) => cb(*settings.persistent()),
|
||||
Self::GetCurrentProfileName(cb) => cb(settings.get_name().to_owned()),
|
||||
Self::GetPath(cb) => cb(settings.get_path().to_owned()),
|
||||
Self::ApplyNow => {},
|
||||
Self::ApplyNow => {}
|
||||
}
|
||||
dirty
|
||||
}
|
||||
|
@ -234,7 +254,9 @@ pub struct ApiMessageHandler {
|
|||
|
||||
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(()));
|
||||
errors
|
||||
.iter()
|
||||
.for_each(|e| write!(err_list, "\t{},\n", e).unwrap_or(()));
|
||||
log::error!("Settings {}() err:\n{}", call_name, err_list);
|
||||
}
|
||||
|
||||
|
@ -248,7 +270,7 @@ impl ApiMessageHandler {
|
|||
}
|
||||
if dirty || dirty_echo {
|
||||
dirty_echo = dirty; // echo only once
|
||||
// run on_set
|
||||
// run on_set
|
||||
if let Err(e) = settings.on_set() {
|
||||
print_errors("on_set", e);
|
||||
}
|
||||
|
@ -259,8 +281,8 @@ impl ApiMessageHandler {
|
|||
// save
|
||||
log::debug!("api_worker is saving...");
|
||||
let is_persistent = *settings.general.persistent();
|
||||
let save_path = crate::utility::settings_dir()
|
||||
.join(settings.general.get_path().clone());
|
||||
let save_path =
|
||||
crate::utility::settings_dir().join(settings.general.get_path().clone());
|
||||
if is_persistent {
|
||||
let settings_clone = settings.json();
|
||||
let save_json: SettingsJson = settings_clone.into();
|
||||
|
@ -272,7 +294,11 @@ impl ApiMessageHandler {
|
|||
} else {
|
||||
if save_path.exists() {
|
||||
if let Err(e) = std::fs::remove_file(&save_path) {
|
||||
log::warn!("Failed to delete persistent settings file {}: {}", save_path.display(), e);
|
||||
log::warn!(
|
||||
"Failed to delete persistent settings file {}: {}",
|
||||
save_path.display(),
|
||||
e
|
||||
);
|
||||
} else {
|
||||
log::debug!("Deleted persistent settings file {}", save_path.display());
|
||||
}
|
||||
|
@ -333,7 +359,7 @@ impl ApiMessageHandler {
|
|||
ApiMessage::WaitForEmptyQueue(callback) => {
|
||||
self.on_empty.push(callback);
|
||||
false
|
||||
},
|
||||
}
|
||||
ApiMessage::LoadSettings(id, name) => {
|
||||
let path = format!("{}.json", id);
|
||||
match settings.load_file(path.into(), name, false) {
|
||||
|
@ -346,7 +372,7 @@ impl ApiMessageHandler {
|
|||
match settings.load_file(
|
||||
crate::consts::DEFAULT_SETTINGS_FILE.into(),
|
||||
crate::consts::DEFAULT_SETTINGS_NAME.to_owned(),
|
||||
true
|
||||
true,
|
||||
) {
|
||||
Ok(success) => log::info!("Loaded main settings file? {}", success),
|
||||
Err(e) => log::warn!("Load file err: {}", e),
|
||||
|
@ -356,7 +382,7 @@ impl ApiMessageHandler {
|
|||
ApiMessage::LoadSystemSettings => {
|
||||
settings.load_system_default(settings.general.get_name().to_owned());
|
||||
true
|
||||
},
|
||||
}
|
||||
ApiMessage::GetLimits(cb) => {
|
||||
cb(super::SettingsLimits {
|
||||
battery: settings.battery.limits(),
|
||||
|
@ -365,7 +391,7 @@ impl ApiMessageHandler {
|
|||
general: settings.general.limits(),
|
||||
});
|
||||
false
|
||||
},
|
||||
}
|
||||
ApiMessage::GetProvider(name, cb) => {
|
||||
cb(match &name as &str {
|
||||
"battery" => settings.battery.provider(),
|
||||
|
@ -380,9 +406,12 @@ impl ApiMessageHandler {
|
|||
|
||||
pub fn new() -> (Self, Sender<ApiMessage>) {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
(Self {
|
||||
intake: rx,
|
||||
on_empty: Vec::with_capacity(4),
|
||||
}, tx)
|
||||
(
|
||||
Self {
|
||||
intake: rx,
|
||||
on_empty: Vec::with_capacity(4),
|
||||
},
|
||||
tx,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
mod api_types;
|
||||
mod async_utils;
|
||||
pub mod battery;
|
||||
pub mod cpu;
|
||||
pub mod general;
|
||||
pub mod gpu;
|
||||
pub mod handler;
|
||||
mod async_utils;
|
||||
mod utility;
|
||||
|
||||
pub(super) type ApiParameterType = Vec<usdpl_back::core::serdes::Primitive>;
|
||||
|
|
|
@ -10,12 +10,14 @@ pub fn map_result<T: Into<Primitive>>(result: Result<T, SettingError>) -> super:
|
|||
Err(e) => {
|
||||
log::debug!("Mapping error to primitive: {}", e);
|
||||
vec![e.msg.into()]
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn map_optional_result<T: Into<Primitive>>(result: Result<Option<T>, SettingError>) -> super::ApiParameterType {
|
||||
pub fn map_optional_result<T: Into<Primitive>>(
|
||||
result: Result<Option<T>, SettingError>,
|
||||
) -> super::ApiParameterType {
|
||||
match result {
|
||||
Ok(val) => match val {
|
||||
Some(val) => vec![val.into()],
|
||||
|
@ -24,7 +26,7 @@ pub fn map_optional_result<T: Into<Primitive>>(result: Result<Option<T>, Setting
|
|||
Err(e) => {
|
||||
log::debug!("Mapping error to primitive: {}", e);
|
||||
vec![e.msg.into()]
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,17 +22,18 @@ fn main() -> Result<(), ()> {
|
|||
#[cfg(debug_assertions)]
|
||||
let log_filepath = usdpl_back::api::dirs::home()
|
||||
.unwrap_or_else(|| "/tmp/".into())
|
||||
.join(PACKAGE_NAME.to_owned()+".log");
|
||||
.join(PACKAGE_NAME.to_owned() + ".log");
|
||||
#[cfg(not(debug_assertions))]
|
||||
let log_filepath = std::path::Path::new("/tmp").join(format!("{}.log", PACKAGE_NAME));
|
||||
#[cfg(debug_assertions)]
|
||||
let old_log_filepath = usdpl_back::api::dirs::home()
|
||||
.unwrap_or_else(|| "/tmp/".into())
|
||||
.join(PACKAGE_NAME.to_owned()+".log.old");
|
||||
.join(PACKAGE_NAME.to_owned() + ".log.old");
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
if std::path::Path::new(&log_filepath).exists() {
|
||||
std::fs::copy(&log_filepath, &old_log_filepath).expect("Unable to increment logs. Do you have write permissions?");
|
||||
std::fs::copy(&log_filepath, &old_log_filepath)
|
||||
.expect("Unable to increment logs. Do you have write permissions?");
|
||||
}
|
||||
}
|
||||
WriteLogger::init(
|
||||
|
@ -53,8 +54,14 @@ fn main() -> Result<(), ()> {
|
|||
println!("Logging to: {:?}", log_filepath);
|
||||
log::info!("Starting back-end ({} v{})", PACKAGE_NAME, PACKAGE_VERSION);
|
||||
println!("Starting back-end ({} v{})", PACKAGE_NAME, PACKAGE_VERSION);
|
||||
log::info!("Current dir `{}`", std::env::current_dir().unwrap().display());
|
||||
println!("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()
|
||||
);
|
||||
|
||||
log::info!("home dir: {:?}", usdpl_back::api::dirs::home());
|
||||
|
||||
|
@ -66,11 +73,20 @@ fn main() -> Result<(), ()> {
|
|||
}
|
||||
|
||||
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()
|
||||
);
|
||||
|
||||
let mut loaded_settings = persist::SettingsJson::open(utility::settings_dir().join(DEFAULT_SETTINGS_FILE))
|
||||
.map(|settings| settings::Settings::from_json(settings, DEFAULT_SETTINGS_FILE.into()))
|
||||
.unwrap_or_else(|_| settings::Settings::system_default(DEFAULT_SETTINGS_FILE.into(), DEFAULT_SETTINGS_NAME.into()));
|
||||
let mut loaded_settings =
|
||||
persist::SettingsJson::open(utility::settings_dir().join(DEFAULT_SETTINGS_FILE))
|
||||
.map(|settings| settings::Settings::from_json(settings, DEFAULT_SETTINGS_FILE.into()))
|
||||
.unwrap_or_else(|_| {
|
||||
settings::Settings::system_default(
|
||||
DEFAULT_SETTINGS_FILE.into(),
|
||||
DEFAULT_SETTINGS_NAME.into(),
|
||||
)
|
||||
});
|
||||
|
||||
log::debug!("Settings: {:?}", loaded_settings);
|
||||
|
||||
|
@ -83,19 +99,33 @@ fn main() -> Result<(), ()> {
|
|||
let instance = Instance::new(PORT)
|
||||
.register("V_INFO", |_: Vec<Primitive>| {
|
||||
#[cfg(debug_assertions)]
|
||||
{vec![format!("v{}-dbg", PACKAGE_VERSION).into()]}
|
||||
{
|
||||
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()]
|
||||
{
|
||||
vec![format!("v{}-rls", PACKAGE_VERSION).into()]
|
||||
}
|
||||
})
|
||||
.register("NAME", |_: Vec<Primitive>| vec![PACKAGE_NAME.into()])
|
||||
.register("LOG", api::general::log_it())
|
||||
// battery API functions
|
||||
.register_async("BATTERY_current_now", api::battery::current_now(api_sender.clone()))
|
||||
.register_async("BATTERY_charge_now", api::battery::charge_now(api_sender.clone()))
|
||||
.register_async("BATTERY_charge_full", api::battery::charge_full(api_sender.clone()))
|
||||
.register_async("BATTERY_charge_design", api::battery::charge_design(api_sender.clone()))
|
||||
.register_async(
|
||||
"BATTERY_current_now",
|
||||
api::battery::current_now(api_sender.clone()),
|
||||
)
|
||||
.register_async(
|
||||
"BATTERY_charge_now",
|
||||
api::battery::charge_now(api_sender.clone()),
|
||||
)
|
||||
.register_async(
|
||||
"BATTERY_charge_full",
|
||||
api::battery::charge_full(api_sender.clone()),
|
||||
)
|
||||
.register_async(
|
||||
"BATTERY_charge_design",
|
||||
api::battery::charge_design(api_sender.clone()),
|
||||
)
|
||||
.register(
|
||||
"BATTERY_set_charge_rate",
|
||||
api::battery::set_charge_rate(api_sender.clone()),
|
||||
|
@ -136,138 +166,124 @@ fn main() -> Result<(), ()> {
|
|||
.register("CPU_count", api::cpu::max_cpus)
|
||||
.register(
|
||||
"CPU_set_online",
|
||||
api::cpu::set_cpu_online(api_sender.clone())
|
||||
api::cpu::set_cpu_online(api_sender.clone()),
|
||||
)
|
||||
.register(
|
||||
"CPU_set_onlines",
|
||||
api::cpu::set_cpus_online(api_sender.clone())
|
||||
api::cpu::set_cpus_online(api_sender.clone()),
|
||||
)
|
||||
.register_async(
|
||||
"CPU_get_onlines",
|
||||
api::cpu::get_cpus_online(api_sender.clone())
|
||||
)
|
||||
.register_async(
|
||||
"CPU_set_smt",
|
||||
api::cpu::set_smt(api_sender.clone())
|
||||
)
|
||||
.register_async(
|
||||
"CPU_get_smt",
|
||||
api::cpu::get_smt(api_sender.clone())
|
||||
api::cpu::get_cpus_online(api_sender.clone()),
|
||||
)
|
||||
.register_async("CPU_set_smt", api::cpu::set_smt(api_sender.clone()))
|
||||
.register_async("CPU_get_smt", api::cpu::get_smt(api_sender.clone()))
|
||||
.register(
|
||||
"CPU_set_clock_limits",
|
||||
api::cpu::set_clock_limits(api_sender.clone())
|
||||
api::cpu::set_clock_limits(api_sender.clone()),
|
||||
)
|
||||
.register(
|
||||
"CPU_get_clock_limits",
|
||||
api::cpu::get_clock_limits(api_sender.clone())
|
||||
api::cpu::get_clock_limits(api_sender.clone()),
|
||||
)
|
||||
.register(
|
||||
"CPU_unset_clock_limits",
|
||||
api::cpu::unset_clock_limits(api_sender.clone())
|
||||
api::cpu::unset_clock_limits(api_sender.clone()),
|
||||
)
|
||||
.register(
|
||||
"CPU_set_governor",
|
||||
api::cpu::set_cpu_governor(api_sender.clone())
|
||||
api::cpu::set_cpu_governor(api_sender.clone()),
|
||||
)
|
||||
.register(
|
||||
"CPU_set_governors",
|
||||
api::cpu::set_cpus_governors(api_sender.clone())
|
||||
api::cpu::set_cpus_governors(api_sender.clone()),
|
||||
)
|
||||
.register(
|
||||
"CPU_get_governors",
|
||||
api::cpu::get_cpu_governors(api_sender.clone())
|
||||
api::cpu::get_cpu_governors(api_sender.clone()),
|
||||
)
|
||||
// gpu API functions
|
||||
.register(
|
||||
"GPU_set_ppt",
|
||||
api::gpu::set_ppt(api_sender.clone())
|
||||
)
|
||||
.register_async(
|
||||
"GPU_get_ppt",
|
||||
api::gpu::get_ppt(api_sender.clone())
|
||||
)
|
||||
.register(
|
||||
"GPU_unset_ppt",
|
||||
api::gpu::unset_ppt(api_sender.clone())
|
||||
)
|
||||
.register("GPU_set_ppt", api::gpu::set_ppt(api_sender.clone()))
|
||||
.register_async("GPU_get_ppt", api::gpu::get_ppt(api_sender.clone()))
|
||||
.register("GPU_unset_ppt", api::gpu::unset_ppt(api_sender.clone()))
|
||||
.register(
|
||||
"GPU_set_clock_limits",
|
||||
api::gpu::set_clock_limits(api_sender.clone())
|
||||
api::gpu::set_clock_limits(api_sender.clone()),
|
||||
)
|
||||
.register_async(
|
||||
"GPU_get_clock_limits",
|
||||
api::gpu::get_clock_limits(api_sender.clone())
|
||||
api::gpu::get_clock_limits(api_sender.clone()),
|
||||
)
|
||||
.register(
|
||||
"GPU_unset_clock_limits",
|
||||
api::gpu::unset_clock_limits(api_sender.clone())
|
||||
api::gpu::unset_clock_limits(api_sender.clone()),
|
||||
)
|
||||
.register(
|
||||
"GPU_set_slow_memory",
|
||||
api::gpu::set_slow_memory(api_sender.clone())
|
||||
api::gpu::set_slow_memory(api_sender.clone()),
|
||||
)
|
||||
.register_async(
|
||||
"GPU_get_slow_memory",
|
||||
api::gpu::get_slow_memory(api_sender.clone())
|
||||
api::gpu::get_slow_memory(api_sender.clone()),
|
||||
)
|
||||
// general API functions
|
||||
.register(
|
||||
"GENERAL_set_persistent",
|
||||
api::general::set_persistent(api_sender.clone())
|
||||
api::general::set_persistent(api_sender.clone()),
|
||||
)
|
||||
.register(
|
||||
"GENERAL_get_persistent",
|
||||
api::general::get_persistent(api_sender.clone())
|
||||
api::general::get_persistent(api_sender.clone()),
|
||||
)
|
||||
.register(
|
||||
"GENERAL_load_settings",
|
||||
api::general::load_settings(api_sender.clone())
|
||||
api::general::load_settings(api_sender.clone()),
|
||||
)
|
||||
.register(
|
||||
"GENERAL_load_default_settings",
|
||||
api::general::load_default_settings(api_sender.clone())
|
||||
api::general::load_default_settings(api_sender.clone()),
|
||||
)
|
||||
.register(
|
||||
"GENERAL_load_system_settings",
|
||||
api::general::load_system_settings(api_sender.clone())
|
||||
api::general::load_system_settings(api_sender.clone()),
|
||||
)
|
||||
.register_async(
|
||||
"GENERAL_get_name",
|
||||
api::general::get_name(api_sender.clone())
|
||||
api::general::get_name(api_sender.clone()),
|
||||
)
|
||||
.register_async(
|
||||
"GENERAL_get_path",
|
||||
api::general::get_path(api_sender.clone())
|
||||
api::general::get_path(api_sender.clone()),
|
||||
)
|
||||
.register_async(
|
||||
"GENERAL_wait_for_unlocks",
|
||||
api::general::lock_unlock_all(api_sender.clone())
|
||||
api::general::lock_unlock_all(api_sender.clone()),
|
||||
)
|
||||
.register_blocking(
|
||||
"GENERAL_get_limits",
|
||||
api::general::get_limits(api_sender.clone())
|
||||
api::general::get_limits(api_sender.clone()),
|
||||
)
|
||||
.register_async(
|
||||
"GENERAL_get_provider",
|
||||
api::general::get_provider(api_sender.clone())
|
||||
api::general::get_provider(api_sender.clone()),
|
||||
)
|
||||
.register("GENERAL_idk", api::general::gunter)
|
||||
.register(
|
||||
"GENERAL_apply_now",
|
||||
api::general::force_apply(api_sender.clone())
|
||||
api::general::force_apply(api_sender.clone()),
|
||||
)
|
||||
.register(
|
||||
"GENERAL_on_pluggedin",
|
||||
api::battery::on_plugged(api_sender.clone())
|
||||
api::battery::on_plugged(api_sender.clone()),
|
||||
)
|
||||
.register(
|
||||
"GENERAL_on_unplugged",
|
||||
api::battery::on_unplugged(api_sender.clone())
|
||||
api::battery::on_unplugged(api_sender.clone()),
|
||||
);
|
||||
|
||||
if let Err(e) = loaded_settings.on_set() {
|
||||
e.iter().for_each(|e| log::error!("Startup Settings.on_set() error: {}", e));
|
||||
e.iter()
|
||||
.for_each(|e| log::error!("Startup Settings.on_set() error: {}", e));
|
||||
} else {
|
||||
log::info!("Startup Settings.on_set() success");
|
||||
}
|
||||
|
@ -278,6 +294,5 @@ fn main() -> Result<(), ()> {
|
|||
|
||||
api_worker::spawn(loaded_settings, api_handler);
|
||||
|
||||
instance
|
||||
.run_blocking()
|
||||
instance.run_blocking()
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ use std::default::Default;
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::JsonError;
|
||||
use super::{BatteryJson, CpuJson, GpuJson, DriverJson};
|
||||
use super::{BatteryJson, CpuJson, DriverJson, GpuJson};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct SettingsJson {
|
||||
|
|
|
@ -5,7 +5,7 @@ mod error;
|
|||
mod general;
|
||||
mod gpu;
|
||||
|
||||
pub use battery::{BatteryJson, BatteryEventJson};
|
||||
pub use battery::{BatteryEventJson, BatteryJson};
|
||||
pub use cpu::CpuJson;
|
||||
pub use driver::DriverJson;
|
||||
pub use general::{MinMaxJson, SettingsJson};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::sync::mpsc::Sender;
|
||||
use std::thread::{self, JoinHandle};
|
||||
use std::time::Duration;
|
||||
use std::sync::mpsc::Sender;
|
||||
|
||||
use crate::api::handler::ApiMessage;
|
||||
//use crate::utility::unwrap_maybe_fatal;
|
||||
|
@ -11,7 +11,9 @@ pub fn spawn(sender: Sender<ApiMessage>) -> JoinHandle<()> {
|
|||
thread::spawn(move || {
|
||||
log::info!("power_worker starting...");
|
||||
loop {
|
||||
sender.send(ApiMessage::PowerVibeCheck).expect("power_worker send failed");
|
||||
sender
|
||||
.send(ApiMessage::PowerVibeCheck)
|
||||
.expect("power_worker send failed");
|
||||
thread::sleep(PERIOD);
|
||||
}
|
||||
//log::warn!("resume_worker completed!");
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::sync::mpsc::Sender;
|
||||
use std::thread::{self, JoinHandle};
|
||||
use std::time::{Duration, Instant};
|
||||
use std::sync::mpsc::Sender;
|
||||
|
||||
use crate::api::handler::ApiMessage;
|
||||
//use crate::utility::unwrap_maybe_fatal;
|
||||
|
@ -11,7 +11,7 @@ pub fn spawn(sender: Sender<ApiMessage>) -> JoinHandle<()> {
|
|||
thread::spawn(move || {
|
||||
log::info!("resume_worker starting...");
|
||||
let duration = Duration::from_millis(10); // very low so it detects before Steam client does
|
||||
// this allows PowerTools to set some values at wakeup and Steam to override them before user notices
|
||||
// this allows PowerTools to set some values at wakeup and Steam to override them before user notices
|
||||
let mut start = Instant::now();
|
||||
loop {
|
||||
let old_start = start.elapsed();
|
||||
|
@ -19,7 +19,9 @@ pub fn spawn(sender: Sender<ApiMessage>) -> JoinHandle<()> {
|
|||
if old_start.as_secs_f64() > duration.as_secs_f64() * (1.0 + ALLOWED_ERROR) {
|
||||
// has just resumed from sleep
|
||||
log::info!("Resume detected");
|
||||
sender.send(ApiMessage::OnResume).expect("resume_worker send failed");
|
||||
sender
|
||||
.send(ApiMessage::OnResume)
|
||||
.expect("resume_worker send failed");
|
||||
log::debug!(
|
||||
"OnResume completed after sleeping for {}s",
|
||||
old_start.as_secs_f32()
|
||||
|
|
|
@ -2,25 +2,31 @@ use std::fs::File;
|
|||
|
||||
use regex::RegexBuilder;
|
||||
|
||||
use limits_core::json::{Limits, BatteryLimit, CpuLimit, GpuLimit};
|
||||
use limits_core::json::{BatteryLimit, CpuLimit, GpuLimit, Limits};
|
||||
|
||||
use crate::persist::{DriverJson, SettingsJson};
|
||||
use crate::settings::{TGeneral, TCpus, TGpu, TBattery, Driver, General};
|
||||
use crate::settings::{Driver, General, TBattery, TCpus, TGeneral, TGpu};
|
||||
|
||||
fn get_limits() -> limits_core::json::Base {
|
||||
let limits_path = super::utility::limits_path();
|
||||
match File::open(&limits_path) {
|
||||
Ok(f) => {
|
||||
match serde_json::from_reader(f) {
|
||||
Ok(lim) => lim,
|
||||
Err(e) => {
|
||||
log::warn!("Failed to parse limits file `{}`, cannot use for auto_detect: {}", limits_path.display(), e);
|
||||
limits_core::json::Base::default()
|
||||
}
|
||||
Ok(f) => match serde_json::from_reader(f) {
|
||||
Ok(lim) => lim,
|
||||
Err(e) => {
|
||||
log::warn!(
|
||||
"Failed to parse limits file `{}`, cannot use for auto_detect: {}",
|
||||
limits_path.display(),
|
||||
e
|
||||
);
|
||||
limits_core::json::Base::default()
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
log::warn!("Failed to open limits file `{}` (trying force refresh...): {}", limits_path.display(), e);
|
||||
log::warn!(
|
||||
"Failed to open limits file `{}` (trying force refresh...): {}",
|
||||
limits_path.display(),
|
||||
e
|
||||
);
|
||||
super::limits_worker::get_limits_blocking()
|
||||
}
|
||||
}
|
||||
|
@ -28,22 +34,34 @@ fn get_limits() -> limits_core::json::Base {
|
|||
|
||||
#[inline]
|
||||
pub fn auto_detect_provider() -> DriverJson {
|
||||
let provider = auto_detect0(None, crate::utility::settings_dir().join("autodetect.json"), "".to_owned())
|
||||
.battery
|
||||
.provider();
|
||||
let provider = auto_detect0(
|
||||
None,
|
||||
crate::utility::settings_dir().join("autodetect.json"),
|
||||
"".to_owned(),
|
||||
)
|
||||
.battery
|
||||
.provider();
|
||||
//log::info!("Detected device automatically, compatible driver: {:?}", provider);
|
||||
provider
|
||||
}
|
||||
|
||||
/// Device detection logic
|
||||
pub fn auto_detect0(settings_opt: Option<SettingsJson>, json_path: std::path::PathBuf, name: String) -> Driver {
|
||||
pub fn auto_detect0(
|
||||
settings_opt: Option<SettingsJson>,
|
||||
json_path: std::path::PathBuf,
|
||||
name: String,
|
||||
) -> Driver {
|
||||
let mut builder = DriverBuilder::new(json_path, name);
|
||||
|
||||
let cpu_info: String = usdpl_back::api::files::read_single("/proc/cpuinfo").unwrap_or_default();
|
||||
log::debug!("Read from /proc/cpuinfo:\n{}", cpu_info);
|
||||
let os_info: String = usdpl_back::api::files::read_single("/etc/os-release").unwrap_or_default();
|
||||
let os_info: String =
|
||||
usdpl_back::api::files::read_single("/etc/os-release").unwrap_or_default();
|
||||
log::debug!("Read from /etc/os-release:\n{}", os_info);
|
||||
let dmi_info: String = std::process::Command::new("dmidecode").output().map(|out| String::from_utf8_lossy(&out.stdout).into_owned()).unwrap_or_default();
|
||||
let dmi_info: String = std::process::Command::new("dmidecode")
|
||||
.output()
|
||||
.map(|out| String::from_utf8_lossy(&out.stdout).into_owned())
|
||||
.unwrap_or_default();
|
||||
log::debug!("Read dmidecode:\n{}", dmi_info);
|
||||
|
||||
let limits = get_limits();
|
||||
|
@ -60,26 +78,27 @@ pub fn auto_detect0(settings_opt: Option<SettingsJson>, json_path: std::path::Pa
|
|||
.multi_line(true)
|
||||
.build()
|
||||
.expect("Invalid DMI regex");
|
||||
matches &=pattern.is_match(&dmi_info);
|
||||
matches &= pattern.is_match(&dmi_info);
|
||||
}
|
||||
if let Some(cpuinfo) = &conditions.cpuinfo {
|
||||
let pattern = RegexBuilder::new(cpuinfo)
|
||||
.multi_line(true)
|
||||
.build()
|
||||
.expect("Invalid CPU regex");
|
||||
matches &=pattern.is_match(&cpu_info);
|
||||
matches &= pattern.is_match(&cpu_info);
|
||||
}
|
||||
if let Some(os) = &conditions.os {
|
||||
let pattern = RegexBuilder::new(os)
|
||||
.multi_line(true)
|
||||
.build()
|
||||
.expect("Invalid OS regex");
|
||||
matches &=pattern.is_match(&os_info);
|
||||
matches &= pattern.is_match(&os_info);
|
||||
}
|
||||
if let Some(cmd) = &conditions.command {
|
||||
match std::process::Command::new("bash")
|
||||
.args(["-c", cmd])
|
||||
.status() {
|
||||
.status()
|
||||
{
|
||||
Ok(status) => matches &= status.code().map(|c| c == 0).unwrap_or(false),
|
||||
Err(e) => log::warn!("Ignoring bash limits error: {}", e),
|
||||
}
|
||||
|
@ -97,30 +116,102 @@ pub fn auto_detect0(settings_opt: Option<SettingsJson>, json_path: std::path::Pa
|
|||
match limit {
|
||||
Limits::Cpu(cpus) => {
|
||||
let cpu_driver: Box<dyn TCpus> = match cpus {
|
||||
CpuLimit::SteamDeck => Box::new(crate::settings::steam_deck::Cpus::from_json(settings.cpus.clone(), settings.version)),
|
||||
CpuLimit::SteamDeckAdvance => Box::new(crate::settings::steam_deck::Cpus::from_json(settings.cpus.clone(), settings.version)),
|
||||
CpuLimit::Generic(x) => Box::new(crate::settings::generic::Cpus::<crate::settings::generic::Cpu>::from_json_and_limits(settings.cpus.clone(), settings.version, x)),
|
||||
CpuLimit::GenericAMD(x) => Box::new(crate::settings::generic_amd::Cpus::from_json_and_limits(settings.cpus.clone(), settings.version, x)),
|
||||
CpuLimit::Unknown => Box::new(crate::settings::unknown::Cpus::from_json(settings.cpus.clone(), settings.version)),
|
||||
CpuLimit::SteamDeck => {
|
||||
Box::new(crate::settings::steam_deck::Cpus::from_json(
|
||||
settings.cpus.clone(),
|
||||
settings.version,
|
||||
))
|
||||
}
|
||||
CpuLimit::SteamDeckAdvance => {
|
||||
Box::new(crate::settings::steam_deck::Cpus::from_json(
|
||||
settings.cpus.clone(),
|
||||
settings.version,
|
||||
))
|
||||
}
|
||||
CpuLimit::Generic(x) => Box::new(crate::settings::generic::Cpus::<
|
||||
crate::settings::generic::Cpu,
|
||||
>::from_json_and_limits(
|
||||
settings.cpus.clone(),
|
||||
settings.version,
|
||||
x,
|
||||
)),
|
||||
CpuLimit::GenericAMD(x) => Box::new(
|
||||
crate::settings::generic_amd::Cpus::from_json_and_limits(
|
||||
settings.cpus.clone(),
|
||||
settings.version,
|
||||
x,
|
||||
),
|
||||
),
|
||||
CpuLimit::Unknown => {
|
||||
Box::new(crate::settings::unknown::Cpus::from_json(
|
||||
settings.cpus.clone(),
|
||||
settings.version,
|
||||
))
|
||||
}
|
||||
};
|
||||
builder.cpus = Some(cpu_driver);
|
||||
},
|
||||
}
|
||||
Limits::Gpu(gpu) => {
|
||||
let driver: Box<dyn TGpu> = match gpu {
|
||||
GpuLimit::SteamDeck => Box::new(crate::settings::steam_deck::Gpu::from_json(settings.gpu.clone(), settings.version)),
|
||||
GpuLimit::SteamDeckAdvance => Box::new(crate::settings::steam_deck::Gpu::from_json(settings.gpu.clone(), settings.version)),
|
||||
GpuLimit::Generic(x) => Box::new(crate::settings::generic::Gpu::from_json_and_limits(settings.gpu.clone(), settings.version, x)),
|
||||
GpuLimit::GenericAMD(x) => Box::new(crate::settings::generic_amd::Gpu::from_json_and_limits(settings.gpu.clone(), settings.version, x)),
|
||||
GpuLimit::Unknown => Box::new(crate::settings::unknown::Gpu::from_json(settings.gpu.clone(), settings.version)),
|
||||
GpuLimit::SteamDeck => {
|
||||
Box::new(crate::settings::steam_deck::Gpu::from_json(
|
||||
settings.gpu.clone(),
|
||||
settings.version,
|
||||
))
|
||||
}
|
||||
GpuLimit::SteamDeckAdvance => {
|
||||
Box::new(crate::settings::steam_deck::Gpu::from_json(
|
||||
settings.gpu.clone(),
|
||||
settings.version,
|
||||
))
|
||||
}
|
||||
GpuLimit::Generic(x) => {
|
||||
Box::new(crate::settings::generic::Gpu::from_json_and_limits(
|
||||
settings.gpu.clone(),
|
||||
settings.version,
|
||||
x,
|
||||
))
|
||||
}
|
||||
GpuLimit::GenericAMD(x) => Box::new(
|
||||
crate::settings::generic_amd::Gpu::from_json_and_limits(
|
||||
settings.gpu.clone(),
|
||||
settings.version,
|
||||
x,
|
||||
),
|
||||
),
|
||||
GpuLimit::Unknown => {
|
||||
Box::new(crate::settings::unknown::Gpu::from_json(
|
||||
settings.gpu.clone(),
|
||||
settings.version,
|
||||
))
|
||||
}
|
||||
};
|
||||
builder.gpu = Some(driver);
|
||||
},
|
||||
}
|
||||
Limits::Battery(batt) => {
|
||||
let driver: Box<dyn TBattery> = match batt {
|
||||
BatteryLimit::SteamDeck => Box::new(crate::settings::steam_deck::Battery::from_json(settings.battery.clone(), settings.version)),
|
||||
BatteryLimit::SteamDeckAdvance => Box::new(crate::settings::steam_deck::Battery::from_json(settings.battery.clone(), settings.version)),
|
||||
BatteryLimit::Generic(x) => Box::new(crate::settings::generic::Battery::from_json_and_limits(settings.battery.clone(), settings.version, x)),
|
||||
BatteryLimit::Unknown => Box::new(crate::settings::unknown::Battery),
|
||||
BatteryLimit::SteamDeck => {
|
||||
Box::new(crate::settings::steam_deck::Battery::from_json(
|
||||
settings.battery.clone(),
|
||||
settings.version,
|
||||
))
|
||||
}
|
||||
BatteryLimit::SteamDeckAdvance => {
|
||||
Box::new(crate::settings::steam_deck::Battery::from_json(
|
||||
settings.battery.clone(),
|
||||
settings.version,
|
||||
))
|
||||
}
|
||||
BatteryLimit::Generic(x) => Box::new(
|
||||
crate::settings::generic::Battery::from_json_and_limits(
|
||||
settings.battery.clone(),
|
||||
settings.version,
|
||||
x,
|
||||
),
|
||||
),
|
||||
BatteryLimit::Unknown => {
|
||||
Box::new(crate::settings::unknown::Battery)
|
||||
}
|
||||
};
|
||||
builder.battery = Some(driver);
|
||||
}
|
||||
|
@ -131,37 +222,66 @@ pub fn auto_detect0(settings_opt: Option<SettingsJson>, json_path: std::path::Pa
|
|||
match limit {
|
||||
Limits::Cpu(cpus) => {
|
||||
let cpu_driver: Box<dyn TCpus> = match cpus {
|
||||
CpuLimit::SteamDeck => Box::new(crate::settings::steam_deck::Cpus::system_default()),
|
||||
CpuLimit::SteamDeckAdvance => Box::new(crate::settings::steam_deck::Cpus::system_default()),
|
||||
CpuLimit::Generic(x) => Box::new(crate::settings::generic::Cpus::<crate::settings::generic::Cpu>::from_limits(x)),
|
||||
CpuLimit::GenericAMD(x) => Box::new(crate::settings::generic_amd::Cpus::from_limits(x)),
|
||||
CpuLimit::Unknown => Box::new(crate::settings::unknown::Cpus::system_default()),
|
||||
CpuLimit::SteamDeck => {
|
||||
Box::new(crate::settings::steam_deck::Cpus::system_default())
|
||||
}
|
||||
CpuLimit::SteamDeckAdvance => {
|
||||
Box::new(crate::settings::steam_deck::Cpus::system_default())
|
||||
}
|
||||
CpuLimit::Generic(x) => {
|
||||
Box::new(crate::settings::generic::Cpus::<
|
||||
crate::settings::generic::Cpu,
|
||||
>::from_limits(x))
|
||||
}
|
||||
CpuLimit::GenericAMD(x) => {
|
||||
Box::new(crate::settings::generic_amd::Cpus::from_limits(x))
|
||||
}
|
||||
CpuLimit::Unknown => {
|
||||
Box::new(crate::settings::unknown::Cpus::system_default())
|
||||
}
|
||||
};
|
||||
builder.cpus = Some(cpu_driver);
|
||||
},
|
||||
}
|
||||
Limits::Gpu(gpu) => {
|
||||
let driver: Box<dyn TGpu> = match gpu {
|
||||
GpuLimit::SteamDeck => Box::new(crate::settings::steam_deck::Gpu::system_default()),
|
||||
GpuLimit::SteamDeckAdvance => Box::new(crate::settings::steam_deck::Gpu::system_default()),
|
||||
GpuLimit::Generic(x) => Box::new(crate::settings::generic::Gpu::from_limits(x)),
|
||||
GpuLimit::GenericAMD(x) => Box::new(crate::settings::generic_amd::Gpu::from_limits(x)),
|
||||
GpuLimit::Unknown => Box::new(crate::settings::unknown::Gpu::system_default()),
|
||||
GpuLimit::SteamDeck => {
|
||||
Box::new(crate::settings::steam_deck::Gpu::system_default())
|
||||
}
|
||||
GpuLimit::SteamDeckAdvance => {
|
||||
Box::new(crate::settings::steam_deck::Gpu::system_default())
|
||||
}
|
||||
GpuLimit::Generic(x) => {
|
||||
Box::new(crate::settings::generic::Gpu::from_limits(x))
|
||||
}
|
||||
GpuLimit::GenericAMD(x) => {
|
||||
Box::new(crate::settings::generic_amd::Gpu::from_limits(x))
|
||||
}
|
||||
GpuLimit::Unknown => {
|
||||
Box::new(crate::settings::unknown::Gpu::system_default())
|
||||
}
|
||||
};
|
||||
builder.gpu = Some(driver);
|
||||
},
|
||||
}
|
||||
Limits::Battery(batt) => {
|
||||
let driver: Box<dyn TBattery> = match batt {
|
||||
BatteryLimit::SteamDeck => Box::new(crate::settings::steam_deck::Battery::system_default()),
|
||||
BatteryLimit::SteamDeckAdvance => Box::new(crate::settings::steam_deck::Battery::system_default()),
|
||||
BatteryLimit::Generic(x) => Box::new(crate::settings::generic::Battery::from_limits(x)),
|
||||
BatteryLimit::Unknown => Box::new(crate::settings::unknown::Battery),
|
||||
BatteryLimit::SteamDeck => {
|
||||
Box::new(crate::settings::steam_deck::Battery::system_default())
|
||||
}
|
||||
BatteryLimit::SteamDeckAdvance => {
|
||||
Box::new(crate::settings::steam_deck::Battery::system_default())
|
||||
}
|
||||
BatteryLimit::Generic(x) => {
|
||||
Box::new(crate::settings::generic::Battery::from_limits(x))
|
||||
}
|
||||
BatteryLimit::Unknown => {
|
||||
Box::new(crate::settings::unknown::Battery)
|
||||
}
|
||||
};
|
||||
builder.battery = Some(driver);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -197,9 +317,15 @@ impl DriverBuilder {
|
|||
fn build(self) -> Driver {
|
||||
Driver {
|
||||
general: self.general,
|
||||
cpus: self.cpus.unwrap_or_else(|| Box::new(crate::settings::unknown::Cpus::system_default())),
|
||||
gpu: self.gpu.unwrap_or_else(|| Box::new(crate::settings::unknown::Gpu::system_default())),
|
||||
battery: self.battery.unwrap_or_else(|| Box::new(crate::settings::unknown::Battery))
|
||||
cpus: self
|
||||
.cpus
|
||||
.unwrap_or_else(|| Box::new(crate::settings::unknown::Cpus::system_default())),
|
||||
gpu: self
|
||||
.gpu
|
||||
.unwrap_or_else(|| Box::new(crate::settings::unknown::Gpu::system_default())),
|
||||
battery: self
|
||||
.battery
|
||||
.unwrap_or_else(|| Box::new(crate::settings::unknown::Battery)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,20 +8,18 @@ use limits_core::json::Base;
|
|||
pub fn spawn() -> JoinHandle<()> {
|
||||
thread::spawn(move || {
|
||||
log::info!("limits_worker starting...");
|
||||
let sleep_dur = Duration::from_secs(60*60*24); // 1 day
|
||||
let sleep_dur = Duration::from_secs(60 * 60 * 24); // 1 day
|
||||
let limits_path = super::utility::limits_path();
|
||||
loop {
|
||||
thread::sleep(sleep_dur);
|
||||
if (limits_path.exists() && limits_path.is_file()) || !limits_path.exists() {
|
||||
// try to load limits from file, fallback to built-in default
|
||||
let base = match std::fs::File::open(&limits_path) {
|
||||
Ok(f) => {
|
||||
match serde_json::from_reader(f) {
|
||||
Ok(b) => b,
|
||||
Err(e) => {
|
||||
log::error!("Cannot parse {}: {}", limits_path.display(), e);
|
||||
Base::default()
|
||||
}
|
||||
Ok(f) => match serde_json::from_reader(f) {
|
||||
Ok(b) => b,
|
||||
Err(e) => {
|
||||
log::error!("Cannot parse {}: {}", limits_path.display(), e);
|
||||
Base::default()
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
|
@ -31,17 +29,18 @@ pub fn spawn() -> JoinHandle<()> {
|
|||
};
|
||||
if let Some(refresh) = &base.refresh {
|
||||
// try to retrieve newer version
|
||||
match ureq::get(refresh)
|
||||
.call() {
|
||||
match ureq::get(refresh).call() {
|
||||
Ok(response) => {
|
||||
let json_res: std::io::Result<Base> = response.into_json();
|
||||
match json_res {
|
||||
Ok(new_base) => {
|
||||
save_base(&new_base, &limits_path);
|
||||
},
|
||||
Err(e) => log::error!("Cannot parse response from `{}`: {}", refresh, e),
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("Cannot parse response from `{}`: {}", refresh, e)
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
Err(e) => log::warn!("Cannot download limits from `{}`: {}", refresh, e),
|
||||
}
|
||||
} else {
|
||||
|
@ -67,13 +66,11 @@ pub fn get_limits_blocking() -> Base {
|
|||
let limits_path = super::utility::limits_path();
|
||||
if limits_path.is_file() {
|
||||
match std::fs::File::open(&limits_path) {
|
||||
Ok(f) => {
|
||||
match serde_json::from_reader(f) {
|
||||
Ok(b) => b,
|
||||
Err(e) => {
|
||||
log::error!("Cannot parse {}: {}", limits_path.display(), e);
|
||||
Base::default()
|
||||
}
|
||||
Ok(f) => match serde_json::from_reader(f) {
|
||||
Ok(b) => b,
|
||||
Err(e) => {
|
||||
log::error!("Cannot parse {}: {}", limits_path.display(), e);
|
||||
Base::default()
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
|
@ -86,17 +83,18 @@ pub fn get_limits_blocking() -> Base {
|
|||
{
|
||||
let refresh = Base::default().refresh.unwrap();
|
||||
match ureq::get(&refresh) // try to retrieve newer version
|
||||
.call() {
|
||||
.call()
|
||||
{
|
||||
Ok(response) => {
|
||||
let json_res: std::io::Result<Base> = response.into_json();
|
||||
match json_res {
|
||||
Ok(new_base) => {
|
||||
save_base(&new_base, &limits_path);
|
||||
return new_base;
|
||||
},
|
||||
Err(e) => log::error!("Cannot parse response from `{}`: {}", refresh, e)
|
||||
}
|
||||
Err(e) => log::error!("Cannot parse response from `{}`: {}", refresh, e),
|
||||
}
|
||||
},
|
||||
}
|
||||
Err(e) => log::warn!("Cannot download limits from `{}`: {}", refresh, e),
|
||||
}
|
||||
}
|
||||
|
@ -108,12 +106,14 @@ pub fn get_limits_blocking() -> Base {
|
|||
fn save_base(new_base: &Base, path: impl AsRef<std::path::Path>) {
|
||||
let limits_path = path.as_ref();
|
||||
match std::fs::File::create(&limits_path) {
|
||||
Ok(f) => {
|
||||
match serde_json::to_writer_pretty(f, &new_base) {
|
||||
Ok(_) => log::info!("Successfully saved new limits to {}", limits_path.display()),
|
||||
Err(e) => log::error!("Failed to save limits json to file `{}`: {}", limits_path.display(), e),
|
||||
}
|
||||
Ok(f) => match serde_json::to_writer_pretty(f, &new_base) {
|
||||
Ok(_) => log::info!("Successfully saved new limits to {}", limits_path.display()),
|
||||
Err(e) => log::error!(
|
||||
"Failed to save limits json to file `{}`: {}",
|
||||
limits_path.display(),
|
||||
e
|
||||
),
|
||||
},
|
||||
Err(e) => log::error!("Cannot create {}: {}", limits_path.display(), e)
|
||||
Err(e) => log::error!("Cannot create {}: {}", limits_path.display(), e),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,4 +2,4 @@ mod auto_detect;
|
|||
pub mod limits_worker;
|
||||
mod utility;
|
||||
|
||||
pub use auto_detect::{auto_detect_provider, auto_detect0};
|
||||
pub use auto_detect::{auto_detect0, auto_detect_provider};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use super::{auto_detect0, General, SettingError, TBattery, TCpus, TGeneral, TGpu};
|
||||
use crate::persist::{DriverJson, SettingsJson};
|
||||
use super::{TGeneral, TCpus, TGpu, TBattery, SettingError, General, auto_detect0};
|
||||
|
||||
pub struct Driver {
|
||||
pub general: Box<dyn TGeneral>,
|
||||
|
@ -9,7 +9,10 @@ pub struct Driver {
|
|||
}
|
||||
|
||||
impl Driver {
|
||||
pub fn init(settings: SettingsJson, json_path: std::path::PathBuf) -> Result<Self, SettingError> {
|
||||
pub fn init(
|
||||
settings: SettingsJson,
|
||||
json_path: std::path::PathBuf,
|
||||
) -> Result<Self, SettingError> {
|
||||
Ok(match settings.version {
|
||||
0 => Self::version0(settings, json_path)?,
|
||||
_ => Self {
|
||||
|
@ -19,14 +22,26 @@ impl Driver {
|
|||
name: settings.name,
|
||||
driver: DriverJson::SteamDeck,
|
||||
}),
|
||||
cpus: Box::new(super::steam_deck::Cpus::from_json(settings.cpus, settings.version)),
|
||||
gpu: Box::new(super::steam_deck::Gpu::from_json(settings.gpu, settings.version)),
|
||||
battery: Box::new(super::steam_deck::Battery::from_json(settings.battery, settings.version)),
|
||||
cpus: Box::new(super::steam_deck::Cpus::from_json(
|
||||
settings.cpus,
|
||||
settings.version,
|
||||
)),
|
||||
gpu: Box::new(super::steam_deck::Gpu::from_json(
|
||||
settings.gpu,
|
||||
settings.version,
|
||||
)),
|
||||
battery: Box::new(super::steam_deck::Battery::from_json(
|
||||
settings.battery,
|
||||
settings.version,
|
||||
)),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
fn version0(settings: SettingsJson, json_path: std::path::PathBuf) -> Result<Self, SettingError> {
|
||||
fn version0(
|
||||
settings: SettingsJson,
|
||||
json_path: std::path::PathBuf,
|
||||
) -> Result<Self, SettingError> {
|
||||
let name = settings.name.clone();
|
||||
if let Some(provider) = &settings.provider {
|
||||
match provider {
|
||||
|
@ -37,9 +52,18 @@ impl Driver {
|
|||
name: settings.name,
|
||||
driver: DriverJson::SteamDeck,
|
||||
}),
|
||||
cpus: Box::new(super::steam_deck::Cpus::from_json(settings.cpus, settings.version)),
|
||||
gpu: Box::new(super::steam_deck::Gpu::from_json(settings.gpu, settings.version)),
|
||||
battery: Box::new(super::steam_deck::Battery::from_json(settings.battery, settings.version)),
|
||||
cpus: Box::new(super::steam_deck::Cpus::from_json(
|
||||
settings.cpus,
|
||||
settings.version,
|
||||
)),
|
||||
gpu: Box::new(super::steam_deck::Gpu::from_json(
|
||||
settings.gpu,
|
||||
settings.version,
|
||||
)),
|
||||
battery: Box::new(super::steam_deck::Battery::from_json(
|
||||
settings.battery,
|
||||
settings.version,
|
||||
)),
|
||||
}),
|
||||
// There's nothing special about SteamDeckAdvance, it just appears different
|
||||
DriverJson::SteamDeckAdvance => Ok(Self {
|
||||
|
@ -49,13 +73,28 @@ impl Driver {
|
|||
name: settings.name,
|
||||
driver: DriverJson::SteamDeckAdvance,
|
||||
}),
|
||||
cpus: Box::new(super::steam_deck::Cpus::from_json(settings.cpus, settings.version)),
|
||||
gpu: Box::new(super::steam_deck::Gpu::from_json(settings.gpu, settings.version)),
|
||||
battery: Box::new(super::steam_deck::Battery::from_json(settings.battery, settings.version)),
|
||||
cpus: Box::new(super::steam_deck::Cpus::from_json(
|
||||
settings.cpus,
|
||||
settings.version,
|
||||
)),
|
||||
gpu: Box::new(super::steam_deck::Gpu::from_json(
|
||||
settings.gpu,
|
||||
settings.version,
|
||||
)),
|
||||
battery: Box::new(super::steam_deck::Battery::from_json(
|
||||
settings.battery,
|
||||
settings.version,
|
||||
)),
|
||||
}),
|
||||
DriverJson::Generic | DriverJson::GenericAMD => Ok(super::detect::auto_detect0(Some(settings), json_path, name)),
|
||||
DriverJson::Unknown => Ok(super::detect::auto_detect0(Some(settings), json_path, name)),
|
||||
DriverJson::AutoDetect => Ok(super::detect::auto_detect0(Some(settings), json_path, name)),
|
||||
DriverJson::Generic | DriverJson::GenericAMD => {
|
||||
Ok(super::detect::auto_detect0(Some(settings), json_path, name))
|
||||
}
|
||||
DriverJson::Unknown => {
|
||||
Ok(super::detect::auto_detect0(Some(settings), json_path, name))
|
||||
}
|
||||
DriverJson::AutoDetect => {
|
||||
Ok(super::detect::auto_detect0(Some(settings), json_path, name))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Ok(super::detect::auto_detect0(Some(settings), json_path, name))
|
||||
|
@ -73,9 +112,11 @@ pub fn maybe_do_button() {
|
|||
match super::auto_detect_provider() {
|
||||
DriverJson::SteamDeck | DriverJson::SteamDeckAdvance => {
|
||||
crate::settings::steam_deck::flash_led();
|
||||
},
|
||||
DriverJson::Generic | DriverJson::GenericAMD => log::warn!("You need to come up with something fun on generic"),
|
||||
}
|
||||
DriverJson::Generic | DriverJson::GenericAMD => {
|
||||
log::warn!("You need to come up with something fun on generic")
|
||||
}
|
||||
DriverJson::Unknown => log::warn!("Can't do button activities on unknown platform"),
|
||||
DriverJson::AutoDetect => log::warn!("WTF, why is auto_detect detecting AutoDetect???")
|
||||
DriverJson::AutoDetect => log::warn!("WTF, why is auto_detect detecting AutoDetect???"),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ use std::path::PathBuf;
|
|||
|
||||
//use super::{Battery, Cpus, Gpu};
|
||||
use super::{OnResume, OnSet, SettingError};
|
||||
use super::{TGeneral, TGpu, TCpus, TBattery};
|
||||
use super::{TBattery, TCpus, TGeneral, TGpu};
|
||||
use crate::persist::SettingsJson;
|
||||
//use crate::utility::unwrap_lock;
|
||||
|
||||
|
@ -52,7 +52,7 @@ impl crate::settings::OnPowerEvent for General {}
|
|||
|
||||
impl TGeneral for General {
|
||||
fn limits(&self) -> crate::api::GeneralLimits {
|
||||
crate::api::GeneralLimits { }
|
||||
crate::api::GeneralLimits {}
|
||||
}
|
||||
|
||||
fn get_persistent(&self) -> bool {
|
||||
|
@ -97,17 +97,25 @@ impl OnSet for Settings {
|
|||
let mut errors = Vec::new();
|
||||
|
||||
log::debug!("Applying settings for on_resume");
|
||||
self.general.on_set().unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
self.general
|
||||
.on_set()
|
||||
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
log::debug!("Resumed general");
|
||||
self.battery.on_set().unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
self.battery
|
||||
.on_set()
|
||||
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
log::debug!("Resumed battery");
|
||||
self.cpus.on_set().unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
self.cpus
|
||||
.on_set()
|
||||
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
log::debug!("Resumed CPUs");
|
||||
self.gpu.on_set().unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
self.gpu
|
||||
.on_set()
|
||||
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
log::debug!("Resumed GPU");
|
||||
|
||||
if errors.is_empty() {
|
||||
Ok(())
|
||||
Ok(())
|
||||
} else {
|
||||
Err(errors)
|
||||
}
|
||||
|
@ -120,14 +128,20 @@ impl Settings {
|
|||
let name_bup = other.name.clone();
|
||||
match super::Driver::init(other, json_path.clone()) {
|
||||
Ok(x) => {
|
||||
log::info!("Loaded settings with drivers general:{:?},cpus:{:?},gpu:{:?},battery:{:?}", x.general.provider(), x.cpus.provider(), x.gpu.provider(), x.battery.provider());
|
||||
log::info!(
|
||||
"Loaded settings with drivers general:{:?},cpus:{:?},gpu:{:?},battery:{:?}",
|
||||
x.general.provider(),
|
||||
x.cpus.provider(),
|
||||
x.gpu.provider(),
|
||||
x.battery.provider()
|
||||
);
|
||||
Self {
|
||||
general: x.general,
|
||||
cpus: x.cpus,
|
||||
gpu: x.gpu,
|
||||
battery: x.battery,
|
||||
}
|
||||
},
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("Driver init error: {}", e);
|
||||
Self::system_default(json_path, name_bup)
|
||||
|
@ -153,7 +167,12 @@ impl Settings {
|
|||
self.general = driver.general;
|
||||
}
|
||||
|
||||
pub fn load_file(&mut self, filename: PathBuf, name: String, system_defaults: bool) -> Result<bool, SettingError> {
|
||||
pub fn load_file(
|
||||
&mut self,
|
||||
filename: PathBuf,
|
||||
name: String,
|
||||
system_defaults: bool,
|
||||
) -> Result<bool, SettingError> {
|
||||
let json_path = crate::utility::settings_dir().join(&filename);
|
||||
if json_path.exists() {
|
||||
let settings_json = SettingsJson::open(&json_path).map_err(|e| SettingError {
|
||||
|
@ -161,7 +180,11 @@ impl Settings {
|
|||
setting: SettingVariant::General,
|
||||
})?;
|
||||
if !settings_json.persistent {
|
||||
log::warn!("Loaded persistent config `{}` ({}) with persistent=false", &settings_json.name, json_path.display());
|
||||
log::warn!(
|
||||
"Loaded persistent config `{}` ({}) with persistent=false",
|
||||
&settings_json.name,
|
||||
json_path.display()
|
||||
);
|
||||
*self.general.persistent() = false;
|
||||
self.general.name(name);
|
||||
} else {
|
||||
|
@ -172,7 +195,7 @@ impl Settings {
|
|||
self.cpus = x.cpus;
|
||||
self.gpu = x.gpu;
|
||||
self.battery = x.battery;
|
||||
},
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("Driver init error: {}", e);
|
||||
self.general.name(name);
|
||||
|
@ -193,7 +216,7 @@ impl Settings {
|
|||
self.general.path(filename);
|
||||
Ok(*self.general.persistent())
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
pub fn load_file(&mut self, filename: PathBuf, name: String, system_defaults: bool) -> Result<bool, SettingError> {
|
||||
let json_path = crate::utility::settings_dir().join(filename);
|
||||
|
@ -243,17 +266,25 @@ impl OnResume for Settings {
|
|||
let mut errors = Vec::new();
|
||||
|
||||
log::debug!("Applying settings for on_resume");
|
||||
self.general.on_resume().unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
self.general
|
||||
.on_resume()
|
||||
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
log::debug!("Resumed general");
|
||||
self.battery.on_resume().unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
self.battery
|
||||
.on_resume()
|
||||
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
log::debug!("Resumed battery");
|
||||
self.cpus.on_resume().unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
self.cpus
|
||||
.on_resume()
|
||||
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
log::debug!("Resumed CPUs");
|
||||
self.gpu.on_resume().unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
self.gpu
|
||||
.on_resume()
|
||||
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
log::debug!("Resumed GPU");
|
||||
|
||||
if errors.is_empty() {
|
||||
Ok(())
|
||||
Ok(())
|
||||
} else {
|
||||
Err(errors)
|
||||
}
|
||||
|
@ -264,13 +295,21 @@ impl crate::settings::OnPowerEvent for Settings {
|
|||
fn on_power_event(&mut self, new_mode: super::PowerMode) -> Result<(), Vec<SettingError>> {
|
||||
let mut errors = Vec::new();
|
||||
|
||||
self.general.on_power_event(new_mode).unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
self.battery.on_power_event(new_mode).unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
self.cpus.on_power_event(new_mode).unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
self.gpu.on_power_event(new_mode).unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
self.general
|
||||
.on_power_event(new_mode)
|
||||
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
self.battery
|
||||
.on_power_event(new_mode)
|
||||
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
self.cpus
|
||||
.on_power_event(new_mode)
|
||||
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
self.gpu
|
||||
.on_power_event(new_mode)
|
||||
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
|
||||
if errors.is_empty() {
|
||||
Ok(())
|
||||
Ok(())
|
||||
} else {
|
||||
Err(errors)
|
||||
}
|
||||
|
|
|
@ -2,9 +2,9 @@ use std::convert::Into;
|
|||
|
||||
use limits_core::json::GenericBatteryLimit;
|
||||
|
||||
use crate::settings::{OnResume, OnSet, SettingError};
|
||||
use crate::settings::TBattery;
|
||||
use crate::persist::BatteryJson;
|
||||
use crate::settings::TBattery;
|
||||
use crate::settings::{OnResume, OnSet, SettingError};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Battery {
|
||||
|
@ -39,16 +39,16 @@ impl Battery {
|
|||
|
||||
pub fn from_limits(limits: limits_core::json::GenericBatteryLimit) -> Self {
|
||||
// TODO
|
||||
Self {
|
||||
limits
|
||||
}
|
||||
Self { limits }
|
||||
}
|
||||
|
||||
pub fn from_json_and_limits(_other: BatteryJson, _version: u64, limits: limits_core::json::GenericBatteryLimit) -> Self {
|
||||
pub fn from_json_and_limits(
|
||||
_other: BatteryJson,
|
||||
_version: u64,
|
||||
limits: limits_core::json::GenericBatteryLimit,
|
||||
) -> Self {
|
||||
// TODO
|
||||
Self {
|
||||
limits
|
||||
}
|
||||
Self { limits }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -83,15 +83,13 @@ impl TBattery for Battery {
|
|||
self.clone().into()
|
||||
}
|
||||
|
||||
fn charge_rate(&mut self, _rate: Option<u64>) {
|
||||
}
|
||||
fn charge_rate(&mut self, _rate: Option<u64>) {}
|
||||
|
||||
fn get_charge_rate(&self) -> Option<u64> {
|
||||
None
|
||||
}
|
||||
|
||||
fn charge_mode(&mut self, _rate: Option<String>) {
|
||||
}
|
||||
fn charge_mode(&mut self, _rate: Option<String>) {}
|
||||
|
||||
fn get_charge_mode(&self) -> Option<String> {
|
||||
None
|
||||
|
@ -133,7 +131,9 @@ impl TBattery for Battery {
|
|||
|
||||
fn charge_limit(&mut self, _limit: Option<f64>) {}
|
||||
|
||||
fn get_charge_limit(&self) -> Option<f64> { None }
|
||||
fn get_charge_limit(&self) -> Option<f64> {
|
||||
None
|
||||
}
|
||||
|
||||
fn provider(&self) -> crate::persist::DriverJson {
|
||||
crate::persist::DriverJson::Generic
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
use std::convert::{Into, AsMut, AsRef};
|
||||
use std::convert::{AsMut, AsRef, Into};
|
||||
|
||||
use limits_core::json::GenericCpuLimit;
|
||||
|
||||
use crate::settings::{MinMax, min_max_from_json};
|
||||
use crate::settings::{OnResume, OnSet, SettingError};
|
||||
use crate::settings::{TCpus, TCpu};
|
||||
use crate::persist::CpuJson;
|
||||
use super::FromGenericCpuInfo;
|
||||
use crate::persist::CpuJson;
|
||||
use crate::settings::{min_max_from_json, MinMax};
|
||||
use crate::settings::{OnResume, OnSet, SettingError};
|
||||
use crate::settings::{TCpu, TCpus};
|
||||
|
||||
const CPU_PRESENT_PATH: &str = "/sys/devices/system/cpu/present";
|
||||
const CPU_SMT_PATH: &str = "/sys/devices/system/cpu/smt/control";
|
||||
|
@ -24,25 +24,19 @@ impl<C: AsMut<Cpu> + AsRef<Cpu> + TCpu + OnSet> OnSet for Cpus<C> {
|
|||
if self.smt_capable {
|
||||
// toggle SMT
|
||||
if self.smt {
|
||||
usdpl_back::api::files::write_single(CPU_SMT_PATH, "on").map_err(|e| {
|
||||
SettingError {
|
||||
msg: format!(
|
||||
"Failed to write `on` to `{}`: {}",
|
||||
CPU_SMT_PATH, e
|
||||
),
|
||||
usdpl_back::api::files::write_single(CPU_SMT_PATH, "on")
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!("Failed to write `on` to `{}`: {}", CPU_SMT_PATH, e),
|
||||
setting: crate::settings::SettingVariant::Cpu,
|
||||
}
|
||||
}).unwrap_or_else(|e| errors.push(e));
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
} else {
|
||||
usdpl_back::api::files::write_single(CPU_SMT_PATH, "off").map_err(|e| {
|
||||
SettingError {
|
||||
msg: format!(
|
||||
"Failed to write `off` to `{}`: {}",
|
||||
CPU_SMT_PATH, e
|
||||
),
|
||||
usdpl_back::api::files::write_single(CPU_SMT_PATH, "off")
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!("Failed to write `off` to `{}`: {}", CPU_SMT_PATH, e),
|
||||
setting: crate::settings::SettingVariant::Cpu,
|
||||
}
|
||||
}).unwrap_or_else(|e| errors.push(e));
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
}
|
||||
}
|
||||
for (i, cpu) in self.cpus.as_mut_slice().iter_mut().enumerate() {
|
||||
|
@ -61,7 +55,8 @@ impl<C: AsMut<Cpu> + AsRef<Cpu> + TCpu + OnResume> OnResume for Cpus<C> {
|
|||
fn on_resume(&self) -> Result<(), Vec<SettingError>> {
|
||||
let mut errors = Vec::new();
|
||||
for cpu in &self.cpus {
|
||||
cpu.on_resume().unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
cpu.on_resume()
|
||||
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
}
|
||||
if errors.is_empty() {
|
||||
Ok(())
|
||||
|
@ -88,7 +83,7 @@ impl<C: AsMut<Cpu> + AsRef<Cpu> + TCpu + FromGenericCpuInfo> Cpus<C> {
|
|||
fn system_smt_capabilities() -> (bool, bool) {
|
||||
match usdpl_back::api::files::read_single::<_, String, _>(CPU_SMT_PATH) {
|
||||
Ok(val) => (val.trim().to_lowercase() == "on", true),
|
||||
Err(_) => (false, false)
|
||||
Err(_) => (false, false),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -107,7 +102,11 @@ impl<C: AsMut<Cpu> + AsRef<Cpu> + TCpu + FromGenericCpuInfo> Cpus<C> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn from_json_and_limits(mut other: Vec<CpuJson>, version: u64, limits: limits_core::json::GenericCpuLimit) -> Self {
|
||||
pub fn from_json_and_limits(
|
||||
mut other: Vec<CpuJson>,
|
||||
version: u64,
|
||||
limits: limits_core::json::GenericCpuLimit,
|
||||
) -> Self {
|
||||
let (_, can_smt) = Self::system_smt_capabilities();
|
||||
let mut result = Vec::with_capacity(other.len());
|
||||
let max_cpus = Self::cpu_count();
|
||||
|
@ -138,11 +137,17 @@ impl<C: AsMut<Cpu> + AsRef<Cpu> + TCpu + FromGenericCpuInfo> Cpus<C> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<C: AsMut<Cpu> + AsRef<Cpu> + TCpu + crate::settings::OnPowerEvent> crate::settings::OnPowerEvent for Cpus<C> {
|
||||
fn on_power_event(&mut self, new_mode: crate::settings::PowerMode) -> Result<(), Vec<SettingError>> {
|
||||
impl<C: AsMut<Cpu> + AsRef<Cpu> + TCpu + crate::settings::OnPowerEvent>
|
||||
crate::settings::OnPowerEvent for Cpus<C>
|
||||
{
|
||||
fn on_power_event(
|
||||
&mut self,
|
||||
new_mode: crate::settings::PowerMode,
|
||||
) -> Result<(), Vec<SettingError>> {
|
||||
let mut errors = Vec::new();
|
||||
for cpu in &mut self.cpus {
|
||||
cpu.on_power_event(new_mode).unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
cpu.on_power_event(new_mode)
|
||||
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
}
|
||||
if errors.is_empty() {
|
||||
Ok(())
|
||||
|
@ -152,7 +157,9 @@ impl<C: AsMut<Cpu> + AsRef<Cpu> + TCpu + crate::settings::OnPowerEvent> crate::s
|
|||
}
|
||||
}
|
||||
|
||||
impl<C: AsMut<Cpu> + AsRef<Cpu> + TCpu + OnResume + OnSet + crate::settings::OnPowerEvent> TCpus for Cpus<C> {
|
||||
impl<C: AsMut<Cpu> + AsRef<Cpu> + TCpu + OnResume + OnSet + crate::settings::OnPowerEvent> TCpus
|
||||
for Cpus<C>
|
||||
{
|
||||
fn limits(&self) -> crate::api::CpusLimits {
|
||||
crate::api::CpusLimits {
|
||||
cpus: self.cpus.iter().map(|x| x.as_ref().limits()).collect(),
|
||||
|
@ -163,7 +170,10 @@ impl<C: AsMut<Cpu> + AsRef<Cpu> + TCpu + OnResume + OnSet + crate::settings::OnP
|
|||
}
|
||||
|
||||
fn json(&self) -> Vec<crate::persist::CpuJson> {
|
||||
self.cpus.iter().map(|x| x.as_ref().to_owned().into()).collect()
|
||||
self.cpus
|
||||
.iter()
|
||||
.map(|x| x.as_ref().to_owned().into())
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn cpus(&mut self) -> Vec<&mut dyn TCpu> {
|
||||
|
@ -228,7 +238,12 @@ impl FromGenericCpuInfo for Cpu {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
fn from_json_and_limits(other: CpuJson, version: u64, i: usize, limits: GenericCpuLimit) -> Self {
|
||||
fn from_json_and_limits(
|
||||
other: CpuJson,
|
||||
version: u64,
|
||||
i: usize,
|
||||
limits: GenericCpuLimit,
|
||||
) -> Self {
|
||||
let clock_lims = if limits.clock_min.is_some() && limits.clock_max.is_some() {
|
||||
other.clock_limits.map(|x| min_max_from_json(x, version))
|
||||
} else {
|
||||
|
@ -259,28 +274,29 @@ impl Cpu {
|
|||
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
|
||||
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 {
|
||||
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));
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
}
|
||||
|
||||
// set governor
|
||||
if self.index == 0 || self.online {
|
||||
let governor_path = cpu_governor_path(self.index);
|
||||
usdpl_back::api::files::write_single(&governor_path, &self.governor).map_err(|e| {
|
||||
SettingError {
|
||||
usdpl_back::api::files::write_single(&governor_path, &self.governor)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!(
|
||||
"Failed to write `{}` to `{}`: {}",
|
||||
&self.governor, &governor_path, e
|
||||
),
|
||||
setting: crate::settings::SettingVariant::Cpu,
|
||||
}
|
||||
}).unwrap_or_else(|e| errors.push(e));
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
}
|
||||
if errors.is_empty() {
|
||||
Ok(())
|
||||
|
@ -301,13 +317,14 @@ impl Cpu {
|
|||
|
||||
fn governors(&self) -> Vec<String> {
|
||||
// NOTE: this eats errors
|
||||
let gov_str: String = match usdpl_back::api::files::read_single(cpu_available_governors_path(self.index)) {
|
||||
Ok(s) => s,
|
||||
Err(e) => {
|
||||
log::warn!("Error getting available CPU governors: {}", e);
|
||||
return vec![];
|
||||
},
|
||||
};
|
||||
let gov_str: String =
|
||||
match usdpl_back::api::files::read_single(cpu_available_governors_path(self.index)) {
|
||||
Ok(s) => s,
|
||||
Err(e) => {
|
||||
log::warn!("Error getting available CPU governors: {}", e);
|
||||
return vec![];
|
||||
}
|
||||
};
|
||||
gov_str.split(' ').map(|s| s.to_owned()).collect()
|
||||
}
|
||||
|
||||
|
|
|
@ -2,10 +2,10 @@ use std::convert::Into;
|
|||
|
||||
use limits_core::json::GenericGpuLimit;
|
||||
|
||||
use crate::settings::{MinMax, min_max_from_json};
|
||||
use crate::settings::{OnResume, OnSet, SettingError};
|
||||
use crate::settings::TGpu;
|
||||
use crate::persist::GpuJson;
|
||||
use crate::settings::TGpu;
|
||||
use crate::settings::{min_max_from_json, MinMax};
|
||||
use crate::settings::{OnResume, OnSet, SettingError};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Gpu {
|
||||
|
@ -40,7 +40,11 @@ impl Gpu {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn from_json_and_limits(other: GpuJson, version: u64, limits: limits_core::json::GenericGpuLimit) -> Self {
|
||||
pub fn from_json_and_limits(
|
||||
other: GpuJson,
|
||||
version: u64,
|
||||
limits: limits_core::json::GenericGpuLimit,
|
||||
) -> Self {
|
||||
let clock_lims = if limits.clock_min.is_some() && limits.clock_max.is_some() {
|
||||
other.clock_limits.map(|x| min_max_from_json(x, version))
|
||||
} else {
|
||||
|
@ -48,8 +52,16 @@ impl Gpu {
|
|||
};
|
||||
Self {
|
||||
slow_memory: false,
|
||||
fast_ppt: if limits.fast_ppt.is_some() {other.fast_ppt} else {None},
|
||||
slow_ppt: if limits.slow_ppt.is_some() {other.slow_ppt} else {None},
|
||||
fast_ppt: if limits.fast_ppt.is_some() {
|
||||
other.fast_ppt
|
||||
} else {
|
||||
None
|
||||
},
|
||||
slow_ppt: if limits.slow_ppt.is_some() {
|
||||
other.slow_ppt
|
||||
} else {
|
||||
None
|
||||
},
|
||||
clock_limits: clock_lims,
|
||||
limits,
|
||||
}
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
use limits_core::json::GenericCpuLimit;
|
||||
use crate::persist::CpuJson;
|
||||
use limits_core::json::GenericCpuLimit;
|
||||
|
||||
pub trait FromGenericCpuInfo {
|
||||
fn from_limits(cpu_index: usize, limits: GenericCpuLimit) -> Self;
|
||||
|
||||
fn from_json_and_limits(other: CpuJson, version: u64, cpu_index: usize, limits: GenericCpuLimit) -> Self;
|
||||
fn from_json_and_limits(
|
||||
other: CpuJson,
|
||||
version: u64,
|
||||
cpu_index: usize,
|
||||
limits: GenericCpuLimit,
|
||||
) -> Self;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use crate::persist::CpuJson;
|
||||
use crate::settings::MinMax;
|
||||
use crate::settings::generic::{Cpu as GenericCpu, Cpus as GenericCpus, FromGenericCpuInfo};
|
||||
use crate::settings::MinMax;
|
||||
use crate::settings::{OnResume, OnSet, SettingError};
|
||||
use crate::settings::{TCpus, TCpu};
|
||||
use crate::settings::{TCpu, TCpus};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Cpus {
|
||||
|
@ -16,7 +16,11 @@ impl Cpus {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn from_json_and_limits(other: Vec<CpuJson>, version: u64, limits: limits_core::json::GenericCpuLimit) -> Self {
|
||||
pub fn from_json_and_limits(
|
||||
other: Vec<CpuJson>,
|
||||
version: u64,
|
||||
limits: limits_core::json::GenericCpuLimit,
|
||||
) -> Self {
|
||||
Self {
|
||||
generic: GenericCpus::from_json_and_limits(other, version, limits),
|
||||
}
|
||||
|
@ -73,16 +77,17 @@ pub struct Cpu {
|
|||
impl FromGenericCpuInfo for Cpu {
|
||||
fn from_limits(cpu_index: usize, limits: limits_core::json::GenericCpuLimit) -> Self {
|
||||
let gen = GenericCpu::from_limits(cpu_index, limits.clone());
|
||||
Self {
|
||||
generic: gen,
|
||||
}
|
||||
Self { generic: gen }
|
||||
}
|
||||
|
||||
fn from_json_and_limits(other: CpuJson, version: u64, cpu_index: usize, limits: limits_core::json::GenericCpuLimit) -> Self {
|
||||
fn from_json_and_limits(
|
||||
other: CpuJson,
|
||||
version: u64,
|
||||
cpu_index: usize,
|
||||
limits: limits_core::json::GenericCpuLimit,
|
||||
) -> Self {
|
||||
let gen = GenericCpu::from_json_and_limits(other, version, cpu_index, limits);
|
||||
Self {
|
||||
generic: gen,
|
||||
}
|
||||
Self { generic: gen }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
use std::sync::Mutex;
|
||||
use libryzenadj::RyzenAdj;
|
||||
use std::sync::Mutex;
|
||||
|
||||
use crate::persist::GpuJson;
|
||||
use crate::settings::MinMax;
|
||||
use crate::settings::generic::Gpu as GenericGpu;
|
||||
use crate::settings::{OnResume, OnSet, SettingError, SettingVariant};
|
||||
use crate::settings::MinMax;
|
||||
use crate::settings::TGpu;
|
||||
use crate::settings::{OnResume, OnSet, SettingError, SettingVariant};
|
||||
|
||||
fn ryzen_adj_or_log() -> Option<Mutex<RyzenAdj>> {
|
||||
match RyzenAdj::new() {
|
||||
|
@ -44,7 +44,11 @@ impl Gpu {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn from_json_and_limits(other: GpuJson, version: u64, limits: limits_core::json::GenericGpuLimit) -> Self {
|
||||
pub fn from_json_and_limits(
|
||||
other: GpuJson,
|
||||
version: u64,
|
||||
limits: limits_core::json::GenericGpuLimit,
|
||||
) -> Self {
|
||||
Self {
|
||||
generic: GenericGpu::from_json_and_limits(other, version, limits),
|
||||
implementor: ryzen_adj_or_log(),
|
||||
|
@ -76,71 +80,95 @@ impl Gpu {
|
|||
if self.state.old_fast_ppt.is_none() {
|
||||
match lock.get_fast_value() {
|
||||
Ok(val) => self.state.old_fast_ppt = Some(val as _),
|
||||
Err(e) => errors.push(
|
||||
SettingError {
|
||||
msg: format!("RyzenAdj get_fast_value() err: {}", e),
|
||||
setting: SettingVariant::Gpu,
|
||||
}
|
||||
)
|
||||
Err(e) => errors.push(SettingError {
|
||||
msg: format!("RyzenAdj get_fast_value() err: {}", e),
|
||||
setting: SettingVariant::Gpu,
|
||||
}),
|
||||
}
|
||||
}
|
||||
lock.set_fast_limit(*fast_ppt as _).map_err(|e| SettingError {
|
||||
msg: format!("RyzenAdj set_fast_limit({}) err: {}", *fast_ppt, e),
|
||||
setting: SettingVariant::Gpu,
|
||||
}).unwrap_or_else(|e| errors.push(e));
|
||||
lock.set_fast_limit(*fast_ppt as _)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!("RyzenAdj set_fast_limit({}) err: {}", *fast_ppt, e),
|
||||
setting: SettingVariant::Gpu,
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
} else if let Some(fast_ppt) = &self.state.old_fast_ppt {
|
||||
lock.set_fast_limit(*fast_ppt as _).map_err(|e| SettingError {
|
||||
msg: format!("RyzenAdj set_fast_limit({}) err: {}", *fast_ppt, e),
|
||||
setting: SettingVariant::Gpu,
|
||||
}).unwrap_or_else(|e| errors.push(e));
|
||||
lock.set_fast_limit(*fast_ppt as _)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!("RyzenAdj set_fast_limit({}) err: {}", *fast_ppt, e),
|
||||
setting: SettingVariant::Gpu,
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
self.state.old_fast_ppt = None;
|
||||
}
|
||||
if let Some(slow_ppt) = &self.generic.slow_ppt {
|
||||
if self.state.old_slow_ppt.is_none() {
|
||||
match lock.get_slow_value() {
|
||||
Ok(val) => self.state.old_fast_ppt = Some(val as _),
|
||||
Err(e) => errors.push(
|
||||
SettingError {
|
||||
msg: format!("RyzenAdj get_slow_value() err: {}", e),
|
||||
setting: SettingVariant::Gpu,
|
||||
}
|
||||
)
|
||||
Err(e) => errors.push(SettingError {
|
||||
msg: format!("RyzenAdj get_slow_value() err: {}", e),
|
||||
setting: SettingVariant::Gpu,
|
||||
}),
|
||||
}
|
||||
}
|
||||
lock.set_slow_limit(*slow_ppt as _).map_err(|e| SettingError {
|
||||
msg: format!("RyzenAdj set_slow_limit({}) err: {}", *slow_ppt, e),
|
||||
setting: SettingVariant::Gpu,
|
||||
}).unwrap_or_else(|e| errors.push(e));
|
||||
lock.set_slow_limit(*slow_ppt as _)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!("RyzenAdj set_slow_limit({}) err: {}", *slow_ppt, e),
|
||||
setting: SettingVariant::Gpu,
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
} else if let Some(slow_ppt) = &self.state.old_slow_ppt {
|
||||
lock.set_slow_limit(*slow_ppt as _).map_err(|e| SettingError {
|
||||
msg: format!("RyzenAdj set_slow_limit({}) err: {}", *slow_ppt, e),
|
||||
setting: SettingVariant::Gpu,
|
||||
}).unwrap_or_else(|e| errors.push(e));
|
||||
lock.set_slow_limit(*slow_ppt as _)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!("RyzenAdj set_slow_limit({}) err: {}", *slow_ppt, e),
|
||||
setting: SettingVariant::Gpu,
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
self.state.old_slow_ppt = None;
|
||||
}
|
||||
if let Some(clock_limits) = &self.generic.clock_limits {
|
||||
self.state.clock_limits_set = true;
|
||||
lock.set_max_gfxclk_freq(clock_limits.max as _).map_err(|e| SettingError {
|
||||
msg: format!("RyzenAdj set_max_gfxclk_freq({}) err: {}", clock_limits.max, e),
|
||||
setting: SettingVariant::Gpu,
|
||||
}).unwrap_or_else(|e| errors.push(e));
|
||||
lock.set_min_gfxclk_freq(clock_limits.min as _).map_err(|e| SettingError {
|
||||
msg: format!("RyzenAdj set_min_gfxclk_freq({}) err: {}", clock_limits.min, e),
|
||||
setting: SettingVariant::Gpu,
|
||||
}).unwrap_or_else(|e| errors.push(e));
|
||||
lock.set_max_gfxclk_freq(clock_limits.max as _)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!(
|
||||
"RyzenAdj set_max_gfxclk_freq({}) err: {}",
|
||||
clock_limits.max, e
|
||||
),
|
||||
setting: SettingVariant::Gpu,
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
lock.set_min_gfxclk_freq(clock_limits.min as _)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!(
|
||||
"RyzenAdj set_min_gfxclk_freq({}) err: {}",
|
||||
clock_limits.min, e
|
||||
),
|
||||
setting: SettingVariant::Gpu,
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
} else if self.state.clock_limits_set {
|
||||
self.state.clock_limits_set = false;
|
||||
let limits = self.generic.limits();
|
||||
if let Some(min_limits) = limits.clock_min_limits {
|
||||
if let Some(max_limits) = limits.clock_max_limits {
|
||||
lock.set_max_gfxclk_freq(max_limits.max as _).map_err(|e| SettingError {
|
||||
msg: format!("RyzenAdj set_max_gfxclk_freq({}) err: {}", max_limits.max, e),
|
||||
setting: SettingVariant::Gpu,
|
||||
}).unwrap_or_else(|e| errors.push(e));
|
||||
lock.set_min_gfxclk_freq(min_limits.min as _).map_err(|e| SettingError {
|
||||
msg: format!("RyzenAdj set_min_gfxclk_freq({}) err: {}", min_limits.min, e),
|
||||
setting: SettingVariant::Gpu,
|
||||
}).unwrap_or_else(|e| errors.push(e));
|
||||
lock.set_max_gfxclk_freq(max_limits.max as _)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!(
|
||||
"RyzenAdj set_max_gfxclk_freq({}) err: {}",
|
||||
max_limits.max, e
|
||||
),
|
||||
setting: SettingVariant::Gpu,
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
lock.set_min_gfxclk_freq(min_limits.min as _)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!(
|
||||
"RyzenAdj set_min_gfxclk_freq({}) err: {}",
|
||||
min_limits.min, e
|
||||
),
|
||||
setting: SettingVariant::Gpu,
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -174,26 +202,40 @@ impl Gpu {
|
|||
};
|
||||
let mut errors = Vec::new();
|
||||
if let Some(fast_ppt) = &self.generic.fast_ppt {
|
||||
lock.set_fast_limit(*fast_ppt as _).map_err(|e| SettingError {
|
||||
msg: format!("RyzenAdj set_fast_limit({}) err: {}", *fast_ppt, e),
|
||||
setting: SettingVariant::Gpu,
|
||||
}).unwrap_or_else(|e| errors.push(e));
|
||||
lock.set_fast_limit(*fast_ppt as _)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!("RyzenAdj set_fast_limit({}) err: {}", *fast_ppt, e),
|
||||
setting: SettingVariant::Gpu,
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
}
|
||||
if let Some(slow_ppt) = &self.generic.slow_ppt {
|
||||
lock.set_slow_limit(*slow_ppt as _).map_err(|e| SettingError {
|
||||
msg: format!("RyzenAdj set_slow_limit({}) err: {}", *slow_ppt, e),
|
||||
setting: SettingVariant::Gpu,
|
||||
}).unwrap_or_else(|e| errors.push(e));
|
||||
lock.set_slow_limit(*slow_ppt as _)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!("RyzenAdj set_slow_limit({}) err: {}", *slow_ppt, e),
|
||||
setting: SettingVariant::Gpu,
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
}
|
||||
if let Some(clock_limits) = &self.generic.clock_limits {
|
||||
lock.set_max_gfxclk_freq(clock_limits.max as _).map_err(|e| SettingError {
|
||||
msg: format!("RyzenAdj set_max_gfxclk_freq({}) err: {}", clock_limits.max, e),
|
||||
setting: SettingVariant::Gpu,
|
||||
}).unwrap_or_else(|e| errors.push(e));
|
||||
lock.set_min_gfxclk_freq(clock_limits.min as _).map_err(|e| SettingError {
|
||||
msg: format!("RyzenAdj set_min_gfxclk_freq({}) err: {}", clock_limits.min, e),
|
||||
setting: SettingVariant::Gpu,
|
||||
}).unwrap_or_else(|e| errors.push(e));
|
||||
lock.set_max_gfxclk_freq(clock_limits.max as _)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!(
|
||||
"RyzenAdj set_max_gfxclk_freq({}) err: {}",
|
||||
clock_limits.max, e
|
||||
),
|
||||
setting: SettingVariant::Gpu,
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
lock.set_min_gfxclk_freq(clock_limits.min as _)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!(
|
||||
"RyzenAdj set_min_gfxclk_freq({}) err: {}",
|
||||
clock_limits.min, e
|
||||
),
|
||||
setting: SettingVariant::Gpu,
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -13,11 +13,11 @@ pub mod unknown;
|
|||
|
||||
pub use detect::{auto_detect0, auto_detect_provider, limits_worker::spawn as limits_worker_spawn};
|
||||
pub use driver::Driver;
|
||||
pub use general::{SettingVariant, Settings, General};
|
||||
pub use min_max::{MinMax, min_max_from_json};
|
||||
pub use general::{General, SettingVariant, Settings};
|
||||
pub use min_max::{min_max_from_json, MinMax};
|
||||
|
||||
pub use error::SettingError;
|
||||
pub use traits::{OnResume, OnSet, TGeneral, TGpu, TCpus, TBattery, TCpu, OnPowerEvent, PowerMode};
|
||||
pub use traits::{OnPowerEvent, OnResume, OnSet, PowerMode, TBattery, TCpu, TCpus, TGeneral, TGpu};
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
use std::convert::Into;
|
||||
|
||||
use crate::api::RangeLimit;
|
||||
use crate::settings::{OnResume, OnSet, SettingError, OnPowerEvent, PowerMode};
|
||||
use crate::settings::TBattery;
|
||||
use crate::persist::{BatteryJson, BatteryEventJson};
|
||||
use super::util::ChargeMode;
|
||||
use super::oc_limits::{BatteryLimits, OverclockLimits};
|
||||
use super::util::ChargeMode;
|
||||
use crate::api::RangeLimit;
|
||||
use crate::persist::{BatteryEventJson, BatteryJson};
|
||||
use crate::settings::TBattery;
|
||||
use crate::settings::{OnPowerEvent, OnResume, OnSet, PowerMode, SettingError};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Battery {
|
||||
|
@ -40,11 +40,11 @@ impl OnPowerEvent for EventInstruction {
|
|||
(EventTrigger::PluggedIn, PowerMode::PluggedIn) => {
|
||||
log::info!("Steam Deck plugged in event handled");
|
||||
self.set_all()
|
||||
},
|
||||
}
|
||||
(EventTrigger::PluggedOut, PowerMode::PluggedOut) => {
|
||||
log::info!("Steam Deck plugged out event handled");
|
||||
self.set_all()
|
||||
},
|
||||
}
|
||||
(EventTrigger::BatteryAbove(exp), PowerMode::BatteryCharge(act)) => {
|
||||
if act > *exp {
|
||||
if self.is_triggered {
|
||||
|
@ -58,7 +58,7 @@ impl OnPowerEvent for EventInstruction {
|
|||
self.is_triggered = false;
|
||||
Ok(())
|
||||
}
|
||||
},
|
||||
}
|
||||
(EventTrigger::BatteryBelow(exp), PowerMode::BatteryCharge(act)) => {
|
||||
if act < *exp {
|
||||
if self.is_triggered {
|
||||
|
@ -72,8 +72,8 @@ impl OnPowerEvent for EventInstruction {
|
|||
self.is_triggered = false;
|
||||
Ok(())
|
||||
}
|
||||
},
|
||||
_ => Ok(())
|
||||
}
|
||||
_ => Ok(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -95,8 +95,16 @@ impl EventInstruction {
|
|||
match s {
|
||||
"normal" => Some(EventTrigger::PluggedIn),
|
||||
"idle" => Some(EventTrigger::PluggedOut),
|
||||
s if s.starts_with('>') => s.trim_start_matches('>').parse::<f64>().ok().map(|x| EventTrigger::BatteryAbove(x)),
|
||||
s if s.starts_with('<') => s.trim_start_matches('<').parse::<f64>().ok().map(|x| EventTrigger::BatteryBelow(x)),
|
||||
s if s.starts_with('>') => s
|
||||
.trim_start_matches('>')
|
||||
.parse::<f64>()
|
||||
.ok()
|
||||
.map(|x| EventTrigger::BatteryAbove(x)),
|
||||
s if s.starts_with('<') => s
|
||||
.trim_start_matches('<')
|
||||
.parse::<f64>()
|
||||
.ok()
|
||||
.map(|x| EventTrigger::BatteryBelow(x)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -105,19 +113,22 @@ impl EventInstruction {
|
|||
Self {
|
||||
trigger: Self::str_to_trigger(&other.trigger).unwrap_or(EventTrigger::Ignored),
|
||||
charge_rate: other.charge_rate,
|
||||
charge_mode: other.charge_mode.map(|x| Battery::str_to_charge_mode(&x)).flatten(),
|
||||
charge_mode: other
|
||||
.charge_mode
|
||||
.map(|x| Battery::str_to_charge_mode(&x))
|
||||
.flatten(),
|
||||
is_triggered: false,
|
||||
}
|
||||
}
|
||||
|
||||
fn set_charge_mode(&self) -> Result<(), SettingError> {
|
||||
if let Some(charge_mode) = self.charge_mode {
|
||||
super::util::set(super::util::Setting::ChargeMode, charge_mode as _).map_err(
|
||||
|e| SettingError {
|
||||
super::util::set(super::util::Setting::ChargeMode, charge_mode as _)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!("Failed to set charge mode: {}", e),
|
||||
setting: crate::settings::SettingVariant::Battery,
|
||||
},
|
||||
).map(|_| ())
|
||||
})
|
||||
.map(|_| ())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
|
@ -125,18 +136,18 @@ impl EventInstruction {
|
|||
|
||||
fn set_charge_rate(&self) -> Result<(), SettingError> {
|
||||
if let Some(charge_rate) = self.charge_rate {
|
||||
usdpl_back::api::files::write_single(BATTERY_CHARGE_RATE_PATH, charge_rate).map_err(
|
||||
|e| SettingError {
|
||||
usdpl_back::api::files::write_single(BATTERY_CHARGE_RATE_PATH, charge_rate)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!("Failed to write to `{}`: {}", BATTERY_CHARGE_RATE_PATH, e),
|
||||
setting: crate::settings::SettingVariant::Battery,
|
||||
},
|
||||
).map(|_| ())
|
||||
})
|
||||
.map(|_| ())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn set_all(&self) -> Result<(), Vec<SettingError>> {
|
||||
fn set_all(&self) -> Result<(), Vec<SettingError>> {
|
||||
let mut errors = Vec::new();
|
||||
|
||||
self.set_charge_rate().unwrap_or_else(|e| errors.push(e));
|
||||
|
@ -174,20 +185,38 @@ impl Battery {
|
|||
pub fn from_json(other: BatteryJson, version: u64) -> Self {
|
||||
let (oc_limits, is_default) = OverclockLimits::load_or_default();
|
||||
let oc_limits = oc_limits.battery;
|
||||
let driver = if is_default { crate::persist::DriverJson::SteamDeck } else { crate::persist::DriverJson::SteamDeckAdvance };
|
||||
let driver = if is_default {
|
||||
crate::persist::DriverJson::SteamDeck
|
||||
} else {
|
||||
crate::persist::DriverJson::SteamDeckAdvance
|
||||
};
|
||||
match version {
|
||||
0 => Self {
|
||||
charge_rate: other.charge_rate,
|
||||
charge_mode: other.charge_mode.map(|x| Self::str_to_charge_mode(&x)).flatten(),
|
||||
events: other.events.into_iter().map(|x| EventInstruction::from_json(x, version)).collect(),
|
||||
charge_mode: other
|
||||
.charge_mode
|
||||
.map(|x| Self::str_to_charge_mode(&x))
|
||||
.flatten(),
|
||||
events: other
|
||||
.events
|
||||
.into_iter()
|
||||
.map(|x| EventInstruction::from_json(x, version))
|
||||
.collect(),
|
||||
limits: oc_limits,
|
||||
state: crate::state::steam_deck::Battery::default(),
|
||||
driver_mode: driver,
|
||||
},
|
||||
_ => Self {
|
||||
charge_rate: other.charge_rate,
|
||||
charge_mode: other.charge_mode.map(|x| Self::str_to_charge_mode(&x)).flatten(),
|
||||
events: other.events.into_iter().map(|x| EventInstruction::from_json(x, version)).collect(),
|
||||
charge_mode: other
|
||||
.charge_mode
|
||||
.map(|x| Self::str_to_charge_mode(&x))
|
||||
.flatten(),
|
||||
events: other
|
||||
.events
|
||||
.into_iter()
|
||||
.map(|x| EventInstruction::from_json(x, version))
|
||||
.collect(),
|
||||
limits: oc_limits,
|
||||
state: crate::state::steam_deck::Battery::default(),
|
||||
driver_mode: driver,
|
||||
|
@ -201,7 +230,8 @@ impl Battery {
|
|||
ChargeMode::Normal => "normal",
|
||||
ChargeMode::Idle => "idle",
|
||||
ChargeMode::Discharge => "discharge",
|
||||
}.to_owned()
|
||||
}
|
||||
.to_owned()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -217,20 +247,20 @@ impl Battery {
|
|||
fn set_charge_mode(&mut self) -> Result<(), SettingError> {
|
||||
if let Some(charge_mode) = self.charge_mode {
|
||||
self.state.charge_mode_set = true;
|
||||
super::util::set(super::util::Setting::ChargeMode, charge_mode as _).map_err(
|
||||
|e| SettingError {
|
||||
super::util::set(super::util::Setting::ChargeMode, charge_mode as _)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!("Failed to set charge mode: {}", e),
|
||||
setting: crate::settings::SettingVariant::Battery,
|
||||
},
|
||||
).map(|_| ())
|
||||
})
|
||||
.map(|_| ())
|
||||
} else if self.state.charge_mode_set {
|
||||
self.state.charge_mode_set = false;
|
||||
super::util::set(super::util::Setting::ChargeMode, ChargeMode::Normal as _).map_err(
|
||||
|e| SettingError {
|
||||
super::util::set(super::util::Setting::ChargeMode, ChargeMode::Normal as _)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!("Failed to set charge mode: {}", e),
|
||||
setting: crate::settings::SettingVariant::Battery,
|
||||
},
|
||||
).map(|_| ())
|
||||
})
|
||||
.map(|_| ())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
|
@ -240,20 +270,23 @@ impl Battery {
|
|||
let mut errors = Vec::new();
|
||||
if let Some(charge_rate) = self.charge_rate {
|
||||
self.state.charge_rate_set = true;
|
||||
usdpl_back::api::files::write_single(BATTERY_CHARGE_RATE_PATH, charge_rate).map_err(
|
||||
|e| SettingError {
|
||||
usdpl_back::api::files::write_single(BATTERY_CHARGE_RATE_PATH, charge_rate)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!("Failed to write to `{}`: {}", BATTERY_CHARGE_RATE_PATH, e),
|
||||
setting: crate::settings::SettingVariant::Battery,
|
||||
},
|
||||
).unwrap_or_else(|e| errors.push(e));
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
} else if self.state.charge_rate_set {
|
||||
self.state.charge_rate_set = false;
|
||||
usdpl_back::api::files::write_single(BATTERY_CHARGE_RATE_PATH, self.limits.charge_rate.max).map_err(
|
||||
|e| SettingError {
|
||||
msg: format!("Failed to write to `{}`: {}", BATTERY_CHARGE_RATE_PATH, e),
|
||||
setting: crate::settings::SettingVariant::Battery,
|
||||
},
|
||||
).unwrap_or_else(|e| errors.push(e));
|
||||
usdpl_back::api::files::write_single(
|
||||
BATTERY_CHARGE_RATE_PATH,
|
||||
self.limits.charge_rate.max,
|
||||
)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!("Failed to write to `{}`: {}", BATTERY_CHARGE_RATE_PATH, e),
|
||||
setting: crate::settings::SettingVariant::Battery,
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
}
|
||||
self.set_charge_mode().unwrap_or_else(|e| errors.push(e));
|
||||
if errors.is_empty() {
|
||||
|
@ -265,7 +298,8 @@ impl Battery {
|
|||
|
||||
fn clamp_all(&mut self) {
|
||||
if let Some(charge_rate) = &mut self.charge_rate {
|
||||
*charge_rate = (*charge_rate).clamp(self.limits.charge_rate.min, self.limits.charge_rate.max);
|
||||
*charge_rate =
|
||||
(*charge_rate).clamp(self.limits.charge_rate.min, self.limits.charge_rate.max);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -306,7 +340,10 @@ impl Battery {
|
|||
pub fn read_charge_design() -> Result<f64, SettingError> {
|
||||
match usdpl_back::api::files::read_single::<_, u64, _>(BATTERY_CHARGE_DESIGN_PATH) {
|
||||
Err(e) => Err(SettingError {
|
||||
msg: format!("Failed to read from `{}`: {}", BATTERY_CHARGE_DESIGN_PATH, e),
|
||||
msg: format!(
|
||||
"Failed to read from `{}`: {}",
|
||||
BATTERY_CHARGE_DESIGN_PATH, e
|
||||
),
|
||||
setting: crate::settings::SettingVariant::Battery,
|
||||
}),
|
||||
// convert to Wh
|
||||
|
@ -321,14 +358,18 @@ impl Battery {
|
|||
setting: crate::settings::SettingVariant::Battery,
|
||||
}),
|
||||
// convert to V (from mV)
|
||||
Ok(val) => Ok((val as f64)/1000.0),
|
||||
Ok(val) => Ok((val as f64) / 1000.0),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn system_default() -> Self {
|
||||
let (oc_limits, is_default) = OverclockLimits::load_or_default();
|
||||
let oc_limits = oc_limits.battery;
|
||||
let driver = if is_default { crate::persist::DriverJson::SteamDeck } else { crate::persist::DriverJson::SteamDeckAdvance };
|
||||
let driver = if is_default {
|
||||
crate::persist::DriverJson::SteamDeck
|
||||
} else {
|
||||
crate::persist::DriverJson::SteamDeckAdvance
|
||||
};
|
||||
Self {
|
||||
charge_rate: None,
|
||||
charge_mode: None,
|
||||
|
@ -346,8 +387,8 @@ impl Battery {
|
|||
if event.charge_mode.is_some() {
|
||||
return Some(i);
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
None
|
||||
|
@ -360,8 +401,8 @@ impl Battery {
|
|||
if event.charge_mode.is_some() {
|
||||
return Some(i);
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
None
|
||||
|
@ -374,7 +415,7 @@ impl Into<BatteryJson> for Battery {
|
|||
BatteryJson {
|
||||
charge_rate: self.charge_rate,
|
||||
charge_mode: self.charge_mode.map(Self::charge_mode_to_str),
|
||||
events: self.events.into_iter().map(|x| x.into()).collect()
|
||||
events: self.events.into_iter().map(|x| x.into()).collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -398,20 +439,24 @@ impl OnPowerEvent for Battery {
|
|||
match new_mode {
|
||||
PowerMode::PluggedIn => {
|
||||
// plug event resets battery settings
|
||||
self.events.iter_mut().for_each(|ev| ev.is_triggered = false);
|
||||
self.set_charge_mode()
|
||||
.map_err(|e| vec![e])
|
||||
},
|
||||
self.events
|
||||
.iter_mut()
|
||||
.for_each(|ev| ev.is_triggered = false);
|
||||
self.set_charge_mode().map_err(|e| vec![e])
|
||||
}
|
||||
PowerMode::PluggedOut => {
|
||||
// plug event resets battery settings
|
||||
self.events.iter_mut().for_each(|ev| ev.is_triggered = false);
|
||||
self.set_charge_mode()
|
||||
.map_err(|e| vec![e])
|
||||
},
|
||||
PowerMode::BatteryCharge(_) => Ok(())
|
||||
}.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
self.events
|
||||
.iter_mut()
|
||||
.for_each(|ev| ev.is_triggered = false);
|
||||
self.set_charge_mode().map_err(|e| vec![e])
|
||||
}
|
||||
PowerMode::BatteryCharge(_) => Ok(()),
|
||||
}
|
||||
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
for ev in &mut self.events {
|
||||
ev.on_power_event(new_mode).unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
ev.on_power_event(new_mode)
|
||||
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
}
|
||||
if errors.is_empty() {
|
||||
Ok(())
|
||||
|
@ -424,12 +469,16 @@ impl OnPowerEvent for Battery {
|
|||
impl TBattery for Battery {
|
||||
fn limits(&self) -> crate::api::BatteryLimits {
|
||||
crate::api::BatteryLimits {
|
||||
charge_current: Some(RangeLimit{
|
||||
charge_current: Some(RangeLimit {
|
||||
min: self.limits.charge_rate.min,
|
||||
max: self.limits.charge_rate.max
|
||||
max: self.limits.charge_rate.max,
|
||||
}),
|
||||
charge_current_step: 50,
|
||||
charge_modes: vec!["normal".to_owned(), "discharge".to_owned(), "idle".to_owned()],
|
||||
charge_modes: vec![
|
||||
"normal".to_owned(),
|
||||
"discharge".to_owned(),
|
||||
"idle".to_owned(),
|
||||
],
|
||||
charge_limit: Some(RangeLimit {
|
||||
min: 10.0,
|
||||
max: 90.0,
|
||||
|
@ -503,9 +552,12 @@ impl TBattery for Battery {
|
|||
let index = self.find_limit_event();
|
||||
if let Some(index) = index {
|
||||
if let Some(limit) = limit {
|
||||
log::info!("Updating Steam Deck charge limit event instruction to >{}", limit);
|
||||
log::info!(
|
||||
"Updating Steam Deck charge limit event instruction to >{}",
|
||||
limit
|
||||
);
|
||||
self.events[index] = EventInstruction {
|
||||
trigger: EventTrigger::BatteryAbove(limit/100.0),
|
||||
trigger: EventTrigger::BatteryAbove(limit / 100.0),
|
||||
charge_rate: None,
|
||||
charge_mode: Some(ChargeMode::Idle),
|
||||
is_triggered: false,
|
||||
|
@ -514,24 +566,28 @@ impl TBattery for Battery {
|
|||
self.events.remove(index);
|
||||
}
|
||||
} else if let Some(limit) = limit {
|
||||
log::info!("Creating Steam Deck charge limit event instruction of >{}", limit);
|
||||
self.events.push(
|
||||
EventInstruction {
|
||||
trigger: EventTrigger::BatteryAbove(limit/100.0),
|
||||
charge_rate: None,
|
||||
charge_mode: Some(ChargeMode::Idle),
|
||||
is_triggered: false,
|
||||
}
|
||||
log::info!(
|
||||
"Creating Steam Deck charge limit event instruction of >{}",
|
||||
limit
|
||||
);
|
||||
self.events.push(EventInstruction {
|
||||
trigger: EventTrigger::BatteryAbove(limit / 100.0),
|
||||
charge_rate: None,
|
||||
charge_mode: Some(ChargeMode::Idle),
|
||||
is_triggered: false,
|
||||
});
|
||||
}
|
||||
// lower limit
|
||||
let index = self.find_unlimit_event();
|
||||
if let Some(index) = index {
|
||||
if let Some(limit) = limit {
|
||||
let limit = (limit - 10.0).clamp(0.0, 100.0);
|
||||
log::info!("Updating Steam Deck charge limit event instruction to <{}", limit);
|
||||
log::info!(
|
||||
"Updating Steam Deck charge limit event instruction to <{}",
|
||||
limit
|
||||
);
|
||||
self.events[index] = EventInstruction {
|
||||
trigger: EventTrigger::BatteryBelow(limit/100.0),
|
||||
trigger: EventTrigger::BatteryBelow(limit / 100.0),
|
||||
charge_rate: None,
|
||||
charge_mode: Some(ChargeMode::Normal),
|
||||
is_triggered: false,
|
||||
|
@ -541,15 +597,16 @@ impl TBattery for Battery {
|
|||
}
|
||||
} else if let Some(limit) = limit {
|
||||
let limit = (limit - 10.0).clamp(0.0, 100.0);
|
||||
log::info!("Creating Steam Deck charge limit event instruction of <{}", limit);
|
||||
self.events.push(
|
||||
EventInstruction {
|
||||
trigger: EventTrigger::BatteryBelow(limit/100.0),
|
||||
charge_rate: None,
|
||||
charge_mode: Some(ChargeMode::Normal),
|
||||
is_triggered: false,
|
||||
}
|
||||
log::info!(
|
||||
"Creating Steam Deck charge limit event instruction of <{}",
|
||||
limit
|
||||
);
|
||||
self.events.push(EventInstruction {
|
||||
trigger: EventTrigger::BatteryBelow(limit / 100.0),
|
||||
charge_rate: None,
|
||||
charge_mode: Some(ChargeMode::Normal),
|
||||
is_triggered: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -572,24 +629,28 @@ impl TBattery for Battery {
|
|||
let mut errors = Vec::new();
|
||||
let mut events = Vec::new();
|
||||
match (Self::read_charge_full(), Self::read_charge_now()) {
|
||||
(Ok(full), Ok(now)) => events.push(PowerMode::BatteryCharge(now/full)),
|
||||
(Ok(full), Ok(now)) => events.push(PowerMode::BatteryCharge(now / full)),
|
||||
(Err(e1), Err(e2)) => {
|
||||
errors.push(e1);
|
||||
errors.push(e2);
|
||||
},
|
||||
}
|
||||
(Err(e), _) => errors.push(e),
|
||||
(_, Err(e)) => errors.push(e),
|
||||
}
|
||||
match Self::read_usb_voltage() {
|
||||
Ok(voltage) => {
|
||||
if voltage > 0.0 && self.state.charger_state != crate::state::steam_deck::ChargeState::PluggedIn {
|
||||
if voltage > 0.0
|
||||
&& self.state.charger_state != crate::state::steam_deck::ChargeState::PluggedIn
|
||||
{
|
||||
events.push(PowerMode::PluggedIn);
|
||||
self.state.charger_state = crate::state::steam_deck::ChargeState::PluggedIn;
|
||||
} else if voltage == 0.0 && self.state.charger_state != crate::state::steam_deck::ChargeState::Unplugged {
|
||||
} else if voltage == 0.0
|
||||
&& self.state.charger_state != crate::state::steam_deck::ChargeState::Unplugged
|
||||
{
|
||||
events.push(PowerMode::PluggedOut);
|
||||
self.state.charger_state = crate::state::steam_deck::ChargeState::Unplugged;
|
||||
}
|
||||
},
|
||||
}
|
||||
Err(e) => errors.push(e),
|
||||
}
|
||||
if errors.is_empty() {
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
use std::convert::Into;
|
||||
|
||||
use crate::api::RangeLimit;
|
||||
use crate::settings::{MinMax, min_max_from_json};
|
||||
use crate::settings::{OnResume, OnSet, SettingError};
|
||||
use crate::settings::{TCpus, TCpu};
|
||||
use crate::persist::CpuJson;
|
||||
use super::oc_limits::{OverclockLimits, CpusLimits, CpuLimits};
|
||||
use super::oc_limits::{CpuLimits, CpusLimits, OverclockLimits};
|
||||
use super::POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT;
|
||||
use crate::api::RangeLimit;
|
||||
use crate::persist::CpuJson;
|
||||
use crate::settings::{min_max_from_json, MinMax};
|
||||
use crate::settings::{OnResume, OnSet, SettingError};
|
||||
use crate::settings::{TCpu, TCpus};
|
||||
|
||||
const CPU_PRESENT_PATH: &str = "/sys/devices/system/cpu/present";
|
||||
const CPU_SMT_PATH: &str = "/sys/devices/system/cpu/smt/control";
|
||||
|
@ -26,25 +26,19 @@ impl OnSet for Cpus {
|
|||
if self.smt_capable {
|
||||
// toggle SMT
|
||||
if self.smt {
|
||||
usdpl_back::api::files::write_single(CPU_SMT_PATH, "on").map_err(|e| {
|
||||
SettingError {
|
||||
msg: format!(
|
||||
"Failed to write `on` to `{}`: {}",
|
||||
CPU_SMT_PATH, e
|
||||
),
|
||||
usdpl_back::api::files::write_single(CPU_SMT_PATH, "on")
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!("Failed to write `on` to `{}`: {}", CPU_SMT_PATH, e),
|
||||
setting: crate::settings::SettingVariant::Cpu,
|
||||
}
|
||||
}).unwrap_or_else(|e| errors.push(e));
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
} else {
|
||||
usdpl_back::api::files::write_single(CPU_SMT_PATH, "off").map_err(|e| {
|
||||
SettingError {
|
||||
msg: format!(
|
||||
"Failed to write `off` to `{}`: {}",
|
||||
CPU_SMT_PATH, e
|
||||
),
|
||||
usdpl_back::api::files::write_single(CPU_SMT_PATH, "off")
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!("Failed to write `off` to `{}`: {}", CPU_SMT_PATH, e),
|
||||
setting: crate::settings::SettingVariant::Cpu,
|
||||
}
|
||||
}).unwrap_or_else(|e| errors.push(e));
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
}
|
||||
}
|
||||
for (i, cpu) in self.cpus.as_mut_slice().iter_mut().enumerate() {
|
||||
|
@ -63,7 +57,8 @@ impl OnResume for Cpus {
|
|||
fn on_resume(&self) -> Result<(), Vec<SettingError>> {
|
||||
let mut errors = Vec::new();
|
||||
for cpu in &self.cpus {
|
||||
cpu.on_resume().unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
cpu.on_resume()
|
||||
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
}
|
||||
if errors.is_empty() {
|
||||
Ok(())
|
||||
|
@ -90,7 +85,7 @@ impl Cpus {
|
|||
fn system_smt_capabilities() -> (bool, bool) {
|
||||
match usdpl_back::api::files::read_single::<_, String, _>(CPU_SMT_PATH) {
|
||||
Ok(val) => (val.trim().to_lowercase() == "on", true),
|
||||
Err(_) => (false, false)
|
||||
Err(_) => (false, false),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -98,11 +93,22 @@ impl Cpus {
|
|||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.reset();
|
||||
let (oc_limits, is_default) = OverclockLimits::load_or_default();
|
||||
let oc_limits = oc_limits.cpus;
|
||||
let driver = if is_default { crate::persist::DriverJson::SteamDeck } else { crate::persist::DriverJson::SteamDeckAdvance };
|
||||
let driver = if is_default {
|
||||
crate::persist::DriverJson::SteamDeck
|
||||
} else {
|
||||
crate::persist::DriverJson::SteamDeckAdvance
|
||||
};
|
||||
if let Some(max_cpu) = Self::cpu_count() {
|
||||
let mut sys_cpus = Vec::with_capacity(max_cpu);
|
||||
for i in 0..max_cpu {
|
||||
sys_cpus.push(Cpu::system_default(i, oc_limits.cpus.get(i).map(|x| x.to_owned()).unwrap_or_default()));
|
||||
sys_cpus.push(Cpu::system_default(
|
||||
i,
|
||||
oc_limits
|
||||
.cpus
|
||||
.get(i)
|
||||
.map(|x| x.to_owned())
|
||||
.unwrap_or_default(),
|
||||
));
|
||||
}
|
||||
let (_, can_smt) = Self::system_smt_capabilities();
|
||||
Self {
|
||||
|
@ -128,7 +134,11 @@ impl Cpus {
|
|||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.reset();
|
||||
let (oc_limits, is_default) = OverclockLimits::load_or_default();
|
||||
let oc_limits = oc_limits.cpus;
|
||||
let driver = if is_default { crate::persist::DriverJson::SteamDeck } else { crate::persist::DriverJson::SteamDeckAdvance };
|
||||
let driver = if is_default {
|
||||
crate::persist::DriverJson::SteamDeck
|
||||
} else {
|
||||
crate::persist::DriverJson::SteamDeckAdvance
|
||||
};
|
||||
let (_, can_smt) = Self::system_smt_capabilities();
|
||||
let mut result = Vec::with_capacity(other.len());
|
||||
let max_cpus = Self::cpu_count();
|
||||
|
@ -140,7 +150,16 @@ impl Cpus {
|
|||
break;
|
||||
}
|
||||
}
|
||||
let new_cpu = Cpu::from_json(cpu, version, i, oc_limits.cpus.get(i).map(|x| x.to_owned()).unwrap_or_default());
|
||||
let new_cpu = Cpu::from_json(
|
||||
cpu,
|
||||
version,
|
||||
i,
|
||||
oc_limits
|
||||
.cpus
|
||||
.get(i)
|
||||
.map(|x| x.to_owned())
|
||||
.unwrap_or_default(),
|
||||
);
|
||||
result.push(new_cpu);
|
||||
}
|
||||
if let Some(max_cpus) = max_cpus {
|
||||
|
@ -170,11 +189,14 @@ impl TCpus for Cpus {
|
|||
count: self.cpus.len(),
|
||||
smt_capable: self.smt_capable,
|
||||
governors: if self.limits.global_governors {
|
||||
self.cpus.iter()
|
||||
self.cpus
|
||||
.iter()
|
||||
.next()
|
||||
.map(|x| x.governors())
|
||||
.unwrap_or_else(|| Vec::with_capacity(0))
|
||||
} else { Vec::with_capacity(0) },
|
||||
} else {
|
||||
Vec::with_capacity(0)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -244,41 +266,52 @@ impl Cpu {
|
|||
if let Some(clock_limits) = &self.clock_limits {
|
||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.set_cpu(true, self.index);
|
||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.enforce_level()?;
|
||||
log::debug!("Setting CPU {} (min, max) clockspeed to ({}, {})", self.index, clock_limits.min, clock_limits.max);
|
||||
log::debug!(
|
||||
"Setting CPU {} (min, max) clockspeed to ({}, {})",
|
||||
self.index,
|
||||
clock_limits.min,
|
||||
clock_limits.max
|
||||
);
|
||||
self.state.clock_limits_set = true;
|
||||
// max clock
|
||||
let payload_max = format!("p {} 1 {}\n", self.index / 2, clock_limits.max);
|
||||
usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, &payload_max).map_err(
|
||||
|e| SettingError {
|
||||
usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, &payload_max)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!(
|
||||
"Failed to write `{}` to `{}`: {}",
|
||||
&payload_max, CPU_CLOCK_LIMITS_PATH, e
|
||||
),
|
||||
setting: crate::settings::SettingVariant::Cpu,
|
||||
},
|
||||
).unwrap_or_else(|e| errors.push(e));
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
// min clock
|
||||
let valid_min = if clock_limits.min < self.limits.clock_min.min {self.limits.clock_min.min} else {clock_limits.min};
|
||||
let 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);
|
||||
usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, &payload_min).map_err(
|
||||
|e| SettingError {
|
||||
usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, &payload_min)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!(
|
||||
"Failed to write `{}` to `{}`: {}",
|
||||
&payload_min, CPU_CLOCK_LIMITS_PATH, e
|
||||
),
|
||||
setting: crate::settings::SettingVariant::Cpu,
|
||||
},
|
||||
).unwrap_or_else(|e| errors.push(e));
|
||||
usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, "c\n")
|
||||
.unwrap_or_else(|e| {
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, "c\n").unwrap_or_else(
|
||||
|e| {
|
||||
errors.push(SettingError {
|
||||
msg: format!("Failed to write `c` to `{}`: {}", CPU_CLOCK_LIMITS_PATH, e),
|
||||
setting: crate::settings::SettingVariant::Cpu,
|
||||
});
|
||||
});
|
||||
} else if self.state.clock_limits_set ||
|
||||
(self.state.is_resuming && !self.limits.skip_resume_reclock)
|
||||
|| POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.needs_manual() {
|
||||
},
|
||||
);
|
||||
} else if self.state.clock_limits_set
|
||||
|| (self.state.is_resuming && !self.limits.skip_resume_reclock)
|
||||
|| POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.needs_manual()
|
||||
{
|
||||
self.state.clock_limits_set = false;
|
||||
if POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.needs_manual() {
|
||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.enforce_level()?;
|
||||
|
@ -286,45 +319,51 @@ impl Cpu {
|
|||
log::debug!("Setting CPU {} to default clockspeed", self.index);
|
||||
// max clock
|
||||
let payload_max = format!("p {} 1 {}\n", self.index / 2, self.limits.clock_max.max);
|
||||
usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, &payload_max).map_err(
|
||||
|e| SettingError {
|
||||
usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, &payload_max)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!(
|
||||
"Failed to write `{}` to `{}`: {}",
|
||||
&payload_max, CPU_CLOCK_LIMITS_PATH, e
|
||||
),
|
||||
setting: crate::settings::SettingVariant::Cpu,
|
||||
},
|
||||
).unwrap_or_else(|e| errors.push(e));
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
// min clock
|
||||
let payload_min = format!("p {} 0 {}\n", self.index / 2, self.limits.clock_min.min);
|
||||
usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, &payload_min).map_err(
|
||||
|e| SettingError {
|
||||
usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, &payload_min)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!(
|
||||
"Failed to write `{}` to `{}`: {}",
|
||||
&payload_min, CPU_CLOCK_LIMITS_PATH, e
|
||||
),
|
||||
setting: crate::settings::SettingVariant::Cpu,
|
||||
},
|
||||
).unwrap_or_else(|e| errors.push(e));
|
||||
usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, "c\n")
|
||||
.unwrap_or_else(|e| {
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
usdpl_back::api::files::write_single(CPU_CLOCK_LIMITS_PATH, "c\n").unwrap_or_else(
|
||||
|e| {
|
||||
errors.push(SettingError {
|
||||
msg: format!("Failed to write `c` to `{}`: {}", CPU_CLOCK_LIMITS_PATH, e),
|
||||
msg: format!(
|
||||
"Failed to write `c` to `{}`: {}",
|
||||
CPU_CLOCK_LIMITS_PATH, e
|
||||
),
|
||||
setting: crate::settings::SettingVariant::Cpu,
|
||||
});
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.set_cpu(false, self.index);
|
||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.enforce_level().unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT
|
||||
.enforce_level()
|
||||
.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(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,
|
||||
}]
|
||||
})
|
||||
vec![SettingError {
|
||||
msg: format!("Failed to write `c` to `{}`: {}", CPU_CLOCK_LIMITS_PATH, e),
|
||||
setting: crate::settings::SettingVariant::Cpu,
|
||||
}]
|
||||
})
|
||||
} else {
|
||||
Err(errors)
|
||||
}
|
||||
|
@ -333,14 +372,15 @@ impl Cpu {
|
|||
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
|
||||
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 {
|
||||
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));
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
}
|
||||
|
||||
self.set_force_performance_related()
|
||||
|
@ -349,15 +389,15 @@ impl Cpu {
|
|||
// set governor
|
||||
if self.index == 0 || self.online {
|
||||
let governor_path = cpu_governor_path(self.index);
|
||||
usdpl_back::api::files::write_single(&governor_path, &self.governor).map_err(|e| {
|
||||
SettingError {
|
||||
usdpl_back::api::files::write_single(&governor_path, &self.governor)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!(
|
||||
"Failed to write `{}` to `{}`: {}",
|
||||
&self.governor, &governor_path, e
|
||||
),
|
||||
setting: crate::settings::SettingVariant::Cpu,
|
||||
}
|
||||
}).unwrap_or_else(|e| errors.push(e));
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
}
|
||||
if errors.is_empty() {
|
||||
Ok(())
|
||||
|
@ -368,8 +408,12 @@ impl Cpu {
|
|||
|
||||
fn clamp_all(&mut self) {
|
||||
if let Some(clock_limits) = &mut self.clock_limits {
|
||||
clock_limits.min = clock_limits.min.clamp(self.limits.clock_min.min, self.limits.clock_min.max);
|
||||
clock_limits.max = clock_limits.max.clamp(self.limits.clock_max.min, self.limits.clock_max.max);
|
||||
clock_limits.min = clock_limits
|
||||
.min
|
||||
.clamp(self.limits.clock_min.min, self.limits.clock_min.max);
|
||||
clock_limits.max = clock_limits
|
||||
.max
|
||||
.clamp(self.limits.clock_max.min, self.limits.clock_max.max);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -400,11 +444,11 @@ impl Cpu {
|
|||
crate::api::CpuLimits {
|
||||
clock_min_limits: Some(RangeLimit {
|
||||
min: self.limits.clock_max.min, // allows min to be set by max (it's weird, blame the kernel)
|
||||
max: self.limits.clock_min.max
|
||||
max: self.limits.clock_min.max,
|
||||
}),
|
||||
clock_max_limits: Some(RangeLimit {
|
||||
min: self.limits.clock_max.min,
|
||||
max: self.limits.clock_max.max
|
||||
max: self.limits.clock_max.max,
|
||||
}),
|
||||
clock_step: self.limits.clock_step,
|
||||
governors: self.governors(),
|
||||
|
@ -413,13 +457,14 @@ impl Cpu {
|
|||
|
||||
fn governors(&self) -> Vec<String> {
|
||||
// NOTE: this eats errors
|
||||
let gov_str: String = match usdpl_back::api::files::read_single(cpu_available_governors_path(self.index)) {
|
||||
Ok(s) => s,
|
||||
Err(e) => {
|
||||
log::warn!("Error getting available CPU governors: {}", e);
|
||||
return vec![];
|
||||
}
|
||||
};
|
||||
let gov_str: String =
|
||||
match usdpl_back::api::files::read_single(cpu_available_governors_path(self.index)) {
|
||||
Ok(s) => s,
|
||||
Err(e) => {
|
||||
log::warn!("Error getting available CPU governors: {}", e);
|
||||
return vec![];
|
||||
}
|
||||
};
|
||||
gov_str.split(' ').map(|s| s.to_owned()).collect()
|
||||
}
|
||||
}
|
||||
|
@ -485,7 +530,6 @@ fn cpu_governor_path(index: usize) -> String {
|
|||
)
|
||||
}
|
||||
|
||||
|
||||
#[inline]
|
||||
fn cpu_available_governors_path(index: usize) -> String {
|
||||
format!(
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
use std::convert::Into;
|
||||
|
||||
use crate::api::RangeLimit;
|
||||
use crate::settings::{MinMax, min_max_from_json};
|
||||
use crate::settings::{OnResume, OnSet, SettingError};
|
||||
use crate::settings::TGpu;
|
||||
use crate::persist::GpuJson;
|
||||
use super::oc_limits::{OverclockLimits, GpuLimits};
|
||||
use super::oc_limits::{GpuLimits, OverclockLimits};
|
||||
use super::POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT;
|
||||
use crate::api::RangeLimit;
|
||||
use crate::persist::GpuJson;
|
||||
use crate::settings::TGpu;
|
||||
use crate::settings::{min_max_from_json, MinMax};
|
||||
use crate::settings::{OnResume, OnSet, SettingError};
|
||||
|
||||
const SLOW_PPT: u8 = 1;
|
||||
const FAST_PPT: u8 = 2;
|
||||
|
@ -30,7 +30,11 @@ impl Gpu {
|
|||
#[inline]
|
||||
pub fn from_json(other: GpuJson, version: u64) -> Self {
|
||||
let (oc_limits, is_default) = OverclockLimits::load_or_default();
|
||||
let driver = if is_default { crate::persist::DriverJson::SteamDeck } else { crate::persist::DriverJson::SteamDeckAdvance };
|
||||
let driver = if is_default {
|
||||
crate::persist::DriverJson::SteamDeck
|
||||
} else {
|
||||
crate::persist::DriverJson::SteamDeckAdvance
|
||||
};
|
||||
match version {
|
||||
0 => Self {
|
||||
fast_ppt: other.fast_ppt,
|
||||
|
@ -62,70 +66,80 @@ impl Gpu {
|
|||
self.state.clock_limits_set = true;
|
||||
// max clock
|
||||
let payload_max = format!("s 1 {}\n", clock_limits.max);
|
||||
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, &payload_max).map_err(
|
||||
|e| SettingError {
|
||||
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, &payload_max)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!(
|
||||
"Failed to write `{}` to `{}`: {}",
|
||||
&payload_max, GPU_CLOCK_LIMITS_PATH, e
|
||||
),
|
||||
setting: crate::settings::SettingVariant::Gpu,
|
||||
},
|
||||
).unwrap_or_else(|e| errors.push(e));
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
// min clock
|
||||
let payload_min = format!("s 0 {}\n", clock_limits.min);
|
||||
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, &payload_min).map_err(
|
||||
|e| SettingError {
|
||||
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, &payload_min)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!(
|
||||
"Failed to write `{}` to `{}`: {}",
|
||||
&payload_min, GPU_CLOCK_LIMITS_PATH, e
|
||||
),
|
||||
setting: crate::settings::SettingVariant::Gpu,
|
||||
},
|
||||
).unwrap_or_else(|e| errors.push(e));
|
||||
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, "c\n").unwrap_or_else(|e| {
|
||||
errors.push(SettingError {
|
||||
msg: format!("Failed to write `c` to `{}`: {}", GPU_CLOCK_LIMITS_PATH, e),
|
||||
setting: crate::settings::SettingVariant::Gpu,
|
||||
})
|
||||
});
|
||||
} else if self.state.clock_limits_set ||
|
||||
(self.state.is_resuming && !self.limits.skip_resume_reclock)
|
||||
|| POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.needs_manual() {
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, "c\n").unwrap_or_else(
|
||||
|e| {
|
||||
errors.push(SettingError {
|
||||
msg: format!("Failed to write `c` to `{}`: {}", GPU_CLOCK_LIMITS_PATH, e),
|
||||
setting: crate::settings::SettingVariant::Gpu,
|
||||
})
|
||||
},
|
||||
);
|
||||
} else if self.state.clock_limits_set
|
||||
|| (self.state.is_resuming && !self.limits.skip_resume_reclock)
|
||||
|| POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.needs_manual()
|
||||
{
|
||||
self.state.clock_limits_set = false;
|
||||
if POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.needs_manual() {
|
||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.enforce_level()?;
|
||||
// disable manual clock limits
|
||||
// max clock
|
||||
let payload_max = format!("s 1 {}\n", self.limits.clock_max.max);
|
||||
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, &payload_max).map_err(
|
||||
|e| SettingError {
|
||||
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, &payload_max)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!(
|
||||
"Failed to write `{}` to `{}`: {}",
|
||||
&payload_max, GPU_CLOCK_LIMITS_PATH, e
|
||||
),
|
||||
setting: crate::settings::SettingVariant::Gpu,
|
||||
},
|
||||
).unwrap_or_else(|e| errors.push(e));
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
// min clock
|
||||
let payload_min = format!("s 0 {}\n", self.limits.clock_min.min);
|
||||
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, &payload_min).map_err(
|
||||
|e| SettingError {
|
||||
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, &payload_min)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!(
|
||||
"Failed to write `{}` to `{}`: {}",
|
||||
&payload_min, GPU_CLOCK_LIMITS_PATH, e
|
||||
),
|
||||
setting: crate::settings::SettingVariant::Gpu,
|
||||
},
|
||||
).unwrap_or_else(|e| errors.push(e));
|
||||
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, "c\n").unwrap_or_else(|e| {
|
||||
errors.push(SettingError {
|
||||
msg: format!("Failed to write `c` to `{}`: {}", GPU_CLOCK_LIMITS_PATH, e),
|
||||
setting: crate::settings::SettingVariant::Gpu,
|
||||
})
|
||||
});
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
usdpl_back::api::files::write_single(GPU_CLOCK_LIMITS_PATH, "c\n").unwrap_or_else(
|
||||
|e| {
|
||||
errors.push(SettingError {
|
||||
msg: format!(
|
||||
"Failed to write `c` to `{}`: {}",
|
||||
GPU_CLOCK_LIMITS_PATH, e
|
||||
),
|
||||
setting: crate::settings::SettingVariant::Gpu,
|
||||
})
|
||||
},
|
||||
);
|
||||
}
|
||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.set_gpu(self.slow_memory);
|
||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.enforce_level().unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT
|
||||
.enforce_level()
|
||||
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
}
|
||||
if errors.is_empty() {
|
||||
Ok(())
|
||||
|
@ -139,24 +153,28 @@ impl Gpu {
|
|||
// enable/disable downclock of GPU memory (to 400Mhz?)
|
||||
if self.slow_memory {
|
||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.set_gpu(true);
|
||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.enforce_level().unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT
|
||||
.enforce_level()
|
||||
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
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,
|
||||
.unwrap_or_else(|e| {
|
||||
errors.push(SettingError {
|
||||
msg: format!("Failed to write to `{}`: {}", GPU_MEMORY_DOWNCLOCK_PATH, e),
|
||||
setting: crate::settings::SettingVariant::Gpu,
|
||||
});
|
||||
});
|
||||
});
|
||||
} else if POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.needs_manual() {
|
||||
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,
|
||||
.unwrap_or_else(|e| {
|
||||
errors.push(SettingError {
|
||||
msg: format!("Failed to write to `{}`: {}", GPU_MEMORY_DOWNCLOCK_PATH, e),
|
||||
setting: crate::settings::SettingVariant::Gpu,
|
||||
});
|
||||
});
|
||||
});
|
||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.set_gpu(self.clock_limits.is_some());
|
||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT.enforce_level().unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT
|
||||
.enforce_level()
|
||||
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
}
|
||||
self.set_clocks()
|
||||
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
|
@ -182,28 +200,32 @@ impl Gpu {
|
|||
// 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 {
|
||||
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);});
|
||||
})
|
||||
.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 {
|
||||
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);});
|
||||
})
|
||||
.unwrap_or_else(|e| {
|
||||
errors.push(e);
|
||||
});
|
||||
}
|
||||
self.set_force_performance_related()
|
||||
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
|
@ -216,20 +238,18 @@ impl Gpu {
|
|||
|
||||
fn clamp_all(&mut self) {
|
||||
if let Some(fast_ppt) = &mut self.fast_ppt {
|
||||
*fast_ppt = (*fast_ppt).clamp(
|
||||
self.limits.fast_ppt.min,
|
||||
self.limits.fast_ppt.max,
|
||||
);
|
||||
*fast_ppt = (*fast_ppt).clamp(self.limits.fast_ppt.min, self.limits.fast_ppt.max);
|
||||
}
|
||||
if let Some(slow_ppt) = &mut self.slow_ppt {
|
||||
*slow_ppt = (*slow_ppt).clamp(
|
||||
self.limits.slow_ppt.min,
|
||||
self.limits.slow_ppt.max,
|
||||
);
|
||||
*slow_ppt = (*slow_ppt).clamp(self.limits.slow_ppt.min, self.limits.slow_ppt.max);
|
||||
}
|
||||
if let Some(clock_limits) = &mut self.clock_limits {
|
||||
clock_limits.min = clock_limits.min.clamp(self.limits.clock_min.min, self.limits.clock_min.max);
|
||||
clock_limits.max = clock_limits.max.clamp(self.limits.clock_max.min, self.limits.clock_max.max);
|
||||
clock_limits.min = clock_limits
|
||||
.min
|
||||
.clamp(self.limits.clock_min.min, self.limits.clock_min.max);
|
||||
clock_limits.max = clock_limits
|
||||
.max
|
||||
.clamp(self.limits.clock_max.min, self.limits.clock_max.max);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -242,7 +262,11 @@ impl Gpu {
|
|||
slow_memory: false,
|
||||
limits: oc_limits.gpu,
|
||||
state: crate::state::steam_deck::Gpu::default(),
|
||||
driver_mode: if is_default { crate::persist::DriverJson::SteamDeck } else { crate::persist::DriverJson::SteamDeckAdvance },
|
||||
driver_mode: if is_default {
|
||||
crate::persist::DriverJson::SteamDeck
|
||||
} else {
|
||||
crate::persist::DriverJson::SteamDeckAdvance
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -314,7 +338,10 @@ impl TGpu for Gpu {
|
|||
}
|
||||
|
||||
fn get_ppt(&self) -> (Option<u64>, Option<u64>) {
|
||||
(self.fast_ppt.map(|x| x / self.limits.ppt_divisor), self.slow_ppt.map(|x| x / self.limits.ppt_divisor))
|
||||
(
|
||||
self.fast_ppt.map(|x| x / self.limits.ppt_divisor),
|
||||
self.slow_ppt.map(|x| x / self.limits.ppt_divisor),
|
||||
)
|
||||
}
|
||||
|
||||
fn clock_limits(&mut self, limits: Option<MinMax<u64>>) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
use crate::settings::MinMax;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
const OC_LIMITS_FILEPATH: &str = "pt_oc.json";
|
||||
|
||||
|
@ -29,22 +29,36 @@ impl OverclockLimits {
|
|||
let mut file = match std::fs::File::open(&path) {
|
||||
Ok(f) => f,
|
||||
Err(e) => {
|
||||
log::warn!("Steam Deck limits file {} err: {} (using default fallback)", path.display(), e);
|
||||
log::warn!(
|
||||
"Steam Deck limits file {} err: {} (using default fallback)",
|
||||
path.display(),
|
||||
e
|
||||
);
|
||||
return (Self::default(), true);
|
||||
},
|
||||
}
|
||||
};
|
||||
match serde_json::from_reader(&mut file) {
|
||||
Ok(result) => {
|
||||
log::debug!("Steam Deck limits file {} successfully loaded", path.display());
|
||||
log::debug!(
|
||||
"Steam Deck limits file {} successfully loaded",
|
||||
path.display()
|
||||
);
|
||||
(result, false)
|
||||
},
|
||||
}
|
||||
Err(e) => {
|
||||
log::warn!("Steam Deck limits file {} json err: {} (using default fallback)", path.display(), e);
|
||||
log::warn!(
|
||||
"Steam Deck limits file {} json err: {} (using default fallback)",
|
||||
path.display(),
|
||||
e
|
||||
);
|
||||
(Self::default(), true)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log::info!("Steam Deck limits file {} not found (using default fallback)", path.display());
|
||||
log::info!(
|
||||
"Steam Deck limits file {} not found (using default fallback)",
|
||||
path.display()
|
||||
);
|
||||
(Self::default(), true)
|
||||
}
|
||||
}
|
||||
|
@ -58,7 +72,10 @@ pub(super) struct BatteryLimits {
|
|||
impl Default for BatteryLimits {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
charge_rate: MinMax { min: 250, max: 2500 },
|
||||
charge_rate: MinMax {
|
||||
min: 250,
|
||||
max: 2500,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -89,8 +106,14 @@ pub(super) struct CpuLimits {
|
|||
impl Default for CpuLimits {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
clock_min: MinMax { min: 1400, max: 3500 },
|
||||
clock_max: MinMax { min: 400, max: 3500 },
|
||||
clock_min: MinMax {
|
||||
min: 1400,
|
||||
max: 3500,
|
||||
},
|
||||
clock_max: MinMax {
|
||||
min: 400,
|
||||
max: 3500,
|
||||
},
|
||||
clock_step: 100,
|
||||
skip_resume_reclock: false,
|
||||
}
|
||||
|
@ -112,12 +135,24 @@ pub(super) struct GpuLimits {
|
|||
impl Default for GpuLimits {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
fast_ppt: MinMax { min: 1000000, max: 30_000_000 },
|
||||
slow_ppt: MinMax { min: 1000000, max: 29_000_000 },
|
||||
fast_ppt: MinMax {
|
||||
min: 1000000,
|
||||
max: 30_000_000,
|
||||
},
|
||||
slow_ppt: MinMax {
|
||||
min: 1000000,
|
||||
max: 29_000_000,
|
||||
},
|
||||
ppt_divisor: 1_000_000,
|
||||
ppt_step: 1,
|
||||
clock_min: MinMax { min: 400, max: 1600 },
|
||||
clock_max: MinMax { min: 400, max: 1600 },
|
||||
clock_min: MinMax {
|
||||
min: 400,
|
||||
max: 1600,
|
||||
},
|
||||
clock_max: MinMax {
|
||||
min: 400,
|
||||
max: 1600,
|
||||
},
|
||||
clock_step: 100,
|
||||
skip_resume_reclock: false,
|
||||
}
|
||||
|
|
|
@ -10,7 +10,8 @@ use crate::settings::SettingError;
|
|||
const DEFAULT_BITS: u64 = 0;
|
||||
|
||||
/// Global usage tracker for the sysfs file by the same name
|
||||
pub static POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT: PDFPLManager = PDFPLManager(AtomicU64::new(DEFAULT_BITS));
|
||||
pub static POWER_DPM_FORCE_PERFORMANCE_LEVEL_MGMT: PDFPLManager =
|
||||
PDFPLManager(AtomicU64::new(DEFAULT_BITS));
|
||||
|
||||
pub struct PDFPLManager(AtomicU64);
|
||||
|
||||
|
@ -58,41 +59,45 @@ impl PDFPLManager {
|
|||
pub fn enforce_level(&self) -> Result<(), Vec<SettingError>> {
|
||||
let needs = self.needs_manual();
|
||||
let mut errors = Vec::new();
|
||||
let mode: String = usdpl_back::api::files::read_single(DPM_FORCE_LIMITS_PATH.to_owned()).map_err(|e| {
|
||||
vec![SettingError {
|
||||
msg: format!(
|
||||
"Failed to read `{}`: {}",
|
||||
DPM_FORCE_LIMITS_PATH, e
|
||||
),
|
||||
setting: crate::settings::SettingVariant::General,
|
||||
}]
|
||||
})?;
|
||||
let mode: String = usdpl_back::api::files::read_single(DPM_FORCE_LIMITS_PATH.to_owned())
|
||||
.map_err(|e| {
|
||||
vec![SettingError {
|
||||
msg: format!("Failed to read `{}`: {}", DPM_FORCE_LIMITS_PATH, e),
|
||||
setting: crate::settings::SettingVariant::General,
|
||||
}]
|
||||
})?;
|
||||
if mode != "manual" && needs {
|
||||
log::info!("Setting `{}` to manual", DPM_FORCE_LIMITS_PATH);
|
||||
// set manual control
|
||||
usdpl_back::api::files::write_single(DPM_FORCE_LIMITS_PATH, "manual").map_err(|e| {
|
||||
errors.push(SettingError {
|
||||
msg: format!(
|
||||
"Failed to write `manual` to `{}`: {}",
|
||||
DPM_FORCE_LIMITS_PATH, e
|
||||
),
|
||||
setting: crate::settings::SettingVariant::General,
|
||||
usdpl_back::api::files::write_single(DPM_FORCE_LIMITS_PATH, "manual")
|
||||
.map_err(|e| {
|
||||
errors.push(SettingError {
|
||||
msg: format!(
|
||||
"Failed to write `manual` to `{}`: {}",
|
||||
DPM_FORCE_LIMITS_PATH, e
|
||||
),
|
||||
setting: crate::settings::SettingVariant::General,
|
||||
})
|
||||
})
|
||||
}).unwrap_or(());
|
||||
.unwrap_or(());
|
||||
} else if mode != "auto" && !needs {
|
||||
log::info!("Setting `{}` to auto", DPM_FORCE_LIMITS_PATH);
|
||||
// unset manual control
|
||||
usdpl_back::api::files::write_single(DPM_FORCE_LIMITS_PATH, "auto").map_err(|e| {
|
||||
errors.push(SettingError {
|
||||
msg: format!(
|
||||
"Failed to write `auto` to `{}`: {}",
|
||||
DPM_FORCE_LIMITS_PATH, e
|
||||
),
|
||||
setting: crate::settings::SettingVariant::General,
|
||||
usdpl_back::api::files::write_single(DPM_FORCE_LIMITS_PATH, "auto")
|
||||
.map_err(|e| {
|
||||
errors.push(SettingError {
|
||||
msg: format!(
|
||||
"Failed to write `auto` to `{}`: {}",
|
||||
DPM_FORCE_LIMITS_PATH, e
|
||||
),
|
||||
setting: crate::settings::SettingVariant::General,
|
||||
})
|
||||
})
|
||||
}).unwrap_or(());
|
||||
.unwrap_or(());
|
||||
}
|
||||
if let Ok(mode_now) = usdpl_back::api::files::read_single::<_, String, _>(DPM_FORCE_LIMITS_PATH.to_owned()) {
|
||||
if let Ok(mode_now) =
|
||||
usdpl_back::api::files::read_single::<_, String, _>(DPM_FORCE_LIMITS_PATH.to_owned())
|
||||
{
|
||||
log::debug!("Mode for `{}` is now `{}`", DPM_FORCE_LIMITS_PATH, mode_now);
|
||||
} else {
|
||||
log::debug!("Error getting new mode for debugging purposes");
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#![allow(dead_code)]
|
||||
|
||||
use std::fs::OpenOptions;
|
||||
use std::io::{Error, Seek, SeekFrom, Read, Write};
|
||||
use std::io::{Error, Read, Seek, SeekFrom, Write};
|
||||
|
||||
#[inline]
|
||||
fn write2(p0: u8, p1: u8) -> Result<usize, Error> {
|
||||
|
@ -27,17 +27,13 @@ fn write_read(p0: u8) -> Result<u8, Error> {
|
|||
}
|
||||
|
||||
fn write_to(location: u64, value: u8) -> Result<usize, Error> {
|
||||
let mut file = OpenOptions::new()
|
||||
.write(true)
|
||||
.open("/dev/port")?;
|
||||
let mut file = OpenOptions::new().write(true).open("/dev/port")?;
|
||||
file.seek(SeekFrom::Start(location))?;
|
||||
file.write(&[value])
|
||||
}
|
||||
|
||||
fn read_from(location: u64) -> Result<u8, Error> {
|
||||
let mut file = OpenOptions::new()
|
||||
.read(true)
|
||||
.open("/dev/port")?;
|
||||
let mut file = OpenOptions::new().read(true).open("/dev/port")?;
|
||||
file.seek(SeekFrom::Start(location))?;
|
||||
let mut buffer = [0];
|
||||
file.read(&mut buffer)?;
|
||||
|
@ -61,21 +57,26 @@ fn wait_ready_for_read() -> Result<(), Error> {
|
|||
}
|
||||
|
||||
pub fn set_led(red_unused: bool, green_aka_white: bool, blue_unused: bool) -> Result<usize, Error> {
|
||||
let payload: u8 = 0x80 | (red_unused as u8 & 1) | ((green_aka_white as u8 & 1) << 1) | ((blue_unused as u8 & 1) << 2);
|
||||
let payload: u8 = 0x80
|
||||
| (red_unused as u8 & 1)
|
||||
| ((green_aka_white as u8 & 1) << 1)
|
||||
| ((blue_unused as u8 & 1) << 2);
|
||||
//log::info!("Payload: {:b}", payload);
|
||||
write2(Setting::LEDStatus as _, payload)
|
||||
}
|
||||
|
||||
const THINGS: &[u8] = &[
|
||||
1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,
|
||||
1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
|
||||
1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,
|
||||
1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0,
|
||||
0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1,
|
||||
1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0,
|
||||
0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0,
|
||||
];
|
||||
|
||||
const TIME_UNIT: std::time::Duration = std::time::Duration::from_millis(200);
|
||||
|
||||
pub fn flash_led() {
|
||||
let old_led_state = write_read(Setting::LEDStatus as _).map_err(|e| log::error!("Failed to read LED status: {}", e));
|
||||
let old_led_state = write_read(Setting::LEDStatus as _)
|
||||
.map_err(|e| log::error!("Failed to read LED status: {}", e));
|
||||
for &code in THINGS {
|
||||
let on = code != 0;
|
||||
if let Err(e) = set_led(on, on, false) {
|
||||
|
@ -85,7 +86,9 @@ pub fn flash_led() {
|
|||
}
|
||||
if let Ok(old_led_state) = old_led_state {
|
||||
log::debug!("Restoring LED state to {:#02b}", old_led_state);
|
||||
write2(Setting::LEDStatus as _, old_led_state).map_err(|e| log::error!("Failed to restore LED status: {}", e)).unwrap();
|
||||
write2(Setting::LEDStatus as _, old_led_state)
|
||||
.map_err(|e| log::error!("Failed to restore LED status: {}", e))
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::fmt::Debug;
|
||||
use super::SettingError;
|
||||
use super::MinMax;
|
||||
use super::SettingError;
|
||||
use std::fmt::Debug;
|
||||
|
||||
pub trait OnSet {
|
||||
fn on_set(&mut self) -> Result<(), Vec<SettingError>>;
|
||||
|
@ -14,7 +14,7 @@ pub trait OnResume {
|
|||
#[derive(Clone, Copy, Debug)]
|
||||
pub enum PowerMode {
|
||||
PluggedIn,
|
||||
PluggedOut, // unplugged
|
||||
PluggedOut, // unplugged
|
||||
BatteryCharge(f64), // battery fill amount: 0 = empty, 1 = full
|
||||
}
|
||||
|
||||
|
@ -135,7 +135,7 @@ pub trait TBattery: OnSet + OnResume + OnPowerEvent + Debug + Send {
|
|||
log::warn!("Power event check using default trait implementation");
|
||||
let mut events = Vec::new();
|
||||
if let (Some(full), Some(now)) = (self.read_charge_full(), self.read_charge_now()) {
|
||||
events.push(PowerMode::BatteryCharge(now/full));
|
||||
events.push(PowerMode::BatteryCharge(now / full));
|
||||
}
|
||||
Ok(events)
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use std::convert::Into;
|
||||
|
||||
use crate::settings::{OnResume, OnSet, SettingError};
|
||||
use crate::settings::TBattery;
|
||||
use crate::persist::BatteryJson;
|
||||
use crate::settings::TBattery;
|
||||
use crate::settings::{OnResume, OnSet, SettingError};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Battery;
|
||||
|
@ -47,31 +47,39 @@ impl TBattery for Battery {
|
|||
self.clone().into()
|
||||
}
|
||||
|
||||
fn charge_rate(&mut self, _rate: Option<u64>) {
|
||||
}
|
||||
fn charge_rate(&mut self, _rate: Option<u64>) {}
|
||||
|
||||
fn get_charge_rate(&self) -> Option<u64> {
|
||||
None
|
||||
}
|
||||
|
||||
fn charge_mode(&mut self, _rate: Option<String>) {
|
||||
}
|
||||
fn charge_mode(&mut self, _rate: Option<String>) {}
|
||||
|
||||
fn get_charge_mode(&self) -> Option<String> {
|
||||
None
|
||||
}
|
||||
|
||||
fn read_charge_full(&self) -> Option<f64> { None }
|
||||
fn read_charge_full(&self) -> Option<f64> {
|
||||
None
|
||||
}
|
||||
|
||||
fn read_charge_now(&self) -> Option<f64> { None }
|
||||
fn read_charge_now(&self) -> Option<f64> {
|
||||
None
|
||||
}
|
||||
|
||||
fn read_charge_design(&self) -> Option<f64> { None }
|
||||
fn read_charge_design(&self) -> Option<f64> {
|
||||
None
|
||||
}
|
||||
|
||||
fn read_current_now(&self) -> Option<f64> { None }
|
||||
fn read_current_now(&self) -> Option<f64> {
|
||||
None
|
||||
}
|
||||
|
||||
fn charge_limit(&mut self, _limit: Option<f64>) {}
|
||||
|
||||
fn get_charge_limit(&self) -> Option<f64> { None }
|
||||
fn get_charge_limit(&self) -> Option<f64> {
|
||||
None
|
||||
}
|
||||
|
||||
fn provider(&self) -> crate::persist::DriverJson {
|
||||
crate::persist::DriverJson::Unknown
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use std::convert::Into;
|
||||
|
||||
use crate::persist::CpuJson;
|
||||
use crate::settings::MinMax;
|
||||
use crate::settings::{OnResume, OnSet, SettingError};
|
||||
use crate::settings::{TCpus, TCpu};
|
||||
use crate::persist::CpuJson;
|
||||
use crate::settings::{TCpu, TCpus};
|
||||
|
||||
const CPU_PRESENT_PATH: &str = "/sys/devices/system/cpu/present";
|
||||
const CPU_SMT_PATH: &str = "/sys/devices/system/cpu/smt/control";
|
||||
|
@ -21,25 +21,23 @@ impl OnSet for Cpus {
|
|||
if self.smt_capable {
|
||||
// toggle SMT
|
||||
if self.smt {
|
||||
usdpl_back::api::files::write_single(CPU_SMT_PATH, "on").map_err(|e| {
|
||||
SettingError {
|
||||
msg: format!(
|
||||
"Failed to write `on` to `{}`: {}",
|
||||
CPU_SMT_PATH, e
|
||||
),
|
||||
usdpl_back::api::files::write_single(CPU_SMT_PATH, "on")
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!("Failed to write `on` to `{}`: {}", CPU_SMT_PATH, e),
|
||||
setting: crate::settings::SettingVariant::Cpu,
|
||||
}
|
||||
}).unwrap_or_else(|e| {errors.push(e);});
|
||||
})
|
||||
.unwrap_or_else(|e| {
|
||||
errors.push(e);
|
||||
});
|
||||
} else {
|
||||
usdpl_back::api::files::write_single(CPU_SMT_PATH, "off").map_err(|e| {
|
||||
SettingError {
|
||||
msg: format!(
|
||||
"Failed to write `off` to `{}`: {}",
|
||||
CPU_SMT_PATH, e
|
||||
),
|
||||
usdpl_back::api::files::write_single(CPU_SMT_PATH, "off")
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!("Failed to write `off` to `{}`: {}", CPU_SMT_PATH, e),
|
||||
setting: crate::settings::SettingVariant::Cpu,
|
||||
}
|
||||
}).unwrap_or_else(|e| {errors.push(e);});
|
||||
})
|
||||
.unwrap_or_else(|e| {
|
||||
errors.push(e);
|
||||
});
|
||||
}
|
||||
}
|
||||
for (i, cpu) in self.cpus.as_mut_slice().iter_mut().enumerate() {
|
||||
|
@ -58,7 +56,8 @@ impl OnResume for Cpus {
|
|||
fn on_resume(&self) -> Result<(), Vec<SettingError>> {
|
||||
let mut errors = Vec::new();
|
||||
for cpu in &self.cpus {
|
||||
cpu.on_resume().unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
cpu.on_resume()
|
||||
.unwrap_or_else(|mut e| errors.append(&mut e));
|
||||
}
|
||||
if errors.is_empty() {
|
||||
Ok(())
|
||||
|
@ -87,7 +86,7 @@ impl Cpus {
|
|||
fn system_smt_capabilities() -> (bool, bool) {
|
||||
match usdpl_back::api::files::read_single::<_, String, _>(CPU_SMT_PATH) {
|
||||
Ok(val) => (val.trim().to_lowercase() == "on", true),
|
||||
Err(_) => (false, false)
|
||||
Err(_) => (false, false),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -183,7 +182,6 @@ pub struct Cpu {
|
|||
state: crate::state::steam_deck::Cpu,
|
||||
}
|
||||
|
||||
|
||||
impl Cpu {
|
||||
#[inline]
|
||||
pub fn from_json(other: CpuJson, version: u64, i: usize) -> Self {
|
||||
|
@ -206,28 +204,29 @@ impl Cpu {
|
|||
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
|
||||
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 {
|
||||
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));
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
}
|
||||
|
||||
// set governor
|
||||
if self.index == 0 || self.online {
|
||||
let governor_path = cpu_governor_path(self.index);
|
||||
usdpl_back::api::files::write_single(&governor_path, &self.governor).map_err(|e| {
|
||||
SettingError {
|
||||
usdpl_back::api::files::write_single(&governor_path, &self.governor)
|
||||
.map_err(|e| SettingError {
|
||||
msg: format!(
|
||||
"Failed to write `{}` to `{}`: {}",
|
||||
&self.governor, &governor_path, e
|
||||
),
|
||||
setting: crate::settings::SettingVariant::Cpu,
|
||||
}
|
||||
}).unwrap_or_else(|e| errors.push(e));
|
||||
})
|
||||
.unwrap_or_else(|e| errors.push(e));
|
||||
}
|
||||
if errors.is_empty() {
|
||||
Ok(())
|
||||
|
@ -238,7 +237,8 @@ impl Cpu {
|
|||
|
||||
fn from_sys(cpu_index: usize) -> Self {
|
||||
Self {
|
||||
online: usdpl_back::api::files::read_single(cpu_online_path(cpu_index)).unwrap_or(1u8) != 0,
|
||||
online: usdpl_back::api::files::read_single(cpu_online_path(cpu_index)).unwrap_or(1u8)
|
||||
!= 0,
|
||||
governor: usdpl_back::api::files::read_single(cpu_governor_path(cpu_index))
|
||||
.unwrap_or("schedutil".to_owned()),
|
||||
index: cpu_index,
|
||||
|
@ -295,8 +295,7 @@ impl TCpu for Cpu {
|
|||
&self.governor
|
||||
}
|
||||
|
||||
fn clock_limits(&mut self, _limits: Option<MinMax<u64>>) {
|
||||
}
|
||||
fn clock_limits(&mut self, _limits: Option<MinMax<u64>>) {}
|
||||
|
||||
fn get_clock_limits(&self) -> Option<&MinMax<u64>> {
|
||||
None
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use std::convert::Into;
|
||||
|
||||
use crate::settings::MinMax;
|
||||
use crate::settings::{OnResume, OnSet, SettingError};
|
||||
use crate::settings::TGpu;
|
||||
use crate::persist::GpuJson;
|
||||
use crate::settings::MinMax;
|
||||
use crate::settings::TGpu;
|
||||
use crate::settings::{OnResume, OnSet, SettingError};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Gpu {
|
||||
|
@ -13,15 +13,11 @@ pub struct Gpu {
|
|||
impl Gpu {
|
||||
#[inline]
|
||||
pub fn from_json(_other: GpuJson, _version: u64) -> Self {
|
||||
Self {
|
||||
slow_memory: false,
|
||||
}
|
||||
Self { slow_memory: false }
|
||||
}
|
||||
|
||||
pub fn system_default() -> Self {
|
||||
Self {
|
||||
slow_memory: false,
|
||||
}
|
||||
Self { slow_memory: false }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,15 +67,13 @@ impl TGpu for Gpu {
|
|||
self.clone().into()
|
||||
}
|
||||
|
||||
fn ppt(&mut self, _fast: Option<u64>, _slow: Option<u64>) {
|
||||
}
|
||||
fn ppt(&mut self, _fast: Option<u64>, _slow: Option<u64>) {}
|
||||
|
||||
fn get_ppt(&self) -> (Option<u64>, Option<u64>) {
|
||||
(None, None)
|
||||
}
|
||||
|
||||
fn clock_limits(&mut self, _limits: Option<MinMax<u64>>) {
|
||||
}
|
||||
fn clock_limits(&mut self, _limits: Option<MinMax<u64>>) {}
|
||||
|
||||
fn get_clock_limits(&self) -> Option<&MinMax<u64>> {
|
||||
None
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
pub fn guess_smt(cpus: &Vec<crate::persist::CpuJson>) -> bool {
|
||||
let mut guess = true;
|
||||
for i in (0..cpus.len()).step_by(2) {
|
||||
guess &= cpus[i].online == cpus[i+1].online;
|
||||
guess &= cpus[i].online == cpus[i + 1].online;
|
||||
}
|
||||
guess
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use std::fmt::Display;
|
||||
//use std::sync::{LockResult, MutexGuard};
|
||||
//use std::fs::{Permissions, metadata};
|
||||
use std::io::{Read, Write};
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
use std::io::{Write, Read};
|
||||
|
||||
pub fn unwrap_maybe_fatal<T: Sized, E: Display>(result: Result<T, E>, message: &str) -> T {
|
||||
match result {
|
||||
|
@ -36,21 +36,36 @@ pub fn settings_dir() -> std::path::PathBuf {
|
|||
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"))?;
|
||||
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 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(".")])
|
||||
.args([
|
||||
"-R",
|
||||
&format!("{}:{}", deck_user, deck_user),
|
||||
&dir.to_str().unwrap_or("."),
|
||||
])
|
||||
.output()?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -61,8 +76,7 @@ fn version_filepath() -> std::path::PathBuf {
|
|||
|
||||
pub fn save_version_file() -> std::io::Result<usize> {
|
||||
let path = version_filepath();
|
||||
std::fs::File::create(path)?
|
||||
.write(crate::consts::PACKAGE_VERSION.as_bytes())
|
||||
std::fs::File::create(path)?.write(crate::consts::PACKAGE_VERSION.as_bytes())
|
||||
}
|
||||
|
||||
pub fn read_version_file() -> String {
|
||||
|
@ -77,7 +91,7 @@ pub fn read_version_file() -> String {
|
|||
crate::consts::PACKAGE_VERSION.to_owned()
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
Err(e) => {
|
||||
log::warn!("Cannot read version file: {}", e);
|
||||
crate::consts::PACKAGE_VERSION.to_owned()
|
||||
|
|
Loading…
Reference in a new issue