1use core::cell::UnsafeCell;
17use core::ops::{Deref, DerefMut};
18use core::sync::atomic::AtomicBool;
19use core::sync::atomic::Ordering::{AcqRel, Relaxed, Release};
20
21#[derive(Default)]
22pub struct SpinLock<T> {
23 locked: AtomicBool,
24 value: UnsafeCell<T>,
25}
26
27unsafe impl<T> Sync for SpinLock<T> where T: Send {}
28
29pub struct Guard<'a, T> {
30 lock: &'a SpinLock<T>,
31}
32
33unsafe impl<T> Sync for Guard<'_, T> where T: Sync {}
34
35impl<T> SpinLock<T> {
36 pub const fn new(value: T) -> Self {
37 Self {
38 locked: AtomicBool::new(false),
39 value: UnsafeCell::new(value),
40 }
41 }
42
43 #[inline]
44 pub fn lock(&self) -> Guard<'_, T> {
45 loop {
46 if !self.locked.swap(true, AcqRel) {
48 break; }
50
51 while self.locked.load(Relaxed) {
53 core::hint::spin_loop();
54 }
55 }
56
57 Guard { lock: self }
58 }
59}
60
61impl<T> Deref for Guard<'_, T> {
62 type Target = T;
63 #[inline]
64 fn deref(&self) -> &T {
65 unsafe { &*self.lock.value.get() }
68 }
69}
70
71impl<T> DerefMut for Guard<'_, T> {
72 #[inline]
73 fn deref_mut(&mut self) -> &mut T {
74 unsafe { &mut *self.lock.value.get() }
77 }
78}
79
80impl<T> Drop for Guard<'_, T> {
81 #[inline]
82 fn drop(&mut self) {
83 self.lock.locked.store(false, Release);
84 }
85}