aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDániel Buga <[email protected]>2024-12-16 18:08:19 +0100
committerDániel Buga <[email protected]>2024-12-16 19:22:22 +0100
commit3c121e5425e0a1901c459d27e3e5929f86d0a206 (patch)
tree39c8c1ff1a5aeaa0c62100880b5d9966866a630f
parentd3f0294fb12e060c4a3ba557ff95766d1c3686e0 (diff)
Remove special handling of integrated timer queue
-rw-r--r--embassy-executor/src/raw/mod.rs22
-rw-r--r--embassy-time-driver/src/lib.rs6
-rw-r--r--embassy-time-queue-driver/src/lib.rs28
-rw-r--r--embassy-time/Cargo.toml8
-rw-r--r--embassy-time/src/timer.rs6
5 files changed, 13 insertions, 57 deletions
diff --git a/embassy-executor/src/raw/mod.rs b/embassy-executor/src/raw/mod.rs
index 5a476213b..997db6756 100644
--- a/embassy-executor/src/raw/mod.rs
+++ b/embassy-executor/src/raw/mod.rs
@@ -195,25 +195,7 @@ impl<F: Future + 'static> TaskStorage<F> {
195 match future.poll(&mut cx) { 195 match future.poll(&mut cx) {
196 Poll::Ready(_) => { 196 Poll::Ready(_) => {
197 this.future.drop_in_place(); 197 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(); 198 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 } 199 }
218 Poll::Pending => {} 200 Poll::Pending => {}
219 } 201 }
@@ -232,10 +214,6 @@ impl<F: Future + 'static> TaskStorage<F> {
232 } 214 }
233} 215}
234 216
235extern "Rust" {
236 fn _embassy_time_schedule_wake(at: u64, waker: &core::task::Waker);
237}
238
239/// An uninitialized [`TaskStorage`]. 217/// An uninitialized [`TaskStorage`].
240pub struct AvailableTask<F: Future + 'static> { 218pub struct AvailableTask<F: Future + 'static> {
241 task: &'static TaskStorage<F>, 219 task: &'static TaskStorage<F>,
diff --git a/embassy-time-driver/src/lib.rs b/embassy-time-driver/src/lib.rs
index 57a9f7587..c776fbdf8 100644
--- a/embassy-time-driver/src/lib.rs
+++ b/embassy-time-driver/src/lib.rs
@@ -131,6 +131,7 @@ pub trait Driver: Send + Sync + 'static {
131 131
132extern "Rust" { 132extern "Rust" {
133 fn _embassy_time_now() -> u64; 133 fn _embassy_time_now() -> u64;
134 fn _embassy_time_schedule_wake(at: u64, waker: &Waker);
134} 135}
135 136
136/// See [`Driver::now`] 137/// See [`Driver::now`]
@@ -138,6 +139,11 @@ pub fn now() -> u64 {
138 unsafe { _embassy_time_now() } 139 unsafe { _embassy_time_now() }
139} 140}
140 141
142/// Schedule the given waker to be woken at `at`.
143pub fn schedule_wake(at: u64, waker: &Waker) {
144 unsafe { _embassy_time_schedule_wake(at, waker) }
145}
146
141/// Set the time Driver implementation. 147/// Set the time Driver implementation.
142/// 148///
143/// See the module documentation for an example. 149/// 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/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 }