From 74037f04933f4ec9a678e0b47fd6819e7c0489a9 Mon Sep 17 00:00:00 2001 From: Dániel Buga Date: Mon, 4 Aug 2025 00:05:25 +0200 Subject: Make TimerQueueItem opaque --- embassy-executor/CHANGELOG.md | 5 +++ embassy-executor/Cargo.toml | 17 +------- embassy-executor/src/raw/mod.rs | 33 ++++++++------- embassy-executor/src/raw/timer_queue.rs | 73 --------------------------------- 4 files changed, 22 insertions(+), 106 deletions(-) delete mode 100644 embassy-executor/src/raw/timer_queue.rs (limited to 'embassy-executor') diff --git a/embassy-executor/CHANGELOG.md b/embassy-executor/CHANGELOG.md index c35ad10f3..e2214b8ef 100644 --- a/embassy-executor/CHANGELOG.md +++ b/embassy-executor/CHANGELOG.md @@ -8,6 +8,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased - ReleaseDate +- Added `extern "Rust" fn __embassy_time_queue_item_from_waker` +- Removed `TaskRef::dangling` and `TaskRef::timer_queue_item` +- Added `embassy_time_queue_utils` as a dependency +- Moved the `TimeQueueItem` struct and `timer-item-payload-size-*` features into embassy-time-queue-utils + ## 0.8.0 - 2025-07-31 - Added `SpawnToken::id` diff --git a/embassy-executor/Cargo.toml b/embassy-executor/Cargo.toml index 5e950bf45..bff13de56 100644 --- a/embassy-executor/Cargo.toml +++ b/embassy-executor/Cargo.toml @@ -35,6 +35,7 @@ rtos-trace = { version = "0.1.3", optional = true } embassy-executor-macros = { version = "0.7.0", path = "../embassy-executor-macros" } embassy-time-driver = { version = "0.2", path = "../embassy-time-driver", optional = true } +embassy-executor-timer-queue = { version = "0.1", path = "../embassy-executor-timer-queue" } critical-section = "1.1" document-features = "0.2.7" @@ -98,19 +99,3 @@ executor-interrupt = [] trace = [] ## Enable support for rtos-trace framework rtos-trace = ["dep:rtos-trace", "trace", "dep:embassy-time-driver"] - -#! ### Timer Item Payload Size -#! Sets the size of the payload for timer items, allowing integrated timer implementors to store -#! additional data in the timer item. The payload field will be aligned to this value as well. -#! If these features are not defined, the timer item will contain no payload field. - -_timer-item-payload = [] # A size was picked - -## 1 bytes -timer-item-payload-size-1 = ["_timer-item-payload"] -## 2 bytes -timer-item-payload-size-2 = ["_timer-item-payload"] -## 4 bytes -timer-item-payload-size-4 = ["_timer-item-payload"] -## 8 bytes -timer-item-payload-size-8 = ["_timer-item-payload"] diff --git a/embassy-executor/src/raw/mod.rs b/embassy-executor/src/raw/mod.rs index c8f1f46c2..8e783b2af 100644 --- a/embassy-executor/src/raw/mod.rs +++ b/embassy-executor/src/raw/mod.rs @@ -16,7 +16,6 @@ mod run_queue; #[cfg_attr(not(target_has_atomic = "8"), path = "state_critical_section.rs")] mod state; -pub mod timer_queue; #[cfg(feature = "trace")] pub mod trace; pub(crate) mod util; @@ -31,8 +30,9 @@ use core::ptr::NonNull; #[cfg(not(feature = "arch-avr"))] use core::sync::atomic::AtomicPtr; use core::sync::atomic::Ordering; -use core::task::{Context, Poll}; +use core::task::{Context, Poll, Waker}; +use embassy_executor_timer_queue::TimerQueueItem; #[cfg(feature = "arch-avr")] use portable_atomic::AtomicPtr; @@ -42,6 +42,11 @@ use self::util::{SyncUnsafeCell, UninitCell}; pub use self::waker::task_from_waker; use super::SpawnToken; +#[no_mangle] +extern "Rust" fn __embassy_time_queue_item_from_waker(waker: &Waker) -> &'static mut TimerQueueItem { + unsafe { task_from_waker(waker).timer_queue_item() } +} + /// Raw task header for use in task pointers. /// /// A task can be in one of the following states: @@ -88,7 +93,7 @@ pub(crate) struct TaskHeader { poll_fn: SyncUnsafeCell>, /// Integrated timer queue storage. This field should not be accessed outside of the timer queue. - pub(crate) timer_queue_item: timer_queue::TimerQueueItem, + pub(crate) timer_queue_item: TimerQueueItem, #[cfg(feature = "trace")] pub(crate) name: Option<&'static str>, #[cfg(feature = "trace")] @@ -120,16 +125,6 @@ impl TaskRef { } } - /// # Safety - /// - /// The result of this function must only be compared - /// for equality, or stored, but not used. - pub const unsafe fn dangling() -> Self { - Self { - ptr: NonNull::dangling(), - } - } - pub(crate) fn header(self) -> &'static TaskHeader { unsafe { self.ptr.as_ref() } } @@ -140,9 +135,13 @@ impl TaskRef { executor.as_ref().map(|e| Executor::wrap(e)) } - /// Returns a reference to the timer queue item. - pub fn timer_queue_item(&self) -> &'static timer_queue::TimerQueueItem { - &self.header().timer_queue_item + /// Returns a mutable reference to the timer queue item. + /// + /// Safety + /// + /// This function must only be called in the context of the integrated timer queue. + unsafe fn timer_queue_item(mut self) -> &'static mut TimerQueueItem { + unsafe { &mut self.ptr.as_mut().timer_queue_item } } /// The returned pointer is valid for the entire TaskStorage. @@ -189,7 +188,7 @@ impl TaskStorage { // Note: this is lazily initialized so that a static `TaskStorage` will go in `.bss` poll_fn: SyncUnsafeCell::new(None), - timer_queue_item: timer_queue::TimerQueueItem::new(), + timer_queue_item: TimerQueueItem::new(), #[cfg(feature = "trace")] name: None, #[cfg(feature = "trace")] diff --git a/embassy-executor/src/raw/timer_queue.rs b/embassy-executor/src/raw/timer_queue.rs deleted file mode 100644 index e52453be4..000000000 --- a/embassy-executor/src/raw/timer_queue.rs +++ /dev/null @@ -1,73 +0,0 @@ -//! Timer queue operations. - -use core::cell::Cell; - -use super::TaskRef; - -#[cfg(feature = "_timer-item-payload")] -macro_rules! define_opaque { - ($size:tt) => { - /// An opaque data type. - #[repr(align($size))] - pub struct OpaqueData { - data: [u8; $size], - } - - impl OpaqueData { - const fn new() -> Self { - Self { data: [0; $size] } - } - - /// Access the data as a reference to a type `T`. - /// - /// Safety: - /// - /// The caller must ensure that the size of the type `T` is less than, or equal to - /// the size of the payload, and must ensure that the alignment of the type `T` is - /// less than, or equal to the alignment of the payload. - /// - /// The type must be valid when zero-initialized. - pub unsafe fn as_ref(&self) -> &T { - &*(self.data.as_ptr() as *const T) - } - } - }; -} - -#[cfg(feature = "timer-item-payload-size-1")] -define_opaque!(1); -#[cfg(feature = "timer-item-payload-size-2")] -define_opaque!(2); -#[cfg(feature = "timer-item-payload-size-4")] -define_opaque!(4); -#[cfg(feature = "timer-item-payload-size-8")] -define_opaque!(8); - -/// An item in the timer queue. -pub struct TimerQueueItem { - /// The next item in the queue. - /// - /// If this field contains `Some`, the item is in the queue. The last item in the queue has a - /// value of `Some(dangling_pointer)` - pub next: Cell>, - - /// The time at which this item expires. - pub expires_at: Cell, - - /// Some implementation-defined, zero-initialized piece of data. - #[cfg(feature = "_timer-item-payload")] - pub payload: OpaqueData, -} - -unsafe impl Sync for TimerQueueItem {} - -impl TimerQueueItem { - pub(crate) const fn new() -> Self { - Self { - next: Cell::new(None), - expires_at: Cell::new(0), - #[cfg(feature = "_timer-item-payload")] - payload: OpaqueData::new(), - } - } -} -- cgit From 1bf3a44e5d9a6709eb0ce1dc518de82a64a72a05 Mon Sep 17 00:00:00 2001 From: Dániel Buga Date: Sun, 17 Aug 2025 11:45:53 +0200 Subject: Retain timer_queue_item --- embassy-executor/CHANGELOG.md | 2 +- embassy-executor/src/raw/mod.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'embassy-executor') diff --git a/embassy-executor/CHANGELOG.md b/embassy-executor/CHANGELOG.md index e2214b8ef..91a1448c2 100644 --- a/embassy-executor/CHANGELOG.md +++ b/embassy-executor/CHANGELOG.md @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased - ReleaseDate - Added `extern "Rust" fn __embassy_time_queue_item_from_waker` -- Removed `TaskRef::dangling` and `TaskRef::timer_queue_item` +- Removed `TaskRef::dangling` - Added `embassy_time_queue_utils` as a dependency - Moved the `TimeQueueItem` struct and `timer-item-payload-size-*` features into embassy-time-queue-utils diff --git a/embassy-executor/src/raw/mod.rs b/embassy-executor/src/raw/mod.rs index 8e783b2af..4b17d4982 100644 --- a/embassy-executor/src/raw/mod.rs +++ b/embassy-executor/src/raw/mod.rs @@ -140,7 +140,7 @@ impl TaskRef { /// Safety /// /// This function must only be called in the context of the integrated timer queue. - unsafe fn timer_queue_item(mut self) -> &'static mut TimerQueueItem { + pub unsafe fn timer_queue_item(mut self) -> &'static mut TimerQueueItem { unsafe { &mut self.ptr.as_mut().timer_queue_item } } -- cgit