Skip to content

Commit fb8e40b

Browse files
authored
Merge pull request #3559 from bugadani/gaw
Generalize AtomicWaker
2 parents bd65906 + e05f6da commit fb8e40b

File tree

2 files changed

+33
-10
lines changed

2 files changed

+33
-10
lines changed

embassy-sync/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1212
- Add `clear`, `len`, `is_empty` and `is_full` functions to `zerocopy_channel`.
1313
- Add `capacity`, `free_capacity`, `clear`, `len`, `is_empty` and `is_full` functions to `channel::{Sender, Receiver}`.
1414
- Add `capacity`, `free_capacity`, `clear`, `len`, `is_empty` and `is_full` functions to `priority_channel::{Sender, Receiver}`.
15+
- Add `GenericAtomicWaker` utility.
1516

1617
## 0.6.0 - 2024-05-29
1718

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,25 @@
11
use core::cell::Cell;
22
use core::task::Waker;
33

4-
use crate::blocking_mutex::raw::CriticalSectionRawMutex;
4+
use crate::blocking_mutex::raw::{CriticalSectionRawMutex, RawMutex};
55
use crate::blocking_mutex::Mutex;
66

77
/// Utility struct to register and wake a waker.
8-
pub struct AtomicWaker {
9-
waker: Mutex<CriticalSectionRawMutex, Cell<Option<Waker>>>,
8+
pub struct GenericAtomicWaker<M: RawMutex> {
9+
waker: Mutex<M, Cell<Option<Waker>>>,
1010
}
1111

12-
impl AtomicWaker {
12+
impl<M: RawMutex> GenericAtomicWaker<M> {
1313
/// Create a new `AtomicWaker`.
14-
pub const fn new() -> Self {
14+
pub const fn new(mutex: M) -> Self {
1515
Self {
16-
waker: Mutex::const_new(CriticalSectionRawMutex::new(), Cell::new(None)),
16+
waker: Mutex::const_new(mutex, Cell::new(None)),
1717
}
1818
}
1919

2020
/// Register a waker. Overwrites the previous waker, if any.
2121
pub fn register(&self, w: &Waker) {
22-
critical_section::with(|cs| {
23-
let cell = self.waker.borrow(cs);
22+
self.waker.lock(|cell| {
2423
cell.set(match cell.replace(None) {
2524
Some(w2) if (w2.will_wake(w)) => Some(w2),
2625
_ => Some(w.clone()),
@@ -30,12 +29,35 @@ impl AtomicWaker {
3029

3130
/// Wake the registered waker, if any.
3231
pub fn wake(&self) {
33-
critical_section::with(|cs| {
34-
let cell = self.waker.borrow(cs);
32+
self.waker.lock(|cell| {
3533
if let Some(w) = cell.replace(None) {
3634
w.wake_by_ref();
3735
cell.set(Some(w));
3836
}
3937
})
4038
}
4139
}
40+
41+
/// Utility struct to register and wake a waker.
42+
pub struct AtomicWaker {
43+
waker: GenericAtomicWaker<CriticalSectionRawMutex>,
44+
}
45+
46+
impl 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+
}

0 commit comments

Comments
 (0)