Skip to content

Commit 2f03852

Browse files
committed
Add fallible from_waker getter, expose queue impls unconditionally
1 parent 54a153a commit 2f03852

File tree

7 files changed

+64
-8
lines changed

7 files changed

+64
-8
lines changed

embassy-executor/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1515
- Added optional "earliest deadline first" EDF scheduling
1616
- Migrate `cortex-ar` to `aarch32-cpu`. The feature name `arch-cortex-ar` remains the same and
1717
legacy ARM architectures are not supported.
18+
- Bump `cortex-ar` to v0.3
19+
- Added `__try_embassy_time_queue_item_from_waker`
1820

1921
## 0.9.1 - 2025-08-31
2022

embassy-executor/src/raw/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ use self::run_queue::{RunQueue, RunQueueItem};
4949
use self::state::State;
5050
use self::util::{SyncUnsafeCell, UninitCell};
5151
pub use self::waker::task_from_waker;
52+
use self::waker::try_task_from_waker;
5253
use super::SpawnToken;
5354
use crate::{Metadata, SpawnError};
5455

@@ -57,6 +58,11 @@ extern "Rust" fn __embassy_time_queue_item_from_waker(waker: &Waker) -> &'static
5758
unsafe { task_from_waker(waker).timer_queue_item() }
5859
}
5960

61+
#[unsafe(no_mangle)]
62+
extern "Rust" fn __try_embassy_time_queue_item_from_waker(waker: &Waker) -> Option<&'static mut TimerQueueItem> {
63+
unsafe { try_task_from_waker(waker).map(|task| task.timer_queue_item()) }
64+
}
65+
6066
/// Raw task header for use in task pointers.
6167
///
6268
/// A task can be in one of the following states:

embassy-executor/src/raw/waker.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,18 @@ pub(crate) unsafe fn from_task(p: TaskRef) -> Waker {
3232
///
3333
/// Panics if the waker is not created by the Embassy executor.
3434
pub fn task_from_waker(waker: &Waker) -> TaskRef {
35+
unwrap!(
36+
try_task_from_waker(waker),
37+
"Found waker not created by the Embassy executor. Unless the generic timer queue is enabled, `embassy_time::Timer` only works with the Embassy executor."
38+
)
39+
}
40+
41+
pub(crate) fn try_task_from_waker(waker: &Waker) -> Option<TaskRef> {
3542
// make sure to compare vtable addresses. Doing `==` on the references
3643
// will compare the contents, which is slower.
3744
if waker.vtable() as *const _ != &VTABLE as *const _ {
38-
panic!(
39-
"Found waker not created by the Embassy executor. `embassy_time::Timer` only works with the Embassy executor."
40-
)
45+
return None;
4146
}
4247
// safety: our wakers are always created with `TaskRef::as_ptr`
43-
unsafe { TaskRef::from_ptr(waker.data() as *const TaskHeader) }
48+
Some(unsafe { TaskRef::from_ptr(waker.data() as *const TaskHeader) })
4449
}

embassy-executor/src/raw/waker_turbo.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ pub fn task_from_waker(waker: &Waker) -> TaskRef {
2525
unsafe { TaskRef::from_ptr(ptr as *const TaskHeader) }
2626
}
2727

28+
pub(crate) fn try_task_from_waker(waker: &Waker) -> Option<TaskRef> {
29+
Some(task_from_waker(waker))
30+
}
31+
2832
#[inline(never)]
2933
#[unsafe(no_mangle)]
3034
fn _turbo_wake(ptr: NonNull<()>) {

embassy-time-queue-utils/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88
<!-- next-header -->
99
## Unreleased - ReleaseDate
1010

11+
- Both integrated and generic queue implementations are available for use, independent of their respective features.
12+
1113
## 0.3.0 - 2025-08-26
1214

1315
## 0.2.1 - 2025-08-26

embassy-time-queue-utils/src/lib.rs

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,41 @@
22
#![doc = include_str!("../README.md")]
33
#![warn(missing_docs)]
44

5-
#[cfg(feature = "_generic-queue")]
65
pub mod queue_generic;
7-
#[cfg(not(feature = "_generic-queue"))]
86
pub mod queue_integrated;
97

108
#[cfg(feature = "_generic-queue")]
11-
pub use queue_generic::Queue;
9+
type QueueImpl = queue_generic::Queue;
1210
#[cfg(not(feature = "_generic-queue"))]
13-
pub use queue_integrated::Queue;
11+
type QueueImpl = queue_integrated::Queue;
12+
13+
/// The default timer queue, configured by the crate's features.
14+
///
15+
/// If any of the `generic-queue-X` features are enabled, this implements a generic
16+
/// timer queue of capacity X. Otherwise, it implements an integrated timer queue.
17+
#[derive(Debug)]
18+
pub struct Queue {
19+
queue: QueueImpl,
20+
}
21+
22+
impl Queue {
23+
/// Creates a new timer queue.
24+
pub const fn new() -> Self {
25+
Self {
26+
queue: QueueImpl::new(),
27+
}
28+
}
29+
30+
/// Schedules a task to run at a specific time, and returns whether any changes were made.
31+
///
32+
/// If this function returns `true`, the called should find the next expiration time and set
33+
/// a new alarm for that time.
34+
pub fn schedule_wake(&mut self, at: u64, waker: &Waker) -> bool {
35+
self.queue.schedule_wake(at, waker)
36+
}
37+
38+
/// Dequeues expired timers and returns the next alarm time.
39+
pub fn next_expiration(&mut self, now: u64) -> u64 {
40+
self.queue.next_expiration(now)
41+
}
42+
}

embassy-time-queue-utils/src/queue_integrated.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,14 @@ impl Queue {
6161
// ensure that this function creates the only mutable reference to the queue item.
6262
TimerQueueItem::from_embassy_waker(waker)
6363
};
64+
self.schedule_wake_queue_item(at, item)
65+
}
66+
67+
/// Schedules a task to run at a specific time, using its integrated queue item.
68+
///
69+
/// If this function returns `true`, the called should find the next expiration time and set
70+
/// a new alarm for that time.
71+
pub fn schedule_wake_queue_item(&mut self, at: u64, item: &mut TimerQueueItem) -> bool {
6472
let item = unsafe { item.as_mut::<QueueItem>() };
6573
match item.waker.as_ref() {
6674
Some(_) if at <= item.expires_at => {

0 commit comments

Comments
 (0)