Skip to content

Commit 57446d0

Browse files
committed
Add an AtomicCell abstraction
1 parent 9f06855 commit 57446d0

File tree

3 files changed

+60
-1
lines changed

3 files changed

+60
-1
lines changed

Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -2780,6 +2780,7 @@ name = "rustc_data_structures"
27802780
version = "0.0.0"
27812781
dependencies = [
27822782
"cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
2783+
"crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
27832784
"ena 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
27842785
"graphviz 0.0.0",
27852786
"indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",

src/librustc_data_structures/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ rustc_cratesio_shim = { path = "../librustc_cratesio_shim" }
1919
serialize = { path = "../libserialize" }
2020
graphviz = { path = "../libgraphviz" }
2121
cfg-if = "0.1.2"
22+
crossbeam-utils = { version = "0.6.5", features = ["nightly"] }
2223
stable_deref_trait = "1.0.0"
2324
rayon = { version = "0.2.0", package = "rustc-rayon" }
2425
rayon-core = { version = "0.2.0", package = "rustc-rayon-core" }

src/librustc_data_structures/sync.rs

+58-1
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,59 @@ cfg_if! {
6767
use std::ops::Add;
6868
use std::panic::{resume_unwind, catch_unwind, AssertUnwindSafe};
6969

70+
#[derive(Debug)]
71+
pub struct AtomicCell<T: Copy>(Cell<T>);
72+
73+
impl<T: Copy> AtomicCell<T> {
74+
#[inline]
75+
pub fn new(v: T) -> Self {
76+
AtomicCell(Cell::new(v))
77+
}
78+
}
79+
80+
impl<T: Copy> AtomicCell<T> {
81+
pub fn into_inner(self) -> T {
82+
self.0.into_inner()
83+
}
84+
85+
#[inline]
86+
pub fn load(&self) -> T {
87+
self.0.get()
88+
}
89+
90+
#[inline]
91+
pub fn store(&self, val: T) {
92+
self.0.set(val)
93+
}
94+
95+
pub fn swap(&self, val: T) -> T {
96+
self.0.replace(val)
97+
}
98+
}
99+
100+
impl<T: Copy + PartialEq> AtomicCell<T> {
101+
pub fn compare_exchange(&self,
102+
current: T,
103+
new: T)
104+
-> Result<T, T> {
105+
let read = self.0.get();
106+
if read == current {
107+
self.0.set(new);
108+
Ok(read)
109+
} else {
110+
Err(read)
111+
}
112+
}
113+
}
114+
115+
impl<T: Add<Output=T> + Copy> AtomicCell<T> {
116+
pub fn fetch_add(&self, val: T) -> T {
117+
let old = self.0.get();
118+
self.0.set(old + val);
119+
old
120+
}
121+
}
122+
70123
#[derive(Debug)]
71124
pub struct Atomic<T: Copy>(Cell<T>);
72125

@@ -77,7 +130,7 @@ cfg_if! {
77130
}
78131
}
79132

80-
impl<T: Copy + PartialEq> Atomic<T> {
133+
impl<T: Copy> Atomic<T> {
81134
pub fn into_inner(self) -> T {
82135
self.0.into_inner()
83136
}
@@ -95,7 +148,9 @@ cfg_if! {
95148
pub fn swap(&self, val: T, _: Ordering) -> T {
96149
self.0.replace(val)
97150
}
151+
}
98152

153+
impl<T: Copy + PartialEq> Atomic<T> {
99154
pub fn compare_exchange(&self,
100155
current: T,
101156
new: T,
@@ -271,6 +326,8 @@ cfg_if! {
271326

272327
pub use std::sync::atomic::{AtomicBool, AtomicUsize, AtomicU32, AtomicU64};
273328

329+
pub use crossbeam_utils::atomic::AtomicCell;
330+
274331
pub use std::sync::Arc as Lrc;
275332
pub use std::sync::Weak as Weak;
276333

0 commit comments

Comments
 (0)