diff options
Diffstat (limited to 'embassy-executor/src/raw/state_atomics.rs')
| -rw-r--r-- | embassy-executor/src/raw/state_atomics.rs | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/embassy-executor/src/raw/state_atomics.rs b/embassy-executor/src/raw/state_atomics.rs index e4127897e..d03c61ade 100644 --- a/embassy-executor/src/raw/state_atomics.rs +++ b/embassy-executor/src/raw/state_atomics.rs | |||
| @@ -1,9 +1,15 @@ | |||
| 1 | use core::sync::atomic::{AtomicU32, Ordering}; | 1 | use core::sync::atomic::{AtomicU32, Ordering}; |
| 2 | 2 | ||
| 3 | #[cfg(feature = "integrated-timers")] | ||
| 4 | use super::timer_queue::TimerEnqueueOperation; | ||
| 5 | |||
| 3 | /// Task is spawned (has a future) | 6 | /// Task is spawned (has a future) |
| 4 | pub(crate) const STATE_SPAWNED: u32 = 1 << 0; | 7 | pub(crate) const STATE_SPAWNED: u32 = 1 << 0; |
| 5 | /// Task is in the executor run queue | 8 | /// Task is in the executor run queue |
| 6 | pub(crate) const STATE_RUN_QUEUED: u32 = 1 << 1; | 9 | pub(crate) const STATE_RUN_QUEUED: u32 = 1 << 1; |
| 10 | /// Task is in the executor timer queue | ||
| 11 | #[cfg(feature = "integrated-timers")] | ||
| 12 | pub(crate) const STATE_TIMER_QUEUED: u32 = 1 << 2; | ||
| 7 | 13 | ||
| 8 | pub(crate) struct State { | 14 | pub(crate) struct State { |
| 9 | state: AtomicU32, | 15 | state: AtomicU32, |
| @@ -52,4 +58,34 @@ impl State { | |||
| 52 | let state = self.state.fetch_and(!STATE_RUN_QUEUED, Ordering::AcqRel); | 58 | let state = self.state.fetch_and(!STATE_RUN_QUEUED, Ordering::AcqRel); |
| 53 | state & STATE_SPAWNED != 0 | 59 | state & STATE_SPAWNED != 0 |
| 54 | } | 60 | } |
| 61 | |||
| 62 | /// Mark the task as timer-queued. Return whether it can be enqueued. | ||
| 63 | #[cfg(feature = "integrated-timers")] | ||
| 64 | #[inline(always)] | ||
| 65 | pub fn timer_enqueue(&self) -> TimerEnqueueOperation { | ||
| 66 | if self | ||
| 67 | .state | ||
| 68 | .fetch_update(Ordering::SeqCst, Ordering::SeqCst, |state| { | ||
| 69 | // If not started, ignore it | ||
| 70 | if state & STATE_SPAWNED == 0 { | ||
| 71 | None | ||
| 72 | } else { | ||
| 73 | // Mark it as enqueued | ||
| 74 | Some(state | STATE_TIMER_QUEUED) | ||
| 75 | } | ||
| 76 | }) | ||
| 77 | .is_ok() | ||
| 78 | { | ||
| 79 | TimerEnqueueOperation::Enqueue | ||
| 80 | } else { | ||
| 81 | TimerEnqueueOperation::Ignore | ||
| 82 | } | ||
| 83 | } | ||
| 84 | |||
| 85 | /// Unmark the task as timer-queued. | ||
| 86 | #[cfg(feature = "integrated-timers")] | ||
| 87 | #[inline(always)] | ||
| 88 | pub fn timer_dequeue(&self) { | ||
| 89 | self.state.fetch_and(!STATE_TIMER_QUEUED, Ordering::Relaxed); | ||
| 90 | } | ||
| 55 | } | 91 | } |
