Skip to content

Added arch specific mutex implementation #209

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ links = "cortex-m" # prevent multiple versions of this crate to be linked toget
[dependencies]
bare-metal = { version = "0.2.0", features = ["const-fn"] }
volatile-register = "0.2.0"
mutex-trait = "0.2.0"
bitfield = "0.13.2"

[features]
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,5 +66,6 @@ pub mod interrupt;
pub mod itm;
pub mod peripheral;
pub mod register;
pub mod mutex;

pub use crate::peripheral::Peripherals;
34 changes: 34 additions & 0 deletions src/mutex.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//! Implementation of a critical section based mutex that also implements the `mutex-trait`.
//!
//! ## Safety
//!
//! Note that this is only safe in single core applications.

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 {}