diff options
| author | Dario Nieuwenhuis <[email protected]> | 2021-01-11 10:38:43 +0100 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2021-01-11 10:38:43 +0100 |
| commit | c91882a72c7bab61749b234c0e523fdbaee2c36b (patch) | |
| tree | 98c73e6d5a0a799028f55104677db49429d7e6ed | |
| parent | 877fc0321a0a6a56f38bdbe3ce03b77b44ab8316 (diff) | |
Add CriticalSectionMutex, ThreadModeMutex.
| -rw-r--r-- | embassy/src/util/mod.rs | 2 | ||||
| -rw-r--r-- | embassy/src/util/mutex.rs | 75 |
2 files changed, 77 insertions, 0 deletions
diff --git a/embassy/src/util/mod.rs b/embassy/src/util/mod.rs index 5694d6bfb..ae434a8b0 100644 --- a/embassy/src/util/mod.rs +++ b/embassy/src/util/mod.rs | |||
| @@ -1,11 +1,13 @@ | |||
| 1 | mod drop_bomb; | 1 | mod drop_bomb; |
| 2 | mod forever; | 2 | mod forever; |
| 3 | mod mutex; | ||
| 3 | mod portal; | 4 | mod portal; |
| 4 | mod signal; | 5 | mod signal; |
| 5 | mod waker; | 6 | mod waker; |
| 6 | 7 | ||
| 7 | pub use drop_bomb::*; | 8 | pub use drop_bomb::*; |
| 8 | pub use forever::*; | 9 | pub use forever::*; |
| 10 | pub use mutex::*; | ||
| 9 | pub use portal::*; | 11 | pub use portal::*; |
| 10 | pub use signal::*; | 12 | pub use signal::*; |
| 11 | pub use waker::*; | 13 | pub use waker::*; |
diff --git a/embassy/src/util/mutex.rs b/embassy/src/util/mutex.rs new file mode 100644 index 000000000..11f880499 --- /dev/null +++ b/embassy/src/util/mutex.rs | |||
| @@ -0,0 +1,75 @@ | |||
| 1 | use core::cell::UnsafeCell; | ||
| 2 | use cortex_m::interrupt::CriticalSection; | ||
| 3 | |||
| 4 | use crate::fmt::{assert, panic, *}; | ||
| 5 | |||
| 6 | /// A "mutex" based on critical sections | ||
| 7 | /// | ||
| 8 | /// # Safety | ||
| 9 | /// | ||
| 10 | /// **This Mutex is only safe on single-core systems.** | ||
| 11 | /// | ||
| 12 | /// On multi-core systems, a `CriticalSection` **is not sufficient** to ensure exclusive access. | ||
| 13 | pub struct CriticalSectionMutex<T> { | ||
| 14 | inner: UnsafeCell<T>, | ||
| 15 | } | ||
| 16 | unsafe impl<T> Sync for CriticalSectionMutex<T> {} | ||
| 17 | unsafe impl<T> Send for CriticalSectionMutex<T> {} | ||
| 18 | |||
| 19 | impl<T> CriticalSectionMutex<T> { | ||
| 20 | /// Creates a new mutex | ||
| 21 | pub const fn new(value: T) -> Self { | ||
| 22 | CriticalSectionMutex { | ||
| 23 | inner: UnsafeCell::new(value), | ||
| 24 | } | ||
| 25 | } | ||
| 26 | } | ||
| 27 | |||
| 28 | impl<T> CriticalSectionMutex<T> { | ||
| 29 | /// Borrows the data for the duration of the critical section | ||
| 30 | pub fn borrow<'cs>(&'cs self, _cs: &'cs CriticalSection) -> &'cs T { | ||
| 31 | unsafe { &*self.inner.get() } | ||
| 32 | } | ||
| 33 | } | ||
| 34 | |||
| 35 | /// A "mutex" that only allows borrowing from thread mode. | ||
| 36 | /// | ||
| 37 | /// # Safety | ||
| 38 | /// | ||
| 39 | /// **This Mutex is only safe on single-core systems.** | ||
| 40 | /// | ||
| 41 | /// On multi-core systems, a `ThreadModeMutex` **is not sufficient** to ensure exclusive access. | ||
| 42 | pub struct ThreadModeMutex<T> { | ||
| 43 | inner: UnsafeCell<T>, | ||
| 44 | } | ||
| 45 | unsafe impl<T> Sync for ThreadModeMutex<T> {} | ||
| 46 | unsafe impl<T> Send for ThreadModeMutex<T> {} | ||
| 47 | |||
| 48 | impl<T> ThreadModeMutex<T> { | ||
| 49 | /// Creates a new mutex | ||
| 50 | pub const fn new(value: T) -> Self { | ||
| 51 | ThreadModeMutex { | ||
| 52 | inner: UnsafeCell::new(value), | ||
| 53 | } | ||
| 54 | } | ||
| 55 | } | ||
| 56 | |||
| 57 | impl<T> ThreadModeMutex<T> { | ||
| 58 | /// Borrows the data | ||
| 59 | pub fn borrow(&self) -> &T { | ||
| 60 | assert!( | ||
| 61 | in_thread_mode(), | ||
| 62 | "ThreadModeMutex can only be borrowed from thread mode." | ||
| 63 | ); | ||
| 64 | unsafe { &*self.inner.get() } | ||
| 65 | } | ||
| 66 | } | ||
| 67 | |||
| 68 | pub fn in_thread_mode() -> bool { | ||
| 69 | #[cfg(feature = "std")] | ||
| 70 | return Some("main") == std::thread::current().name(); | ||
| 71 | |||
| 72 | #[cfg(not(feature = "std"))] | ||
| 73 | return cortex_m::peripheral::SCB::vect_active() | ||
| 74 | == cortex_m::peripheral::scb::VectActive::ThreadMode; | ||
| 75 | } | ||
