From 8dce55f2472905c69988d1e8bcc2d9ab577f7e2f Mon Sep 17 00:00:00 2001 From: Thomas de Zeeuw Date: Sun, 14 Apr 2024 14:30:22 +0200 Subject: [PATCH] Relax SeqCst in heph-inbox This replaces all SeqCst atomic operations with Release, Acquire or AcqRel. Also see https://github.com/rust-lang/rust/pull/122729. --- inbox/src/lib.rs | 4 ++-- inbox/src/tests.rs | 6 +++--- inbox/src/waker.rs | 10 +++++----- inbox/tests/util/mod.rs | 6 +++--- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/inbox/src/lib.rs b/inbox/src/lib.rs index 0e2673890..f5cdf3da5 100644 --- a/inbox/src/lib.rs +++ b/inbox/src/lib.rs @@ -401,7 +401,7 @@ fn try_send(channel: &Channel, value: T) -> Result<(), SendError> { /// enough for most practical use cases. impl Clone for Sender { fn clone(&self) -> Sender { - // For the reasoning behind this relaxed ordering see `Arc::clone`. + // SAFETY: for the reasoning behind this relaxed ordering see `Arc::clone`. let old_ref_count = self.channel().ref_count.fetch_add(1, Ordering::Relaxed); debug_assert!(old_ref_count & SENDER_ACCESS != 0); Sender { @@ -452,7 +452,7 @@ impl Drop for Sender { return; } - // For the reasoning behind this ordering see `Arc::drop`. + // SAFETY: for the reasoning behind this ordering see `Arc::drop`. fence!(self.channel().ref_count, Ordering::Acquire); // Drop the memory. diff --git a/inbox/src/tests.rs b/inbox/src/tests.rs index 651691c8e..d40d6d717 100644 --- a/inbox/src/tests.rs +++ b/inbox/src/tests.rs @@ -22,7 +22,7 @@ struct AwokenCount { impl PartialEq for AwokenCount { fn eq(&self, other: &usize) -> bool { - self.inner.count.load(Ordering::SeqCst) == *other + self.inner.count.load(Ordering::Acquire) == *other } } @@ -33,11 +33,11 @@ struct WakerInner { impl Wake for WakerInner { fn wake(self: Arc) { - let _ = self.count.fetch_add(1, Ordering::SeqCst); + let _ = self.count.fetch_add(1, Ordering::AcqRel); } fn wake_by_ref(self: &Arc) { - let _ = self.count.fetch_add(1, Ordering::SeqCst); + let _ = self.count.fetch_add(1, Ordering::AcqRel); } } diff --git a/inbox/src/waker.rs b/inbox/src/waker.rs index 771b9adfb..ed8aab146 100644 --- a/inbox/src/waker.rs +++ b/inbox/src/waker.rs @@ -24,7 +24,7 @@ impl WakerRegistration { let stored_waker = self.waker.read().unwrap(); if let Some(stored_waker) = &*stored_waker { if stored_waker.will_wake(waker) { - self.needs_wakeup.store(true, Ordering::SeqCst); + self.needs_wakeup.store(true, Ordering::Release); return false; } } @@ -36,26 +36,26 @@ impl WakerRegistration { // again. if let Some(stored_waker) = &*stored_waker { if stored_waker.will_wake(waker) { - self.needs_wakeup.store(true, Ordering::SeqCst); + self.needs_wakeup.store(true, Ordering::Release); return false; } } *stored_waker = Some(waker.clone()); drop(stored_waker); - self.needs_wakeup.store(true, Ordering::SeqCst); + self.needs_wakeup.store(true, Ordering::Release); true } /// Wake the waker registered, if required. pub(crate) fn wake(&self) { - if !self.needs_wakeup.load(Ordering::SeqCst) { + if !self.needs_wakeup.load(Ordering::Acquire) { // Receiver doesn't need a wake-up. return; } // Mark that we've woken and after actually do the waking. - if self.needs_wakeup.swap(false, Ordering::SeqCst) { + if self.needs_wakeup.swap(false, Ordering::AcqRel) { if let Some(waker) = &*self.waker.read().unwrap() { waker.wake_by_ref(); } diff --git a/inbox/tests/util/mod.rs b/inbox/tests/util/mod.rs index bc508dde3..7d6785996 100644 --- a/inbox/tests/util/mod.rs +++ b/inbox/tests/util/mod.rs @@ -22,7 +22,7 @@ pub struct AwokenCount { impl AwokenCount { /// Get the current count. pub fn get(&self) -> usize { - self.inner.count.load(Ordering::SeqCst) + self.inner.count.load(Ordering::Acquire) } } @@ -39,11 +39,11 @@ struct WakerInner { impl Wake for WakerInner { fn wake(self: Arc) { - let _ = self.count.fetch_add(1, Ordering::SeqCst); + let _ = self.count.fetch_add(1, Ordering::AcqRel); } fn wake_by_ref(self: &Arc) { - let _ = self.count.fetch_add(1, Ordering::SeqCst); + let _ = self.count.fetch_add(1, Ordering::AcqRel); } }