Skip to content

Commit 7420011

Browse files
Add a StaticResource trait
1 parent 621fd69 commit 7420011

File tree

2 files changed

+52
-0
lines changed

2 files changed

+52
-0
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).
55

66
## [Unreleased]
77

8+
### Added
9+
10+
- Added the `StaticResource` trait.
11+
812
### Breaking Changes
913

1014
- Use `CriticalSection<'cs>` everywhere instead of `&'cs CriticalSection`

src/lib.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,51 @@ pub unsafe trait Nr {
7272
/// Returns the number associated with an interrupt.
7373
fn nr(&self) -> u8;
7474
}
75+
76+
/// Trait for static (singleton) resources with managed ownership.
77+
///
78+
/// This trait allows application code and libraries to take ownership of resources that exist once
79+
/// on every core, or once on the entire system.
80+
///
81+
/// # Safety
82+
///
83+
/// In order to safely implement this trait, the implementor must ensure that:
84+
/// - A call to `take()` or `steal()` atomically ensures that no further call to `take()` will
85+
/// succeed. This is commonly accomplished by using a static `AtomicBool` variable and a
86+
/// compare-and-swap operation or a critical section.
87+
/// - It is impossible to link multiple crates containing the synchronization state together. This
88+
/// is usually accomplished by defining a well-known [`links = "..."`][links] key in the
89+
/// `Cargo.toml`.
90+
///
91+
/// [links]: https://doc.rust-lang.org/cargo/reference/build-scripts.html#the-links-manifest-key
92+
pub unsafe trait StaticResource: Sized {
93+
/// Obtains ownership of this resource singleton and makes it unavailable to future callers of
94+
/// `take()`.
95+
///
96+
/// If `take()` or `steal()` have been called before, this returns `None`.
97+
fn take() -> Option<Self>;
98+
99+
/// Obtains an instance of this resource and makes all future calls to `take()` return `None`.
100+
///
101+
/// This will not check if `take()` or `steal()` have already been called before. It is the
102+
/// caller's responsibility to use the returned instance in a safe way that does not conflict
103+
/// with other instances.
104+
///
105+
/// This function is intended to be used when it is statically known that the resource is still
106+
/// available (for example, in generated code that runs immediately after reset). It generally
107+
/// has lower cost than `take().unwrap()`.
108+
unsafe fn steal() -> Self;
109+
110+
/// Unsafely obtains an instance of this resource.
111+
///
112+
/// This will not check if `take()` or `steal()` have already been called before. It is the
113+
/// caller's responsibility to use the returned instance in a safe way that does not conflict
114+
/// with other instances.
115+
///
116+
/// Contrary to `steal()`, `conjure()` will *not* make future calls to `take()` return `None`.
117+
///
118+
/// This function can be used to perform operations on a resource, ignoring any current
119+
/// ownership of the resource. The safety of this depends on the specific resource, and on the
120+
/// operations performed.
121+
unsafe fn conjure() -> Self;
122+
}

0 commit comments

Comments
 (0)