diff options
| author | Dario Nieuwenhuis <[email protected]> | 2025-09-11 13:52:14 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-09-11 13:52:14 +0000 |
| commit | 42c68622eeba3be05e8f8ccdc4072b7aa57f78d1 (patch) | |
| tree | 431aa79f8343a7ed8eb948ad52dec5ef13f5869a /embassy-executor/src/metadata.rs | |
| parent | d860530009c1bf96a20edeff22f10f738bab1503 (diff) | |
| parent | e1209c5563576d18c4d033b015c9a5dd6145d581 (diff) | |
Merge pull request #4608 from diondokter/upstream-drs-2
[embassy-executor]: Upstream "Earliest Deadline First" Scheduler (version 2)
Diffstat (limited to 'embassy-executor/src/metadata.rs')
| -rw-r--r-- | embassy-executor/src/metadata.rs | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/embassy-executor/src/metadata.rs b/embassy-executor/src/metadata.rs index f92c9b37c..4220048a6 100644 --- a/embassy-executor/src/metadata.rs +++ b/embassy-executor/src/metadata.rs | |||
| @@ -7,11 +7,15 @@ use core::task::Poll; | |||
| 7 | use critical_section::Mutex; | 7 | use critical_section::Mutex; |
| 8 | 8 | ||
| 9 | use crate::raw; | 9 | use crate::raw; |
| 10 | #[cfg(feature = "scheduler-deadline")] | ||
| 11 | use crate::raw::Deadline; | ||
| 10 | 12 | ||
| 11 | /// Metadata associated with a task. | 13 | /// Metadata associated with a task. |
| 12 | pub struct Metadata { | 14 | pub struct Metadata { |
| 13 | #[cfg(feature = "metadata-name")] | 15 | #[cfg(feature = "metadata-name")] |
| 14 | name: Mutex<Cell<Option<&'static str>>>, | 16 | name: Mutex<Cell<Option<&'static str>>>, |
| 17 | #[cfg(feature = "scheduler-deadline")] | ||
| 18 | deadline: raw::Deadline, | ||
| 15 | } | 19 | } |
| 16 | 20 | ||
| 17 | impl Metadata { | 21 | impl Metadata { |
| @@ -19,6 +23,10 @@ impl Metadata { | |||
| 19 | Self { | 23 | Self { |
| 20 | #[cfg(feature = "metadata-name")] | 24 | #[cfg(feature = "metadata-name")] |
| 21 | name: Mutex::new(Cell::new(None)), | 25 | name: Mutex::new(Cell::new(None)), |
| 26 | // NOTE: The deadline is set to zero to allow the initializer to reside in `.bss`. This | ||
| 27 | // will be lazily initalized in `initialize_impl` | ||
| 28 | #[cfg(feature = "scheduler-deadline")] | ||
| 29 | deadline: raw::Deadline::new_unset(), | ||
| 22 | } | 30 | } |
| 23 | } | 31 | } |
| 24 | 32 | ||
| @@ -52,4 +60,63 @@ impl Metadata { | |||
| 52 | pub fn set_name(&self, name: &'static str) { | 60 | pub fn set_name(&self, name: &'static str) { |
| 53 | critical_section::with(|cs| self.name.borrow(cs).set(Some(name))) | 61 | critical_section::with(|cs| self.name.borrow(cs).set(Some(name))) |
| 54 | } | 62 | } |
| 63 | |||
| 64 | /// Get this task's deadline. | ||
| 65 | #[cfg(feature = "scheduler-deadline")] | ||
| 66 | pub fn deadline(&self) -> u64 { | ||
| 67 | self.deadline.instant_ticks() | ||
| 68 | } | ||
| 69 | |||
| 70 | /// Set this task's deadline. | ||
| 71 | /// | ||
| 72 | /// This method does NOT check whether the deadline has already passed. | ||
| 73 | #[cfg(feature = "scheduler-deadline")] | ||
| 74 | pub fn set_deadline(&self, instant_ticks: u64) { | ||
| 75 | self.deadline.set(instant_ticks); | ||
| 76 | } | ||
| 77 | |||
| 78 | /// Remove this task's deadline. | ||
| 79 | /// This brings it back to the defaul where it's not scheduled ahead of other tasks. | ||
| 80 | #[cfg(feature = "scheduler-deadline")] | ||
| 81 | pub fn unset_deadline(&self) { | ||
| 82 | self.deadline.set(Deadline::UNSET_TICKS); | ||
| 83 | } | ||
| 84 | |||
| 85 | /// Set this task's deadline `duration_ticks` in the future from when | ||
| 86 | /// this future is polled. This deadline is saturated to the max tick value. | ||
| 87 | /// | ||
| 88 | /// Analogous to `Timer::after`. | ||
| 89 | #[cfg(all(feature = "scheduler-deadline", feature = "embassy-time-driver"))] | ||
| 90 | pub fn set_deadline_after(&self, duration_ticks: u64) { | ||
| 91 | let now = embassy_time_driver::now(); | ||
| 92 | |||
| 93 | // Since ticks is a u64, saturating add is PROBABLY overly cautious, leave | ||
| 94 | // it for now, we can probably make this wrapping_add for performance | ||
| 95 | // reasons later. | ||
| 96 | let deadline = now.saturating_add(duration_ticks); | ||
| 97 | |||
| 98 | self.set_deadline(deadline); | ||
| 99 | } | ||
| 100 | |||
| 101 | /// Set the this task's deadline `increment_ticks` from the previous deadline. | ||
| 102 | /// | ||
| 103 | /// This deadline is saturated to the max tick value. | ||
| 104 | /// | ||
| 105 | /// Note that by default (unless otherwise set), tasks start life with the deadline | ||
| 106 | /// not set, which means this method will have no effect. | ||
| 107 | /// | ||
| 108 | /// Analogous to one increment of `Ticker::every().next()`. | ||
| 109 | /// | ||
| 110 | /// Returns the deadline that was set. | ||
| 111 | #[cfg(feature = "scheduler-deadline")] | ||
| 112 | pub fn increment_deadline(&self, duration_ticks: u64) { | ||
| 113 | let last = self.deadline(); | ||
| 114 | |||
| 115 | // Since ticks is a u64, saturating add is PROBABLY overly cautious, leave | ||
| 116 | // it for now, we can probably make this wrapping_add for performance | ||
| 117 | // reasons later. | ||
| 118 | let deadline = last.saturating_add(duration_ticks); | ||
| 119 | |||
| 120 | self.set_deadline(deadline); | ||
| 121 | } | ||
| 55 | } | 122 | } |
