diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index 8b47143f63ca..f22862ae7019 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -945,6 +945,7 @@ macro_rules! atomic_int { $stable_debug:meta, $stable_access:meta, $stable_from:meta, + $stable_nand:meta, $s_int_type:expr, $int_ref:expr, $int_type:ident $atomic_type:ident $atomic_init:ident) => { /// An integer type which can be safely shared between threads. @@ -1325,6 +1326,29 @@ macro_rules! atomic_int { unsafe { atomic_and(self.v.get(), val, order) } } + /// Bitwise "nand" with the current value. + /// + /// Performs a bitwise "nand" operation on the current value and the argument `val`, and + /// sets the new value to the result. + /// + /// Returns the previous value. + /// + /// # Examples + /// + /// ``` + /// #![feature(atomic_nand)] + /// + /// use std::sync::atomic::{AtomicIsize, Ordering}; + /// + /// let foo = AtomicIsize::new(0xf731); + /// assert_eq!(foo.fetch_nand(0x137f, Ordering::SeqCst), 0xf731); + /// assert_eq!(foo.load(Ordering::SeqCst), !(0xf731 & 0x137f)); + #[inline] + #[$stable_nand] + pub fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type { + unsafe { atomic_nand(self.v.get(), val, order) } + } + /// Bitwise "or" with the current value. /// /// Performs a bitwise "or" operation on the current value and the argument `val`, and @@ -1377,6 +1401,7 @@ atomic_int! { unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "integer_atomics", issue = "32976"), + unstable(feature = "atomic_nand", issue = "13226"), "i8", "../../../std/primitive.i8.html", i8 AtomicI8 ATOMIC_I8_INIT } @@ -1387,6 +1412,7 @@ atomic_int! { unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "integer_atomics", issue = "32976"), + unstable(feature = "atomic_nand", issue = "13226"), "u8", "../../../std/primitive.u8.html", u8 AtomicU8 ATOMIC_U8_INIT } @@ -1397,6 +1423,7 @@ atomic_int! { unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "integer_atomics", issue = "32976"), + unstable(feature = "atomic_nand", issue = "13226"), "i16", "../../../std/primitive.i16.html", i16 AtomicI16 ATOMIC_I16_INIT } @@ -1407,6 +1434,7 @@ atomic_int! { unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "integer_atomics", issue = "32976"), + unstable(feature = "atomic_nand", issue = "13226"), "u16", "../../../std/primitive.u16.html", u16 AtomicU16 ATOMIC_U16_INIT } @@ -1417,6 +1445,7 @@ atomic_int! { unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "integer_atomics", issue = "32976"), + unstable(feature = "atomic_nand", issue = "13226"), "i32", "../../../std/primitive.i32.html", i32 AtomicI32 ATOMIC_I32_INIT } @@ -1427,6 +1456,7 @@ atomic_int! { unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "integer_atomics", issue = "32976"), + unstable(feature = "atomic_nand", issue = "13226"), "u32", "../../../std/primitive.u32.html", u32 AtomicU32 ATOMIC_U32_INIT } @@ -1437,6 +1467,7 @@ atomic_int! { unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "integer_atomics", issue = "32976"), + unstable(feature = "atomic_nand", issue = "13226"), "i64", "../../../std/primitive.i64.html", i64 AtomicI64 ATOMIC_I64_INIT } @@ -1447,6 +1478,7 @@ atomic_int! { unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "integer_atomics", issue = "32976"), unstable(feature = "integer_atomics", issue = "32976"), + unstable(feature = "atomic_nand", issue = "13226"), "u64", "../../../std/primitive.u64.html", u64 AtomicU64 ATOMIC_U64_INIT } @@ -1457,6 +1489,7 @@ atomic_int!{ stable(feature = "atomic_debug", since = "1.3.0"), stable(feature = "atomic_access", since = "1.15.0"), stable(feature = "atomic_from", since = "1.23.0"), + unstable(feature = "atomic_nand", issue = "13226"), "isize", "../../../std/primitive.isize.html", isize AtomicIsize ATOMIC_ISIZE_INIT } @@ -1467,6 +1500,7 @@ atomic_int!{ stable(feature = "atomic_debug", since = "1.3.0"), stable(feature = "atomic_access", since = "1.15.0"), stable(feature = "atomic_from", since = "1.23.0"), + unstable(feature = "atomic_nand", issue = "13226"), "usize", "../../../std/primitive.usize.html", usize AtomicUsize ATOMIC_USIZE_INIT } @@ -1609,6 +1643,18 @@ unsafe fn atomic_and(dst: *mut T, val: T, order: Ordering) -> T { } } +#[inline] +unsafe fn atomic_nand(dst: *mut T, val: T, order: Ordering) -> T { + match order { + Acquire => intrinsics::atomic_nand_acq(dst, val), + Release => intrinsics::atomic_nand_rel(dst, val), + AcqRel => intrinsics::atomic_nand_acqrel(dst, val), + Relaxed => intrinsics::atomic_nand_relaxed(dst, val), + SeqCst => intrinsics::atomic_nand(dst, val), + __Nonexhaustive => panic!("invalid memory ordering"), + } +} + #[inline] unsafe fn atomic_or(dst: *mut T, val: T, order: Ordering) -> T { match order { diff --git a/src/libcore/tests/atomic.rs b/src/libcore/tests/atomic.rs index 9babe24a9856..f634fabe5039 100644 --- a/src/libcore/tests/atomic.rs +++ b/src/libcore/tests/atomic.rs @@ -48,6 +48,13 @@ fn uint_and() { assert_eq!(x.load(SeqCst), 0xf731 & 0x137f); } +#[test] +fn uint_nand() { + let x = AtomicUsize::new(0xf731); + assert_eq!(x.fetch_nand(0x137f, SeqCst), 0xf731); + assert_eq!(x.load(SeqCst), !(0xf731 & 0x137f)); +} + #[test] fn uint_or() { let x = AtomicUsize::new(0xf731); @@ -69,6 +76,13 @@ fn int_and() { assert_eq!(x.load(SeqCst), 0xf731 & 0x137f); } +#[test] +fn int_nand() { + let x = AtomicIsize::new(0xf731); + assert_eq!(x.fetch_nand(0x137f, SeqCst), 0xf731); + assert_eq!(x.load(SeqCst), !(0xf731 & 0x137f)); +} + #[test] fn int_or() { let x = AtomicIsize::new(0xf731); diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 1c32452f8463..9e90313bc0e9 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -42,6 +42,7 @@ #![feature(try_from)] #![feature(try_trait)] #![feature(exact_chunks)] +#![feature(atomic_nand)] extern crate core; extern crate test;