aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2021-03-26 23:20:53 +0100
committerDario Nieuwenhuis <[email protected]>2021-03-29 00:58:58 +0200
commit0e8bb5dc0b59a490f679f82c3efc6c2994c2d1d9 (patch)
treed003a7448947ab7424d1bb7760b39566eef74b59
parenteedb51bbb63677f53cfdfb4d0e342981a4866df7 (diff)
util: Do not unregister waker on wake in AtomicWaker.
-rw-r--r--embassy-nrf/src/gpiote.rs8
-rw-r--r--embassy/src/util/waker.rs15
-rw-r--r--embassy/src/util/waker_agnostic.rs13
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;
9use core::task::{Context, Poll}; 9use core::task::{Context, Poll};
10use embassy::interrupt::InterruptExt; 10use embassy::interrupt::InterruptExt;
11use embassy::traits::gpio::{WaitForHigh, WaitForLow}; 11use embassy::traits::gpio::{WaitForHigh, WaitForLow};
12use embassy::util::{AtomicWakerRegistration, PeripheralBorrow, Signal}; 12use embassy::util::{AtomicWaker, PeripheralBorrow, Signal};
13use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin}; 13use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin};
14 14
15use crate::gpio::sealed::Pin as _; 15use crate::gpio::sealed::Pin as _;
@@ -68,9 +68,9 @@ impl ChannelID for ChAny {
68 } 68 }
69} 69}
70 70
71const NEW_AWR: AtomicWakerRegistration = AtomicWakerRegistration::new(); 71const NEW_AWR: AtomicWaker = AtomicWaker::new();
72static CHANNEL_WAKERS: [AtomicWakerRegistration; CHANNEL_COUNT] = [NEW_AWR; CHANNEL_COUNT]; 72static CHANNEL_WAKERS: [AtomicWaker; CHANNEL_COUNT] = [NEW_AWR; CHANNEL_COUNT];
73static PORT_WAKERS: [AtomicWakerRegistration; PIN_COUNT] = [NEW_AWR; PIN_COUNT]; 73static PORT_WAKERS: [AtomicWaker; PIN_COUNT] = [NEW_AWR; PIN_COUNT];
74 74
75pub enum InputChannelPolarity { 75pub 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
51pub struct AtomicWakerRegistration { 51pub struct AtomicWaker {
52 waker: AtomicPtr<TaskHeader>, 52 waker: AtomicPtr<TaskHeader>,
53} 53}
54 54
55impl AtomicWakerRegistration { 55impl 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.
52pub struct AtomicWakerRegistration { 52pub struct AtomicWaker {
53 waker: Mutex<Cell<Option<Waker>>>, 53 waker: Mutex<Cell<Option<Waker>>>,
54} 54}
55 55
56impl AtomicWakerRegistration { 56impl 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 }