diff options
author | Brian Cully <bjc@kublai.com> | 2019-05-10 11:50:53 -0400 |
---|---|---|
committer | Brian Cully <bjc@kublai.com> | 2019-06-03 09:23:29 -0400 |
commit | 5781e9391fe3d7d3dabec620cb782d38f5f9cb9e (patch) | |
tree | 9ed0b09fd40f128733e8441fc63f91a9ee17d3f6 /src/cs | |
parent | f12811a0a5e15b596a0cc06c095832a6b795172b (diff) | |
download | clint-5781e9391fe3d7d3dabec620cb782d38f5f9cb9e.tar.gz clint-5781e9391fe3d7d3dabec620cb782d38f5f9cb9e.zip |
Update to 0.2.0: Add HandlerArray type.v0.2.0
* Create HandlerArray as a safe wrapper around Handler.
* Add Cargo features for HandlerArray size.
* Move Handler into sub-module.
* Add CriticalSection sub-module for architecture dependent support
of interrupt-free contexts.
* Add build rules to pull in cortex-m support for CriticalSection
automatically.
Diffstat (limited to 'src/cs')
-rw-r--r-- | src/cs/cortex.rs | 20 | ||||
-rw-r--r-- | src/cs/dummy.rs | 18 | ||||
-rw-r--r-- | src/cs/mod.rs | 38 |
3 files changed, 76 insertions, 0 deletions
diff --git a/src/cs/cortex.rs b/src/cs/cortex.rs new file mode 100644 index 0000000..cc97a12 --- /dev/null +++ b/src/cs/cortex.rs @@ -0,0 +1,20 @@ +use super::CriticalSection; + +use cortex_m::interrupt; + +pub struct Locker {} + +impl Locker { + pub const fn new() -> Self { + Self {} + } +} + +impl CriticalSection for Locker { + fn with_lock<F, R>(&self, f: F) -> R + where + F: FnOnce() -> R, + { + interrupt::free(|_cs| f()) + } +} diff --git a/src/cs/dummy.rs b/src/cs/dummy.rs new file mode 100644 index 0000000..86f4e90 --- /dev/null +++ b/src/cs/dummy.rs @@ -0,0 +1,18 @@ +use super::CriticalSection; + +pub struct Locker {} + +impl Locker { + pub const fn new() -> Self { + Self {} + } +} + +impl CriticalSection for Locker { + fn with_lock<F, R>(&self, f: F) -> R + where + F: FnOnce() -> R, + { + f() + } +} diff --git a/src/cs/mod.rs b/src/cs/mod.rs new file mode 100644 index 0000000..8f97b6e --- /dev/null +++ b/src/cs/mod.rs @@ -0,0 +1,38 @@ +//! Critical Section support. +//! +//! Types that implement the `CriticalSection` trait can be used to +//! create critical sections to prevent data races between interrupt +//! and non-interrupt contexts. +//! +//! # Note +//! +//! Critical sections are only acquired for updating a +//! `HandlerTable`'s entries. They are *not* used when calling into a +//! closure. This is because the expected implementation of critical +//! sections turns off interrupts entirely. Given that interrupts are +//! off, it is impossible to call an ISR, and thus no data race can +//! occur. Additionally, because critcal sections are only enforced on +//! updates, deadlock is impossible between updating a `HandlerTable` +//! entry and calling into it. +//! +//! However, if you are going to implement your own `CriticalSection`, +//! you need to be aware of this limitation and its rationale to avoid +//! getting into trouble. + +/// Generic trait which supplies the ability to create a critical +/// section. +pub trait CriticalSection { + /// Execute `f` within a critical section. + fn with_lock<F, R>(&self, f: F) -> R + where + F: FnOnce() -> R; +} + +#[cfg_attr(any(all(target_arch = "arm", target_os = "none")), path = "cortex.rs")] +#[cfg_attr( + not(any(all(target_arch = "arm", target_os = "none"))), + path = "dummy.rs" +)] +mod csimpl; + +pub use csimpl::Locker; |