Skip to content

Commit 5afd523

Browse files
committed
Add an AtomicCell abstraction
1 parent 5384ce8 commit 5afd523

File tree

2 files changed

+71
-1
lines changed

2 files changed

+71
-1
lines changed

src/librustc_data_structures/Cargo.toml

Lines changed: 1 addition & 0 deletions
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

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,71 @@ 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+
#[inline]
80+
pub fn get_mut(&mut self) -> &mut T {
81+
self.0.get_mut()
82+
}
83+
}
84+
85+
impl<T: Copy> AtomicCell<T> {
86+
pub fn into_inner(self) -> T {
87+
self.0.into_inner()
88+
}
89+
90+
#[inline]
91+
pub fn load(&self) -> T {
92+
self.0.get()
93+
}
94+
95+
#[inline]
96+
pub fn store(&self, val: T) {
97+
self.0.set(val)
98+
}
99+
100+
pub fn swap(&self, val: T) -> T {
101+
self.0.replace(val)
102+
}
103+
}
104+
105+
impl<T: Copy + PartialEq> AtomicCell<T> {
106+
pub fn compare_and_swap(&self, current: T, new: T) -> T {
107+
match self.compare_exchange(current, new) {
108+
Ok(v) => v,
109+
Err(v) => v,
110+
}
111+
}
112+
113+
pub fn compare_exchange(&self,
114+
current: T,
115+
new: T)
116+
-> Result<T, T> {
117+
let read = self.0.get();
118+
if read == current {
119+
self.0.set(new);
120+
Ok(read)
121+
} else {
122+
Err(read)
123+
}
124+
}
125+
}
126+
127+
impl<T: Add<Output=T> + Copy> AtomicCell<T> {
128+
pub fn fetch_add(&self, val: T) -> T {
129+
let old = self.0.get();
130+
self.0.set(old + val);
131+
old
132+
}
133+
}
134+
70135
#[derive(Debug)]
71136
pub struct Atomic<T: Copy>(Cell<T>);
72137

@@ -77,7 +142,7 @@ cfg_if! {
77142
}
78143
}
79144

80-
impl<T: Copy + PartialEq> Atomic<T> {
145+
impl<T: Copy> Atomic<T> {
81146
pub fn into_inner(self) -> T {
82147
self.0.into_inner()
83148
}
@@ -95,7 +160,9 @@ cfg_if! {
95160
pub fn swap(&self, val: T, _: Ordering) -> T {
96161
self.0.replace(val)
97162
}
163+
}
98164

165+
impl<T: Copy + PartialEq> Atomic<T> {
99166
pub fn compare_exchange(&self,
100167
current: T,
101168
new: T,
@@ -271,6 +338,8 @@ cfg_if! {
271338

272339
pub use std::sync::atomic::{AtomicBool, AtomicUsize, AtomicU32, AtomicU64};
273340

341+
pub use crossbeam_utils::atomic::AtomicCell;
342+
274343
pub use std::sync::Arc as Lrc;
275344
pub use std::sync::Weak as Weak;
276345

0 commit comments

Comments
 (0)