From 1a61232b3580ae7191125147237bfff4bcf2db1c Mon Sep 17 00:00:00 2001 From: Pedro Fedricci Date: Thu, 7 Nov 2024 17:09:25 -0300 Subject: [PATCH] refact: use relaxed ordering for park loop --- src/inner/barging/mod.rs | 4 ++-- src/inner/raw/mod.rs | 2 +- src/lock.rs | 8 ++++---- src/parking/parker.rs | 34 +++++++++++++++++----------------- 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/inner/barging/mod.rs b/src/inner/barging/mod.rs index 90b416f..1b4562c 100644 --- a/src/inner/barging/mod.rs +++ b/src/inner/barging/mod.rs @@ -65,12 +65,12 @@ impl Mutex { /// /// This function does not guarantee strong ordering, only atomicity. pub fn is_locked(&self) -> bool { - self.lock.is_locked() + self.lock.is_locked_relaxed() } /// Unlocks this mutex. pub fn unlock(&self) { - self.lock.notify(); + self.lock.notify_release(); } } diff --git a/src/inner/raw/mod.rs b/src/inner/raw/mod.rs index 990f4ac..dc8f60b 100644 --- a/src/inner/raw/mod.rs +++ b/src/inner/raw/mod.rs @@ -172,7 +172,7 @@ impl Mutex { fence(Acquire); // Notify our successor that they hold the lock. // SAFETY: We already verified that our successor is not null. - unsafe { &*next }.lock.notify(); + unsafe { &*next }.lock.notify_release(); } } diff --git a/src/lock.rs b/src/lock.rs index 7282a7d..5a346e7 100644 --- a/src/lock.rs +++ b/src/lock.rs @@ -64,11 +64,11 @@ pub trait Lock { /// Returns `true` if the lock is currently held. /// /// This function does not guarantee strong ordering, only atomicity. - fn is_locked(&self) -> bool; + fn is_locked_relaxed(&self) -> bool; /// Changes the state of the lock and, possibly, notifies that change /// to some other interested party. - fn notify(&self); + fn notify_release(&self); } /// The waiting policy that should be applied while the lock state has not @@ -123,11 +123,11 @@ impl Lock for AtomicBool { } } - fn is_locked(&self) -> bool { + fn is_locked_relaxed(&self) -> bool { self.load(Relaxed) } - fn notify(&self) { + fn notify_release(&self) { self.store(false, Release); } } diff --git a/src/parking/parker.rs b/src/parking/parker.rs index aa7bad7..97dc959 100644 --- a/src/parking/parker.rs +++ b/src/parking/parker.rs @@ -45,7 +45,7 @@ pub trait ParkerT { /// Returns `true` if the lock is currently held. /// /// This function does not guarantee strong ordering, only atomicity. - fn is_locked(&self) -> bool; + fn is_locked_relaxed(&self) -> bool; /// Tries to lock this mutex with acquire load. /// @@ -66,13 +66,13 @@ pub trait ParkerT { /// to safeguard agains spurious wake-ups if they are possible. That is, /// this function should only unblock once a corresponding unpark call has /// been issued to this parked thread. - fn park_loop(&self); + fn park_loop_relaxed(&self); /// Atomically makes the handle’s token available if it is not already. /// /// Implementors of this function are expected to call the platform's /// specific API for thread unparking. - fn unpark(&self); + fn unpark_release(&self); } impl Lock for Parker { @@ -110,7 +110,7 @@ impl Lock for Parker { // Block the thread with a relaxed loop untin either all attempts have // already been made or the lock has been handed over to this thread. while !parker.should_park() { - if ParkerT::is_locked(self) { + if ParkerT::is_locked_relaxed(self) { // Whenever the thread is not ready to be put to sleep yet and // it also fails to acquire the lock, then update parker's // state and apply its associated relax operation. @@ -124,15 +124,15 @@ impl Lock for Parker { } // The limit of attempts have been reached and the lock remains locked, // then park the thread. The parking loop will handle spurious wakeups. - ParkerT::park_loop(self); + ParkerT::park_loop_relaxed(self); } - fn is_locked(&self) -> bool { - ParkerT::is_locked(self) + fn is_locked_relaxed(&self) -> bool { + ParkerT::is_locked_relaxed(self) } - fn notify(&self) { - ParkerT::unpark(self); + fn notify_release(&self) { + ParkerT::unpark_release(self); } } @@ -173,17 +173,17 @@ mod common { self.state.compare_exchange_weak(UNLOCKED, LOCKED, Acquire, Relaxed).is_ok() } - fn is_locked(&self) -> bool { + fn is_locked_relaxed(&self) -> bool { self.state.load(Relaxed) == LOCKED } - fn park_loop(&self) { - while self.state.load(Acquire) == LOCKED { + fn park_loop_relaxed(&self) { + while self.state.load(Relaxed) == LOCKED { atomic_wait::wait(&self.state, LOCKED); } } - fn unpark(&self) { + fn unpark_release(&self) { let state = &self.state; // TODO: 1.82.0 supports native syntax: // let ptr = &raw const self.state; @@ -231,17 +231,17 @@ mod loom { self.locked.compare_exchange_weak(UNLOCKED, LOCKED, Acquire, Relaxed).is_ok() } - fn is_locked(&self) -> bool { + fn is_locked_relaxed(&self) -> bool { self.locked.load(Relaxed) == LOCKED } - fn park_loop(&self) { - while self.locked.load(Acquire) == LOCKED { + fn park_loop_relaxed(&self) { + while self.locked.load(Relaxed) == LOCKED { thread::yield_now(); } } - fn unpark(&self) { + fn unpark_release(&self) { self.locked.store(UNLOCKED, Release); thread::yield_now(); }