4 use crate::cell::UnsafeCell;
6 use crate::ops::{Deref, DerefMut};
7 use crate::sync::atomic::{AtomicBool, Ordering};
10 pub struct SpinMutex<T> {
15 unsafe impl<T: Send> Send for SpinMutex<T> {}
16 unsafe impl<T: Send> Sync for SpinMutex<T> {}
18 pub struct SpinMutexGuard<'a, T: 'a> {
19 mutex: &'a SpinMutex<T>,
22 impl<'a, T> !Send for SpinMutexGuard<'a, T> {}
23 unsafe impl<'a, T: Sync> Sync for SpinMutexGuard<'a, T> {}
25 impl<T> SpinMutex<T> {
26 pub const fn new(value: T) -> Self {
27 SpinMutex { value: UnsafeCell::new(value), lock: AtomicBool::new(false) }
31 pub fn lock(&self) -> SpinMutexGuard<'_, T> {
33 match self.try_lock() {
35 while self.lock.load(Ordering::Relaxed) {
39 Some(guard) => return guard,
45 pub fn try_lock(&self) -> Option<SpinMutexGuard<'_, T>> {
46 if self.lock.compare_exchange(false, true, Ordering::Acquire, Ordering::Acquire).is_ok() {
47 Some(SpinMutexGuard { mutex: self })
54 /// Lock the Mutex or return false.
55 pub macro try_lock_or_false($e:expr) {
56 if let Some(v) = $e.try_lock() { v } else { return false }
59 impl<'a, T> Deref for SpinMutexGuard<'a, T> {
62 fn deref(&self) -> &T {
63 unsafe { &*self.mutex.value.get() }
67 impl<'a, T> DerefMut for SpinMutexGuard<'a, T> {
68 fn deref_mut(&mut self) -> &mut T {
69 unsafe { &mut *self.mutex.value.get() }
73 impl<'a, T> Drop for SpinMutexGuard<'a, T> {
75 self.mutex.lock.store(false, Ordering::Release)