about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock1
-rw-r--r--src/librustc_data_structures/Cargo.toml1
-rw-r--r--src/librustc_data_structures/sync.rs55
3 files changed, 56 insertions, 1 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 5a20e6e102b..9a9c89cd9c1 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3018,6 +3018,7 @@ name = "rustc_data_structures"
 version = "0.0.0"
 dependencies = [
  "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "ena 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "graphviz 0.0.0",
  "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
diff --git a/src/librustc_data_structures/Cargo.toml b/src/librustc_data_structures/Cargo.toml
index acddb3448ca..79cbe26e73e 100644
--- a/src/librustc_data_structures/Cargo.toml
+++ b/src/librustc_data_structures/Cargo.toml
@@ -18,6 +18,7 @@ lazy_static = "1"
 serialize = { path = "../libserialize" }
 graphviz = { path = "../libgraphviz" }
 cfg-if = "0.1.2"
+crossbeam-utils = { version = "0.6.5", features = ["nightly"] }
 stable_deref_trait = "1.0.0"
 rayon = { version = "0.2.0", package = "rustc-rayon" }
 rayon-core = { version = "0.2.0", package = "rustc-rayon-core" }
diff --git a/src/librustc_data_structures/sync.rs b/src/librustc_data_structures/sync.rs
index 73247c1469e..3277b85c281 100644
--- a/src/librustc_data_structures/sync.rs
+++ b/src/librustc_data_structures/sync.rs
@@ -67,6 +67,51 @@ cfg_if! {
         use std::ops::Add;
         use std::panic::{resume_unwind, catch_unwind, AssertUnwindSafe};
 
+        /// This is a single threaded variant of AtomicCell provided by crossbeam.
+        /// Unlike `Atomic` this is intended for all `Copy` types,
+        /// but it lacks the explicit ordering arguments.
+        #[derive(Debug)]
+        pub struct AtomicCell<T: Copy>(Cell<T>);
+
+        impl<T: Copy> AtomicCell<T> {
+            #[inline]
+            pub fn new(v: T) -> Self {
+                AtomicCell(Cell::new(v))
+            }
+
+            #[inline]
+            pub fn get_mut(&mut self) -> &mut T {
+                self.0.get_mut()
+            }
+        }
+
+        impl<T: Copy> AtomicCell<T> {
+            #[inline]
+            pub fn into_inner(self) -> T {
+                self.0.into_inner()
+            }
+
+            #[inline]
+            pub fn load(&self) -> T {
+                self.0.get()
+            }
+
+            #[inline]
+            pub fn store(&self, val: T) {
+                self.0.set(val)
+            }
+
+            #[inline]
+            pub fn swap(&self, val: T) -> T {
+                self.0.replace(val)
+            }
+        }
+
+        /// This is a single threaded variant of `AtomicU64`, `AtomicUsize`, etc.
+        /// It differs from `AtomicCell` in that it has explicit ordering arguments
+        /// and is only intended for use with the native atomic types.
+        /// You should use this type through the `AtomicU64`, `AtomicUsize`, etc, type aliases
+        /// as it's not intended to be used separately.
         #[derive(Debug)]
         pub struct Atomic<T: Copy>(Cell<T>);
 
@@ -77,7 +122,8 @@ cfg_if! {
             }
         }
 
-        impl<T: Copy + PartialEq> Atomic<T> {
+        impl<T: Copy> Atomic<T> {
+            #[inline]
             pub fn into_inner(self) -> T {
                 self.0.into_inner()
             }
@@ -92,10 +138,14 @@ cfg_if! {
                 self.0.set(val)
             }
 
+            #[inline]
             pub fn swap(&self, val: T, _: Ordering) -> T {
                 self.0.replace(val)
             }
+        }
 
+        impl<T: Copy + PartialEq> Atomic<T> {
+            #[inline]
             pub fn compare_exchange(&self,
                                     current: T,
                                     new: T,
@@ -113,6 +163,7 @@ cfg_if! {
         }
 
         impl<T: Add<Output=T> + Copy> Atomic<T> {
+            #[inline]
             pub fn fetch_add(&self, val: T, _: Ordering) -> T {
                 let old = self.0.get();
                 self.0.set(old + val);
@@ -271,6 +322,8 @@ cfg_if! {
 
         pub use std::sync::atomic::{AtomicBool, AtomicUsize, AtomicU32, AtomicU64};
 
+        pub use crossbeam_utils::atomic::AtomicCell;
+
         pub use std::sync::Arc as Lrc;
         pub use std::sync::Weak as Weak;