1use crate::base::*;
2use crate::prelude::v1::*;
3use crate::shim::*;
4use crate::units::*;
5
6pub type Mutex<T> = MutexImpl<T, MutexNormal>;
7pub type RecursiveMutex<T> = MutexImpl<T, MutexRecursive>;
8
9unsafe impl<T: Send, M> Send for MutexImpl<T, M> {}
10
11unsafe impl<T: Send, M> Sync for MutexImpl<T, M> {}
12
13pub struct MutexImpl<T: ?Sized, M> {
16 mutex: M,
17 data: UnsafeCell<T>,
18}
19
20impl<T: ?Sized, M> fmt::Debug for MutexImpl<T, M>
21where
22 M: MutexInnerImpl + fmt::Debug,
23{
24 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
25 write!(f, "Mutex address: {:?}", self.mutex)
26 }
27}
28
29impl<T, M> MutexImpl<T, M>
30where
31 M: MutexInnerImpl,
32{
33 pub fn new(value: T) -> Result<Self, FreeRtosError> {
35 Ok(Self::from_parts(M::create()?, value))
36 }
37
38 pub fn lock<D: DurationTicks>(
40 &self,
41 max_wait: D,
42 ) -> Result<MutexGuard<'_, T, M>, FreeRtosError> {
43 self.mutex.take(max_wait)?;
44
45 Ok(MutexGuard {
46 __mutex: &self.mutex,
47 __data: &self.data,
48 })
49 }
50
51 pub fn into_inner(self) -> T {
53 self.into_parts().1
54 }
55
56 pub fn get_mut(&mut self) -> &mut T {
60 self.data.get_mut()
61 }
62
63 pub fn from_parts(mutex: M, value: T) -> Self {
67 Self {
68 mutex,
69 data: UnsafeCell::new(value),
70 }
71 }
72
73 pub fn into_parts(self) -> (M, T) {
75 (self.mutex, self.data.into_inner())
76 }
77
78 pub fn inner_mutex_mut(&mut self) -> &mut M {
80 &mut self.mutex
81 }
82}
83
84pub struct MutexGuard<'a, T: ?Sized + 'a, M: 'a>
86where
87 M: MutexInnerImpl,
88{
89 __mutex: &'a M,
90 __data: &'a UnsafeCell<T>,
91}
92
93impl<'mutex, T: ?Sized, M> Deref for MutexGuard<'mutex, T, M>
94where
95 M: MutexInnerImpl,
96{
97 type Target = T;
98
99 fn deref<'a>(&'a self) -> &'a T {
100 unsafe { &*self.__data.get() }
101 }
102}
103
104impl<'mutex, T: ?Sized, M> DerefMut for MutexGuard<'mutex, T, M>
105where
106 M: MutexInnerImpl,
107{
108 fn deref_mut<'a>(&'a mut self) -> &'a mut T {
109 unsafe { &mut *self.__data.get() }
110 }
111}
112
113impl<'a, T: ?Sized, M> Drop for MutexGuard<'a, T, M>
114where
115 M: MutexInnerImpl,
116{
117 fn drop(&mut self) {
118 self.__mutex.give();
119 }
120}
121
122pub trait MutexInnerImpl
123where
124 Self: Sized,
125{
126 fn create() -> Result<Self, FreeRtosError>;
127 fn take<D: DurationTicks>(&self, max_wait: D) -> Result<(), FreeRtosError>;
128 fn give(&self);
129
130 unsafe fn from_raw_handle(handle: FreeRtosSemaphoreHandle) -> Self;
137 fn raw_handle(&self) -> FreeRtosSemaphoreHandle;
138}
139
140pub struct MutexNormal(FreeRtosSemaphoreHandle);
141
142impl MutexInnerImpl for MutexNormal {
143 fn create() -> Result<Self, FreeRtosError> {
144 let m = unsafe { freertos_rs_create_mutex() };
145 if m == 0 as *const _ {
146 return Err(FreeRtosError::OutOfMemory);
147 }
148 Ok(MutexNormal(m))
149 }
150
151 fn take<D: DurationTicks>(&self, max_wait: D) -> Result<(), FreeRtosError> {
152 let res = unsafe { freertos_rs_take_semaphore(self.0, max_wait.to_ticks()) };
153
154 if res != 0 {
155 return Err(FreeRtosError::MutexTimeout);
156 }
157
158 Ok(())
159 }
160
161 fn give(&self) {
162 unsafe {
163 freertos_rs_give_semaphore(self.0);
164 }
165 }
166
167 #[inline]
168 unsafe fn from_raw_handle(handle: FreeRtosSemaphoreHandle) -> Self {
169 Self(handle)
170 }
171
172 #[inline]
173 fn raw_handle(&self) -> FreeRtosSemaphoreHandle {
174 self.0
175 }
176}
177
178impl Drop for MutexNormal {
179 fn drop(&mut self) {
180 unsafe { freertos_rs_delete_semaphore(self.0) }
181 }
182}
183
184impl fmt::Debug for MutexNormal {
185 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
186 write!(f, "{:?}", self.0)
187 }
188}
189
190pub struct MutexRecursive(FreeRtosSemaphoreHandle);
191
192impl MutexInnerImpl for MutexRecursive {
193 fn create() -> Result<Self, FreeRtosError> {
194 let m = unsafe { freertos_rs_create_recursive_mutex() };
195 if m == 0 as *const _ {
196 return Err(FreeRtosError::OutOfMemory);
197 }
198 Ok(MutexRecursive(m))
199 }
200
201 fn take<D: DurationTicks>(&self, max_wait: D) -> Result<(), FreeRtosError> {
202 let res = unsafe { freertos_rs_take_recursive_semaphore(self.0, max_wait.to_ticks()) };
203
204 if res != 0 {
205 return Err(FreeRtosError::MutexTimeout);
206 }
207
208 Ok(())
209 }
210
211 fn give(&self) {
212 unsafe {
213 freertos_rs_give_recursive_semaphore(self.0);
214 }
215 }
216
217 #[inline]
218 unsafe fn from_raw_handle(handle: FreeRtosSemaphoreHandle) -> Self {
219 Self(handle)
220 }
221
222 #[inline]
223 fn raw_handle(&self) -> FreeRtosSemaphoreHandle {
224 self.0
225 }
226}
227
228impl Drop for MutexRecursive {
229 fn drop(&mut self) {
230 unsafe { freertos_rs_delete_semaphore(self.0) }
231 }
232}
233
234impl fmt::Debug for MutexRecursive {
235 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
236 write!(f, "{:?}", self.0)
237 }
238}
239
240use mutex_traits::{ConstInit, RawMutex};
241pub struct FreeRtosRawMutex {
243 inner: UnsafeCell<FreeRtosSemaphoreHandle>,
244}
245
246impl FreeRtosRawMutex {
247 pub const fn empty() -> Self {
249 Self {
250 inner: UnsafeCell::new(core::ptr::null()),
251 }
252 }
253
254 fn get_inner(&self) -> &FreeRtosSemaphoreHandle {
255 let inner = unsafe { &mut *self.inner.get() };
256 if (*inner).is_null() {
257 critical_section::with(|_| {
258 if (*inner).is_null() {
259 let m = unsafe { freertos_rs_create_mutex() };
260 if m.is_null() {
261 panic!();
262 }
263 *inner = m;
264 }
265 });
266 }
267 inner
268 }
269
270 #[inline]
271 fn try_lock_block(&self, block: bool) -> bool {
272 let t = if block {
273 FreeRtosTimeUnitsShimmed::get_max_wait()
274 } else {
275 0
276 };
277 let res = unsafe { freertos_rs_take_semaphore(*self.get_inner(), t) };
278 res == 0
279 }
280}
281
282unsafe impl Send for FreeRtosRawMutex {}
283
284impl ConstInit for FreeRtosRawMutex {
285 const INIT: Self = Self::empty();
286}
287
288unsafe impl RawMutex for FreeRtosRawMutex {
289 type GuardMarker = *mut ();
290
291 #[inline]
292 fn lock(&self) {
293 if !self.try_lock() {
294 panic!("Deadlocked");
295 }
296 }
297
298 #[inline]
299 fn try_lock(&self) -> bool {
300 self.try_lock_block(true)
301 }
302
303 #[inline]
304 unsafe fn unlock(&self) {
305 unsafe {
306 freertos_rs_give_semaphore(*self.get_inner());
307 }
308 }
309
310 #[inline]
311 fn is_locked(&self) -> bool {
312 if self.try_lock_block(false) {
313 unsafe {
314 self.unlock();
315 }
316 false
317 } else {
318 true
319 }
320 }
321}
322
323impl Drop for FreeRtosRawMutex {
324 fn drop(&mut self) {
325 unsafe { freertos_rs_delete_semaphore(*self.get_inner()) }
326 }
327}