sync: spinlock: Check state before compare_exchange_weak

Checking the state with a relaxed load before doing a
compare_exchange_weak can reduce unnecessary coherence traffic on the
CPU and improve performance.

BUG=none
TEST=unit tests

Change-Id: Icabd9863ceb5ba674dbec601afee8f7962f69413
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2805753
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Commit-Queue: Chirantan Ekbote <chirantan@chromium.org>
This commit is contained in:
Chirantan Ekbote 2021-04-05 18:55:40 +09:00 committed by Commit Bot
parent 9e44b5b3d7
commit 19353d3e68

View file

@ -54,11 +54,16 @@ impl<T: ?Sized> SpinLock<T> {
/// `SpinLockGuard` is dropped. Attempting to call `lock` while already holding the `SpinLock`
/// will cause a deadlock.
pub fn lock(&self) -> SpinLockGuard<T> {
while self
.lock
.compare_exchange_weak(UNLOCKED, LOCKED, Ordering::Acquire, Ordering::Relaxed)
.is_err()
{
loop {
let state = self.lock.load(Ordering::Relaxed);
if state == UNLOCKED
&& self
.lock
.compare_exchange_weak(UNLOCKED, LOCKED, Ordering::Acquire, Ordering::Relaxed)
.is_ok()
{
break;
}
spin_loop_hint();
}