diff options
| -rw-r--r-- | embassy-executor/Cargo.toml | 7 | ||||
| -rw-r--r-- | embassy-executor/src/raw/deadline.rs | 4 | ||||
| -rw-r--r-- | embassy-executor/src/raw/mod.rs | 14 | ||||
| -rw-r--r-- | embassy-executor/src/raw/run_queue_atomics.rs | 8 |
4 files changed, 17 insertions, 16 deletions
diff --git a/embassy-executor/Cargo.toml b/embassy-executor/Cargo.toml index e740f9ccf..17315eaa3 100644 --- a/embassy-executor/Cargo.toml +++ b/embassy-executor/Cargo.toml | |||
| @@ -46,7 +46,7 @@ flavors = [ | |||
| 46 | [package.metadata.docs.rs] | 46 | [package.metadata.docs.rs] |
| 47 | default-target = "thumbv7em-none-eabi" | 47 | default-target = "thumbv7em-none-eabi" |
| 48 | targets = ["thumbv7em-none-eabi"] | 48 | targets = ["thumbv7em-none-eabi"] |
| 49 | features = ["defmt", "arch-cortex-m", "executor-thread", "executor-interrupt", "drs-scheduler"] | 49 | features = ["defmt", "arch-cortex-m", "executor-thread", "executor-interrupt", "edf-scheduler"] |
| 50 | 50 | ||
| 51 | [dependencies] | 51 | [dependencies] |
| 52 | defmt = { version = "1.0.1", optional = true } | 52 | defmt = { version = "1.0.1", optional = true } |
| @@ -91,6 +91,7 @@ embassy-sync = { path = "../embassy-sync" } | |||
| 91 | rustversion = "1.0.21" | 91 | rustversion = "1.0.21" |
| 92 | 92 | ||
| 93 | [features] | 93 | [features] |
| 94 | |||
| 94 | ## Enable nightly-only features | 95 | ## Enable nightly-only features |
| 95 | nightly = ["embassy-executor-macros/nightly"] | 96 | nightly = ["embassy-executor-macros/nightly"] |
| 96 | 97 | ||
| @@ -133,7 +134,7 @@ trace = ["_any_trace"] | |||
| 133 | rtos-trace = ["_any_trace", "metadata-name", "dep:rtos-trace", "dep:embassy-time-driver"] | 134 | rtos-trace = ["_any_trace", "metadata-name", "dep:rtos-trace", "dep:embassy-time-driver"] |
| 134 | _any_trace = [] | 135 | _any_trace = [] |
| 135 | 136 | ||
| 136 | ## Enable "Deadline Rank Sorted" Scheduler, using soft-realtime "deadlines" to prioritize | 137 | ## Enable "Earliest Deadline First" Scheduler, using soft-realtime "deadlines" to prioritize |
| 137 | ## tasks based on the remaining time before their deadline. Adds some overhead. Requires | 138 | ## tasks based on the remaining time before their deadline. Adds some overhead. Requires |
| 138 | ## hardware atomic support | 139 | ## hardware atomic support |
| 139 | drs-scheduler = ["dep:embassy-time-driver"] | 140 | edf-scheduler = ["dep:embassy-time-driver"] |
diff --git a/embassy-executor/src/raw/deadline.rs b/embassy-executor/src/raw/deadline.rs index ae6394822..006c7caf1 100644 --- a/embassy-executor/src/raw/deadline.rs +++ b/embassy-executor/src/raw/deadline.rs | |||
| @@ -2,11 +2,11 @@ use core::future::{poll_fn, Future}; | |||
| 2 | use core::task::Poll; | 2 | use core::task::Poll; |
| 3 | 3 | ||
| 4 | #[cfg(not(target_has_atomic = "ptr"))] | 4 | #[cfg(not(target_has_atomic = "ptr"))] |
| 5 | compile_error!("The `drs-scheduler` feature is currently only supported on targets with atomics."); | 5 | compile_error!("The `edf-scheduler` feature is currently only supported on targets with atomics."); |
| 6 | 6 | ||
| 7 | /// A type for interacting with the deadline of the current task | 7 | /// A type for interacting with the deadline of the current task |
| 8 | /// | 8 | /// |
| 9 | /// Requires the `drs-scheduler` feature | 9 | /// Requires the `edf-scheduler` feature |
| 10 | pub struct Deadline { | 10 | pub struct Deadline { |
| 11 | /// Deadline value in ticks, same time base and ticks as `embassy-time` | 11 | /// Deadline value in ticks, same time base and ticks as `embassy-time` |
| 12 | pub instant_ticks: u64, | 12 | pub instant_ticks: u64, |
diff --git a/embassy-executor/src/raw/mod.rs b/embassy-executor/src/raw/mod.rs index 21dc67b7e..96e7fda74 100644 --- a/embassy-executor/src/raw/mod.rs +++ b/embassy-executor/src/raw/mod.rs | |||
| @@ -28,7 +28,7 @@ pub(crate) mod util; | |||
| 28 | #[cfg_attr(feature = "turbowakers", path = "waker_turbo.rs")] | 28 | #[cfg_attr(feature = "turbowakers", path = "waker_turbo.rs")] |
| 29 | mod waker; | 29 | mod waker; |
| 30 | 30 | ||
| 31 | #[cfg(feature = "drs-scheduler")] | 31 | #[cfg(feature = "edf-scheduler")] |
| 32 | mod deadline; | 32 | mod deadline; |
| 33 | 33 | ||
| 34 | use core::future::Future; | 34 | use core::future::Future; |
| @@ -45,7 +45,7 @@ use embassy_executor_timer_queue::TimerQueueItem; | |||
| 45 | #[cfg(feature = "arch-avr")] | 45 | #[cfg(feature = "arch-avr")] |
| 46 | use portable_atomic::AtomicPtr; | 46 | use portable_atomic::AtomicPtr; |
| 47 | 47 | ||
| 48 | #[cfg(feature = "drs-scheduler")] | 48 | #[cfg(feature = "edf-scheduler")] |
| 49 | pub use deadline::Deadline; | 49 | pub use deadline::Deadline; |
| 50 | #[cfg(feature = "arch-avr")] | 50 | #[cfg(feature = "arch-avr")] |
| 51 | use portable_atomic::AtomicPtr; | 51 | use portable_atomic::AtomicPtr; |
| @@ -105,9 +105,9 @@ pub(crate) struct TaskHeader { | |||
| 105 | pub(crate) state: State, | 105 | pub(crate) state: State, |
| 106 | pub(crate) run_queue_item: RunQueueItem, | 106 | pub(crate) run_queue_item: RunQueueItem, |
| 107 | 107 | ||
| 108 | /// Deadline Rank Scheduler Deadline. This field should not be accessed outside the context of | 108 | /// Earliest Deadline First scheduler Deadline. This field should not be accessed |
| 109 | /// the task itself as it being polled by the executor. | 109 | /// outside the context of the task itself as it being polled by the executor. |
| 110 | #[cfg(feature = "drs-scheduler")] | 110 | #[cfg(feature = "edf-scheduler")] |
| 111 | pub(crate) deadline: SyncUnsafeCell<u64>, | 111 | pub(crate) deadline: SyncUnsafeCell<u64>, |
| 112 | 112 | ||
| 113 | pub(crate) executor: AtomicPtr<SyncExecutor>, | 113 | pub(crate) executor: AtomicPtr<SyncExecutor>, |
| @@ -216,7 +216,7 @@ impl<F: Future + 'static> TaskStorage<F> { | |||
| 216 | run_queue_item: RunQueueItem::new(), | 216 | run_queue_item: RunQueueItem::new(), |
| 217 | // NOTE: The deadline is set to zero to allow the initializer to reside in `.bss`. This | 217 | // NOTE: The deadline is set to zero to allow the initializer to reside in `.bss`. This |
| 218 | // will be lazily initalized in `initialize_impl` | 218 | // will be lazily initalized in `initialize_impl` |
| 219 | #[cfg(feature = "drs-scheduler")] | 219 | #[cfg(feature = "edf-scheduler")] |
| 220 | deadline: SyncUnsafeCell::new(0u64), | 220 | deadline: SyncUnsafeCell::new(0u64), |
| 221 | executor: AtomicPtr::new(core::ptr::null_mut()), | 221 | executor: AtomicPtr::new(core::ptr::null_mut()), |
| 222 | // Note: this is lazily initialized so that a static `TaskStorage` will go in `.bss` | 222 | // Note: this is lazily initialized so that a static `TaskStorage` will go in `.bss` |
| @@ -316,7 +316,7 @@ impl<F: Future + 'static> AvailableTask<F> { | |||
| 316 | 316 | ||
| 317 | // By default, deadlines are set to the maximum value, so that any task WITH | 317 | // By default, deadlines are set to the maximum value, so that any task WITH |
| 318 | // a set deadline will ALWAYS be scheduled BEFORE a task WITHOUT a set deadline | 318 | // a set deadline will ALWAYS be scheduled BEFORE a task WITHOUT a set deadline |
| 319 | #[cfg(feature = "drs-scheduler")] | 319 | #[cfg(feature = "edf-scheduler")] |
| 320 | self.task.raw.deadline.set(deadline::Deadline::UNSET_DEADLINE_TICKS); | 320 | self.task.raw.deadline.set(deadline::Deadline::UNSET_DEADLINE_TICKS); |
| 321 | 321 | ||
| 322 | let task = TaskRef::new(self.task); | 322 | let task = TaskRef::new(self.task); |
diff --git a/embassy-executor/src/raw/run_queue_atomics.rs b/embassy-executor/src/raw/run_queue_atomics.rs index 08765e06b..65a9b7859 100644 --- a/embassy-executor/src/raw/run_queue_atomics.rs +++ b/embassy-executor/src/raw/run_queue_atomics.rs | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | use core::ptr::{addr_of_mut, NonNull}; | 1 | use core::ptr::{addr_of_mut, NonNull}; |
| 2 | 2 | ||
| 3 | use cordyceps::sorted_list::Links; | 3 | use cordyceps::sorted_list::Links; |
| 4 | #[cfg(feature = "drs-scheduler")] | 4 | #[cfg(feature = "edf-scheduler")] |
| 5 | use cordyceps::SortedList; | 5 | use cordyceps::SortedList; |
| 6 | use cordyceps::{Linked, TransferStack}; | 6 | use cordyceps::{Linked, TransferStack}; |
| 7 | 7 | ||
| @@ -73,7 +73,7 @@ impl RunQueue { | |||
| 73 | /// Empty the queue, then call `on_task` for each task that was in the queue. | 73 | /// Empty the queue, then call `on_task` for each task that was in the queue. |
| 74 | /// NOTE: It is OK for `on_task` to enqueue more tasks. In this case they're left in the queue | 74 | /// NOTE: It is OK for `on_task` to enqueue more tasks. In this case they're left in the queue |
| 75 | /// and will be processed by the *next* call to `dequeue_all`, *not* the current one. | 75 | /// and will be processed by the *next* call to `dequeue_all`, *not* the current one. |
| 76 | #[cfg(not(feature = "drs-scheduler"))] | 76 | #[cfg(not(feature = "edf-scheduler"))] |
| 77 | pub(crate) fn dequeue_all(&self, on_task: impl Fn(TaskRef)) { | 77 | pub(crate) fn dequeue_all(&self, on_task: impl Fn(TaskRef)) { |
| 78 | let taken = self.stack.take_all(); | 78 | let taken = self.stack.take_all(); |
| 79 | for taskref in taken { | 79 | for taskref in taken { |
| @@ -82,7 +82,7 @@ impl RunQueue { | |||
| 82 | } | 82 | } |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | /// # Deadline Ranked Sorted Scheduler | 85 | /// # Earliest Deadline First Scheduler |
| 86 | /// | 86 | /// |
| 87 | /// This algorithm will loop until all enqueued tasks are processed. | 87 | /// This algorithm will loop until all enqueued tasks are processed. |
| 88 | /// | 88 | /// |
| @@ -96,7 +96,7 @@ impl RunQueue { | |||
| 96 | /// | 96 | /// |
| 97 | /// This process will repeat until the local `sorted` queue AND the global | 97 | /// This process will repeat until the local `sorted` queue AND the global |
| 98 | /// runqueue are both empty, at which point this function will return. | 98 | /// runqueue are both empty, at which point this function will return. |
| 99 | #[cfg(feature = "drs-scheduler")] | 99 | #[cfg(feature = "edf-scheduler")] |
| 100 | pub(crate) fn dequeue_all(&self, on_task: impl Fn(TaskRef)) { | 100 | pub(crate) fn dequeue_all(&self, on_task: impl Fn(TaskRef)) { |
| 101 | // SAFETY: `deadline` can only be set through the `Deadline` interface, which | 101 | // SAFETY: `deadline` can only be set through the `Deadline` interface, which |
| 102 | // only allows access to this value while the given task is being polled. | 102 | // only allows access to this value while the given task is being polled. |
