about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMark Simulacrum <mark.simulacrum@gmail.com>2018-02-09 11:19:52 -0700
committerMark Simulacrum <mark.simulacrum@gmail.com>2018-02-09 16:04:41 -0700
commit1335b3da5a80fa4b74b25642e1bb651388bac3a8 (patch)
tree8916fa05f761c107c1bf8590fd34e8592f1c0279 /src
parent3bcda48a30b21e46b81a7989deb30a3ba85fb918 (diff)
downloadrust-1335b3da5a80fa4b74b25642e1bb651388bac3a8.tar.gz
rust-1335b3da5a80fa4b74b25642e1bb651388bac3a8.zip
Add fetch_nand.
cc #13226 (the tracking issue)
Diffstat (limited to 'src')
-rw-r--r--src/libcore/sync/atomic.rs46
-rw-r--r--src/libcore/tests/atomic.rs14
-rw-r--r--src/libcore/tests/lib.rs1
3 files changed, 61 insertions, 0 deletions
diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs
index 8b47143f63c..f22862ae701 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
 }
@@ -1610,6 +1644,18 @@ unsafe fn atomic_and<T>(dst: *mut T, val: T, order: Ordering) -> T {
 }
 
 #[inline]
+unsafe fn atomic_nand<T>(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<T>(dst: *mut T, val: T, order: Ordering) -> T {
     match order {
         Acquire => intrinsics::atomic_or_acq(dst, val),
diff --git a/src/libcore/tests/atomic.rs b/src/libcore/tests/atomic.rs
index 9babe24a985..f634fabe503 100644
--- a/src/libcore/tests/atomic.rs
+++ b/src/libcore/tests/atomic.rs
@@ -49,6 +49,13 @@ fn uint_and() {
 }
 
 #[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);
     assert_eq!(x.fetch_or(0x137f, SeqCst), 0xf731);
@@ -70,6 +77,13 @@ fn int_and() {
 }
 
 #[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);
     assert_eq!(x.fetch_or(0x137f, SeqCst), 0xf731);
diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs
index 1c32452f846..9e90313bc0e 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;