Skip to content

Commit a02bce1

Browse files
committed
macros: Don't use Option in singleton!()
As detailed in #364, niche optimization of the `Option` used in the `singleton!()` macro can lead to the initial value of the static to contain non-zero bits. This in turn leads to the whole static being moved from `.bss` to `.data` which means it eats up flash space for no reason. Especially if the singleton stores a particularly large type, this can be quite problematic. Prevent this by using an explicit boolean flag instead of the `Option` type. This is not quite as nice but at least there is no chance for the `singleton!()` to end up in `.data`...
1 parent 19125ac commit a02bce1

File tree

1 file changed

+6
-8
lines changed

1 file changed

+6
-8
lines changed

Diff for: src/macros.rs

+6-8
Original file line numberDiff line numberDiff line change
@@ -63,23 +63,21 @@ macro_rules! iprintln {
6363
macro_rules! singleton {
6464
($name:ident: $ty:ty = $expr:expr) => {
6565
$crate::interrupt::free(|_| {
66-
static mut $name: Option<$ty> = None;
66+
static mut $name: (::core::mem::MaybeUninit<$ty>, bool) =
67+
(::core::mem::MaybeUninit::uninit(), false);
6768

6869
#[allow(unsafe_code)]
69-
let used = unsafe { $name.is_some() };
70+
let used = unsafe { $name.1 };
7071
if used {
7172
None
7273
} else {
7374
let expr = $expr;
7475

7576
#[allow(unsafe_code)]
7677
unsafe {
77-
$name = Some(expr)
78-
}
79-
80-
#[allow(unsafe_code)]
81-
unsafe {
82-
$name.as_mut()
78+
$name.1 = true;
79+
$name.0 = ::core::mem::MaybeUninit::new(expr);
80+
Some(&mut *$name.0.as_mut_ptr())
8381
}
8482
}
8583
})

0 commit comments

Comments
 (0)