time: split queue driver too, don't reexport drivers.

This commit is contained in:
Dario Nieuwenhuis
2024-01-11 22:47:05 +01:00
parent b3ab2d91f7
commit f0606da9ad
17 changed files with 100 additions and 128 deletions

View File

@@ -33,7 +33,8 @@ log = { version = "0.4.14", optional = true }
rtos-trace = { version = "0.1.2", optional = true }
embassy-executor-macros = { version = "0.4.0", path = "../embassy-executor-macros" }
embassy-time = { version = "0.2", path = "../embassy-time", optional = true}
embassy-time-driver = { version = "0.1.0", path = "../embassy-time-driver", optional = true }
embassy-time-queue-driver = { version = "0.1.0", path = "../embassy-time-queue-driver", optional = true }
critical-section = "1.1"
document-features = "0.2.7"
@@ -63,8 +64,8 @@ nightly = ["embassy-executor-macros/nightly"]
# See: https://github.com/embassy-rs/embassy/pull/1263
turbowakers = []
## Use timers from `embassy-time`
integrated-timers = ["dep:embassy-time"]
## Use the executor-integrated `embassy-time` timer queue.
integrated-timers = ["dep:embassy-time-driver", "dep:embassy-time-queue-driver"]
#! ### Architecture
_arch = [] # some arch was picked
@@ -177,4 +178,4 @@ task-arena-size-1048576 = []
# END AUTOGENERATED CONFIG FEATURES
#! </details>
#! </details>

View File

@@ -30,9 +30,7 @@ use core::ptr::NonNull;
use core::task::{Context, Poll};
#[cfg(feature = "integrated-timers")]
use embassy_time::driver::{self, AlarmHandle};
#[cfg(feature = "integrated-timers")]
use embassy_time::Instant;
use embassy_time_driver::{self, AlarmHandle};
#[cfg(feature = "rtos-trace")]
use rtos_trace::trace;
@@ -50,7 +48,7 @@ pub(crate) struct TaskHeader {
poll_fn: SyncUnsafeCell<Option<unsafe fn(TaskRef)>>,
#[cfg(feature = "integrated-timers")]
pub(crate) expires_at: SyncUnsafeCell<Instant>,
pub(crate) expires_at: SyncUnsafeCell<u64>,
#[cfg(feature = "integrated-timers")]
pub(crate) timer_queue_item: timer_queue::TimerQueueItem,
}
@@ -123,7 +121,7 @@ impl<F: Future + 'static> TaskStorage<F> {
poll_fn: SyncUnsafeCell::new(None),
#[cfg(feature = "integrated-timers")]
expires_at: SyncUnsafeCell::new(Instant::from_ticks(0)),
expires_at: SyncUnsafeCell::new(0),
#[cfg(feature = "integrated-timers")]
timer_queue_item: timer_queue::TimerQueueItem::new(),
},
@@ -164,7 +162,7 @@ impl<F: Future + 'static> TaskStorage<F> {
this.raw.state.despawn();
#[cfg(feature = "integrated-timers")]
this.raw.expires_at.set(Instant::MAX);
this.raw.expires_at.set(u64::MAX);
}
Poll::Pending => {}
}
@@ -328,7 +326,7 @@ pub(crate) struct SyncExecutor {
impl SyncExecutor {
pub(crate) fn new(pender: Pender) -> Self {
#[cfg(feature = "integrated-timers")]
let alarm = unsafe { unwrap!(driver::allocate_alarm()) };
let alarm = unsafe { unwrap!(embassy_time_driver::allocate_alarm()) };
Self {
run_queue: RunQueue::new(),
@@ -377,18 +375,19 @@ impl SyncExecutor {
/// Same as [`Executor::poll`], plus you must only call this on the thread this executor was created.
pub(crate) unsafe fn poll(&'static self) {
#[cfg(feature = "integrated-timers")]
driver::set_alarm_callback(self.alarm, Self::alarm_callback, self as *const _ as *mut ());
embassy_time_driver::set_alarm_callback(self.alarm, Self::alarm_callback, self as *const _ as *mut ());
#[allow(clippy::never_loop)]
loop {
#[cfg(feature = "integrated-timers")]
self.timer_queue.dequeue_expired(Instant::now(), wake_task_no_pend);
self.timer_queue
.dequeue_expired(embassy_time_driver::now(), wake_task_no_pend);
self.run_queue.dequeue_all(|p| {
let task = p.header();
#[cfg(feature = "integrated-timers")]
task.expires_at.set(Instant::MAX);
task.expires_at.set(u64::MAX);
if !task.state.run_dequeue() {
// If task is not running, ignore it. This can happen in the following scenario:
@@ -418,7 +417,7 @@ impl SyncExecutor {
// If this is already in the past, set_alarm might return false
// In that case do another poll loop iteration.
let next_expiration = self.timer_queue.next_expiration();
if driver::set_alarm(self.alarm, next_expiration.as_ticks()) {
if embassy_time_driver::set_alarm(self.alarm, next_expiration) {
break;
}
}
@@ -568,8 +567,8 @@ pub fn wake_task_no_pend(task: TaskRef) {
struct TimerQueue;
#[cfg(feature = "integrated-timers")]
impl embassy_time::queue::TimerQueue for TimerQueue {
fn schedule_wake(&'static self, at: Instant, waker: &core::task::Waker) {
impl embassy_time_queue_driver::TimerQueue for TimerQueue {
fn schedule_wake(&'static self, at: u64, waker: &core::task::Waker) {
let task = waker::task_from_waker(waker);
let task = task.header();
unsafe {
@@ -580,7 +579,7 @@ impl embassy_time::queue::TimerQueue for TimerQueue {
}
#[cfg(feature = "integrated-timers")]
embassy_time::timer_queue_impl!(static TIMER_QUEUE: TimerQueue = TimerQueue);
embassy_time_queue_driver::timer_queue_impl!(static TIMER_QUEUE: TimerQueue = TimerQueue);
#[cfg(feature = "rtos-trace")]
impl rtos_trace::RtosTraceOSCallbacks for Executor {

View File

@@ -1,7 +1,5 @@
use core::cmp::min;
use embassy_time::Instant;
use super::TaskRef;
use crate::raw::util::SyncUnsafeCell;
@@ -30,7 +28,7 @@ impl TimerQueue {
pub(crate) unsafe fn update(&self, p: TaskRef) {
let task = p.header();
if task.expires_at.get() != Instant::MAX {
if task.expires_at.get() != u64::MAX {
if task.state.timer_enqueue() {
task.timer_queue_item.next.set(self.head.get());
self.head.set(Some(p));
@@ -38,18 +36,18 @@ impl TimerQueue {
}
}
pub(crate) unsafe fn next_expiration(&self) -> Instant {
let mut res = Instant::MAX;
pub(crate) unsafe fn next_expiration(&self) -> u64 {
let mut res = u64::MAX;
self.retain(|p| {
let task = p.header();
let expires = task.expires_at.get();
res = min(res, expires);
expires != Instant::MAX
expires != u64::MAX
});
res
}
pub(crate) unsafe fn dequeue_expired(&self, now: Instant, on_task: impl Fn(TaskRef)) {
pub(crate) unsafe fn dequeue_expired(&self, now: u64, on_task: impl Fn(TaskRef)) {
self.retain(|p| {
let task = p.header();
if task.expires_at.get() <= now {