4 use crate::cell
::UnsafeCell
;
5 use crate::ops
::{Deref, DerefMut}
;
6 use crate::sync
::atomic
::{spin_loop_hint, AtomicBool, Ordering}
;
9 pub struct SpinMutex
<T
> {
14 unsafe impl<T
: Send
> Send
for SpinMutex
<T
> {}
15 unsafe impl<T
: Send
> Sync
for SpinMutex
<T
> {}
17 pub struct SpinMutexGuard
<'a
, T
: 'a
> {
18 mutex
: &'a SpinMutex
<T
>,
21 impl<'a
, T
> !Send
for SpinMutexGuard
<'a
, T
> {}
22 unsafe impl<'a
, T
: Sync
> Sync
for SpinMutexGuard
<'a
, T
> {}
24 impl<T
> SpinMutex
<T
> {
25 pub const fn new(value
: T
) -> Self {
26 SpinMutex { value: UnsafeCell::new(value), lock: AtomicBool::new(false) }
30 pub fn lock(&self) -> SpinMutexGuard
<'_
, T
> {
32 match self.try_lock() {
34 while self.lock
.load(Ordering
::Relaxed
) {
38 Some(guard
) => return guard
,
44 pub fn try_lock(&self) -> Option
<SpinMutexGuard
<'_
, T
>> {
45 if self.lock
.compare_exchange(false, true, Ordering
::Acquire
, Ordering
::Acquire
).is_ok() {
46 Some(SpinMutexGuard { mutex: self }
)
53 /// Lock the Mutex or return false.
54 pub macro try_lock_or_false($e
:expr
) {
55 if let Some(v
) = $e
.try_lock() { v }
else { return false }
58 impl<'a
, T
> Deref
for SpinMutexGuard
<'a
, T
> {
61 fn deref(&self) -> &T
{
62 unsafe { &*self.mutex.value.get() }
66 impl<'a
, T
> DerefMut
for SpinMutexGuard
<'a
, T
> {
67 fn deref_mut(&mut self) -> &mut T
{
68 unsafe { &mut *self.mutex.value.get() }
72 impl<'a
, T
> Drop
for SpinMutexGuard
<'a
, T
> {
74 self.mutex
.lock
.store(false, Ordering
::Release
)