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