diff options
| author | Dániel Buga <[email protected]> | 2024-12-09 08:43:57 +0100 |
|---|---|---|
| committer | Dániel Buga <[email protected]> | 2024-12-13 21:20:57 +0100 |
| commit | ec96395d084d5edc8be25ddaea8547e2ebd447a6 (patch) | |
| tree | b1edf825c8d67013df3cec1283376a7558951a3f /embassy-executor/src/raw/state_critical_section.rs | |
| parent | d45ea43892198484b5f6dcea4c351dc11d226cc4 (diff) | |
Prevent task from respawning while in the timer queue
Diffstat (limited to 'embassy-executor/src/raw/state_critical_section.rs')
| -rw-r--r-- | embassy-executor/src/raw/state_critical_section.rs | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/embassy-executor/src/raw/state_critical_section.rs b/embassy-executor/src/raw/state_critical_section.rs index b92eed006..c0ec2f530 100644 --- a/embassy-executor/src/raw/state_critical_section.rs +++ b/embassy-executor/src/raw/state_critical_section.rs | |||
| @@ -2,10 +2,16 @@ use core::cell::Cell; | |||
| 2 | 2 | ||
| 3 | use critical_section::Mutex; | 3 | use critical_section::Mutex; |
| 4 | 4 | ||
| 5 | #[cfg(feature = "integrated-timers")] | ||
| 6 | use super::timer_queue::TimerEnqueueOperation; | ||
| 7 | |||
| 5 | /// Task is spawned (has a future) | 8 | /// Task is spawned (has a future) |
| 6 | pub(crate) const STATE_SPAWNED: u32 = 1 << 0; | 9 | pub(crate) const STATE_SPAWNED: u32 = 1 << 0; |
| 7 | /// Task is in the executor run queue | 10 | /// Task is in the executor run queue |
| 8 | pub(crate) const STATE_RUN_QUEUED: u32 = 1 << 1; | 11 | pub(crate) const STATE_RUN_QUEUED: u32 = 1 << 1; |
| 12 | /// Task is in the executor timer queue | ||
| 13 | #[cfg(feature = "integrated-timers")] | ||
| 14 | pub(crate) const STATE_TIMER_QUEUED: u32 = 1 << 2; | ||
| 9 | 15 | ||
| 10 | pub(crate) struct State { | 16 | pub(crate) struct State { |
| 11 | state: Mutex<Cell<u32>>, | 17 | state: Mutex<Cell<u32>>, |
| @@ -69,4 +75,27 @@ impl State { | |||
| 69 | ok | 75 | ok |
| 70 | }) | 76 | }) |
| 71 | } | 77 | } |
| 78 | |||
| 79 | /// Mark the task as timer-queued. Return whether it can be enqueued. | ||
| 80 | #[cfg(feature = "integrated-timers")] | ||
| 81 | #[inline(always)] | ||
| 82 | pub fn timer_enqueue(&self) -> TimerEnqueueOperation { | ||
| 83 | self.update(|s| { | ||
| 84 | // FIXME: we need to split SPAWNED into two phases, to prevent enqueueing a task that is | ||
| 85 | // just being spawned, because its executor pointer may still be changing. | ||
| 86 | if *s & STATE_SPAWNED == STATE_SPAWNED { | ||
| 87 | *s |= STATE_TIMER_QUEUED; | ||
| 88 | TimerEnqueueOperation::Enqueue | ||
| 89 | } else { | ||
| 90 | TimerEnqueueOperation::Ignore | ||
| 91 | } | ||
| 92 | }) | ||
| 93 | } | ||
| 94 | |||
| 95 | /// Unmark the task as timer-queued. | ||
| 96 | #[cfg(feature = "integrated-timers")] | ||
| 97 | #[inline(always)] | ||
| 98 | pub fn timer_dequeue(&self) { | ||
| 99 | self.update(|s| *s &= !STATE_TIMER_QUEUED); | ||
| 100 | } | ||
| 72 | } | 101 | } |
