aboutsummaryrefslogtreecommitdiff
path: root/embassy-executor/src
diff options
context:
space:
mode:
authorDániel Buga <[email protected]>2025-08-04 00:05:25 +0200
committerDániel Buga <[email protected]>2025-08-18 12:50:51 +0200
commit74037f04933f4ec9a678e0b47fd6819e7c0489a9 (patch)
treecb81e7394b6b59324a08eb92eba6fd0d8d9f2a9c /embassy-executor/src
parenta5cb04bdab602bc3bd056d254a9d61cad55bd967 (diff)
Make TimerQueueItem opaque
Diffstat (limited to 'embassy-executor/src')
-rw-r--r--embassy-executor/src/raw/mod.rs33
-rw-r--r--embassy-executor/src/raw/timer_queue.rs73
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")]
17mod state; 17mod state;
18 18
19pub mod timer_queue;
20#[cfg(feature = "trace")] 19#[cfg(feature = "trace")]
21pub mod trace; 20pub mod trace;
22pub(crate) mod util; 21pub(crate) mod util;
@@ -31,8 +30,9 @@ use core::ptr::NonNull;
31#[cfg(not(feature = "arch-avr"))] 30#[cfg(not(feature = "arch-avr"))]
32use core::sync::atomic::AtomicPtr; 31use core::sync::atomic::AtomicPtr;
33use core::sync::atomic::Ordering; 32use core::sync::atomic::Ordering;
34use core::task::{Context, Poll}; 33use core::task::{Context, Poll, Waker};
35 34
35use embassy_executor_timer_queue::TimerQueueItem;
36#[cfg(feature = "arch-avr")] 36#[cfg(feature = "arch-avr")]
37use portable_atomic::AtomicPtr; 37use portable_atomic::AtomicPtr;
38 38
@@ -42,6 +42,11 @@ use self::util::{SyncUnsafeCell, UninitCell};
42pub use self::waker::task_from_waker; 42pub use self::waker::task_from_waker;
43use super::SpawnToken; 43use super::SpawnToken;
44 44
45#[no_mangle]
46extern "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
3use core::cell::Cell;
4
5use super::TaskRef;
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
46/// An item in the timer queue.
47pub 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
62unsafe impl Sync for TimerQueueItem {}
63
64impl 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}