diff options
| author | Dario Nieuwenhuis <[email protected]> | 2021-03-26 23:20:53 +0100 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2021-03-29 00:58:58 +0200 |
| commit | 0e8bb5dc0b59a490f679f82c3efc6c2994c2d1d9 (patch) | |
| tree | d003a7448947ab7424d1bb7760b39566eef74b59 | |
| parent | eedb51bbb63677f53cfdfb4d0e342981a4866df7 (diff) | |
util: Do not unregister waker on wake in AtomicWaker.
| -rw-r--r-- | embassy-nrf/src/gpiote.rs | 8 | ||||
| -rw-r--r-- | embassy/src/util/waker.rs | 15 | ||||
| -rw-r--r-- | embassy/src/util/waker_agnostic.rs | 13 |
3 files changed, 15 insertions, 21 deletions
diff --git a/embassy-nrf/src/gpiote.rs b/embassy-nrf/src/gpiote.rs index 9a7642c51..920d69236 100644 --- a/embassy-nrf/src/gpiote.rs +++ b/embassy-nrf/src/gpiote.rs | |||
| @@ -9,7 +9,7 @@ use core::ptr; | |||
| 9 | use core::task::{Context, Poll}; | 9 | use core::task::{Context, Poll}; |
| 10 | use embassy::interrupt::InterruptExt; | 10 | use embassy::interrupt::InterruptExt; |
| 11 | use embassy::traits::gpio::{WaitForHigh, WaitForLow}; | 11 | use embassy::traits::gpio::{WaitForHigh, WaitForLow}; |
| 12 | use embassy::util::{AtomicWakerRegistration, PeripheralBorrow, Signal}; | 12 | use embassy::util::{AtomicWaker, PeripheralBorrow, Signal}; |
| 13 | use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin}; | 13 | use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin}; |
| 14 | 14 | ||
| 15 | use crate::gpio::sealed::Pin as _; | 15 | use crate::gpio::sealed::Pin as _; |
| @@ -68,9 +68,9 @@ impl ChannelID for ChAny { | |||
| 68 | } | 68 | } |
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | const NEW_AWR: AtomicWakerRegistration = AtomicWakerRegistration::new(); | 71 | const NEW_AWR: AtomicWaker = AtomicWaker::new(); |
| 72 | static CHANNEL_WAKERS: [AtomicWakerRegistration; CHANNEL_COUNT] = [NEW_AWR; CHANNEL_COUNT]; | 72 | static CHANNEL_WAKERS: [AtomicWaker; CHANNEL_COUNT] = [NEW_AWR; CHANNEL_COUNT]; |
| 73 | static PORT_WAKERS: [AtomicWakerRegistration; PIN_COUNT] = [NEW_AWR; PIN_COUNT]; | 73 | static PORT_WAKERS: [AtomicWaker; PIN_COUNT] = [NEW_AWR; PIN_COUNT]; |
| 74 | 74 | ||
| 75 | pub enum InputChannelPolarity { | 75 | pub enum InputChannelPolarity { |
| 76 | None, | 76 | None, |
diff --git a/embassy/src/util/waker.rs b/embassy/src/util/waker.rs index 2b72fd560..cd53cca61 100644 --- a/embassy/src/util/waker.rs +++ b/embassy/src/util/waker.rs | |||
| @@ -48,11 +48,11 @@ impl WakerRegistration { | |||
| 48 | } | 48 | } |
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | pub struct AtomicWakerRegistration { | 51 | pub struct AtomicWaker { |
| 52 | waker: AtomicPtr<TaskHeader>, | 52 | waker: AtomicPtr<TaskHeader>, |
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | impl AtomicWakerRegistration { | 55 | impl AtomicWaker { |
| 56 | pub const fn new() -> Self { | 56 | pub const fn new() -> Self { |
| 57 | Self { | 57 | Self { |
| 58 | waker: AtomicPtr::new(ptr::null_mut()), | 58 | waker: AtomicPtr::new(ptr::null_mut()), |
| @@ -62,17 +62,14 @@ impl AtomicWakerRegistration { | |||
| 62 | /// Register a waker. Overwrites the previous waker, if any. | 62 | /// Register a waker. Overwrites the previous waker, if any. |
| 63 | pub fn register(&self, w: &Waker) { | 63 | pub fn register(&self, w: &Waker) { |
| 64 | let w = unsafe { task_from_waker(w) }; | 64 | let w = unsafe { task_from_waker(w) }; |
| 65 | let w2 = self.waker.swap(w.as_ptr(), Ordering::Relaxed); | 65 | self.waker.store(w.as_ptr(), Ordering::Relaxed); |
| 66 | if !w2.is_null() && w2 != w.as_ptr() { | ||
| 67 | unsafe { wake_task(NonNull::new_unchecked(w2)) }; | ||
| 68 | } | ||
| 69 | } | 66 | } |
| 70 | 67 | ||
| 71 | /// Wake the registered waker, if any. | 68 | /// Wake the registered waker, if any. |
| 72 | pub fn wake(&self) { | 69 | pub fn wake(&self) { |
| 73 | let w2 = self.waker.swap(ptr::null_mut(), Ordering::Relaxed); | 70 | let w2 = self.waker.load(Ordering::Relaxed); |
| 74 | if !w2.is_null() { | 71 | if let Some(w2) = NonNull::new(w2) { |
| 75 | unsafe { wake_task(NonNull::new_unchecked(w2)) }; | 72 | unsafe { wake_task(w2) }; |
| 76 | } | 73 | } |
| 77 | } | 74 | } |
| 78 | } | 75 | } |
diff --git a/embassy/src/util/waker_agnostic.rs b/embassy/src/util/waker_agnostic.rs index b4234c0f5..3f6ad373a 100644 --- a/embassy/src/util/waker_agnostic.rs +++ b/embassy/src/util/waker_agnostic.rs | |||
| @@ -49,11 +49,11 @@ impl WakerRegistration { | |||
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | /// Utility struct to register and wake a waker. | 51 | /// Utility struct to register and wake a waker. |
| 52 | pub struct AtomicWakerRegistration { | 52 | pub struct AtomicWaker { |
| 53 | waker: Mutex<Cell<Option<Waker>>>, | 53 | waker: Mutex<Cell<Option<Waker>>>, |
| 54 | } | 54 | } |
| 55 | 55 | ||
| 56 | impl AtomicWakerRegistration { | 56 | impl AtomicWaker { |
| 57 | pub const fn new() -> Self { | 57 | pub const fn new() -> Self { |
| 58 | Self { | 58 | Self { |
| 59 | waker: Mutex::new(Cell::new(None)), | 59 | waker: Mutex::new(Cell::new(None)), |
| @@ -66,11 +66,7 @@ impl AtomicWakerRegistration { | |||
| 66 | let cell = self.waker.borrow(cs); | 66 | let cell = self.waker.borrow(cs); |
| 67 | cell.set(match cell.replace(None) { | 67 | cell.set(match cell.replace(None) { |
| 68 | Some(w2) if (w2.will_wake(w)) => Some(w2), | 68 | Some(w2) if (w2.will_wake(w)) => Some(w2), |
| 69 | Some(w2) => { | 69 | _ => Some(w.clone()), |
| 70 | w2.wake(); | ||
| 71 | Some(w.clone()) | ||
| 72 | } | ||
| 73 | None => Some(w.clone()), | ||
| 74 | }) | 70 | }) |
| 75 | }) | 71 | }) |
| 76 | } | 72 | } |
| @@ -80,7 +76,8 @@ impl AtomicWakerRegistration { | |||
| 80 | cortex_m::interrupt::free(|cs| { | 76 | cortex_m::interrupt::free(|cs| { |
| 81 | let cell = self.waker.borrow(cs); | 77 | let cell = self.waker.borrow(cs); |
| 82 | if let Some(w) = cell.replace(None) { | 78 | if let Some(w) = cell.replace(None) { |
| 83 | w.wake() | 79 | w.wake_by_ref(); |
| 80 | cell.set(Some(w)); | ||
| 84 | } | 81 | } |
| 85 | }) | 82 | }) |
| 86 | } | 83 | } |
