diff options
| author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2022-08-22 14:12:13 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2022-08-22 14:12:13 +0000 |
| commit | 381ac97746c318963b42eec6ced6773301c91519 (patch) | |
| tree | b1b3f644b77c6fcf4a0bbe2eabe19caba27c4c08 /embassy-util/src | |
| parent | 1b9599025868d3a5d0d8e773593b05df8b2fecf2 (diff) | |
| parent | 478f4727846f6a43c28fff3b09cb639c0b800465 (diff) | |
Merge #920
920: Remove Forever, switch to static_cell. r=Dirbaio a=Dirbaio
Co-authored-by: Dario Nieuwenhuis <[email protected]>
Diffstat (limited to 'embassy-util/src')
| -rw-r--r-- | embassy-util/src/channel/mpmc.rs | 10 | ||||
| -rw-r--r-- | embassy-util/src/forever.rs | 95 | ||||
| -rw-r--r-- | embassy-util/src/lib.rs | 2 | ||||
| -rw-r--r-- | embassy-util/src/pipe.rs | 6 |
4 files changed, 8 insertions, 105 deletions
diff --git a/embassy-util/src/channel/mpmc.rs b/embassy-util/src/channel/mpmc.rs index 535f77e6f..263f29bfc 100644 --- a/embassy-util/src/channel/mpmc.rs +++ b/embassy-util/src/channel/mpmc.rs | |||
| @@ -471,10 +471,10 @@ mod tests { | |||
| 471 | use futures_executor::ThreadPool; | 471 | use futures_executor::ThreadPool; |
| 472 | use futures_timer::Delay; | 472 | use futures_timer::Delay; |
| 473 | use futures_util::task::SpawnExt; | 473 | use futures_util::task::SpawnExt; |
| 474 | use static_cell::StaticCell; | ||
| 474 | 475 | ||
| 475 | use super::*; | 476 | use super::*; |
| 476 | use crate::blocking_mutex::raw::{CriticalSectionRawMutex, NoopRawMutex}; | 477 | use crate::blocking_mutex::raw::{CriticalSectionRawMutex, NoopRawMutex}; |
| 477 | use crate::Forever; | ||
| 478 | 478 | ||
| 479 | fn capacity<T, const N: usize>(c: &ChannelState<T, N>) -> usize { | 479 | fn capacity<T, const N: usize>(c: &ChannelState<T, N>) -> usize { |
| 480 | c.queue.capacity() - c.queue.len() | 480 | c.queue.capacity() - c.queue.len() |
| @@ -549,8 +549,8 @@ mod tests { | |||
| 549 | async fn receiver_receives_given_try_send_async() { | 549 | async fn receiver_receives_given_try_send_async() { |
| 550 | let executor = ThreadPool::new().unwrap(); | 550 | let executor = ThreadPool::new().unwrap(); |
| 551 | 551 | ||
| 552 | static CHANNEL: Forever<Channel<CriticalSectionRawMutex, u32, 3>> = Forever::new(); | 552 | static CHANNEL: StaticCell<Channel<CriticalSectionRawMutex, u32, 3>> = StaticCell::new(); |
| 553 | let c = &*CHANNEL.put(Channel::new()); | 553 | let c = &*CHANNEL.init(Channel::new()); |
| 554 | let c2 = c; | 554 | let c2 = c; |
| 555 | assert!(executor | 555 | assert!(executor |
| 556 | .spawn(async move { | 556 | .spawn(async move { |
| @@ -571,8 +571,8 @@ mod tests { | |||
| 571 | async fn senders_sends_wait_until_capacity() { | 571 | async fn senders_sends_wait_until_capacity() { |
| 572 | let executor = ThreadPool::new().unwrap(); | 572 | let executor = ThreadPool::new().unwrap(); |
| 573 | 573 | ||
| 574 | static CHANNEL: Forever<Channel<CriticalSectionRawMutex, u32, 1>> = Forever::new(); | 574 | static CHANNEL: StaticCell<Channel<CriticalSectionRawMutex, u32, 1>> = StaticCell::new(); |
| 575 | let c = &*CHANNEL.put(Channel::new()); | 575 | let c = &*CHANNEL.init(Channel::new()); |
| 576 | assert!(c.try_send(1).is_ok()); | 576 | assert!(c.try_send(1).is_ok()); |
| 577 | 577 | ||
| 578 | let c2 = c; | 578 | let c2 = c; |
diff --git a/embassy-util/src/forever.rs b/embassy-util/src/forever.rs deleted file mode 100644 index 4f3698211..000000000 --- a/embassy-util/src/forever.rs +++ /dev/null | |||
| @@ -1,95 +0,0 @@ | |||
| 1 | use core::cell::UnsafeCell; | ||
| 2 | use core::mem::MaybeUninit; | ||
| 3 | |||
| 4 | use atomic_polyfill::{AtomicBool, Ordering}; | ||
| 5 | |||
| 6 | /// Type with static lifetime that may be written to once at runtime. | ||
| 7 | /// | ||
| 8 | /// This may be used to initialize static objects at runtime, typically in the init routine. | ||
| 9 | /// This is useful for objects such as Embassy's RTC, which cannot be initialized in a const | ||
| 10 | /// context. | ||
| 11 | /// | ||
| 12 | /// Note: IF a global mutable variable is desired, use a CriticalSectionMutex or ThreadModeMutex instead. | ||
| 13 | /// | ||
| 14 | /// ``` | ||
| 15 | /// use embassy_util::Forever; | ||
| 16 | /// // Using an integer for the sake of keeping this example self-contained, | ||
| 17 | /// // see https://github.com/embassy-rs/embassy/wiki/Getting-Started for a more "proper" example. | ||
| 18 | /// static SOME_INT: Forever<u32> =Forever::new(); | ||
| 19 | /// | ||
| 20 | /// // put returns a mutable pointer to the object stored in the forever, which may then be passed | ||
| 21 | /// // around. | ||
| 22 | /// let mut x = SOME_INT.put(42); | ||
| 23 | /// assert_eq!(*x, 42); | ||
| 24 | /// ``` | ||
| 25 | pub struct Forever<T> { | ||
| 26 | used: AtomicBool, | ||
| 27 | t: UnsafeCell<MaybeUninit<T>>, | ||
| 28 | } | ||
| 29 | |||
| 30 | unsafe impl<T> Send for Forever<T> {} | ||
| 31 | unsafe impl<T> Sync for Forever<T> {} | ||
| 32 | |||
| 33 | impl<T> Forever<T> { | ||
| 34 | /// Create a new `Forever`. | ||
| 35 | #[inline(always)] | ||
| 36 | pub const fn new() -> Self { | ||
| 37 | Self { | ||
| 38 | used: AtomicBool::new(false), | ||
| 39 | t: UnsafeCell::new(MaybeUninit::uninit()), | ||
| 40 | } | ||
| 41 | } | ||
| 42 | |||
| 43 | /// Store a value in this `Forever`, returning a mutable reference to it. | ||
| 44 | /// | ||
| 45 | /// Using this method, the compiler usually constructs `val` in the stack and then moves | ||
| 46 | /// it into the `Forever`. If `T` is big, this is likely to cause stack overflows. | ||
| 47 | /// Considering using [`Signal::put_with`] instead, which will construct it in-place inside the `Forever`. | ||
| 48 | /// | ||
| 49 | /// # Panics | ||
| 50 | /// | ||
| 51 | /// Panics if this `Forever` already has a value stored in it. | ||
| 52 | #[inline(always)] | ||
| 53 | #[allow(clippy::mut_from_ref)] | ||
| 54 | pub fn put(&'static self, val: T) -> &'static mut T { | ||
| 55 | self.put_with(|| val) | ||
| 56 | } | ||
| 57 | |||
| 58 | /// Store the closure return value in this `Forever`, returning a mutable reference to it. | ||
| 59 | /// | ||
| 60 | /// The advantage over [`Forever::put`] is that this method allows the closure to construct | ||
| 61 | /// the `T` value in-place directly inside the `Forever`, saving stack space. | ||
| 62 | /// | ||
| 63 | /// # Panics | ||
| 64 | /// | ||
| 65 | /// Panics if this `Forever` already has a value stored in it. | ||
| 66 | #[inline(always)] | ||
| 67 | #[allow(clippy::mut_from_ref)] | ||
| 68 | pub fn put_with(&'static self, val: impl FnOnce() -> T) -> &'static mut T { | ||
| 69 | if self | ||
| 70 | .used | ||
| 71 | .compare_exchange(false, true, Ordering::Relaxed, Ordering::Relaxed) | ||
| 72 | .is_err() | ||
| 73 | { | ||
| 74 | panic!("Forever.put() called multiple times"); | ||
| 75 | } | ||
| 76 | |||
| 77 | let p: &'static mut MaybeUninit<T> = unsafe { &mut *self.t.get() }; | ||
| 78 | p.write(val()) | ||
| 79 | } | ||
| 80 | |||
| 81 | /// Unsafely get a mutable reference to the contents of this Forever. | ||
| 82 | /// | ||
| 83 | /// # Safety | ||
| 84 | /// | ||
| 85 | /// This is undefined behavior if: | ||
| 86 | /// | ||
| 87 | /// - The `Forever` has not been initialized yet (with `put' or `put_with`), or | ||
| 88 | /// - A reference to the contents (mutable or not) already exists. | ||
| 89 | #[inline(always)] | ||
| 90 | #[allow(clippy::mut_from_ref)] | ||
| 91 | pub unsafe fn steal(&self) -> &mut T { | ||
| 92 | let p: &mut MaybeUninit<T> = &mut *self.t.get(); | ||
| 93 | p.assume_init_mut() | ||
| 94 | } | ||
| 95 | } | ||
diff --git a/embassy-util/src/lib.rs b/embassy-util/src/lib.rs index 110c72811..8ec3300d9 100644 --- a/embassy-util/src/lib.rs +++ b/embassy-util/src/lib.rs | |||
| @@ -16,10 +16,8 @@ pub mod mutex; | |||
| 16 | pub mod pipe; | 16 | pub mod pipe; |
| 17 | pub mod waitqueue; | 17 | pub mod waitqueue; |
| 18 | 18 | ||
| 19 | mod forever; | ||
| 20 | mod select; | 19 | mod select; |
| 21 | mod yield_now; | 20 | mod yield_now; |
| 22 | 21 | ||
| 23 | pub use forever::*; | ||
| 24 | pub use select::*; | 22 | pub use select::*; |
| 25 | pub use yield_now::*; | 23 | pub use yield_now::*; |
diff --git a/embassy-util/src/pipe.rs b/embassy-util/src/pipe.rs index 9c20aeeff..d85b843e4 100644 --- a/embassy-util/src/pipe.rs +++ b/embassy-util/src/pipe.rs | |||
| @@ -461,10 +461,10 @@ mod io_impls { | |||
| 461 | mod tests { | 461 | mod tests { |
| 462 | use futures_executor::ThreadPool; | 462 | use futures_executor::ThreadPool; |
| 463 | use futures_util::task::SpawnExt; | 463 | use futures_util::task::SpawnExt; |
| 464 | use static_cell::StaticCell; | ||
| 464 | 465 | ||
| 465 | use super::*; | 466 | use super::*; |
| 466 | use crate::blocking_mutex::raw::{CriticalSectionRawMutex, NoopRawMutex}; | 467 | use crate::blocking_mutex::raw::{CriticalSectionRawMutex, NoopRawMutex}; |
| 467 | use crate::Forever; | ||
| 468 | 468 | ||
| 469 | fn capacity<const N: usize>(c: &PipeState<N>) -> usize { | 469 | fn capacity<const N: usize>(c: &PipeState<N>) -> usize { |
| 470 | N - c.buffer.len() | 470 | N - c.buffer.len() |
| @@ -528,8 +528,8 @@ mod tests { | |||
| 528 | async fn receiver_receives_given_try_write_async() { | 528 | async fn receiver_receives_given_try_write_async() { |
| 529 | let executor = ThreadPool::new().unwrap(); | 529 | let executor = ThreadPool::new().unwrap(); |
| 530 | 530 | ||
| 531 | static CHANNEL: Forever<Pipe<CriticalSectionRawMutex, 3>> = Forever::new(); | 531 | static CHANNEL: StaticCell<Pipe<CriticalSectionRawMutex, 3>> = StaticCell::new(); |
| 532 | let c = &*CHANNEL.put(Pipe::new()); | 532 | let c = &*CHANNEL.init(Pipe::new()); |
| 533 | let c2 = c; | 533 | let c2 = c; |
| 534 | let f = async move { | 534 | let f = async move { |
| 535 | assert_eq!(c2.try_write(&[42]), Ok(1)); | 535 | assert_eq!(c2.try_write(&[42]), Ok(1)); |
