aboutsummaryrefslogtreecommitdiff
path: root/embassy-sync/src/waitqueue/atomic_waker.rs
diff options
context:
space:
mode:
authorDion Dokter <[email protected]>2025-11-20 13:22:38 +0100
committerDion Dokter <[email protected]>2025-11-20 13:22:38 +0100
commit4f2c36e447455e8d33607d586859d3d075cabf1d (patch)
tree003cd822d688acd7c074dd229663b4648d100f71 /embassy-sync/src/waitqueue/atomic_waker.rs
parent663732d85abbae400f2dbab2c411802a5b60e9b1 (diff)
parent661874d11de7d93ed52e08e020a9d4c7ee11122d (diff)
Merge branch 'main' into u0-lcd
Diffstat (limited to 'embassy-sync/src/waitqueue/atomic_waker.rs')
-rw-r--r--embassy-sync/src/waitqueue/atomic_waker.rs45
1 files changed, 35 insertions, 10 deletions
diff --git a/embassy-sync/src/waitqueue/atomic_waker.rs b/embassy-sync/src/waitqueue/atomic_waker.rs
index 63fe04a6e..d2bf890e5 100644
--- a/embassy-sync/src/waitqueue/atomic_waker.rs
+++ b/embassy-sync/src/waitqueue/atomic_waker.rs
@@ -1,26 +1,28 @@
1use core::cell::Cell; 1use core::cell::Cell;
2use core::task::Waker; 2use core::task::Waker;
3 3
4use crate::blocking_mutex::raw::CriticalSectionRawMutex;
5use crate::blocking_mutex::Mutex; 4use crate::blocking_mutex::Mutex;
5use crate::blocking_mutex::raw::{CriticalSectionRawMutex, RawMutex};
6 6
7/// Utility struct to register and wake a waker. 7/// Utility struct to register and wake a waker.
8pub struct AtomicWaker { 8/// If a waker is registered, registering another waker will replace the previous one without waking it.
9 waker: Mutex<CriticalSectionRawMutex, Cell<Option<Waker>>>, 9/// Intended to wake a task from an interrupt. Therefore, it is generally not expected,
10/// that multiple tasks register try to register a waker simultaneously.
11pub struct GenericAtomicWaker<M: RawMutex> {
12 waker: Mutex<M, Cell<Option<Waker>>>,
10} 13}
11 14
12impl AtomicWaker { 15impl<M: RawMutex> GenericAtomicWaker<M> {
13 /// Create a new `AtomicWaker`. 16 /// Create a new `AtomicWaker`.
14 pub const fn new() -> Self { 17 pub const fn new(mutex: M) -> Self {
15 Self { 18 Self {
16 waker: Mutex::const_new(CriticalSectionRawMutex::new(), Cell::new(None)), 19 waker: Mutex::const_new(mutex, Cell::new(None)),
17 } 20 }
18 } 21 }
19 22
20 /// Register a waker. Overwrites the previous waker, if any. 23 /// Register a waker. Overwrites the previous waker, if any.
21 pub fn register(&self, w: &Waker) { 24 pub fn register(&self, w: &Waker) {
22 critical_section::with(|cs| { 25 self.waker.lock(|cell| {
23 let cell = self.waker.borrow(cs);
24 cell.set(match cell.replace(None) { 26 cell.set(match cell.replace(None) {
25 Some(w2) if (w2.will_wake(w)) => Some(w2), 27 Some(w2) if (w2.will_wake(w)) => Some(w2),
26 _ => Some(w.clone()), 28 _ => Some(w.clone()),
@@ -30,8 +32,7 @@ impl AtomicWaker {
30 32
31 /// Wake the registered waker, if any. 33 /// Wake the registered waker, if any.
32 pub fn wake(&self) { 34 pub fn wake(&self) {
33 critical_section::with(|cs| { 35 self.waker.lock(|cell| {
34 let cell = self.waker.borrow(cs);
35 if let Some(w) = cell.replace(None) { 36 if let Some(w) = cell.replace(None) {
36 w.wake_by_ref(); 37 w.wake_by_ref();
37 cell.set(Some(w)); 38 cell.set(Some(w));
@@ -39,3 +40,27 @@ impl AtomicWaker {
39 }) 40 })
40 } 41 }
41} 42}
43
44/// Utility struct to register and wake a waker.
45pub struct AtomicWaker {
46 waker: GenericAtomicWaker<CriticalSectionRawMutex>,
47}
48
49impl AtomicWaker {
50 /// Create a new `AtomicWaker`.
51 pub const fn new() -> Self {
52 Self {
53 waker: GenericAtomicWaker::new(CriticalSectionRawMutex::new()),
54 }
55 }
56
57 /// Register a waker. Overwrites the previous waker, if any.
58 pub fn register(&self, w: &Waker) {
59 self.waker.register(w);
60 }
61
62 /// Wake the registered waker, if any.
63 pub fn wake(&self) {
64 self.waker.wake();
65 }
66}