1use core::{
11 cell::UnsafeCell,
12 ops::{Deref, DerefMut},
13 sync::atomic::{AtomicBool, AtomicU8, Ordering},
14};
15
16pub struct Mutex<T> {
20 locked: AtomicBool,
21 data: UnsafeCell<T>,
22}
23
24pub struct MutexGuard<'a, T> {
26 mutex: &'a Mutex<T>,
27}
28
29impl<T> Mutex<T> {
30 pub const fn new(data: T) -> Self {
32 Self { locked: AtomicBool::new(false), data: UnsafeCell::new(data) }
33 }
34
35 pub fn lock(&self) -> Result<MutexGuard<'_, T>, PoisonError<MutexGuard<'_, T>>> {
40 while self.locked.swap(true, Ordering::Acquire) {
41 core::hint::spin_loop();
42 }
43 Ok(MutexGuard { mutex: self })
44 }
45}
46
47unsafe impl<T: Send> Sync for Mutex<T> {}
49unsafe impl<T: Send> Send for Mutex<T> {}
50
51impl<T> Deref for MutexGuard<'_, T> {
52 type Target = T;
53
54 fn deref(&self) -> &T {
55 unsafe { &*self.mutex.data.get() }
57 }
58}
59
60impl<T> DerefMut for MutexGuard<'_, T> {
61 fn deref_mut(&mut self) -> &mut T {
62 unsafe { &mut *self.mutex.data.get() }
64 }
65}
66
67impl<T> Drop for MutexGuard<'_, T> {
68 fn drop(&mut self) {
69 self.mutex.locked.store(false, Ordering::Release);
70 }
71}
72
73pub struct PoisonError<T> {
77 _guard: T,
78}
79
80impl<T> PoisonError<T> {
81 #[allow(dead_code)]
82 pub fn new(guard: T) -> Self {
83 PoisonError { _guard: guard }
84 }
85}
86
87impl<T> core::fmt::Debug for PoisonError<T> {
88 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
89 f.write_str("PoisonError { .. }")
90 }
91}
92
93impl<T> core::fmt::Display for PoisonError<T> {
94 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
95 f.write_str("poisoned lock: another task failed while holding the lock")
96 }
97}
98
99const UNINIT: u8 = 0;
100const INITIALIZING: u8 = 1;
101const INITIALIZED: u8 = 2;
102
103pub struct OnceLock<T> {
108 inner: UnsafeCell<Option<T>>,
109 state: AtomicU8,
110}
111
112unsafe impl<T: Send> Sync for OnceLock<T> {}
115unsafe impl<T: Send> Send for OnceLock<T> {}
116
117impl<T> OnceLock<T> {
118 pub const fn new() -> Self {
120 OnceLock { inner: UnsafeCell::new(None), state: AtomicU8::new(UNINIT) }
121 }
122
123 pub fn get(&self) -> Option<&T> {
125 if self.state.load(Ordering::Acquire) == INITIALIZED {
126 unsafe { (*self.inner.get()).as_ref() }
128 } else {
129 None
130 }
131 }
132
133 pub fn set(&self, value: T) -> Result<(), T> {
135 match self.state.compare_exchange(
136 UNINIT,
137 INITIALIZING,
138 Ordering::Acquire,
139 Ordering::Acquire,
140 ) {
141 Ok(_) => {
142 unsafe {
144 *self.inner.get() = Some(value);
145 }
146 self.state.store(INITIALIZED, Ordering::Release);
147 Ok(())
148 }
149 Err(_) => Err(value),
150 }
151 }
152
153 pub fn get_or_init<F>(&self, f: F) -> &T
156 where
157 F: FnOnce() -> T,
158 {
159 match self.state.compare_exchange(
160 UNINIT,
161 INITIALIZING,
162 Ordering::Acquire,
163 Ordering::Acquire,
164 ) {
165 Ok(_) => {
166 let value = f();
167 unsafe {
169 *self.inner.get() = Some(value);
170 }
171 self.state.store(INITIALIZED, Ordering::Release);
172 }
173 Err(INITIALIZED) => {}
174 Err(_) => {
175 while self.state.load(Ordering::Acquire) != INITIALIZED {
176 core::hint::spin_loop();
177 }
178 }
179 }
180 unsafe { (*self.inner.get()).as_ref().unwrap() }
182 }
183}
184
185impl<T> Default for OnceLock<T> {
186 fn default() -> Self {
187 Self::new()
188 }
189}
190
191pub struct LazyLock<T, F = fn() -> T> {
196 once: OnceLock<T>,
197 init: Mutex<Option<F>>,
198}
199
200unsafe impl<T: Send + Sync, F: Send> Sync for LazyLock<T, F> {}
203unsafe impl<T: Send, F: Send> Send for LazyLock<T, F> {}
204
205impl<T, F: FnOnce() -> T> LazyLock<T, F> {
206 pub const fn new(f: F) -> Self {
208 LazyLock { once: OnceLock::new(), init: Mutex::new(Some(f)) }
209 }
210
211 pub fn force(&self) -> &T {
213 self.once.get_or_init(|| {
214 let f = self
215 .init
216 .lock()
217 .expect("LazyLock init mutex poisoned")
218 .take()
219 .expect("LazyLock init function already taken");
220 f()
221 })
222 }
223}
224
225impl<T, F: FnOnce() -> T> core::ops::Deref for LazyLock<T, F> {
226 type Target = T;
227
228 fn deref(&self) -> &Self::Target {
229 self.force()
230 }
231}