From dcfe92e193eb0d3d9df455f3274d6ba2d90c45c1 Mon Sep 17 00:00:00 2001 From: leocth Date: Sat, 25 Jun 2022 11:19:08 +0800 Subject: [PATCH] add `fetch_not` method on `AtomicBool` --- library/core/src/sync/atomic.rs | 35 +++++++++++++++++++++++++++++++++ library/core/tests/atomic.rs | 14 +++++++++++++ 2 files changed, 49 insertions(+) diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index a66ecc35bbdb1..afc4eda49abd5 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -854,6 +854,41 @@ impl AtomicBool { unsafe { atomic_xor(self.v.get(), val as u8, order) != 0 } } + /// Logical "not" with a boolean value. + /// + /// Performs a logical "not" operation on the current value, and sets + /// the new value to the result. + /// + /// Returns the previous value. + /// + /// `fetch_not` takes an [`Ordering`] argument which describes the memory ordering + /// of this operation. All ordering modes are possible. Note that using + /// [`Acquire`] makes the store part of this operation [`Relaxed`], and + /// using [`Release`] makes the load part [`Relaxed`]. + /// + /// **Note:** This method is only available on platforms that support atomic + /// operations on `u8`. + /// + /// # Examples + /// + /// ``` + /// use std::sync::atomic::{AtomicBool, Ordering}; + /// + /// let foo = AtomicBool::new(true); + /// assert_eq!(foo.fetch_not(Ordering::SeqCst), true); + /// assert_eq!(foo.load(Ordering::SeqCst), false); + /// + /// let foo = AtomicBool::new(false); + /// assert_eq!(foo.fetch_not(Ordering::SeqCst), false); + /// assert_eq!(foo.load(Ordering::SeqCst), true); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + #[cfg(target_has_atomic = "8")] + pub fn fetch_not(&self, order: Ordering) -> bool { + self.fetch_xor(true, order) + } + /// Returns a mutable pointer to the underlying [`bool`]. /// /// Doing non-atomic reads and writes on the resulting integer can be a data race. diff --git a/library/core/tests/atomic.rs b/library/core/tests/atomic.rs index 7f8672f035417..36d1929d5be46 100644 --- a/library/core/tests/atomic.rs +++ b/library/core/tests/atomic.rs @@ -30,6 +30,18 @@ fn bool_nand() { assert_eq!(a.fetch_nand(true, SeqCst), false); assert_eq!(a.load(SeqCst), true); } +#[test] +fn bool_not() { + let a = AtomicBool::new(false); + assert_eq!(a.fetch_not(SeqCst), false); + assert_eq!(a.load(SeqCst), true); + assert_eq!(a.fetch_not(SeqCst), true); + assert_eq!(a.load(SeqCst), false); + assert_eq!(a.fetch_not(SeqCst), false); + assert_eq!(a.load(SeqCst), true); + assert_eq!(a.fetch_not(SeqCst), true); + assert_eq!(a.load(SeqCst), false); +} #[test] fn uint_and() { @@ -158,6 +170,8 @@ fn atomic_access_bool() { assert_eq!(*ATOMIC.get_mut(), true); ATOMIC.fetch_xor(true, SeqCst); assert_eq!(*ATOMIC.get_mut(), false); + ATOMIC.fetch_not(SeqCst); + assert_eq!(*ATOMIC.get_mut(), true); } }