From 13bb434ff1129b1d74d95c3bf3c663ace1d3a38d Mon Sep 17 00:00:00 2001 From: NotAShelf Date: Sun, 18 May 2025 05:42:39 +0300 Subject: [PATCH 1/2] engine: fix race condition in turbo state init --- src/engine.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/engine.rs b/src/engine.rs index 2834ecb..966cc20 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -69,11 +69,8 @@ impl TurboHysteresis { /// Initialize the state with a specific value if not already initialized /// Only one thread should be able to initialize the state fn initialize_with(&self, initial_state: bool) -> bool { - // First store the initial state so that it's visible before initialized=true - self.previous_state.store(initial_state, Ordering::Release); - - // Try to atomically change initialized from false to true - // Now, only one thread can win the initialization race + // First, try to atomically change initialized from false to true + // Only one thread can win the initialization race match self.initialized.compare_exchange( false, // expected: not initialized true, // desired: mark as initialized @@ -82,11 +79,14 @@ impl TurboHysteresis { ) { Ok(_) => { // We won the race to initialize + // Now it's safe to set the initial state since we know we're the only + // thread that has successfully marked this as initialized + self.previous_state.store(initial_state, Ordering::Release); initial_state } Err(_) => { // Another thread already initialized it. - // Read the current state in bitter defeat + // Just read the current state value that was set by the winning thread self.previous_state.load(Ordering::Acquire) } } From 64bebe9f47e46e7d158e4809422842cb56cb80da Mon Sep 17 00:00:00 2001 From: NotAShelf Date: Sun, 18 May 2025 06:03:35 +0300 Subject: [PATCH 2/2] config: simplify default value functions Create a macro that generates constant-returning functions for default configuration values to reduce code duplication. This macro takes a function name, return type, and value. --- src/config/types.rs | 72 ++++++++++++++++++++------------------------- 1 file changed, 32 insertions(+), 40 deletions(-) diff --git a/src/config/types.rs b/src/config/types.rs index 63dff9a..03711c1 100644 --- a/src/config/types.rs +++ b/src/config/types.rs @@ -3,6 +3,17 @@ use crate::core::TurboSetting; use serde::{Deserialize, Serialize}; use std::convert::TryFrom; +/// Defines constant-returning functions used for default values. +/// This hopefully reduces repetition since we have way too many default functions +/// that just return constants. +macro_rules! default_const { + ($name:ident, $type:ty, $value:expr) => { + const fn $name() -> $type { + $value + } + }; +} + #[derive(Deserialize, Serialize, Debug, Clone, PartialEq, Eq)] pub struct BatteryChargeThresholds { pub start: u8, @@ -186,18 +197,22 @@ pub const DEFAULT_LOAD_THRESHOLD_LOW: f32 = 30.0; // disable turbo if load is be pub const DEFAULT_TEMP_THRESHOLD_HIGH: f32 = 75.0; // disable turbo if temperature is above this pub const DEFAULT_INITIAL_TURBO_STATE: bool = false; // by default, start with turbo disabled -const fn default_load_threshold_high() -> f32 { +default_const!( + default_load_threshold_high, + f32, DEFAULT_LOAD_THRESHOLD_HIGH -} -const fn default_load_threshold_low() -> f32 { - DEFAULT_LOAD_THRESHOLD_LOW -} -const fn default_temp_threshold_high() -> f32 { +); +default_const!(default_load_threshold_low, f32, DEFAULT_LOAD_THRESHOLD_LOW); +default_const!( + default_temp_threshold_high, + f32, DEFAULT_TEMP_THRESHOLD_HIGH -} -const fn default_initial_turbo_state() -> bool { +); +default_const!( + default_initial_turbo_state, + bool, DEFAULT_INITIAL_TURBO_STATE -} +); impl Default for TurboAutoSettings { fn default() -> Self { @@ -274,37 +289,14 @@ impl Default for DaemonConfig { } } -const fn default_poll_interval_sec() -> u64 { - 5 -} - -const fn default_adaptive_interval() -> bool { - false -} - -const fn default_min_poll_interval_sec() -> u64 { - 1 -} - -const fn default_max_poll_interval_sec() -> u64 { - 30 -} - -const fn default_throttle_on_battery() -> bool { - true -} - -const fn default_log_level() -> LogLevel { - LogLevel::Info -} - -const fn default_stats_file_path() -> Option { - None -} - -const fn default_enable_auto_turbo() -> bool { - true -} +default_const!(default_poll_interval_sec, u64, 5); +default_const!(default_adaptive_interval, bool, false); +default_const!(default_min_poll_interval_sec, u64, 1); +default_const!(default_max_poll_interval_sec, u64, 30); +default_const!(default_throttle_on_battery, bool, true); +default_const!(default_log_level, LogLevel, LogLevel::Info); +default_const!(default_stats_file_path, Option, None); +default_const!(default_enable_auto_turbo, bool, true); #[derive(Deserialize, Serialize, Debug, Clone)] pub struct DaemonConfigToml {