Skip to content

Commit bbd8c2f

Browse files
committed
Add an AtomicCell abstraction
1 parent 9743f63 commit bbd8c2f

File tree

2 files changed

+59
-1
lines changed

2 files changed

+59
-1
lines changed

src/librustc_data_structures/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ rustc_cratesio_shim = { path = "../librustc_cratesio_shim" }
1818
serialize = { path = "../libserialize" }
1919
graphviz = { path = "../libgraphviz" }
2020
cfg-if = "0.1.2"
21+
crossbeam-utils = { version = "0.6.5", features = ["nightly"] }
2122
stable_deref_trait = "1.0.0"
2223
rayon = { version = "0.2.0", package = "rustc-rayon" }
2324
rayon-core = { version = "0.2.0", package = "rustc-rayon-core" }

src/librustc_data_structures/sync.rs

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,59 @@ cfg_if! {
6969
use std::ops::Add;
7070
use std::panic::{resume_unwind, catch_unwind, AssertUnwindSafe};
7171

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

@@ -79,7 +132,7 @@ cfg_if! {
79132
}
80133
}
81134

82-
impl<T: Copy + PartialEq> Atomic<T> {
135+
impl<T: Copy> Atomic<T> {
83136
pub fn into_inner(self) -> T {
84137
self.0.into_inner()
85138
}
@@ -97,7 +150,9 @@ cfg_if! {
97150
pub fn swap(&self, val: T, _: Ordering) -> T {
98151
self.0.replace(val)
99152
}
153+
}
100154

155+
impl<T: Copy + PartialEq> Atomic<T> {
101156
pub fn compare_exchange(&self,
102157
current: T,
103158
new: T,
@@ -273,6 +328,8 @@ cfg_if! {
273328

274329
pub use std::sync::atomic::{AtomicBool, AtomicUsize, AtomicU32, AtomicU64};
275330

331+
pub use crossbeam_utils::atomic::AtomicCell;
332+
276333
pub use std::sync::Arc as Lrc;
277334
pub use std::sync::Weak as Weak;
278335

0 commit comments

Comments
 (0)