polars_utils/
relaxed_cell.rs1use std::fmt;
2use std::sync::atomic::*;
3
4#[derive(Default)]
5#[repr(transparent)]
6pub struct RelaxedCell<T: AtomicNative>(T::Atomic);
7
8impl<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 get_mut(&mut self) -> &mut T {
26 T::get_mut(&mut self.0)
27 }
28}
29
30impl<T: AtomicNative> From<T> for RelaxedCell<T> {
31 #[inline(always)]
32 fn from(value: T) -> Self {
33 RelaxedCell(T::Atomic::from(value))
34 }
35}
36
37impl<T: AtomicNative> Clone for RelaxedCell<T> {
38 fn clone(&self) -> Self {
39 Self(T::Atomic::from(self.load()))
40 }
41}
42
43impl<T: AtomicNative> fmt::Debug for RelaxedCell<T> {
44 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
45 f.debug_tuple("RelaxedCell").field(&self.load()).finish()
46 }
47}
48
49pub trait AtomicNative: Sized + Default + fmt::Debug {
50 type Atomic: From<Self>;
51
52 fn load(atomic: &Self::Atomic) -> Self;
53 fn store(atomic: &Self::Atomic, val: Self);
54 fn fetch_add(atomic: &Self::Atomic, val: Self) -> Self;
55 fn get_mut(atomic: &mut Self::Atomic) -> &mut Self;
56}
57
58macro_rules! impl_relaxed_cell {
59 ($T:ty, $new:ident, $A:ty) => {
60 impl RelaxedCell<$T> {
61 pub const fn $new(value: $T) -> Self {
63 Self(<$A>::new(value))
64 }
65 }
66
67 impl AtomicNative for $T {
68 type Atomic = $A;
69
70 #[inline(always)]
71 fn load(atomic: &Self::Atomic) -> Self {
72 atomic.load(Ordering::Relaxed)
73 }
74
75 #[inline(always)]
76 fn store(atomic: &Self::Atomic, val: Self) {
77 atomic.store(val, Ordering::Relaxed);
78 }
79
80 #[inline(always)]
81 fn fetch_add(atomic: &Self::Atomic, val: Self) -> Self {
82 atomic.fetch_add(val, Ordering::Relaxed)
83 }
84
85 #[inline(always)]
86 fn get_mut(atomic: &mut Self::Atomic) -> &mut Self {
87 atomic.get_mut()
88 }
89 }
90 };
91}
92
93impl_relaxed_cell!(u8, new_u8, AtomicU8);
94impl_relaxed_cell!(u32, new_u32, AtomicU32);
95impl_relaxed_cell!(u64, new_u64, AtomicU64);
96impl_relaxed_cell!(usize, new_usize, AtomicUsize);
97
98impl RelaxedCell<bool> {
99 pub const fn new_bool(value: bool) -> Self {
101 Self(AtomicBool::new(value))
102 }
103}
104
105impl AtomicNative for bool {
106 type Atomic = AtomicBool;
107
108 #[inline(always)]
109 fn load(atomic: &Self::Atomic) -> Self {
110 atomic.load(Ordering::Relaxed)
111 }
112
113 #[inline(always)]
114 fn store(atomic: &Self::Atomic, val: Self) {
115 atomic.store(val, Ordering::Relaxed);
116 }
117
118 #[inline(always)]
119 fn fetch_add(_atomic: &Self::Atomic, _val: Self) -> Self {
120 unimplemented!()
121 }
122
123 #[inline(always)]
124 fn get_mut(atomic: &mut Self::Atomic) -> &mut Self {
125 atomic.get_mut()
126 }
127}