5
5
//!
6
6
//! [`ScopedRawMutex`]: crate::ScopedRawMutex
7
7
//! [`RawMutex`]: crate::RawMutex
8
+ //!
9
+ //! ## Which impl should I use?
10
+ //!
11
+ //! This module contains different implementations based on their capabilities and what
12
+ //! features or dependencies they require.
13
+ //!
14
+ //! ### `local` impl
15
+ //!
16
+ //! The [`local`] module implements a mutex that acts similarly to a `RefCell`, and is
17
+ //! useful when a type requires a [`ScopedRawMutex`], but the item is only ever used locally
18
+ //! within the same thread or task. This implementation does NOT impl `Sync`, so it cannot
19
+ //! be placed in a static. Because this property is checkable at compile time, this mutex
20
+ //! has the lowest overall cost to lock/unlock.
21
+ //!
22
+ //! This module requires no features to be enabled.
23
+ //!
24
+ //! ### `single_core_thread_mode` impl
25
+ //!
26
+ //! The [`single_core_thread_mode`] module implements a mutex that DOES impl `Sync`, but
27
+ //! only allows access when NOT in interrupt mode, e.g. "thread mode" on cortex-m devices.
28
+ //! This property is useful when you'd like to place a mutex in a static for lifetime or
29
+ //! accessibility reasons, but don't want to require a critical section to access, if all
30
+ //! access is done outside of interrupt context. This requires a runtime check, making it
31
+ //! a bit less efficient than the [`local`] impl, but less costly or disruptive than
32
+ //! taking a critical section.
33
+ //!
34
+ //! This impl is currently only usable on bare metal cortex-m targets, as it checks the
35
+ //! `ICSR.VECTACTIVE` field at runtime. PRs to allow similar checks for other architectures
36
+ //! are welcome. This impl ALSO requires the `impl-unsafe-cortex-m-single-core` feature to
37
+ //! be active, which should ONLY be enabled if your target is single core or is only being
38
+ //! used in a single core configuration, otherwise both cores could unsoundly gain access
39
+ //! at the same time.
40
+ //!
41
+ //! ### `cs` impl
42
+ //!
43
+ //! The [`cs`] module implements a mutex that DOES impl `Sync`, and provides exclusive
44
+ //! access using a critical section via the `critical-section` crate. The `critical-section`
45
+ //! crate allows users to define how a critical section can be obtained: on single core embedded
46
+ //! platforms, this usually involves disabling interrupts for the duration of the critical
47
+ //! section. On multicore embedded platforms, this usually involves using some hardware
48
+ //! synchronization utility, for example using the "Spinlock" peripheral on RP2xxx targets.
49
+ //! On desktop/`std` platforms, this typically involves using a `std` Mutex from the operating
50
+ //! system, which will prevent concurrent access.
51
+ //!
52
+ //! This impl can be used in the widest variety of cases, but generally has the highest cost
53
+ //! or largest impact to scheduling/latency. That being said: simply taking or releasing critical
54
+ //! sections is rarely an expensive operation (only a few cycles on embedded targets), however if an
55
+ //! expensive operation is done WHILE holding the critical section, latency of servicing interrupts
56
+ //! or other threads may be impacted.
57
+ //!
58
+ //! This impl requires the `impl-critical-section` feature to be active, and requires that a
59
+ //! `critical-section` implementation has been provided. If both the `std` and `impl-critical-section`
60
+ //! features of this crate are active, the `critical-section/std` feature is enabled, fulfilling this
61
+ //! requirement on std targets. For embedded targets, `critical-section` impls are usually provided
62
+ //! by your architecture crate (e.g. `cortex-m`) for single core targets or HAL crate
63
+ //! (e.g. `embassy-rp`) for multi-core targets.
64
+ //!
65
+ //! ### `lock_api_0_4`
66
+ //!
67
+ //! The `lock_api_0_4` module implements a mutex based on the `lock_api` crate. This is provided
68
+ //! for compatibility if your system is using mutexes based on the `lock_api`/`parking_lot`
69
+ //! crates. This is uncommon for embedded targets.
8
70
#![ allow( clippy:: new_without_default) ]
9
71
#![ allow( clippy:: declare_interior_mutable_const) ]
10
72
@@ -89,7 +151,7 @@ pub mod local {
89
151
#[ cfg_attr( feature = "fmt" , derive( Debug ) ) ]
90
152
pub struct LocalRawMutex {
91
153
taken : AtomicBool ,
92
- /// Prevent this from being sync or send
154
+ /// Prevent this from being sync
93
155
_phantom : PhantomData < * mut ( ) > ,
94
156
}
95
157
@@ -113,7 +175,7 @@ pub mod local {
113
175
#[ inline]
114
176
#[ must_use]
115
177
fn try_with_lock < R > ( & self , f : impl FnOnce ( ) -> R ) -> Option < R > {
116
- // NOTE: separated load/stores are acceptable as we are !Send and ! Sync,
178
+ // NOTE: separated load/stores are acceptable as we are !Sync,
117
179
// meaning that we can only be accessed within a single thread
118
180
if self . taken . load ( Ordering :: Relaxed ) {
119
181
return None ;
0 commit comments