1use core::{
27 cell::UnsafeCell,
28 fmt::{Debug, Display},
29 ops::{Deref, DerefMut},
30 sync::atomic::{AtomicBool, Ordering},
31};
32use vera_portal::sys_client::yield_now;
33
34pub struct Mutex<T: ?Sized> {
36 lock: AtomicBool,
37 inner: UnsafeCell<T>,
38}
39
40unsafe impl<T: ?Sized> Send for Mutex<T> {}
41unsafe impl<T: ?Sized> Sync for Mutex<T> {}
42
43impl<T> Mutex<T> {
44 pub const fn new(value: T) -> Self {
46 Self {
47 lock: AtomicBool::new(false),
48 inner: UnsafeCell::new(value),
49 }
50 }
51}
52
53impl<T: ?Sized> Mutex<T> {
54 pub fn try_lock<'a>(&'a self) -> Option<MutexGuard<'a, T>> {
56 while let Err(failed_lock) =
57 self.lock
58 .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed)
59 {
60 if failed_lock {
62 return None;
63 }
64 }
65
66 Some(MutexGuard {
67 lock: &self.lock,
68 ptr: self.inner.get(),
69 })
70 }
71
72 pub fn lock<'a>(&'a self) -> MutexGuard<'a, T> {
74 loop {
75 match self.try_lock() {
76 Some(lock) => return lock,
77 None => {
78 yield_now();
80 }
81 }
82 }
83 }
84}
85
86pub struct MutexGuard<'a, T: ?Sized> {
88 lock: &'a AtomicBool,
89 ptr: *mut T,
90}
91
92impl<'a, T: ?Sized> Drop for MutexGuard<'a, T> {
93 fn drop(&mut self) {
94 while let Err(failed_unlock) =
95 self.lock
96 .compare_exchange(true, false, Ordering::Release, Ordering::Relaxed)
97 {
98 assert!(
99 failed_unlock,
100 "Mutex is marked as unlocked while dropping MutexGuard"
101 );
102 }
103 }
104}
105
106impl<'a, T: ?Sized> Deref for MutexGuard<'a, T> {
107 type Target = T;
108
109 fn deref(&self) -> &Self::Target {
110 unsafe { &*self.ptr }
111 }
112}
113
114impl<'a, T: ?Sized> DerefMut for MutexGuard<'a, T> {
115 fn deref_mut(&mut self) -> &mut Self::Target {
116 unsafe { &mut *self.ptr }
117 }
118}
119
120impl<'a, T: ?Sized + Debug> Debug for MutexGuard<'a, T> {
121 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
122 unsafe { &*self.ptr }.fmt(f)
123 }
124}
125
126impl<'a, T: ?Sized + Display> Display for MutexGuard<'a, T> {
127 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
128 unsafe { &*self.ptr }.fmt(f)
129 }
130}
131
132impl<T: Clone> Clone for Mutex<T> {
133 fn clone(&self) -> Self {
134 Mutex::new(self.lock().clone())
135 }
136}