From 19353d3e68be31ea8d6627696c2d95243725082c Mon Sep 17 00:00:00 2001 From: Chirantan Ekbote Date: Mon, 5 Apr 2021 18:55:40 +0900 Subject: [PATCH] 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 Reviewed-by: Daniel Verkamp Commit-Queue: Chirantan Ekbote --- cros_async/src/sync/spin.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/cros_async/src/sync/spin.rs b/cros_async/src/sync/spin.rs index 4fb6172699..8b7b811939 100644 --- a/cros_async/src/sync/spin.rs +++ b/cros_async/src/sync/spin.rs @@ -54,11 +54,16 @@ impl SpinLock { /// `SpinLockGuard` is dropped. Attempting to call `lock` while already holding the `SpinLock` /// will cause a deadlock. pub fn lock(&self) -> SpinLockGuard { - 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(); }