aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs1
-rw-r--r--src/mutex.rs30
2 files changed, 31 insertions, 0 deletions
diff --git a/src/lib.rs b/src/lib.rs
index aedb95a..6b280f0 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -66,5 +66,6 @@ pub mod interrupt;
pub mod itm;
pub mod peripheral;
pub mod register;
+pub mod mutex;
pub use crate::peripheral::Peripherals;
diff --git a/src/mutex.rs b/src/mutex.rs
new file mode 100644
index 0000000..86bd5d5
--- /dev/null
+++ b/src/mutex.rs
@@ -0,0 +1,30 @@
+//! Implementation of a critical section based mutex that also implements the `mutex-trait`.
+
+use core::cell::UnsafeCell;
+
+/// A critical section based mutex.
+pub struct CriticalSectionMutex<T> {
+ data: UnsafeCell<T>,
+}
+
+impl<T> CriticalSectionMutex<T> {
+ /// Create a new mutex
+ pub const fn new(data: T) -> Self {
+ CriticalSectionMutex {
+ data: UnsafeCell::new(data),
+ }
+ }
+}
+
+impl<T> mutex_trait::Mutex for &'_ CriticalSectionMutex<T> {
+ type Data = T;
+
+ fn lock<R>(&mut self, f: impl FnOnce(&mut Self::Data) -> R) -> R {
+ crate::interrupt::free(|_| f(unsafe { &mut *self.data.get() }))
+ }
+}
+
+// NOTE A `Mutex` can be used as a channel so the protected data must be `Send`
+// to prevent sending non-Sendable stuff (e.g. access tokens) across different
+// execution contexts (e.g. interrupts)
+unsafe impl<T> Sync for CriticalSectionMutex<T> where T: Send {}