diff --git a/embassy/src/util/forever.rs b/embassy/src/util/forever.rs new file mode 100644 index 00000000..670f6f13 --- /dev/null +++ b/embassy/src/util/forever.rs @@ -0,0 +1,33 @@ +use core::cell::UnsafeCell; +use core::mem::MaybeUninit; +use core::sync::atomic::{AtomicBool, Ordering}; + +pub struct Forever { + used: AtomicBool, + t: UnsafeCell>, +} + +unsafe impl Send for Forever {} +unsafe impl Sync for Forever {} + +impl Forever { + pub const fn new() -> Self { + Self { + used: AtomicBool::new(false), + t: UnsafeCell::new(MaybeUninit::uninit()), + } + } + + pub fn put(&self, val: T) -> &'static mut T { + if self.used.compare_and_swap(false, true, Ordering::SeqCst) { + panic!("Forever.put() called multiple times"); + } + + unsafe { + let p = self.t.get(); + let p = (&mut *p).as_mut_ptr(); + p.write(val); + &mut *p + } + } +} diff --git a/embassy/src/util/mod.rs b/embassy/src/util/mod.rs index 109cc35a..9f44c08c 100644 --- a/embassy/src/util/mod.rs +++ b/embassy/src/util/mod.rs @@ -10,6 +10,8 @@ mod waker_store; pub use waker_store::*; mod drop_bomb; pub use drop_bomb::*; +mod forever; +pub use forever::*; use defmt::{debug, error, info, intern, trace, warn};