Skip to content

Commit

Permalink
Add an AtomicCell abstraction
Browse files Browse the repository at this point in the history
  • Loading branch information
Zoxc committed Jul 10, 2019
1 parent d4e1565 commit 498bdc9
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 1 deletion.
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3019,6 +3019,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)",
Expand Down
1 change: 1 addition & 0 deletions src/librustc_data_structures/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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" }
Expand Down
55 changes: 54 additions & 1 deletion src/librustc_data_structures/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>);

Expand All @@ -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()
}
Expand All @@ -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,
Expand All @@ -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);
Expand Down Expand Up @@ -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;

Expand Down

0 comments on commit 498bdc9

Please sign in to comment.