Skip to content

Commit

Permalink
add fetch_not method on AtomicBool
Browse files Browse the repository at this point in the history
  • Loading branch information
leocth committed Jun 25, 2022
1 parent d017d59 commit dcfe92e
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 0 deletions.
35 changes: 35 additions & 0 deletions library/core/src/sync/atomic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
14 changes: 14 additions & 0 deletions library/core/tests/atomic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down Expand Up @@ -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);
}
}

Expand Down

0 comments on commit dcfe92e

Please sign in to comment.