diff options
Diffstat (limited to 'embassy-executor/src/raw/state_atomics.rs')
| -rw-r--r-- | embassy-executor/src/raw/state_atomics.rs | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/embassy-executor/src/raw/state_atomics.rs b/embassy-executor/src/raw/state_atomics.rs index 15eb9a368..abfe94486 100644 --- a/embassy-executor/src/raw/state_atomics.rs +++ b/embassy-executor/src/raw/state_atomics.rs | |||
| @@ -2,6 +2,15 @@ use core::sync::atomic::{AtomicU32, Ordering}; | |||
| 2 | 2 | ||
| 3 | use super::timer_queue::TimerEnqueueOperation; | 3 | use super::timer_queue::TimerEnqueueOperation; |
| 4 | 4 | ||
| 5 | pub(crate) struct Token(()); | ||
| 6 | |||
| 7 | /// Creates a token and passes it to the closure. | ||
| 8 | /// | ||
| 9 | /// This is a no-op replacement for `CriticalSection::with` because we don't need any locking. | ||
| 10 | pub(crate) fn locked(f: impl FnOnce(Token)) { | ||
| 11 | f(Token(())); | ||
| 12 | } | ||
| 13 | |||
| 5 | /// Task is spawned (has a future) | 14 | /// Task is spawned (has a future) |
| 6 | pub(crate) const STATE_SPAWNED: u32 = 1 << 0; | 15 | pub(crate) const STATE_SPAWNED: u32 = 1 << 0; |
| 7 | /// Task is in the executor run queue | 16 | /// Task is in the executor run queue |
| @@ -34,10 +43,12 @@ impl State { | |||
| 34 | self.state.fetch_and(!STATE_SPAWNED, Ordering::AcqRel); | 43 | self.state.fetch_and(!STATE_SPAWNED, Ordering::AcqRel); |
| 35 | } | 44 | } |
| 36 | 45 | ||
| 37 | /// Mark the task as run-queued if it's spawned and isn't already run-queued. Return true on success. | 46 | /// Mark the task as run-queued if it's spawned and isn't already run-queued. Run the given |
| 47 | /// function if the task was successfully marked. | ||
| 38 | #[inline(always)] | 48 | #[inline(always)] |
| 39 | pub fn run_enqueue(&self) -> bool { | 49 | pub fn run_enqueue(&self, f: impl FnOnce(Token)) { |
| 40 | self.state | 50 | if self |
| 51 | .state | ||
| 41 | .fetch_update(Ordering::SeqCst, Ordering::SeqCst, |state| { | 52 | .fetch_update(Ordering::SeqCst, Ordering::SeqCst, |state| { |
| 42 | // If already scheduled, or if not started, | 53 | // If already scheduled, or if not started, |
| 43 | if (state & STATE_RUN_QUEUED != 0) || (state & STATE_SPAWNED == 0) { | 54 | if (state & STATE_RUN_QUEUED != 0) || (state & STATE_SPAWNED == 0) { |
| @@ -48,6 +59,9 @@ impl State { | |||
| 48 | } | 59 | } |
| 49 | }) | 60 | }) |
| 50 | .is_ok() | 61 | .is_ok() |
| 62 | { | ||
| 63 | locked(f); | ||
| 64 | } | ||
| 51 | } | 65 | } |
| 52 | 66 | ||
| 53 | /// Unmark the task as run-queued. Return whether the task is spawned. | 67 | /// Unmark the task as run-queued. Return whether the task is spawned. |
