1use crate::prelude::v1::*;
2use crate::base::*;
3use crate::units::*;
4use crate::shim::*;
5
6pub type Mutex<T> = MutexImpl<T, MutexNormal>;
7pub type RecursiveMutex<T> = MutexImpl<T, MutexRecursive>;
8
9unsafe impl<T: Sync + Send, M> Send for MutexImpl<T, M> {}
10
11unsafe impl<T: Sync + 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> where M: MutexInnerImpl + fmt::Debug {
21 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
22 write!(f, "Mutex address: {:?}", self.mutex)
23 }
24}
25
26impl<T> MutexImpl<T, MutexNormal> {
27 pub fn new(t: T) -> Result<Self, FreeRtosError> {
29 Ok(MutexImpl {
30 mutex: MutexNormal::create()?,
31 data: UnsafeCell::new(t),
32 })
33 }
34}
35
36impl<T> MutexImpl<T, MutexRecursive> {
37 pub fn new(t: T) -> Result<Self, FreeRtosError> {
39 Ok(MutexImpl {
40 mutex: MutexRecursive::create()?,
41 data: UnsafeCell::new(t),
42 })
43 }
44}
45
46impl<T, M> MutexImpl<T, M> where M: MutexInnerImpl {
47 pub fn lock<D: DurationTicks>(&self, max_wait: D) -> Result<MutexGuard<T, M>, FreeRtosError> {
49 self.mutex.take(max_wait)?;
50
51 Ok(MutexGuard {
52 __mutex: &self.mutex,
53 __data: &self.data,
54 })
55 }
56
57 pub fn into_inner(self) -> T {
59 unsafe {
62 let (mutex, data) = {
63 let Self { ref mutex, ref data } = self;
64 (ptr::read(mutex), ptr::read(data))
65 };
66 mem::forget(self);
67
68 drop(mutex);
69
70 data.into_inner()
71 }
72 }
73}
74
75pub struct MutexGuard<'a, T: ?Sized + 'a, M: 'a> where M: MutexInnerImpl {
77 __mutex: &'a M,
78 __data: &'a UnsafeCell<T>,
79}
80
81impl<'mutex, T: ?Sized, M> Deref for MutexGuard<'mutex, T, M> where M: MutexInnerImpl {
82 type Target = T;
83
84 fn deref<'a>(&'a self) -> &'a T {
85 unsafe { &*self.__data.get() }
86 }
87}
88
89impl<'mutex, T: ?Sized, M> DerefMut for MutexGuard<'mutex, T, M> where M: MutexInnerImpl {
90 fn deref_mut<'a>(&'a mut self) -> &'a mut T {
91 unsafe { &mut *self.__data.get() }
92 }
93}
94
95impl<'a, T: ?Sized, M> Drop for MutexGuard<'a, T, M> where M: MutexInnerImpl {
96 fn drop(&mut self) {
97 self.__mutex.give();
98 }
99}
100
101
102pub trait MutexInnerImpl where Self: Sized + Drop {
103 fn create() -> Result<Self, FreeRtosError>;
104 fn take<D: DurationTicks>(&self, max_wait: D) -> Result<(), FreeRtosError>;
105 fn give(&self);
106}
107
108pub struct MutexNormal(FreeRtosSemaphoreHandle);
109
110impl MutexInnerImpl for MutexNormal {
111 fn create() -> Result<Self, FreeRtosError> {
112 let m = unsafe { freertos_rs_create_mutex() };
113 if m == 0 as *const _ {
114 return Err(FreeRtosError::OutOfMemory);
115 }
116 Ok(MutexNormal(m))
117 }
118
119 fn take<D: DurationTicks>(&self, max_wait: D) -> Result<(), FreeRtosError> {
120 let res = unsafe { freertos_rs_take_mutex(self.0, max_wait.to_ticks()) };
121
122 if res != 0 {
123 return Err(FreeRtosError::MutexTimeout);
124 }
125
126 Ok(())
127 }
128
129 fn give(&self) {
130 unsafe { freertos_rs_give_mutex(self.0); }
131 }
132}
133
134impl Drop for MutexNormal {
135 fn drop(&mut self) {
136 unsafe { freertos_rs_delete_semaphore(self.0) }
137 }
138}
139
140impl fmt::Debug for MutexNormal {
141 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
142 write!(f, "{:?}", self.0)
143 }
144}
145
146pub struct MutexRecursive(FreeRtosSemaphoreHandle);
147
148impl MutexInnerImpl for MutexRecursive {
149 fn create() -> Result<Self, FreeRtosError> {
150 let m = unsafe { freertos_rs_create_recursive_mutex() };
151 if m == 0 as *const _ {
152 return Err(FreeRtosError::OutOfMemory);
153 }
154 Ok(MutexRecursive(m))
155 }
156
157 fn take<D: DurationTicks>(&self, max_wait: D) -> Result<(), FreeRtosError> {
158 let res = unsafe { freertos_rs_take_recursive_mutex(self.0, max_wait.to_ticks()) };
159
160 if res != 0 {
161 return Err(FreeRtosError::MutexTimeout);
162 }
163
164 Ok(())
165 }
166
167 fn give(&self) {
168 unsafe { freertos_rs_give_recursive_mutex(self.0); }
169 }
170}
171
172impl Drop for MutexRecursive {
173 fn drop(&mut self) {
174 unsafe { freertos_rs_delete_semaphore(self.0) }
175 }
176}
177
178impl fmt::Debug for MutexRecursive {
179 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
180 write!(f, "{:?}", self.0)
181 }
182}