diff options
| author | Dario Nieuwenhuis <[email protected]> | 2025-09-11 16:15:27 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2025-09-11 16:33:48 +0200 |
| commit | 6ec9bcb1c4dfbe5fc5365d93e75c516bb03bf9fc (patch) | |
| tree | 9094e4fb8745849ada00f61144aba60d8a51b5bf /embassy-executor/src/raw | |
| parent | 42c68622eeba3be05e8f8ccdc4072b7aa57f78d1 (diff) | |
executor: add priority scheduler.
Diffstat (limited to 'embassy-executor/src/raw')
| -rw-r--r-- | embassy-executor/src/raw/mod.rs | 5 | ||||
| -rw-r--r-- | embassy-executor/src/raw/run_queue.rs | 29 |
2 files changed, 24 insertions, 10 deletions
diff --git a/embassy-executor/src/raw/mod.rs b/embassy-executor/src/raw/mod.rs index 51a363385..9f36c60bc 100644 --- a/embassy-executor/src/raw/mod.rs +++ b/embassy-executor/src/raw/mod.rs | |||
| @@ -300,11 +300,6 @@ impl<F: Future + 'static> AvailableTask<F> { | |||
| 300 | self.task.raw.poll_fn.set(Some(TaskStorage::<F>::poll)); | 300 | self.task.raw.poll_fn.set(Some(TaskStorage::<F>::poll)); |
| 301 | self.task.future.write_in_place(future); | 301 | self.task.future.write_in_place(future); |
| 302 | 302 | ||
| 303 | // By default, deadlines are set to the maximum value, so that any task WITH | ||
| 304 | // a set deadline will ALWAYS be scheduled BEFORE a task WITHOUT a set deadline | ||
| 305 | #[cfg(feature = "scheduler-deadline")] | ||
| 306 | self.task.raw.metadata.unset_deadline(); | ||
| 307 | |||
| 308 | let task = TaskRef::new(self.task); | 303 | let task = TaskRef::new(self.task); |
| 309 | 304 | ||
| 310 | SpawnToken::new(task) | 305 | SpawnToken::new(task) |
diff --git a/embassy-executor/src/raw/run_queue.rs b/embassy-executor/src/raw/run_queue.rs index d98c26f73..b8b052310 100644 --- a/embassy-executor/src/raw/run_queue.rs +++ b/embassy-executor/src/raw/run_queue.rs | |||
| @@ -2,7 +2,7 @@ use core::ptr::{addr_of_mut, NonNull}; | |||
| 2 | 2 | ||
| 3 | use cordyceps::sorted_list::Links; | 3 | use cordyceps::sorted_list::Links; |
| 4 | use cordyceps::Linked; | 4 | use cordyceps::Linked; |
| 5 | #[cfg(feature = "scheduler-deadline")] | 5 | #[cfg(any(feature = "scheduler-priority", feature = "scheduler-deadline"))] |
| 6 | use cordyceps::SortedList; | 6 | use cordyceps::SortedList; |
| 7 | 7 | ||
| 8 | #[cfg(target_has_atomic = "ptr")] | 8 | #[cfg(target_has_atomic = "ptr")] |
| @@ -83,7 +83,7 @@ impl RunQueue { | |||
| 83 | /// Empty the queue, then call `on_task` for each task that was in the queue. | 83 | /// Empty the queue, then call `on_task` for each task that was in the queue. |
| 84 | /// NOTE: It is OK for `on_task` to enqueue more tasks. In this case they're left in the queue | 84 | /// NOTE: It is OK for `on_task` to enqueue more tasks. In this case they're left in the queue |
| 85 | /// and will be processed by the *next* call to `dequeue_all`, *not* the current one. | 85 | /// and will be processed by the *next* call to `dequeue_all`, *not* the current one. |
| 86 | #[cfg(not(feature = "scheduler-deadline"))] | 86 | #[cfg(not(any(feature = "scheduler-priority", feature = "scheduler-deadline")))] |
| 87 | pub(crate) fn dequeue_all(&self, on_task: impl Fn(TaskRef)) { | 87 | pub(crate) fn dequeue_all(&self, on_task: impl Fn(TaskRef)) { |
| 88 | let taken = self.stack.take_all(); | 88 | let taken = self.stack.take_all(); |
| 89 | for taskref in taken { | 89 | for taskref in taken { |
| @@ -106,10 +106,29 @@ impl RunQueue { | |||
| 106 | /// | 106 | /// |
| 107 | /// This process will repeat until the local `sorted` queue AND the global | 107 | /// This process will repeat until the local `sorted` queue AND the global |
| 108 | /// runqueue are both empty, at which point this function will return. | 108 | /// runqueue are both empty, at which point this function will return. |
| 109 | #[cfg(feature = "scheduler-deadline")] | 109 | #[cfg(any(feature = "scheduler-priority", feature = "scheduler-deadline"))] |
| 110 | pub(crate) fn dequeue_all(&self, on_task: impl Fn(TaskRef)) { | 110 | pub(crate) fn dequeue_all(&self, on_task: impl Fn(TaskRef)) { |
| 111 | let mut sorted = | 111 | let mut sorted = SortedList::<TaskHeader>::new_with_cmp(|lhs, rhs| { |
| 112 | SortedList::<TaskHeader>::new_with_cmp(|lhs, rhs| lhs.metadata.deadline().cmp(&rhs.metadata.deadline())); | 112 | // compare by priority first |
| 113 | #[cfg(feature = "scheduler-priority")] | ||
| 114 | { | ||
| 115 | let lp = lhs.metadata.priority(); | ||
| 116 | let rp = rhs.metadata.priority(); | ||
| 117 | if lp != rp { | ||
| 118 | return lp.cmp(&rp).reverse(); | ||
| 119 | } | ||
| 120 | } | ||
| 121 | // compare deadlines in case of tie. | ||
| 122 | #[cfg(feature = "scheduler-deadline")] | ||
| 123 | { | ||
| 124 | let ld = lhs.metadata.deadline(); | ||
| 125 | let rd = rhs.metadata.deadline(); | ||
| 126 | if ld != rd { | ||
| 127 | return ld.cmp(&rd); | ||
| 128 | } | ||
| 129 | } | ||
| 130 | core::cmp::Ordering::Equal | ||
| 131 | }); | ||
| 113 | 132 | ||
| 114 | loop { | 133 | loop { |
| 115 | // For each loop, grab any newly pended items | 134 | // For each loop, grab any newly pended items |
