aboutsummaryrefslogtreecommitdiff
path: root/embassy-sync/src/waitqueue/atomic_waker.rs
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-sync/src/waitqueue/atomic_waker.rs')
-rw-r--r--embassy-sync/src/waitqueue/atomic_waker.rs42
1 files changed, 32 insertions, 10 deletions
diff --git a/embassy-sync/src/waitqueue/atomic_waker.rs b/embassy-sync/src/waitqueue/atomic_waker.rs
index 63fe04a6e..231902c5a 100644
--- a/embassy-sync/src/waitqueue/atomic_waker.rs
+++ b/embassy-sync/src/waitqueue/atomic_waker.rs
@@ -1,26 +1,25 @@
1use core::cell::Cell; 1use core::cell::Cell;
2use core::task::Waker; 2use core::task::Waker;
3 3
4use crate::blocking_mutex::raw::CriticalSectionRawMutex; 4use crate::blocking_mutex::raw::{CriticalSectionRawMutex, RawMutex};
5use crate::blocking_mutex::Mutex; 5use crate::blocking_mutex::Mutex;
6 6
7/// Utility struct to register and wake a waker. 7/// Utility struct to register and wake a waker.
8pub struct AtomicWaker { 8pub struct GenericAtomicWaker<M: RawMutex> {
9 waker: Mutex<CriticalSectionRawMutex, Cell<Option<Waker>>>, 9 waker: Mutex<M, Cell<Option<Waker>>>,
10} 10}
11 11
12impl AtomicWaker { 12impl<M: RawMutex> GenericAtomicWaker<M> {
13 /// Create a new `AtomicWaker`. 13 /// Create a new `AtomicWaker`.
14 pub const fn new() -> Self { 14 pub const fn new(mutex: M) -> Self {
15 Self { 15 Self {
16 waker: Mutex::const_new(CriticalSectionRawMutex::new(), Cell::new(None)), 16 waker: Mutex::const_new(mutex, Cell::new(None)),
17 } 17 }
18 } 18 }
19 19
20 /// Register a waker. Overwrites the previous waker, if any. 20 /// Register a waker. Overwrites the previous waker, if any.
21 pub fn register(&self, w: &Waker) { 21 pub fn register(&self, w: &Waker) {
22 critical_section::with(|cs| { 22 self.waker.lock(|cell| {
23 let cell = self.waker.borrow(cs);
24 cell.set(match cell.replace(None) { 23 cell.set(match cell.replace(None) {
25 Some(w2) if (w2.will_wake(w)) => Some(w2), 24 Some(w2) if (w2.will_wake(w)) => Some(w2),
26 _ => Some(w.clone()), 25 _ => Some(w.clone()),
@@ -30,8 +29,7 @@ impl AtomicWaker {
30 29
31 /// Wake the registered waker, if any. 30 /// Wake the registered waker, if any.
32 pub fn wake(&self) { 31 pub fn wake(&self) {
33 critical_section::with(|cs| { 32 self.waker.lock(|cell| {
34 let cell = self.waker.borrow(cs);
35 if let Some(w) = cell.replace(None) { 33 if let Some(w) = cell.replace(None) {
36 w.wake_by_ref(); 34 w.wake_by_ref();
37 cell.set(Some(w)); 35 cell.set(Some(w));
@@ -39,3 +37,27 @@ impl AtomicWaker {
39 }) 37 })
40 } 38 }
41} 39}
40
41/// Utility struct to register and wake a waker.
42pub struct AtomicWaker {
43 waker: GenericAtomicWaker<CriticalSectionRawMutex>,
44}
45
46impl AtomicWaker {
47 /// Create a new `AtomicWaker`.
48 pub const fn new() -> Self {
49 Self {
50 waker: GenericAtomicWaker::new(CriticalSectionRawMutex::new()),
51 }
52 }
53
54 /// Register a waker. Overwrites the previous waker, if any.
55 pub fn register(&self, w: &Waker) {
56 self.waker.register(w);
57 }
58
59 /// Wake the registered waker, if any.
60 pub fn wake(&self) {
61 self.waker.wake();
62 }
63}