Skip to content

Commit dcfe92e

Browse files
author
leocth
committed
add fetch_not method on AtomicBool
1 parent d017d59 commit dcfe92e

File tree

2 files changed

+49
-0
lines changed

2 files changed

+49
-0
lines changed

library/core/src/sync/atomic.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -854,6 +854,41 @@ impl AtomicBool {
854854
unsafe { atomic_xor(self.v.get(), val as u8, order) != 0 }
855855
}
856856

857+
/// Logical "not" with a boolean value.
858+
///
859+
/// Performs a logical "not" operation on the current value, and sets
860+
/// the new value to the result.
861+
///
862+
/// Returns the previous value.
863+
///
864+
/// `fetch_not` takes an [`Ordering`] argument which describes the memory ordering
865+
/// of this operation. All ordering modes are possible. Note that using
866+
/// [`Acquire`] makes the store part of this operation [`Relaxed`], and
867+
/// using [`Release`] makes the load part [`Relaxed`].
868+
///
869+
/// **Note:** This method is only available on platforms that support atomic
870+
/// operations on `u8`.
871+
///
872+
/// # Examples
873+
///
874+
/// ```
875+
/// use std::sync::atomic::{AtomicBool, Ordering};
876+
///
877+
/// let foo = AtomicBool::new(true);
878+
/// assert_eq!(foo.fetch_not(Ordering::SeqCst), true);
879+
/// assert_eq!(foo.load(Ordering::SeqCst), false);
880+
///
881+
/// let foo = AtomicBool::new(false);
882+
/// assert_eq!(foo.fetch_not(Ordering::SeqCst), false);
883+
/// assert_eq!(foo.load(Ordering::SeqCst), true);
884+
/// ```
885+
#[inline]
886+
#[stable(feature = "rust1", since = "1.0.0")]
887+
#[cfg(target_has_atomic = "8")]
888+
pub fn fetch_not(&self, order: Ordering) -> bool {
889+
self.fetch_xor(true, order)
890+
}
891+
857892
/// Returns a mutable pointer to the underlying [`bool`].
858893
///
859894
/// Doing non-atomic reads and writes on the resulting integer can be a data race.

library/core/tests/atomic.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,18 @@ fn bool_nand() {
3030
assert_eq!(a.fetch_nand(true, SeqCst), false);
3131
assert_eq!(a.load(SeqCst), true);
3232
}
33+
#[test]
34+
fn bool_not() {
35+
let a = AtomicBool::new(false);
36+
assert_eq!(a.fetch_not(SeqCst), false);
37+
assert_eq!(a.load(SeqCst), true);
38+
assert_eq!(a.fetch_not(SeqCst), true);
39+
assert_eq!(a.load(SeqCst), false);
40+
assert_eq!(a.fetch_not(SeqCst), false);
41+
assert_eq!(a.load(SeqCst), true);
42+
assert_eq!(a.fetch_not(SeqCst), true);
43+
assert_eq!(a.load(SeqCst), false);
44+
}
3345

3446
#[test]
3547
fn uint_and() {
@@ -158,6 +170,8 @@ fn atomic_access_bool() {
158170
assert_eq!(*ATOMIC.get_mut(), true);
159171
ATOMIC.fetch_xor(true, SeqCst);
160172
assert_eq!(*ATOMIC.get_mut(), false);
173+
ATOMIC.fetch_not(SeqCst);
174+
assert_eq!(*ATOMIC.get_mut(), true);
161175
}
162176
}
163177

0 commit comments

Comments
 (0)