lockfree_object_pool/
spin_lock.rs
1use std::cell::UnsafeCell;
2use std::ops::{Deref, DerefMut};
3use std::sync::atomic::{AtomicBool, Ordering};
4use std::thread;
5
6pub struct SpinLock<T> {
7 data: UnsafeCell<T>,
8 lock: AtomicBool,
9}
10
11impl<T> SpinLock<T> {
12 #[inline]
13 pub fn new(data: T) -> Self {
14 Self {
15 data: UnsafeCell::new(data),
16 lock: AtomicBool::new(false),
17 }
18 }
19
20 #[inline]
21 pub fn lock(&self) -> SpinLockGuard<T> {
22 self.acquire();
23 SpinLockGuard { lock: self }
24 }
25
26 #[inline]
27 fn acquire(&self) {
28 self.exchange(false, true);
29 }
30
31 #[inline]
32 fn release(&self) {
33 self.exchange(true, false);
34 }
35
36 #[inline]
37 fn exchange(&self, from: bool, to: bool) {
38 loop {
39 match self
40 .lock
41 .compare_exchange_weak(from, to, Ordering::SeqCst, Ordering::Relaxed)
42 {
43 Ok(_) => break,
44 Err(_) => {
45 thread::yield_now();
46 }
47 }
48 }
49 }
50}
51
52unsafe impl<T: Send> Send for SpinLock<T> {} unsafe impl<T: Send> Sync for SpinLock<T> {} pub struct SpinLockGuard<'a, T> {
56 lock: &'a SpinLock<T>,
57}
58
59impl<'a, T> DerefMut for SpinLockGuard<'a, T> {
60 #[inline]
61 fn deref_mut(&mut self) -> &mut Self::Target {
62 unsafe {
63 &mut *self.lock.data.get()
65 }
66 }
67}
68
69impl<'a, T> Deref for SpinLockGuard<'a, T> {
70 type Target = T;
71
72 #[inline]
73 fn deref(&self) -> &Self::Target {
74 unsafe {
75 &*self.lock.data.get()
77 }
78 }
79}
80
81impl<'a, T> Drop for SpinLockGuard<'a, T> {
82 #[inline]
83 fn drop(&mut self) {
84 self.lock.release();
85 }
86}
87
88unsafe impl<T: Send> Send for SpinLockGuard<'_, T> {} unsafe impl<T: Sync> Sync for SpinLockGuard<'_, T> {}