embassy: Improve RawMutex docs, mark it as unsafe.
This commit is contained in:
parent
17cab1a2d4
commit
f4e2686eca
1 changed files with 27 additions and 7 deletions
|
@ -3,12 +3,32 @@
|
||||||
//! This module provides a trait for mutexes that can be used in different contexts.
|
//! This module provides a trait for mutexes that can be used in different contexts.
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
|
||||||
/// Any object implementing this trait guarantees exclusive access to the data contained
|
/// Raw mutex trait.
|
||||||
/// within the mutex for the duration of the lock.
|
///
|
||||||
/// Adapted from <https://github.com/rust-embedded/mutex-trait>.
|
/// This mutex is "raw", which means it does not actually contain the protected data, it
|
||||||
pub trait RawMutex {
|
/// just implements the mutex mechanism. For most uses you should use [`super::Mutex`] instead,
|
||||||
|
/// which is generic over a RawMutex and contains the protected data.
|
||||||
|
///
|
||||||
|
/// Note that, unlike other mutexes, implementations only guarantee no
|
||||||
|
/// concurrent access from other threads: concurrent access from the current
|
||||||
|
/// thread is allwed. For example, it's possible to lock the same mutex multiple times reentrantly.
|
||||||
|
///
|
||||||
|
/// Therefore, locking a `RawMutex` is only enough to guarantee safe shared (`&`) access
|
||||||
|
/// to the data, it is not enough to guarantee exclusive (`&mut`) access.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// RawMutex implementations must ensure that, while locked, no other thread can lock
|
||||||
|
/// the RawMutex concurrently.
|
||||||
|
///
|
||||||
|
/// Unsafe code is allowed to rely on this fact, so incorrect implementations will cause undefined behavior.
|
||||||
|
pub unsafe trait RawMutex {
|
||||||
|
/// Create a new `RawMutex` instance.
|
||||||
|
///
|
||||||
|
/// This is a const instead of a method to allow creating instances in const context.
|
||||||
const INIT: Self;
|
const INIT: Self;
|
||||||
|
|
||||||
|
/// Lock this `RawMutex`.
|
||||||
fn lock<R>(&self, f: impl FnOnce() -> R) -> R;
|
fn lock<R>(&self, f: impl FnOnce() -> R) -> R;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +49,7 @@ impl CriticalSectionRawMutex {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RawMutex for CriticalSectionRawMutex {
|
unsafe impl RawMutex for CriticalSectionRawMutex {
|
||||||
const INIT: Self = Self::new();
|
const INIT: Self = Self::new();
|
||||||
|
|
||||||
fn lock<R>(&self, f: impl FnOnce() -> R) -> R {
|
fn lock<R>(&self, f: impl FnOnce() -> R) -> R {
|
||||||
|
@ -56,7 +76,7 @@ impl NoopRawMutex {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RawMutex for NoopRawMutex {
|
unsafe impl RawMutex for NoopRawMutex {
|
||||||
const INIT: Self = Self::new();
|
const INIT: Self = Self::new();
|
||||||
fn lock<R>(&self, f: impl FnOnce() -> R) -> R {
|
fn lock<R>(&self, f: impl FnOnce() -> R) -> R {
|
||||||
f()
|
f()
|
||||||
|
@ -89,7 +109,7 @@ mod thread_mode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RawMutex for ThreadModeRawMutex {
|
unsafe impl RawMutex for ThreadModeRawMutex {
|
||||||
const INIT: Self = Self::new();
|
const INIT: Self = Self::new();
|
||||||
fn lock<R>(&self, f: impl FnOnce() -> R) -> R {
|
fn lock<R>(&self, f: impl FnOnce() -> R) -> R {
|
||||||
assert!(in_thread_mode(), "ThreadModeMutex can only be locked from thread mode.");
|
assert!(in_thread_mode(), "ThreadModeMutex can only be locked from thread mode.");
|
||||||
|
|
Loading…
Reference in a new issue