aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2024-12-17 14:52:12 +0100
committerGitHub <[email protected]>2024-12-17 14:52:12 +0100
commitc504ae8d3a5eb754e0b0920b346dd1a2dc9e2b48 (patch)
treedfc3ac53ba9ffd270dc3d4e8b5a3d3daec3c3611
parent9cf037bc954cc347b5d52d90207f68090cc5b09e (diff)
parentc3c571e01ef902ccd2c3b176a4bc6ee3547d5da7 (diff)
Merge pull request #3656 from bugadani/timer-queue-special
Remove special handling of integrated timer queues and items
-rw-r--r--embassy-executor/CHANGELOG.md1
-rw-r--r--embassy-executor/Cargo.toml16
-rw-r--r--embassy-executor/src/raw/mod.rs45
-rw-r--r--embassy-executor/src/raw/state_atomics.rs32
-rw-r--r--embassy-executor/src/raw/state_atomics_arm.rs36
-rw-r--r--embassy-executor/src/raw/state_critical_section.rs25
-rw-r--r--embassy-executor/src/raw/timer_queue.rs56
-rw-r--r--embassy-executor/tests/test.rs4
-rw-r--r--embassy-time-driver/src/lib.rs9
-rw-r--r--embassy-time-queue-driver/src/lib.rs28
-rw-r--r--embassy-time-queue-driver/src/queue_integrated.rs1
-rw-r--r--embassy-time/Cargo.toml8
-rw-r--r--embassy-time/src/timer.rs6
13 files changed, 80 insertions, 187 deletions
diff --git a/embassy-executor/CHANGELOG.md b/embassy-executor/CHANGELOG.md
index 068156210..59ea88d0c 100644
--- a/embassy-executor/CHANGELOG.md
+++ b/embassy-executor/CHANGELOG.md
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
10- embassy-executor no longer provides an `embassy-time-queue-driver` implementation 10- embassy-executor no longer provides an `embassy-time-queue-driver` implementation
11- Added `TaskRef::executor` to obtain a reference to a task's executor 11- Added `TaskRef::executor` to obtain a reference to a task's executor
12- integrated-timers are no longer processed when polling the executor. 12- integrated-timers are no longer processed when polling the executor.
13- Added the option to store data in timer queue items
13 14
14## 0.6.3 - 2024-11-12 15## 0.6.3 - 2024-11-12
15 16
diff --git a/embassy-executor/Cargo.toml b/embassy-executor/Cargo.toml
index 60fe7087a..2a64b9c83 100644
--- a/embassy-executor/Cargo.toml
+++ b/embassy-executor/Cargo.toml
@@ -92,6 +92,22 @@ trace = []
92## Enable support for rtos-trace framework 92## Enable support for rtos-trace framework
93rtos-trace = ["dep:rtos-trace", "trace", "dep:embassy-time-driver"] 93rtos-trace = ["dep:rtos-trace", "trace", "dep:embassy-time-driver"]
94 94
95#! ### Timer Item Payload Size
96#! Sets the size of the payload for timer items, allowing integrated timer implementors to store
97#! additional data in the timer item. The payload field will be aligned to this value as well.
98#! If these features are not defined, the timer item will contain no payload field.
99
100_timer-item-payload = [] # A size was picked
101
102## 1 bytes
103timer-item-payload-size-1 = ["_timer-item-payload"]
104## 2 bytes
105timer-item-payload-size-2 = ["_timer-item-payload"]
106## 4 bytes
107timer-item-payload-size-4 = ["_timer-item-payload"]
108## 8 bytes
109timer-item-payload-size-8 = ["_timer-item-payload"]
110
95#! ### Task Arena Size 111#! ### Task Arena Size
96#! Sets the [task arena](#task-arena) size. Necessary if you’re not using `nightly`. 112#! Sets the [task arena](#task-arena) size. Necessary if you’re not using `nightly`.
97#! 113#!
diff --git a/embassy-executor/src/raw/mod.rs b/embassy-executor/src/raw/mod.rs
index 5a476213b..bdd5ff5ae 100644
--- a/embassy-executor/src/raw/mod.rs
+++ b/embassy-executor/src/raw/mod.rs
@@ -96,29 +96,6 @@ impl TaskRef {
96 &self.header().timer_queue_item 96 &self.header().timer_queue_item
97 } 97 }
98 98
99 /// Mark the task as timer-queued. Return whether it should be actually enqueued
100 /// using `_embassy_time_schedule_wake`.
101 ///
102 /// Entering this state prevents the task from being respawned while in a timer queue.
103 ///
104 /// Safety:
105 ///
106 /// This functions should only be called by the timer queue driver, before
107 /// enqueueing the timer item.
108 pub unsafe fn timer_enqueue(&self) -> timer_queue::TimerEnqueueOperation {
109 self.header().state.timer_enqueue()
110 }
111
112 /// Unmark the task as timer-queued.
113 ///
114 /// Safety:
115 ///
116 /// This functions should only be called by the timer queue implementation, after the task has
117 /// been removed from the timer queue.
118 pub unsafe fn timer_dequeue(&self) {
119 self.header().state.timer_dequeue()
120 }
121
122 /// The returned pointer is valid for the entire TaskStorage. 99 /// The returned pointer is valid for the entire TaskStorage.
123 pub(crate) fn as_ptr(self) -> *const TaskHeader { 100 pub(crate) fn as_ptr(self) -> *const TaskHeader {
124 self.ptr.as_ptr() 101 self.ptr.as_ptr()
@@ -195,25 +172,7 @@ impl<F: Future + 'static> TaskStorage<F> {
195 match future.poll(&mut cx) { 172 match future.poll(&mut cx) {
196 Poll::Ready(_) => { 173 Poll::Ready(_) => {
197 this.future.drop_in_place(); 174 this.future.drop_in_place();
198
199 // Mark this task to be timer queued.
200 // We're splitting the enqueue in two parts, so that we can change task state
201 // to something that prevent re-queueing.
202 let op = this.raw.state.timer_enqueue();
203
204 // Now mark the task as not spawned, so that
205 // - it can be spawned again once it has been removed from the timer queue
206 // - it can not be timer-queued again
207 // We must do this before scheduling the wake, to prevent the task from being
208 // dequeued by the time driver while it's still SPAWNED.
209 this.raw.state.despawn(); 175 this.raw.state.despawn();
210
211 // Now let's finish enqueueing. While we shouldn't get an `Ignore` here, it's
212 // better to be safe.
213 if op == timer_queue::TimerEnqueueOperation::Enqueue {
214 // Schedule the task in the past, so it gets dequeued ASAP.
215 unsafe { _embassy_time_schedule_wake(0, &waker) }
216 }
217 } 176 }
218 Poll::Pending => {} 177 Poll::Pending => {}
219 } 178 }
@@ -232,10 +191,6 @@ impl<F: Future + 'static> TaskStorage<F> {
232 } 191 }
233} 192}
234 193
235extern "Rust" {
236 fn _embassy_time_schedule_wake(at: u64, waker: &core::task::Waker);
237}
238
239/// An uninitialized [`TaskStorage`]. 194/// An uninitialized [`TaskStorage`].
240pub struct AvailableTask<F: Future + 'static> { 195pub struct AvailableTask<F: Future + 'static> {
241 task: &'static TaskStorage<F>, 196 task: &'static TaskStorage<F>,
diff --git a/embassy-executor/src/raw/state_atomics.rs b/embassy-executor/src/raw/state_atomics.rs
index d7350464f..6f5266bda 100644
--- a/embassy-executor/src/raw/state_atomics.rs
+++ b/embassy-executor/src/raw/state_atomics.rs
@@ -1,7 +1,5 @@
1use core::sync::atomic::{AtomicU32, Ordering}; 1use core::sync::atomic::{AtomicU32, Ordering};
2 2
3use super::timer_queue::TimerEnqueueOperation;
4
5#[derive(Clone, Copy)] 3#[derive(Clone, Copy)]
6pub(crate) struct Token(()); 4pub(crate) struct Token(());
7 5
@@ -16,8 +14,6 @@ pub(crate) fn locked<R>(f: impl FnOnce(Token) -> R) -> R {
16pub(crate) const STATE_SPAWNED: u32 = 1 << 0; 14pub(crate) const STATE_SPAWNED: u32 = 1 << 0;
17/// Task is in the executor run queue 15/// Task is in the executor run queue
18pub(crate) const STATE_RUN_QUEUED: u32 = 1 << 1; 16pub(crate) const STATE_RUN_QUEUED: u32 = 1 << 1;
19/// Task is in the executor timer queue
20pub(crate) const STATE_TIMER_QUEUED: u32 = 1 << 2;
21 17
22pub(crate) struct State { 18pub(crate) struct State {
23 state: AtomicU32, 19 state: AtomicU32,
@@ -71,32 +67,4 @@ impl State {
71 let state = self.state.fetch_and(!STATE_RUN_QUEUED, Ordering::AcqRel); 67 let state = self.state.fetch_and(!STATE_RUN_QUEUED, Ordering::AcqRel);
72 state & STATE_SPAWNED != 0 68 state & STATE_SPAWNED != 0
73 } 69 }
74
75 /// Mark the task as timer-queued. Return whether it can be enqueued.
76 #[inline(always)]
77 pub fn timer_enqueue(&self) -> TimerEnqueueOperation {
78 if self
79 .state
80 .fetch_update(Ordering::SeqCst, Ordering::SeqCst, |state| {
81 // If not started, ignore it
82 if state & STATE_SPAWNED == 0 {
83 None
84 } else {
85 // Mark it as enqueued
86 Some(state | STATE_TIMER_QUEUED)
87 }
88 })
89 .is_ok()
90 {
91 TimerEnqueueOperation::Enqueue
92 } else {
93 TimerEnqueueOperation::Ignore
94 }
95 }
96
97 /// Unmark the task as timer-queued.
98 #[inline(always)]
99 pub fn timer_dequeue(&self) {
100 self.state.fetch_and(!STATE_TIMER_QUEUED, Ordering::Relaxed);
101 }
102} 70}
diff --git a/embassy-executor/src/raw/state_atomics_arm.rs b/embassy-executor/src/raw/state_atomics_arm.rs
index c1e8f69ab..4896b33c5 100644
--- a/embassy-executor/src/raw/state_atomics_arm.rs
+++ b/embassy-executor/src/raw/state_atomics_arm.rs
@@ -1,8 +1,6 @@
1use core::arch::asm; 1use core::arch::asm;
2use core::sync::atomic::{compiler_fence, AtomicBool, AtomicU32, Ordering}; 2use core::sync::atomic::{compiler_fence, AtomicBool, AtomicU32, Ordering};
3 3
4use super::timer_queue::TimerEnqueueOperation;
5
6#[derive(Clone, Copy)] 4#[derive(Clone, Copy)]
7pub(crate) struct Token(()); 5pub(crate) struct Token(());
8 6
@@ -16,7 +14,6 @@ pub(crate) fn locked<R>(f: impl FnOnce(Token) -> R) -> R {
16// Must be kept in sync with the layout of `State`! 14// Must be kept in sync with the layout of `State`!
17pub(crate) const STATE_SPAWNED: u32 = 1 << 0; 15pub(crate) const STATE_SPAWNED: u32 = 1 << 0;
18pub(crate) const STATE_RUN_QUEUED: u32 = 1 << 8; 16pub(crate) const STATE_RUN_QUEUED: u32 = 1 << 8;
19pub(crate) const STATE_TIMER_QUEUED: u32 = 1 << 16;
20 17
21#[repr(C, align(4))] 18#[repr(C, align(4))]
22pub(crate) struct State { 19pub(crate) struct State {
@@ -24,9 +21,8 @@ pub(crate) struct State {
24 spawned: AtomicBool, 21 spawned: AtomicBool,
25 /// Task is in the executor run queue 22 /// Task is in the executor run queue
26 run_queued: AtomicBool, 23 run_queued: AtomicBool,
27 /// Task is in the executor timer queue
28 timer_queued: AtomicBool,
29 pad: AtomicBool, 24 pad: AtomicBool,
25 pad2: AtomicBool,
30} 26}
31 27
32impl State { 28impl State {
@@ -34,8 +30,8 @@ impl State {
34 Self { 30 Self {
35 spawned: AtomicBool::new(false), 31 spawned: AtomicBool::new(false),
36 run_queued: AtomicBool::new(false), 32 run_queued: AtomicBool::new(false),
37 timer_queued: AtomicBool::new(false),
38 pad: AtomicBool::new(false), 33 pad: AtomicBool::new(false),
34 pad2: AtomicBool::new(false),
39 } 35 }
40 } 36 }
41 37
@@ -101,32 +97,4 @@ impl State {
101 self.run_queued.store(false, Ordering::Relaxed); 97 self.run_queued.store(false, Ordering::Relaxed);
102 r 98 r
103 } 99 }
104
105 /// Mark the task as timer-queued. Return whether it can be enqueued.
106 #[inline(always)]
107 pub fn timer_enqueue(&self) -> TimerEnqueueOperation {
108 if self
109 .as_u32()
110 .fetch_update(Ordering::SeqCst, Ordering::SeqCst, |state| {
111 // If not started, ignore it
112 if state & STATE_SPAWNED == 0 {
113 None
114 } else {
115 // Mark it as enqueued
116 Some(state | STATE_TIMER_QUEUED)
117 }
118 })
119 .is_ok()
120 {
121 TimerEnqueueOperation::Enqueue
122 } else {
123 TimerEnqueueOperation::Ignore
124 }
125 }
126
127 /// Unmark the task as timer-queued.
128 #[inline(always)]
129 pub fn timer_dequeue(&self) {
130 self.timer_queued.store(false, Ordering::Relaxed);
131 }
132} 100}
diff --git a/embassy-executor/src/raw/state_critical_section.rs b/embassy-executor/src/raw/state_critical_section.rs
index 8e570b33c..29b10f6e3 100644
--- a/embassy-executor/src/raw/state_critical_section.rs
+++ b/embassy-executor/src/raw/state_critical_section.rs
@@ -3,14 +3,10 @@ use core::cell::Cell;
3pub(crate) use critical_section::{with as locked, CriticalSection as Token}; 3pub(crate) use critical_section::{with as locked, CriticalSection as Token};
4use critical_section::{CriticalSection, Mutex}; 4use critical_section::{CriticalSection, Mutex};
5 5
6use super::timer_queue::TimerEnqueueOperation;
7
8/// Task is spawned (has a future) 6/// Task is spawned (has a future)
9pub(crate) const STATE_SPAWNED: u32 = 1 << 0; 7pub(crate) const STATE_SPAWNED: u32 = 1 << 0;
10/// Task is in the executor run queue 8/// Task is in the executor run queue
11pub(crate) const STATE_RUN_QUEUED: u32 = 1 << 1; 9pub(crate) const STATE_RUN_QUEUED: u32 = 1 << 1;
12/// Task is in the executor timer queue
13pub(crate) const STATE_TIMER_QUEUED: u32 = 1 << 2;
14 10
15pub(crate) struct State { 11pub(crate) struct State {
16 state: Mutex<Cell<u32>>, 12 state: Mutex<Cell<u32>>,
@@ -81,25 +77,4 @@ impl State {
81 ok 77 ok
82 }) 78 })
83 } 79 }
84
85 /// Mark the task as timer-queued. Return whether it can be enqueued.
86 #[inline(always)]
87 pub fn timer_enqueue(&self) -> TimerEnqueueOperation {
88 self.update(|s| {
89 // FIXME: we need to split SPAWNED into two phases, to prevent enqueueing a task that is
90 // just being spawned, because its executor pointer may still be changing.
91 if *s & STATE_SPAWNED == STATE_SPAWNED {
92 *s |= STATE_TIMER_QUEUED;
93 TimerEnqueueOperation::Enqueue
94 } else {
95 TimerEnqueueOperation::Ignore
96 }
97 })
98 }
99
100 /// Unmark the task as timer-queued.
101 #[inline(always)]
102 pub fn timer_dequeue(&self) {
103 self.update(|s| *s &= !STATE_TIMER_QUEUED);
104 }
105} 80}
diff --git a/embassy-executor/src/raw/timer_queue.rs b/embassy-executor/src/raw/timer_queue.rs
index 2ba0e00a9..e52453be4 100644
--- a/embassy-executor/src/raw/timer_queue.rs
+++ b/embassy-executor/src/raw/timer_queue.rs
@@ -4,6 +4,45 @@ use core::cell::Cell;
4 4
5use super::TaskRef; 5use super::TaskRef;
6 6
7#[cfg(feature = "_timer-item-payload")]
8macro_rules! define_opaque {
9 ($size:tt) => {
10 /// An opaque data type.
11 #[repr(align($size))]
12 pub struct OpaqueData {
13 data: [u8; $size],
14 }
15
16 impl OpaqueData {
17 const fn new() -> Self {
18 Self { data: [0; $size] }
19 }
20
21 /// Access the data as a reference to a type `T`.
22 ///
23 /// Safety:
24 ///
25 /// The caller must ensure that the size of the type `T` is less than, or equal to
26 /// the size of the payload, and must ensure that the alignment of the type `T` is
27 /// less than, or equal to the alignment of the payload.
28 ///
29 /// The type must be valid when zero-initialized.
30 pub unsafe fn as_ref<T>(&self) -> &T {
31 &*(self.data.as_ptr() as *const T)
32 }
33 }
34 };
35}
36
37#[cfg(feature = "timer-item-payload-size-1")]
38define_opaque!(1);
39#[cfg(feature = "timer-item-payload-size-2")]
40define_opaque!(2);
41#[cfg(feature = "timer-item-payload-size-4")]
42define_opaque!(4);
43#[cfg(feature = "timer-item-payload-size-8")]
44define_opaque!(8);
45
7/// An item in the timer queue. 46/// An item in the timer queue.
8pub struct TimerQueueItem { 47pub struct TimerQueueItem {
9 /// The next item in the queue. 48 /// The next item in the queue.
@@ -14,6 +53,10 @@ pub struct TimerQueueItem {
14 53
15 /// The time at which this item expires. 54 /// The time at which this item expires.
16 pub expires_at: Cell<u64>, 55 pub expires_at: Cell<u64>,
56
57 /// Some implementation-defined, zero-initialized piece of data.
58 #[cfg(feature = "_timer-item-payload")]
59 pub payload: OpaqueData,
17} 60}
18 61
19unsafe impl Sync for TimerQueueItem {} 62unsafe impl Sync for TimerQueueItem {}
@@ -23,17 +66,8 @@ impl TimerQueueItem {
23 Self { 66 Self {
24 next: Cell::new(None), 67 next: Cell::new(None),
25 expires_at: Cell::new(0), 68 expires_at: Cell::new(0),
69 #[cfg(feature = "_timer-item-payload")]
70 payload: OpaqueData::new(),
26 } 71 }
27 } 72 }
28} 73}
29
30/// The operation to perform after `timer_enqueue` is called.
31#[derive(Debug, Copy, Clone, PartialEq)]
32#[cfg_attr(feature = "defmt", derive(defmt::Format))]
33#[must_use]
34pub enum TimerEnqueueOperation {
35 /// Enqueue the task (or update its expiration time).
36 Enqueue,
37 /// The task must not be enqueued in the timer queue.
38 Ignore,
39}
diff --git a/embassy-executor/tests/test.rs b/embassy-executor/tests/test.rs
index 992ab3da9..0ce1f1891 100644
--- a/embassy-executor/tests/test.rs
+++ b/embassy-executor/tests/test.rs
@@ -150,7 +150,3 @@ fn executor_task_cfg_args() {
150 let (_, _, _) = (a, b, c); 150 let (_, _, _) = (a, b, c);
151 } 151 }
152} 152}
153
154// We need this for the test to compile, even though we don't want to use timers at the moment.
155#[no_mangle]
156fn _embassy_time_schedule_wake(_at: u64, _waker: &core::task::Waker) {}
diff --git a/embassy-time-driver/src/lib.rs b/embassy-time-driver/src/lib.rs
index 57a9f7587..9f2795a01 100644
--- a/embassy-time-driver/src/lib.rs
+++ b/embassy-time-driver/src/lib.rs
@@ -46,6 +46,9 @@
46//! 46//!
47//! Then, you'll need to adapt the `schedule_wake` method to use this queue. 47//! Then, you'll need to adapt the `schedule_wake` method to use this queue.
48//! 48//!
49//! Note that if you are using multiple queues, you will need to ensure that a single timer
50//! queue item is only ever enqueued into a single queue at a time.
51//!
49//! ```ignore 52//! ```ignore
50//! use core::cell::RefCell; 53//! use core::cell::RefCell;
51//! use core::task::Waker; 54//! use core::task::Waker;
@@ -131,6 +134,7 @@ pub trait Driver: Send + Sync + 'static {
131 134
132extern "Rust" { 135extern "Rust" {
133 fn _embassy_time_now() -> u64; 136 fn _embassy_time_now() -> u64;
137 fn _embassy_time_schedule_wake(at: u64, waker: &Waker);
134} 138}
135 139
136/// See [`Driver::now`] 140/// See [`Driver::now`]
@@ -138,6 +142,11 @@ pub fn now() -> u64 {
138 unsafe { _embassy_time_now() } 142 unsafe { _embassy_time_now() }
139} 143}
140 144
145/// Schedule the given waker to be woken at `at`.
146pub fn schedule_wake(at: u64, waker: &Waker) {
147 unsafe { _embassy_time_schedule_wake(at, waker) }
148}
149
141/// Set the time Driver implementation. 150/// Set the time Driver implementation.
142/// 151///
143/// See the module documentation for an example. 152/// See the module documentation for an example.
diff --git a/embassy-time-queue-driver/src/lib.rs b/embassy-time-queue-driver/src/lib.rs
index 97c81a124..333b6124d 100644
--- a/embassy-time-queue-driver/src/lib.rs
+++ b/embassy-time-queue-driver/src/lib.rs
@@ -10,8 +10,6 @@
10//! As a HAL implementer, you need to depend on this crate if you want to implement a time driver, 10//! As a HAL implementer, you need to depend on this crate if you want to implement a time driver,
11//! but how you should do so is documented in `embassy-time-driver`. 11//! but how you should do so is documented in `embassy-time-driver`.
12 12
13use core::task::Waker;
14
15#[cfg(feature = "_generic-queue")] 13#[cfg(feature = "_generic-queue")]
16pub mod queue_generic; 14pub mod queue_generic;
17#[cfg(not(feature = "_generic-queue"))] 15#[cfg(not(feature = "_generic-queue"))]
@@ -21,29 +19,3 @@ pub mod queue_integrated;
21pub use queue_generic::Queue; 19pub use queue_generic::Queue;
22#[cfg(not(feature = "_generic-queue"))] 20#[cfg(not(feature = "_generic-queue"))]
23pub use queue_integrated::Queue; 21pub use queue_integrated::Queue;
24
25extern "Rust" {
26 fn _embassy_time_schedule_wake(at: u64, waker: &Waker);
27}
28
29/// Schedule the given waker to be woken at `at`.
30pub fn schedule_wake(at: u64, waker: &Waker) {
31 // This function is not implemented in embassy-time-driver because it needs access to executor
32 // internals. The function updates task state, then delegates to the implementation provided
33 // by the time driver.
34 #[cfg(not(feature = "_generic-queue"))]
35 {
36 use embassy_executor::raw::task_from_waker;
37 use embassy_executor::raw::timer_queue::TimerEnqueueOperation;
38 // The very first thing we must do, before we even access the timer queue, is to
39 // mark the task a TIMER_QUEUED. This ensures that the task that is being scheduled
40 // can not be respawn while we are accessing the timer queue.
41 let task = task_from_waker(waker);
42 if unsafe { task.timer_enqueue() } == TimerEnqueueOperation::Ignore {
43 // We are not allowed to enqueue the task in the timer queue. This is because the
44 // task is not spawned, and so it makes no sense to schedule it.
45 return;
46 }
47 }
48 unsafe { _embassy_time_schedule_wake(at, waker) }
49}
diff --git a/embassy-time-queue-driver/src/queue_integrated.rs b/embassy-time-queue-driver/src/queue_integrated.rs
index 6bb4c0c1a..246cf1d63 100644
--- a/embassy-time-queue-driver/src/queue_integrated.rs
+++ b/embassy-time-queue-driver/src/queue_integrated.rs
@@ -83,7 +83,6 @@ impl Queue {
83 // Remove it 83 // Remove it
84 prev.set(item.next.get()); 84 prev.set(item.next.get());
85 item.next.set(None); 85 item.next.set(None);
86 unsafe { p.timer_dequeue() };
87 } 86 }
88 } 87 }
89 } 88 }
diff --git a/embassy-time/Cargo.toml b/embassy-time/Cargo.toml
index e3074119f..4f4ea0b14 100644
--- a/embassy-time/Cargo.toml
+++ b/embassy-time/Cargo.toml
@@ -24,8 +24,8 @@ target = "x86_64-unknown-linux-gnu"
24features = ["defmt", "std"] 24features = ["defmt", "std"]
25 25
26[features] 26[features]
27std = ["tick-hz-1_000_000", "critical-section/std"] 27std = ["tick-hz-1_000_000", "critical-section/std", "dep:embassy-time-queue-driver"]
28wasm = ["dep:wasm-bindgen", "dep:js-sys", "dep:wasm-timer", "tick-hz-1_000_000"] 28wasm = ["dep:wasm-bindgen", "dep:js-sys", "dep:wasm-timer", "tick-hz-1_000_000", "dep:embassy-time-queue-driver"]
29 29
30## Display the time since startup next to defmt log messages. 30## Display the time since startup next to defmt log messages.
31## At most 1 `defmt-timestamp-uptime-*` feature can be used. 31## At most 1 `defmt-timestamp-uptime-*` feature can be used.
@@ -40,7 +40,7 @@ defmt-timestamp-uptime-tms = ["defmt"]
40defmt-timestamp-uptime-tus = ["defmt"] 40defmt-timestamp-uptime-tus = ["defmt"]
41 41
42## Create a `MockDriver` that can be manually advanced for testing purposes. 42## Create a `MockDriver` that can be manually advanced for testing purposes.
43mock-driver = ["tick-hz-1_000_000"] 43mock-driver = ["tick-hz-1_000_000", "dep:embassy-time-queue-driver"]
44 44
45#! ### Tick Rate 45#! ### Tick Rate
46#! 46#!
@@ -384,7 +384,7 @@ tick-hz-5_242_880_000 = ["embassy-time-driver/tick-hz-5_242_880_000"]
384 384
385[dependencies] 385[dependencies]
386embassy-time-driver = { version = "0.1.0", path = "../embassy-time-driver" } 386embassy-time-driver = { version = "0.1.0", path = "../embassy-time-driver" }
387embassy-time-queue-driver = { version = "0.1.0", path = "../embassy-time-queue-driver" } 387embassy-time-queue-driver = { version = "0.1.0", path = "../embassy-time-queue-driver", optional = true}
388 388
389defmt = { version = "0.3", optional = true } 389defmt = { version = "0.3", optional = true }
390log = { version = "0.4.14", optional = true } 390log = { version = "0.4.14", optional = true }
diff --git a/embassy-time/src/timer.rs b/embassy-time/src/timer.rs
index 4d7194b20..295ddbd9b 100644
--- a/embassy-time/src/timer.rs
+++ b/embassy-time/src/timer.rs
@@ -157,7 +157,7 @@ impl Future for Timer {
157 if self.yielded_once && self.expires_at <= Instant::now() { 157 if self.yielded_once && self.expires_at <= Instant::now() {
158 Poll::Ready(()) 158 Poll::Ready(())
159 } else { 159 } else {
160 embassy_time_queue_driver::schedule_wake(self.expires_at.as_ticks(), cx.waker()); 160 embassy_time_driver::schedule_wake(self.expires_at.as_ticks(), cx.waker());
161 self.yielded_once = true; 161 self.yielded_once = true;
162 Poll::Pending 162 Poll::Pending
163 } 163 }
@@ -238,7 +238,7 @@ impl Ticker {
238 self.expires_at += dur; 238 self.expires_at += dur;
239 Poll::Ready(()) 239 Poll::Ready(())
240 } else { 240 } else {
241 embassy_time_queue_driver::schedule_wake(self.expires_at.as_ticks(), cx.waker()); 241 embassy_time_driver::schedule_wake(self.expires_at.as_ticks(), cx.waker());
242 Poll::Pending 242 Poll::Pending
243 } 243 }
244 }) 244 })
@@ -255,7 +255,7 @@ impl Stream for Ticker {
255 self.expires_at += dur; 255 self.expires_at += dur;
256 Poll::Ready(Some(())) 256 Poll::Ready(Some(()))
257 } else { 257 } else {
258 embassy_time_queue_driver::schedule_wake(self.expires_at.as_ticks(), cx.waker()); 258 embassy_time_driver::schedule_wake(self.expires_at.as_ticks(), cx.waker());
259 Poll::Pending 259 Poll::Pending
260 } 260 }
261 } 261 }