aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2021-01-11 10:38:43 +0100
committerDario Nieuwenhuis <[email protected]>2021-01-11 10:38:43 +0100
commitc91882a72c7bab61749b234c0e523fdbaee2c36b (patch)
tree98c73e6d5a0a799028f55104677db49429d7e6ed
parent877fc0321a0a6a56f38bdbe3ce03b77b44ab8316 (diff)
Add CriticalSectionMutex, ThreadModeMutex.
-rw-r--r--embassy/src/util/mod.rs2
-rw-r--r--embassy/src/util/mutex.rs75
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 @@
1mod drop_bomb; 1mod drop_bomb;
2mod forever; 2mod forever;
3mod mutex;
3mod portal; 4mod portal;
4mod signal; 5mod signal;
5mod waker; 6mod waker;
6 7
7pub use drop_bomb::*; 8pub use drop_bomb::*;
8pub use forever::*; 9pub use forever::*;
10pub use mutex::*;
9pub use portal::*; 11pub use portal::*;
10pub use signal::*; 12pub use signal::*;
11pub use waker::*; 13pub 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 @@
1use core::cell::UnsafeCell;
2use cortex_m::interrupt::CriticalSection;
3
4use 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.
13pub struct CriticalSectionMutex<T> {
14 inner: UnsafeCell<T>,
15}
16unsafe impl<T> Sync for CriticalSectionMutex<T> {}
17unsafe impl<T> Send for CriticalSectionMutex<T> {}
18
19impl<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
28impl<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.
42pub struct ThreadModeMutex<T> {
43 inner: UnsafeCell<T>,
44}
45unsafe impl<T> Sync for ThreadModeMutex<T> {}
46unsafe impl<T> Send for ThreadModeMutex<T> {}
47
48impl<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
57impl<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
68pub 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}