1
Fork 0
mirror of https://github.com/RGBCube/superfreq synced 2025-07-27 17:07:44 +00:00

engine: fix race condition in turbo state init

This commit is contained in:
NotAShelf 2025-05-18 05:42:39 +03:00
parent ed3ba94f74
commit 13bb434ff1
No known key found for this signature in database
GPG key ID: 29D95B64378DB4BF

View file

@ -69,11 +69,8 @@ impl TurboHysteresis {
/// Initialize the state with a specific value if not already initialized /// Initialize the state with a specific value if not already initialized
/// Only one thread should be able to initialize the state /// Only one thread should be able to initialize the state
fn initialize_with(&self, initial_state: bool) -> bool { fn initialize_with(&self, initial_state: bool) -> bool {
// First store the initial state so that it's visible before initialized=true // First, try to atomically change initialized from false to true
self.previous_state.store(initial_state, Ordering::Release); // Only one thread can win the initialization race
// Try to atomically change initialized from false to true
// Now, only one thread can win the initialization race
match self.initialized.compare_exchange( match self.initialized.compare_exchange(
false, // expected: not initialized false, // expected: not initialized
true, // desired: mark as initialized true, // desired: mark as initialized
@ -82,11 +79,14 @@ impl TurboHysteresis {
) { ) {
Ok(_) => { Ok(_) => {
// We won the race to initialize // 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 initial_state
} }
Err(_) => { Err(_) => {
// Another thread already initialized it. // 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) self.previous_state.load(Ordering::Acquire)
} }
} }