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>(&self, max_wait: D) -> Result<MutexGuard<'_, T, M>, FreeRtosError> {
40 self.mutex.take(max_wait)?;
41
42 Ok(MutexGuard {
43 __mutex: &self.mutex,
44 __data: &self.data,
45 })
46 }
47
48 pub fn into_inner(self) -> T {
50 self.into_parts().1
51 }
52
53 pub fn get_mut(&mut self) -> &mut T {
57 self.data.get_mut()
58 }
59
60 pub fn from_parts(mutex: M, value: T) -> Self {
64 Self {
65 mutex,
66 data: UnsafeCell::new(value),
67 }
68 }
69
70 pub fn into_parts(self) -> (M, T) {
72 (self.mutex, self.data.into_inner())
73 }
74
75 pub fn inner_mutex_mut(&mut self) -> &mut M {
77 &mut self.mutex
78 }
79}
80
81pub struct MutexGuard<'a, T: ?Sized + 'a, M: 'a>
83where
84 M: MutexInnerImpl,
85{
86 __mutex: &'a M,
87 __data: &'a UnsafeCell<T>,
88}
89
90impl<'mutex, T: ?Sized, M> Deref for MutexGuard<'mutex, T, M>
91where
92 M: MutexInnerImpl,
93{
94 type Target = T;
95
96 fn deref<'a>(&'a self) -> &'a T {
97 unsafe { &*self.__data.get() }
98 }
99}
100
101impl<'mutex, T: ?Sized, M> DerefMut for MutexGuard<'mutex, T, M>
102where
103 M: MutexInnerImpl,
104{
105 fn deref_mut<'a>(&'a mut self) -> &'a mut T {
106 unsafe { &mut *self.__data.get() }
107 }
108}
109
110impl<'a, T: ?Sized, M> Drop for MutexGuard<'a, T, M>
111where
112 M: MutexInnerImpl,
113{
114 fn drop(&mut self) {
115 self.__mutex.give();
116 }
117}
118
119pub trait MutexInnerImpl
120where
121 Self: Sized,
122{
123 fn create() -> Result<Self, FreeRtosError>;
124 fn take<D: DurationTicks>(&self, max_wait: D) -> Result<(), FreeRtosError>;
125 fn give(&self);
126
127 unsafe fn from_raw_handle(handle: FreeRtosSemaphoreHandle) -> Self;
134 fn raw_handle(&self) -> FreeRtosSemaphoreHandle;
135}
136
137pub struct MutexNormal(FreeRtosSemaphoreHandle);
138
139impl MutexInnerImpl for MutexNormal {
140 fn create() -> Result<Self, FreeRtosError> {
141 let m = unsafe { freertos_rs_create_mutex() };
142 if m == 0 as *const _ {
143 return Err(FreeRtosError::OutOfMemory);
144 }
145 Ok(MutexNormal(m))
146 }
147
148 fn take<D: DurationTicks>(&self, max_wait: D) -> Result<(), FreeRtosError> {
149 let res = unsafe { freertos_rs_take_semaphore(self.0, max_wait.to_ticks()) };
150
151 if res != 0 {
152 return Err(FreeRtosError::MutexTimeout);
153 }
154
155 Ok(())
156 }
157
158 fn give(&self) {
159 unsafe {
160 freertos_rs_give_semaphore(self.0);
161 }
162 }
163
164 #[inline]
165 unsafe fn from_raw_handle(handle: FreeRtosSemaphoreHandle) -> Self {
166 Self(handle)
167 }
168
169 #[inline]
170 fn raw_handle(&self) -> FreeRtosSemaphoreHandle {
171 self.0
172 }
173}
174
175impl Drop for MutexNormal {
176 fn drop(&mut self) {
177 unsafe { freertos_rs_delete_semaphore(self.0) }
178 }
179}
180
181impl fmt::Debug for MutexNormal {
182 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
183 write!(f, "{:?}", self.0)
184 }
185}
186
187pub struct MutexRecursive(FreeRtosSemaphoreHandle);
188
189impl MutexInnerImpl for MutexRecursive {
190 fn create() -> Result<Self, FreeRtosError> {
191 let m = unsafe { freertos_rs_create_recursive_mutex() };
192 if m == 0 as *const _ {
193 return Err(FreeRtosError::OutOfMemory);
194 }
195 Ok(MutexRecursive(m))
196 }
197
198 fn take<D: DurationTicks>(&self, max_wait: D) -> Result<(), FreeRtosError> {
199 let res = unsafe { freertos_rs_take_recursive_semaphore(self.0, max_wait.to_ticks()) };
200
201 if res != 0 {
202 return Err(FreeRtosError::MutexTimeout);
203 }
204
205 Ok(())
206 }
207
208 fn give(&self) {
209 unsafe {
210 freertos_rs_give_recursive_semaphore(self.0);
211 }
212 }
213
214 #[inline]
215 unsafe fn from_raw_handle(handle: FreeRtosSemaphoreHandle) -> Self {
216 Self(handle)
217 }
218
219 #[inline]
220 fn raw_handle(&self) -> FreeRtosSemaphoreHandle {
221 self.0
222 }
223}
224
225impl Drop for MutexRecursive {
226 fn drop(&mut self) {
227 unsafe { freertos_rs_delete_semaphore(self.0) }
228 }
229}
230
231impl fmt::Debug for MutexRecursive {
232 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
233 write!(f, "{:?}", self.0)
234 }
235}