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 | } |
74 | |