Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pola-rs
GitHub Repository: pola-rs/polars
Path: blob/main/crates/polars-utils/src/relaxed_cell.rs
8430 views
1
use std::fmt;
2
use std::sync::atomic::*;
3
4
#[derive(Default)]
5
#[repr(transparent)]
6
pub struct RelaxedCell<T: AtomicNative>(T::Atomic);
7
8
impl<T: AtomicNative> RelaxedCell<T> {
9
#[inline(always)]
10
pub fn load(&self) -> T {
11
T::load(&self.0)
12
}
13
14
#[inline(always)]
15
pub fn store(&self, value: T) {
16
T::store(&self.0, value)
17
}
18
19
#[inline(always)]
20
pub fn fetch_add(&self, value: T) -> T {
21
T::fetch_add(&self.0, value)
22
}
23
24
#[inline(always)]
25
pub fn fetch_sub(&self, value: T) -> T {
26
T::fetch_sub(&self.0, value)
27
}
28
29
#[inline(always)]
30
pub fn fetch_max(&self, value: T) -> T {
31
T::fetch_max(&self.0, value)
32
}
33
34
#[inline(always)]
35
pub fn get_mut(&mut self) -> &mut T {
36
T::get_mut(&mut self.0)
37
}
38
}
39
40
impl<T: AtomicNative> From<T> for RelaxedCell<T> {
41
#[inline(always)]
42
fn from(value: T) -> Self {
43
RelaxedCell(T::Atomic::from(value))
44
}
45
}
46
47
impl<T: AtomicNative> Clone for RelaxedCell<T> {
48
fn clone(&self) -> Self {
49
Self(T::Atomic::from(self.load()))
50
}
51
}
52
53
impl<T: AtomicNative> fmt::Debug for RelaxedCell<T> {
54
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55
f.debug_tuple("RelaxedCell").field(&self.load()).finish()
56
}
57
}
58
59
pub trait AtomicNative: Sized + Default + fmt::Debug {
60
type Atomic: From<Self>;
61
62
fn load(atomic: &Self::Atomic) -> Self;
63
fn store(atomic: &Self::Atomic, val: Self);
64
fn fetch_add(atomic: &Self::Atomic, val: Self) -> Self;
65
fn fetch_sub(atomic: &Self::Atomic, val: Self) -> Self;
66
fn fetch_max(atomic: &Self::Atomic, val: Self) -> Self;
67
fn get_mut(atomic: &mut Self::Atomic) -> &mut Self;
68
}
69
70
macro_rules! impl_relaxed_cell {
71
($T:ty, $new:ident, $A:ty) => {
72
impl RelaxedCell<$T> {
73
// Not part of the trait as it should be const.
74
pub const fn $new(value: $T) -> Self {
75
Self(<$A>::new(value))
76
}
77
}
78
79
impl AtomicNative for $T {
80
type Atomic = $A;
81
82
#[inline(always)]
83
fn load(atomic: &Self::Atomic) -> Self {
84
atomic.load(Ordering::Relaxed)
85
}
86
87
#[inline(always)]
88
fn store(atomic: &Self::Atomic, val: Self) {
89
atomic.store(val, Ordering::Relaxed);
90
}
91
92
#[inline(always)]
93
fn fetch_add(atomic: &Self::Atomic, val: Self) -> Self {
94
atomic.fetch_add(val, Ordering::Relaxed)
95
}
96
97
#[inline(always)]
98
fn fetch_sub(atomic: &Self::Atomic, val: Self) -> Self {
99
atomic.fetch_sub(val, Ordering::Relaxed)
100
}
101
102
#[inline(always)]
103
fn fetch_max(atomic: &Self::Atomic, val: Self) -> Self {
104
atomic.fetch_max(val, Ordering::Relaxed)
105
}
106
107
#[inline(always)]
108
fn get_mut(atomic: &mut Self::Atomic) -> &mut Self {
109
atomic.get_mut()
110
}
111
}
112
};
113
}
114
115
impl_relaxed_cell!(u8, new_u8, AtomicU8);
116
impl_relaxed_cell!(u32, new_u32, AtomicU32);
117
impl_relaxed_cell!(u64, new_u64, AtomicU64);
118
impl_relaxed_cell!(usize, new_usize, AtomicUsize);
119
120
impl RelaxedCell<bool> {
121
// Not part of the trait as it should be const.
122
pub const fn new_bool(value: bool) -> Self {
123
Self(AtomicBool::new(value))
124
}
125
126
#[inline(always)]
127
pub fn fetch_or(&self, val: bool) -> bool {
128
self.0.fetch_or(val, Ordering::Relaxed)
129
}
130
}
131
132
impl AtomicNative for bool {
133
type Atomic = AtomicBool;
134
135
#[inline(always)]
136
fn load(atomic: &Self::Atomic) -> Self {
137
atomic.load(Ordering::Relaxed)
138
}
139
140
#[inline(always)]
141
fn store(atomic: &Self::Atomic, val: Self) {
142
atomic.store(val, Ordering::Relaxed);
143
}
144
145
#[inline(always)]
146
fn fetch_add(_atomic: &Self::Atomic, _val: Self) -> Self {
147
unimplemented!()
148
}
149
150
#[inline(always)]
151
fn fetch_sub(_atomic: &Self::Atomic, _val: Self) -> Self {
152
unimplemented!()
153
}
154
155
#[inline(always)]
156
fn fetch_max(atomic: &Self::Atomic, val: Self) -> Self {
157
atomic.fetch_or(val, Ordering::Relaxed)
158
}
159
160
#[inline(always)]
161
fn get_mut(atomic: &mut Self::Atomic) -> &mut Self {
162
atomic.get_mut()
163
}
164
}
165
166