conc_util/sync/
spinlock.rs1use core::{
2 cell::UnsafeCell,
3 ops::{Deref, DerefMut},
4 sync::atomic::{AtomicBool, Ordering},
5};
6
7#[derive(Debug)]
8pub struct SpinLock<T = ()>(AtomicBool, UnsafeCell<T>);
9
10unsafe impl Sync for SpinLock {}
12
13impl<T> SpinLock<T> {
14 pub fn new(data: T) -> Self {
15 Self(AtomicBool::new(false), UnsafeCell::new(data))
16 }
17
18 pub fn get(&mut self) -> &mut T {
19 self.1.get_mut()
20 }
21
22 pub fn lock<'a>(&'a self) -> SpinLockScope<'a, T> {
23 while self.0.swap(true, Ordering::AcqRel) {}
24 let locked = unsafe { self.1.get().as_mut_unchecked() };
26 SpinLockScope(&self.0, locked)
27 }
28}
29
30#[derive(Debug)]
31pub struct SpinLockScope<'a, T>(&'a AtomicBool, &'a mut T);
32
33impl<'a, T> Drop for SpinLockScope<'a, T> {
34 fn drop(&mut self) {
35 self.0.store(false, Ordering::Release);
36 }
37}
38
39impl<'a, T> Deref for SpinLockScope<'a, T> {
40 type Target = T;
41
42 fn deref(&self) -> &Self::Target {
43 self.1
44 }
45}
46
47impl<'a, T> DerefMut for SpinLockScope<'a, T> {
48 fn deref_mut(&mut self) -> &mut Self::Target {
49 self.1
50 }
51}