diff options
| -rw-r--r-- | embassy/src/util/forever.rs | 33 | ||||
| -rw-r--r-- | embassy/src/util/mod.rs | 2 |
2 files changed, 35 insertions, 0 deletions
diff --git a/embassy/src/util/forever.rs b/embassy/src/util/forever.rs new file mode 100644 index 000000000..670f6f133 --- /dev/null +++ b/embassy/src/util/forever.rs | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | use core::cell::UnsafeCell; | ||
| 2 | use core::mem::MaybeUninit; | ||
| 3 | use core::sync::atomic::{AtomicBool, Ordering}; | ||
| 4 | |||
| 5 | pub struct Forever<T> { | ||
| 6 | used: AtomicBool, | ||
| 7 | t: UnsafeCell<MaybeUninit<T>>, | ||
| 8 | } | ||
| 9 | |||
| 10 | unsafe impl<T> Send for Forever<T> {} | ||
| 11 | unsafe impl<T> Sync for Forever<T> {} | ||
| 12 | |||
| 13 | impl<T> Forever<T> { | ||
| 14 | pub const fn new() -> Self { | ||
| 15 | Self { | ||
| 16 | used: AtomicBool::new(false), | ||
| 17 | t: UnsafeCell::new(MaybeUninit::uninit()), | ||
| 18 | } | ||
| 19 | } | ||
| 20 | |||
| 21 | pub fn put(&self, val: T) -> &'static mut T { | ||
| 22 | if self.used.compare_and_swap(false, true, Ordering::SeqCst) { | ||
| 23 | panic!("Forever.put() called multiple times"); | ||
| 24 | } | ||
| 25 | |||
| 26 | unsafe { | ||
| 27 | let p = self.t.get(); | ||
| 28 | let p = (&mut *p).as_mut_ptr(); | ||
| 29 | p.write(val); | ||
| 30 | &mut *p | ||
| 31 | } | ||
| 32 | } | ||
| 33 | } | ||
diff --git a/embassy/src/util/mod.rs b/embassy/src/util/mod.rs index 109cc35a8..9f44c08c9 100644 --- a/embassy/src/util/mod.rs +++ b/embassy/src/util/mod.rs | |||
| @@ -10,6 +10,8 @@ mod waker_store; | |||
| 10 | pub use waker_store::*; | 10 | pub use waker_store::*; |
| 11 | mod drop_bomb; | 11 | mod drop_bomb; |
| 12 | pub use drop_bomb::*; | 12 | pub use drop_bomb::*; |
| 13 | mod forever; | ||
| 14 | pub use forever::*; | ||
| 13 | 15 | ||
| 14 | use defmt::{debug, error, info, intern, trace, warn}; | 16 | use defmt::{debug, error, info, intern, trace, warn}; |
| 15 | 17 | ||
