1#[cfg(loom)]
9pub use ::loom;
10
11#[cfg(loom)]
12macro_rules! loom {
13 ($($tt:tt)*) => { $($tt)* }
14}
15
16#[cfg(not(loom))]
17macro_rules! loom {
18 ($($tt:tt)*) => {};
19}
20
21#[cfg(loom)]
22macro_rules! not_loom {
23 ($($tt:tt)*) => {};
24}
25
26#[cfg(not(loom))]
27macro_rules! not_loom {
28 ($($tt:tt)*) => { $($tt)* }
29}
30
31pub mod cell {
32 loom! {
33 pub use loom::cell::UnsafeCell;
34 }
35 not_loom! {
36 pub struct UnsafeCell<T: ?Sized>(core::cell::UnsafeCell<T>);
37
38 impl<T: ?Sized> UnsafeCell<T> {
39 #[inline]
40 pub fn new(value: T) -> Self
41 where
42 T: Sized,
43 {
44 Self(core::cell::UnsafeCell::new(value))
45 }
46
47 #[inline]
48 pub fn with_mut<F, R>(&self, f: F) -> R
49 where
50 F: FnOnce(*mut T) -> R,
51 {
52 f(self.0.get())
53 }
54
55 #[inline]
56 pub fn with<F, R>(&self, f: F) -> R
57 where
58 F: FnOnce(*const T) -> R,
59 {
60 f(self.0.get())
61 }
62 }
63 }
64}
65
66pub mod future {
67 loom! {
68 pub use loom::future::AtomicWaker;
69 }
70 not_loom! {
71 pub struct AtomicWaker(futures::task::AtomicWaker);
72
73 impl AtomicWaker {
74 #[inline]
75 pub fn new() -> Self {
76 Self(futures::task::AtomicWaker::new())
77 }
78
79 #[inline]
80 pub fn register_by_ref(&self, waker: &core::task::Waker) {
81 self.0.register(waker);
82 }
83
84 #[inline]
85 pub fn wake(&self) {
86 self.0.wake();
87 }
88 }
89 }
90}
91
92pub mod hint {
93 loom! {
94 pub use loom::hint::unreachable_unchecked;
95 }
96 not_loom! {
97 pub use core::hint::unreachable_unchecked;
98 }
99}
100
101pub mod sync {
102 loom! {
103 pub use loom::sync::{Arc, Mutex};
104 }
105 not_loom! {
106 pub use std::sync::{Arc, Mutex};
107 }
108
109 pub mod atomic {
110 macro_rules! define_atomic {
111 ($atomic:ident, $prim:ident) => {
112 loom! {
113 pub use loom::sync::atomic::$atomic;
114 }
115 not_loom! {
116 pub struct $atomic(core::sync::atomic::$atomic);
117
118 impl $atomic {
119 #[inline]
120 pub fn new(v: $prim) -> Self {
121 Self(core::sync::atomic::$atomic::new(v))
122 }
123
124 #[inline]
125 pub fn with_mut<R>(&mut self, f: impl FnOnce(&mut $prim) -> R) -> R {
126 f(self.0.get_mut())
127 }
128
129 #[inline]
130 pub fn load(&self, order: Ordering) -> $prim {
131 self.0.load(order)
132 }
133
134 #[inline]
135 pub fn store(&self, val: $prim, order: Ordering) {
136 self.0.store(val, order)
137 }
138
139 #[inline]
140 pub fn fetch_add(&self, val: $prim, order: Ordering) -> $prim {
141 self.0.fetch_add(val, order)
142 }
143
144 #[inline]
145 pub fn fetch_sub(&self, val: $prim, order: Ordering) -> $prim {
146 self.0.fetch_sub(val, order)
147 }
148
149 #[inline]
150 pub fn fetch_or(&self, val: $prim, order: Ordering) -> $prim {
151 self.0.fetch_or(val, order)
152 }
153 }
154 }
155 };
156 }
157
158 define_atomic!(AtomicU8, u8);
159 define_atomic!(AtomicU16, u16);
160 define_atomic!(AtomicU32, u32);
161 define_atomic!(AtomicU64, u64);
162 define_atomic!(AtomicUsize, usize);
163 define_atomic!(AtomicI8, i8);
164 define_atomic!(AtomicI16, i16);
165 define_atomic!(AtomicI32, i32);
166 define_atomic!(AtomicI64, i64);
167 define_atomic!(AtomicIsize, isize);
168
169 loom! {
170 pub use loom::sync::atomic::AtomicBool;
171 }
172 not_loom! {
173 pub struct AtomicBool(core::sync::atomic::AtomicBool);
174
175 impl AtomicBool {
176 #[inline]
177 pub fn new(v: bool) -> Self {
178 Self(core::sync::atomic::AtomicBool::new(v))
179 }
180
181 #[inline]
182 pub fn load(&self, order: Ordering) -> bool {
183 self.0.load(order)
184 }
185
186 #[inline]
187 pub fn store(&self, val: bool, order: Ordering) {
188 self.0.store(val, order)
189 }
190 }
191 }
192
193 pub use core::sync::atomic::Ordering;
194 }
195
196 pub mod mpsc {
197 loom! {
198 pub use loom::sync::mpsc::{channel, Sender, Receiver};
199 }
200 not_loom! {
201 pub use std::sync::mpsc::{channel, Sender, Receiver};
202 }
203
204 pub use std::sync::mpsc::TryRecvError;
205 }
206}