Rollup merge of #62577 - Zoxc:atomic-cell, r=matthewjasper
Add an AtomicCell abstraction Split out from https://github.com/rust-lang/rust/pull/61923.
This commit is contained in:
commit
5e1891c474
3 changed files with 56 additions and 1 deletions
|
@ -3018,6 +3018,7 @@ name = "rustc_data_structures"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"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)",
|
"ena 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"graphviz 0.0.0",
|
"graphviz 0.0.0",
|
||||||
"indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|
|
@ -18,6 +18,7 @@ lazy_static = "1"
|
||||||
serialize = { path = "../libserialize" }
|
serialize = { path = "../libserialize" }
|
||||||
graphviz = { path = "../libgraphviz" }
|
graphviz = { path = "../libgraphviz" }
|
||||||
cfg-if = "0.1.2"
|
cfg-if = "0.1.2"
|
||||||
|
crossbeam-utils = { version = "0.6.5", features = ["nightly"] }
|
||||||
stable_deref_trait = "1.0.0"
|
stable_deref_trait = "1.0.0"
|
||||||
rayon = { version = "0.2.0", package = "rustc-rayon" }
|
rayon = { version = "0.2.0", package = "rustc-rayon" }
|
||||||
rayon-core = { version = "0.2.0", package = "rustc-rayon-core" }
|
rayon-core = { version = "0.2.0", package = "rustc-rayon-core" }
|
||||||
|
|
|
@ -67,6 +67,51 @@ cfg_if! {
|
||||||
use std::ops::Add;
|
use std::ops::Add;
|
||||||
use std::panic::{resume_unwind, catch_unwind, AssertUnwindSafe};
|
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)]
|
#[derive(Debug)]
|
||||||
pub struct Atomic<T: Copy>(Cell<T>);
|
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 {
|
pub fn into_inner(self) -> T {
|
||||||
self.0.into_inner()
|
self.0.into_inner()
|
||||||
}
|
}
|
||||||
|
@ -92,10 +138,14 @@ cfg_if! {
|
||||||
self.0.set(val)
|
self.0.set(val)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn swap(&self, val: T, _: Ordering) -> T {
|
pub fn swap(&self, val: T, _: Ordering) -> T {
|
||||||
self.0.replace(val)
|
self.0.replace(val)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Copy + PartialEq> Atomic<T> {
|
||||||
|
#[inline]
|
||||||
pub fn compare_exchange(&self,
|
pub fn compare_exchange(&self,
|
||||||
current: T,
|
current: T,
|
||||||
new: T,
|
new: T,
|
||||||
|
@ -113,6 +163,7 @@ cfg_if! {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Add<Output=T> + Copy> Atomic<T> {
|
impl<T: Add<Output=T> + Copy> Atomic<T> {
|
||||||
|
#[inline]
|
||||||
pub fn fetch_add(&self, val: T, _: Ordering) -> T {
|
pub fn fetch_add(&self, val: T, _: Ordering) -> T {
|
||||||
let old = self.0.get();
|
let old = self.0.get();
|
||||||
self.0.set(old + val);
|
self.0.set(old + val);
|
||||||
|
@ -271,6 +322,8 @@ cfg_if! {
|
||||||
|
|
||||||
pub use std::sync::atomic::{AtomicBool, AtomicUsize, AtomicU32, AtomicU64};
|
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::Arc as Lrc;
|
||||||
pub use std::sync::Weak as Weak;
|
pub use std::sync::Weak as Weak;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue