diff options
| author | Dániel Buga <[email protected]> | 2025-08-04 00:05:25 +0200 |
|---|---|---|
| committer | Dániel Buga <[email protected]> | 2025-08-18 12:50:51 +0200 |
| commit | 74037f04933f4ec9a678e0b47fd6819e7c0489a9 (patch) | |
| tree | cb81e7394b6b59324a08eb92eba6fd0d8d9f2a9c /embassy-executor/src | |
| parent | a5cb04bdab602bc3bd056d254a9d61cad55bd967 (diff) | |
Make TimerQueueItem opaque
Diffstat (limited to 'embassy-executor/src')
| -rw-r--r-- | embassy-executor/src/raw/mod.rs | 33 | ||||
| -rw-r--r-- | embassy-executor/src/raw/timer_queue.rs | 73 |
2 files changed, 16 insertions, 90 deletions
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; | |||
| 16 | #[cfg_attr(not(target_has_atomic = "8"), path = "state_critical_section.rs")] | 16 | #[cfg_attr(not(target_has_atomic = "8"), path = "state_critical_section.rs")] |
| 17 | mod state; | 17 | mod state; |
| 18 | 18 | ||
| 19 | pub mod timer_queue; | ||
| 20 | #[cfg(feature = "trace")] | 19 | #[cfg(feature = "trace")] |
| 21 | pub mod trace; | 20 | pub mod trace; |
| 22 | pub(crate) mod util; | 21 | pub(crate) mod util; |
| @@ -31,8 +30,9 @@ use core::ptr::NonNull; | |||
| 31 | #[cfg(not(feature = "arch-avr"))] | 30 | #[cfg(not(feature = "arch-avr"))] |
| 32 | use core::sync::atomic::AtomicPtr; | 31 | use core::sync::atomic::AtomicPtr; |
| 33 | use core::sync::atomic::Ordering; | 32 | use core::sync::atomic::Ordering; |
| 34 | use core::task::{Context, Poll}; | 33 | use core::task::{Context, Poll, Waker}; |
| 35 | 34 | ||
| 35 | use embassy_executor_timer_queue::TimerQueueItem; | ||
| 36 | #[cfg(feature = "arch-avr")] | 36 | #[cfg(feature = "arch-avr")] |
| 37 | use portable_atomic::AtomicPtr; | 37 | use portable_atomic::AtomicPtr; |
| 38 | 38 | ||
| @@ -42,6 +42,11 @@ use self::util::{SyncUnsafeCell, UninitCell}; | |||
| 42 | pub use self::waker::task_from_waker; | 42 | pub use self::waker::task_from_waker; |
| 43 | use super::SpawnToken; | 43 | use super::SpawnToken; |
| 44 | 44 | ||
| 45 | #[no_mangle] | ||
| 46 | extern "Rust" fn __embassy_time_queue_item_from_waker(waker: &Waker) -> &'static mut TimerQueueItem { | ||
| 47 | unsafe { task_from_waker(waker).timer_queue_item() } | ||
| 48 | } | ||
| 49 | |||
| 45 | /// Raw task header for use in task pointers. | 50 | /// Raw task header for use in task pointers. |
| 46 | /// | 51 | /// |
| 47 | /// A task can be in one of the following states: | 52 | /// A task can be in one of the following states: |
| @@ -88,7 +93,7 @@ pub(crate) struct TaskHeader { | |||
| 88 | poll_fn: SyncUnsafeCell<Option<unsafe fn(TaskRef)>>, | 93 | poll_fn: SyncUnsafeCell<Option<unsafe fn(TaskRef)>>, |
| 89 | 94 | ||
| 90 | /// Integrated timer queue storage. This field should not be accessed outside of the timer queue. | 95 | /// Integrated timer queue storage. This field should not be accessed outside of the timer queue. |
| 91 | pub(crate) timer_queue_item: timer_queue::TimerQueueItem, | 96 | pub(crate) timer_queue_item: TimerQueueItem, |
| 92 | #[cfg(feature = "trace")] | 97 | #[cfg(feature = "trace")] |
| 93 | pub(crate) name: Option<&'static str>, | 98 | pub(crate) name: Option<&'static str>, |
| 94 | #[cfg(feature = "trace")] | 99 | #[cfg(feature = "trace")] |
| @@ -120,16 +125,6 @@ impl TaskRef { | |||
| 120 | } | 125 | } |
| 121 | } | 126 | } |
| 122 | 127 | ||
| 123 | /// # Safety | ||
| 124 | /// | ||
| 125 | /// The result of this function must only be compared | ||
| 126 | /// for equality, or stored, but not used. | ||
| 127 | pub const unsafe fn dangling() -> Self { | ||
| 128 | Self { | ||
| 129 | ptr: NonNull::dangling(), | ||
| 130 | } | ||
| 131 | } | ||
| 132 | |||
| 133 | pub(crate) fn header(self) -> &'static TaskHeader { | 128 | pub(crate) fn header(self) -> &'static TaskHeader { |
| 134 | unsafe { self.ptr.as_ref() } | 129 | unsafe { self.ptr.as_ref() } |
| 135 | } | 130 | } |
| @@ -140,9 +135,13 @@ impl TaskRef { | |||
| 140 | executor.as_ref().map(|e| Executor::wrap(e)) | 135 | executor.as_ref().map(|e| Executor::wrap(e)) |
| 141 | } | 136 | } |
| 142 | 137 | ||
| 143 | /// Returns a reference to the timer queue item. | 138 | /// Returns a mutable reference to the timer queue item. |
| 144 | pub fn timer_queue_item(&self) -> &'static timer_queue::TimerQueueItem { | 139 | /// |
| 145 | &self.header().timer_queue_item | 140 | /// Safety |
| 141 | /// | ||
| 142 | /// This function must only be called in the context of the integrated timer queue. | ||
| 143 | unsafe fn timer_queue_item(mut self) -> &'static mut TimerQueueItem { | ||
| 144 | unsafe { &mut self.ptr.as_mut().timer_queue_item } | ||
| 146 | } | 145 | } |
| 147 | 146 | ||
| 148 | /// The returned pointer is valid for the entire TaskStorage. | 147 | /// The returned pointer is valid for the entire TaskStorage. |
| @@ -189,7 +188,7 @@ impl<F: Future + 'static> TaskStorage<F> { | |||
| 189 | // Note: this is lazily initialized so that a static `TaskStorage` will go in `.bss` | 188 | // Note: this is lazily initialized so that a static `TaskStorage` will go in `.bss` |
| 190 | poll_fn: SyncUnsafeCell::new(None), | 189 | poll_fn: SyncUnsafeCell::new(None), |
| 191 | 190 | ||
| 192 | timer_queue_item: timer_queue::TimerQueueItem::new(), | 191 | timer_queue_item: TimerQueueItem::new(), |
| 193 | #[cfg(feature = "trace")] | 192 | #[cfg(feature = "trace")] |
| 194 | name: None, | 193 | name: None, |
| 195 | #[cfg(feature = "trace")] | 194 | #[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 @@ | |||
| 1 | //! Timer queue operations. | ||
| 2 | |||
| 3 | use core::cell::Cell; | ||
| 4 | |||
| 5 | use super::TaskRef; | ||
| 6 | |||
| 7 | #[cfg(feature = "_timer-item-payload")] | ||
| 8 | macro_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")] | ||
| 38 | define_opaque!(1); | ||
| 39 | #[cfg(feature = "timer-item-payload-size-2")] | ||
| 40 | define_opaque!(2); | ||
| 41 | #[cfg(feature = "timer-item-payload-size-4")] | ||
| 42 | define_opaque!(4); | ||
| 43 | #[cfg(feature = "timer-item-payload-size-8")] | ||
| 44 | define_opaque!(8); | ||
| 45 | |||
| 46 | /// An item in the timer queue. | ||
| 47 | pub struct TimerQueueItem { | ||
| 48 | /// The next item in the queue. | ||
| 49 | /// | ||
| 50 | /// If this field contains `Some`, the item is in the queue. The last item in the queue has a | ||
| 51 | /// value of `Some(dangling_pointer)` | ||
| 52 | pub next: Cell<Option<TaskRef>>, | ||
| 53 | |||
| 54 | /// The time at which this item expires. | ||
| 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, | ||
| 60 | } | ||
| 61 | |||
| 62 | unsafe impl Sync for TimerQueueItem {} | ||
| 63 | |||
| 64 | impl TimerQueueItem { | ||
| 65 | pub(crate) const fn new() -> Self { | ||
| 66 | Self { | ||
| 67 | next: Cell::new(None), | ||
| 68 | expires_at: Cell::new(0), | ||
| 69 | #[cfg(feature = "_timer-item-payload")] | ||
| 70 | payload: OpaqueData::new(), | ||
| 71 | } | ||
| 72 | } | ||
| 73 | } | ||
