1use super::MTX_UNOWNED;
2use crate::context::{BorrowedArc, current_thread};
3use alloc::rc::Rc;
4use core::cell::UnsafeCell;
5use core::marker::PhantomData;
6use core::ops::{Deref, DerefMut};
7use core::sync::atomic::{AtomicUsize, Ordering};
8
9pub struct Mutex<T> {
11 data: UnsafeCell<T>,
12 owning: AtomicUsize, phantom: PhantomData<Rc<()>>, }
15
16impl<T> Mutex<T> {
17 pub const fn new(data: T) -> Self {
19 Self {
20 data: UnsafeCell::new(data),
21 owning: AtomicUsize::new(MTX_UNOWNED),
22 phantom: PhantomData,
23 }
24 }
25
26 pub fn lock(&self) -> MutexGuard<'_, T> {
36 let td = current_thread();
38
39 if !td.can_sleep() {
40 panic!("locking a mutex in a non-sleeping context is not supported");
41 }
42
43 let new_owner = BorrowedArc::as_ptr(&td) as usize;
45
46 if let Err(p) = self.owning.compare_exchange(
47 MTX_UNOWNED,
48 new_owner,
49 Ordering::Acquire,
50 Ordering::Relaxed,
51 ) {
52 if p == new_owner {
53 panic!("attempt to recursive lock on a mutex");
54 }
55
56 todo!()
57 }
58
59 td.set_active_mutexes(td.active_mutexes() + 1);
60
61 MutexGuard {
62 data: self.data.get(),
63 lock: &self.owning,
64 phantom: PhantomData,
65 }
66 }
67
68 unsafe fn unlock(lock: &AtomicUsize) {
73 let td = current_thread();
74
75 td.set_active_mutexes(td.active_mutexes() - 1);
76
77 if lock
79 .compare_exchange(
80 BorrowedArc::as_ptr(&td) as usize,
81 MTX_UNOWNED,
82 Ordering::Release,
83 Ordering::Relaxed,
84 )
85 .is_err()
86 {
87 todo!()
88 }
89 }
90}
91
92impl<T: Default> Default for Mutex<T> {
93 fn default() -> Self {
94 Self::new(T::default())
95 }
96}
97
98unsafe impl<T: Send> Send for Mutex<T> {}
99unsafe impl<T: Send> Sync for Mutex<T> {}
100
101pub struct MutexGuard<'a, T> {
106 data: *mut T,
107 lock: *const AtomicUsize,
108 phantom: PhantomData<&'a Mutex<T>>,
109}
110
111impl<'a, T> MutexGuard<'a, T> {
112 pub fn map<O, F>(this: Self, f: F) -> MappedMutex<'a, O>
113 where
114 F: FnOnce(&'a mut T) -> O + 'a,
115 {
116 let data = unsafe { f(&mut *this.data) };
117 let lock = this.lock;
118
119 core::mem::forget(this);
120
121 MappedMutex {
122 data,
123 lock,
124 phantom: PhantomData,
125 }
126 }
127}
128
129impl<T> Drop for MutexGuard<'_, T> {
130 fn drop(&mut self) {
131 unsafe { Mutex::<T>::unlock(&*self.lock) };
133 }
134}
135
136impl<T> Deref for MutexGuard<'_, T> {
137 type Target = T;
138
139 fn deref(&self) -> &Self::Target {
140 unsafe { &*self.data }
141 }
142}
143
144impl<T> DerefMut for MutexGuard<'_, T> {
145 fn deref_mut(&mut self) -> &mut Self::Target {
146 unsafe { &mut *self.data }
147 }
148}
149
150unsafe impl<T: Sync> Sync for MutexGuard<'_, T> {}
151
152pub struct MappedMutex<'a, T> {
156 data: T,
157 lock: *const AtomicUsize,
158 phantom: PhantomData<&'a Mutex<T>>,
159}
160
161impl<T> Drop for MappedMutex<'_, T> {
162 fn drop(&mut self) {
163 unsafe { Mutex::<T>::unlock(&*self.lock) };
165 }
166}
167
168impl<T> Deref for MappedMutex<'_, T> {
169 type Target = T;
170
171 fn deref(&self) -> &Self::Target {
172 &self.data
173 }
174}
175
176impl<T> DerefMut for MappedMutex<'_, T> {
177 fn deref_mut(&mut self) -> &mut Self::Target {
178 &mut self.data
179 }
180}
181
182unsafe impl<T: Sync> Sync for MappedMutex<'_, T> {}