about summary refs log tree commit diff
diff options
context:
space:
mode:
authorleocth <leocth31@gmail.com>2022-06-25 11:19:08 +0800
committerleocth <leocth31@gmail.com>2022-06-25 11:19:08 +0800
commitdcfe92e193eb0d3d9df455f3274d6ba2d90c45c1 (patch)
tree7a6d3c6437a89827dadaa27c85c4dbf960b2aae9
parentd017d59ed013a4bc2431d023077eb7209fe9c60d (diff)
downloadrust-dcfe92e193eb0d3d9df455f3274d6ba2d90c45c1.tar.gz
rust-dcfe92e193eb0d3d9df455f3274d6ba2d90c45c1.zip
add `fetch_not` method on `AtomicBool`
-rw-r--r--library/core/src/sync/atomic.rs35
-rw-r--r--library/core/tests/atomic.rs14
2 files changed, 49 insertions, 0 deletions
diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs
index a66ecc35bbd..afc4eda49ab 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 7f8672f0354..36d1929d5be 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);
     }
 }