aboutsummaryrefslogtreecommitdiff
path: root/embassy-executor/src/raw
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2025-09-11 16:15:27 +0200
committerDario Nieuwenhuis <[email protected]>2025-09-11 16:33:48 +0200
commit6ec9bcb1c4dfbe5fc5365d93e75c516bb03bf9fc (patch)
tree9094e4fb8745849ada00f61144aba60d8a51b5bf /embassy-executor/src/raw
parent42c68622eeba3be05e8f8ccdc4072b7aa57f78d1 (diff)
executor: add priority scheduler.
Diffstat (limited to 'embassy-executor/src/raw')
-rw-r--r--embassy-executor/src/raw/mod.rs5
-rw-r--r--embassy-executor/src/raw/run_queue.rs29
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
3use cordyceps::sorted_list::Links; 3use cordyceps::sorted_list::Links;
4use cordyceps::Linked; 4use cordyceps::Linked;
5#[cfg(feature = "scheduler-deadline")] 5#[cfg(any(feature = "scheduler-priority", feature = "scheduler-deadline"))]
6use cordyceps::SortedList; 6use 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