diff options
Diffstat (limited to 'embassy-executor/src/metadata.rs')
| -rw-r--r-- | embassy-executor/src/metadata.rs | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/embassy-executor/src/metadata.rs b/embassy-executor/src/metadata.rs index f92c9b37c..bc0df0f83 100644 --- a/embassy-executor/src/metadata.rs +++ b/embassy-executor/src/metadata.rs | |||
| @@ -1,17 +1,25 @@ | |||
| 1 | #[cfg(feature = "metadata-name")] | 1 | #[cfg(feature = "metadata-name")] |
| 2 | use core::cell::Cell; | 2 | use core::cell::Cell; |
| 3 | use core::future::{poll_fn, Future}; | 3 | use core::future::{poll_fn, Future}; |
| 4 | #[cfg(feature = "scheduler-priority")] | ||
| 5 | use core::sync::atomic::{AtomicU8, Ordering}; | ||
| 4 | use core::task::Poll; | 6 | use core::task::Poll; |
| 5 | 7 | ||
| 6 | #[cfg(feature = "metadata-name")] | 8 | #[cfg(feature = "metadata-name")] |
| 7 | use critical_section::Mutex; | 9 | use critical_section::Mutex; |
| 8 | 10 | ||
| 9 | use crate::raw; | 11 | use crate::raw; |
| 12 | #[cfg(feature = "scheduler-deadline")] | ||
| 13 | use crate::raw::Deadline; | ||
| 10 | 14 | ||
| 11 | /// Metadata associated with a task. | 15 | /// Metadata associated with a task. |
| 12 | pub struct Metadata { | 16 | pub struct Metadata { |
| 13 | #[cfg(feature = "metadata-name")] | 17 | #[cfg(feature = "metadata-name")] |
| 14 | name: Mutex<Cell<Option<&'static str>>>, | 18 | name: Mutex<Cell<Option<&'static str>>>, |
| 19 | #[cfg(feature = "scheduler-priority")] | ||
| 20 | priority: AtomicU8, | ||
| 21 | #[cfg(feature = "scheduler-deadline")] | ||
| 22 | deadline: raw::Deadline, | ||
| 15 | } | 23 | } |
| 16 | 24 | ||
| 17 | impl Metadata { | 25 | impl Metadata { |
| @@ -19,12 +27,26 @@ impl Metadata { | |||
| 19 | Self { | 27 | Self { |
| 20 | #[cfg(feature = "metadata-name")] | 28 | #[cfg(feature = "metadata-name")] |
| 21 | name: Mutex::new(Cell::new(None)), | 29 | name: Mutex::new(Cell::new(None)), |
| 30 | #[cfg(feature = "scheduler-priority")] | ||
| 31 | priority: AtomicU8::new(0), | ||
| 32 | // NOTE: The deadline is set to zero to allow the initializer to reside in `.bss`. This | ||
| 33 | // will be lazily initalized in `initialize_impl` | ||
| 34 | #[cfg(feature = "scheduler-deadline")] | ||
| 35 | deadline: raw::Deadline::new_unset(), | ||
| 22 | } | 36 | } |
| 23 | } | 37 | } |
| 24 | 38 | ||
| 25 | pub(crate) fn reset(&self) { | 39 | pub(crate) fn reset(&self) { |
| 26 | #[cfg(feature = "metadata-name")] | 40 | #[cfg(feature = "metadata-name")] |
| 27 | critical_section::with(|cs| self.name.borrow(cs).set(None)); | 41 | critical_section::with(|cs| self.name.borrow(cs).set(None)); |
| 42 | |||
| 43 | #[cfg(feature = "scheduler-priority")] | ||
| 44 | self.set_priority(0); | ||
| 45 | |||
| 46 | // By default, deadlines are set to the maximum value, so that any task WITH | ||
| 47 | // a set deadline will ALWAYS be scheduled BEFORE a task WITHOUT a set deadline | ||
| 48 | #[cfg(feature = "scheduler-deadline")] | ||
| 49 | self.unset_deadline(); | ||
| 28 | } | 50 | } |
| 29 | 51 | ||
| 30 | /// Get the metadata for the current task. | 52 | /// Get the metadata for the current task. |
| @@ -52,4 +74,75 @@ impl Metadata { | |||
| 52 | pub fn set_name(&self, name: &'static str) { | 74 | pub fn set_name(&self, name: &'static str) { |
| 53 | critical_section::with(|cs| self.name.borrow(cs).set(Some(name))) | 75 | critical_section::with(|cs| self.name.borrow(cs).set(Some(name))) |
| 54 | } | 76 | } |
| 77 | |||
| 78 | /// Get this task's priority. | ||
| 79 | #[cfg(feature = "scheduler-priority")] | ||
| 80 | pub fn priority(&self) -> u8 { | ||
| 81 | self.priority.load(Ordering::Relaxed) | ||
| 82 | } | ||
| 83 | |||
| 84 | /// Set this task's priority. | ||
| 85 | #[cfg(feature = "scheduler-priority")] | ||
| 86 | pub fn set_priority(&self, priority: u8) { | ||
| 87 | self.priority.store(priority, Ordering::Relaxed) | ||
| 88 | } | ||
| 89 | |||
| 90 | /// Get this task's deadline. | ||
| 91 | #[cfg(feature = "scheduler-deadline")] | ||
| 92 | pub fn deadline(&self) -> u64 { | ||
| 93 | self.deadline.instant_ticks() | ||
| 94 | } | ||
| 95 | |||
| 96 | /// Set this task's deadline. | ||
| 97 | /// | ||
| 98 | /// This method does NOT check whether the deadline has already passed. | ||
| 99 | #[cfg(feature = "scheduler-deadline")] | ||
| 100 | pub fn set_deadline(&self, instant_ticks: u64) { | ||
| 101 | self.deadline.set(instant_ticks); | ||
| 102 | } | ||
| 103 | |||
| 104 | /// Remove this task's deadline. | ||
| 105 | /// This brings it back to the defaul where it's not scheduled ahead of other tasks. | ||
| 106 | #[cfg(feature = "scheduler-deadline")] | ||
| 107 | pub fn unset_deadline(&self) { | ||
| 108 | self.deadline.set(Deadline::UNSET_TICKS); | ||
| 109 | } | ||
| 110 | |||
| 111 | /// Set this task's deadline `duration_ticks` in the future from when | ||
| 112 | /// this future is polled. This deadline is saturated to the max tick value. | ||
| 113 | /// | ||
| 114 | /// Analogous to `Timer::after`. | ||
| 115 | #[cfg(all(feature = "scheduler-deadline", feature = "embassy-time-driver"))] | ||
| 116 | pub fn set_deadline_after(&self, duration_ticks: u64) { | ||
| 117 | let now = embassy_time_driver::now(); | ||
| 118 | |||
| 119 | // Since ticks is a u64, saturating add is PROBABLY overly cautious, leave | ||
| 120 | // it for now, we can probably make this wrapping_add for performance | ||
| 121 | // reasons later. | ||
| 122 | let deadline = now.saturating_add(duration_ticks); | ||
| 123 | |||
| 124 | self.set_deadline(deadline); | ||
| 125 | } | ||
| 126 | |||
| 127 | /// Set the this task's deadline `increment_ticks` from the previous deadline. | ||
| 128 | /// | ||
| 129 | /// This deadline is saturated to the max tick value. | ||
| 130 | /// | ||
| 131 | /// Note that by default (unless otherwise set), tasks start life with the deadline | ||
| 132 | /// not set, which means this method will have no effect. | ||
| 133 | /// | ||
| 134 | /// Analogous to one increment of `Ticker::every().next()`. | ||
| 135 | /// | ||
| 136 | /// Returns the deadline that was set. | ||
| 137 | #[cfg(feature = "scheduler-deadline")] | ||
| 138 | pub fn increment_deadline(&self, duration_ticks: u64) { | ||
| 139 | let last = self.deadline(); | ||
| 140 | |||
| 141 | // Since ticks is a u64, saturating add is PROBABLY overly cautious, leave | ||
| 142 | // it for now, we can probably make this wrapping_add for performance | ||
| 143 | // reasons later. | ||
| 144 | let deadline = last.saturating_add(duration_ticks); | ||
| 145 | |||
| 146 | self.set_deadline(deadline); | ||
| 147 | } | ||
| 55 | } | 148 | } |
