Skip to content

Commit ca3d4ef

Browse files
committed
Auto merge of #70 - japaric:safe-static-mut, r=japaric
safe `&'static mut` references through a runtime checked macro runtime checked implementation of japaric/cortex-m-rtfm#59 that doesn't depend on RTFM macros TODO - [ ] bikeshed macro syntax
2 parents 024527b + 4f9664c commit ca3d4ef

File tree

1 file changed

+44
-0
lines changed

1 file changed

+44
-0
lines changed

src/macros.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,47 @@ macro_rules! iprintln {
2222
iprint!($channel, concat!($fmt, "\n"), $($arg)*);
2323
};
2424
}
25+
26+
/// Macro to create a mutable reference to a statically allocated value
27+
///
28+
/// This macro returns a value with type `Option<&'static mut $ty>`. `Some($expr)` will be returned
29+
/// the first time the macro is executed; further calls will return `None`. To avoid `unwrap`ping a
30+
/// `None` variant the caller must ensure that the macro is called from a function that's executed
31+
/// at most once in the whole lifetime of the program.
32+
///
33+
/// # Example
34+
///
35+
/// ``` no_run
36+
/// #[macro_use(singleton)]
37+
/// extern crate cortex_m;
38+
///
39+
/// fn main() {
40+
/// // OK if `main` is executed only once
41+
/// let x: &'static mut bool = singleton!(: bool = false).unwrap();
42+
///
43+
/// let y = alias();
44+
/// // BAD this second call to `alias` will definitively `panic!`
45+
/// let y_alias = alias();
46+
/// }
47+
///
48+
/// fn alias() -> &'static mut bool {
49+
/// singleton!(: bool = false).unwrap()
50+
/// }
51+
/// ```
52+
#[macro_export]
53+
macro_rules! singleton {
54+
(: $ty:ty = $expr:expr) => {
55+
$crate::interrupt::free(|_| unsafe {
56+
static mut USED: bool = false;
57+
static mut VAR: $ty = $expr;
58+
59+
if USED {
60+
None
61+
} else {
62+
USED = true;
63+
let var: &'static mut _ = &mut VAR;
64+
Some(var)
65+
}
66+
})
67+
}
68+
}

0 commit comments

Comments
 (0)