diff options
| author | Dario Nieuwenhuis <[email protected]> | 2024-12-16 14:46:08 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-12-16 14:46:08 +0000 |
| commit | 47e96beff4fc4c8dff8bf6d6a67e1d2e81c40495 (patch) | |
| tree | bee175817d7dc3119c5533bd78069cd6ce0a7f44 /embassy-executor/src/raw/state_critical_section.rs | |
| parent | 2c3bc75da6008afa7cacc1045954cef7e3d8740f (diff) | |
| parent | f389ba37219d842d7db0ab94cd421c69645a5757 (diff) | |
Merge pull request #3644 from bugadani/lock_once
Only lock once to wake a task
Diffstat (limited to 'embassy-executor/src/raw/state_critical_section.rs')
| -rw-r--r-- | embassy-executor/src/raw/state_critical_section.rs | 42 |
1 files changed, 25 insertions, 17 deletions
diff --git a/embassy-executor/src/raw/state_critical_section.rs b/embassy-executor/src/raw/state_critical_section.rs index 367162ba2..8e570b33c 100644 --- a/embassy-executor/src/raw/state_critical_section.rs +++ b/embassy-executor/src/raw/state_critical_section.rs | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | use core::cell::Cell; | 1 | use core::cell::Cell; |
| 2 | 2 | ||
| 3 | use critical_section::Mutex; | 3 | pub(crate) use critical_section::{with as locked, CriticalSection as Token}; |
| 4 | use critical_section::{CriticalSection, Mutex}; | ||
| 4 | 5 | ||
| 5 | use super::timer_queue::TimerEnqueueOperation; | 6 | use super::timer_queue::TimerEnqueueOperation; |
| 6 | 7 | ||
| @@ -23,13 +24,15 @@ impl State { | |||
| 23 | } | 24 | } |
| 24 | 25 | ||
| 25 | fn update<R>(&self, f: impl FnOnce(&mut u32) -> R) -> R { | 26 | fn update<R>(&self, f: impl FnOnce(&mut u32) -> R) -> R { |
| 26 | critical_section::with(|cs| { | 27 | critical_section::with(|cs| self.update_with_cs(cs, f)) |
| 27 | let s = self.state.borrow(cs); | 28 | } |
| 28 | let mut val = s.get(); | 29 | |
| 29 | let r = f(&mut val); | 30 | fn update_with_cs<R>(&self, cs: CriticalSection<'_>, f: impl FnOnce(&mut u32) -> R) -> R { |
| 30 | s.set(val); | 31 | let s = self.state.borrow(cs); |
| 31 | r | 32 | let mut val = s.get(); |
| 32 | }) | 33 | let r = f(&mut val); |
| 34 | s.set(val); | ||
| 35 | r | ||
| 33 | } | 36 | } |
| 34 | 37 | ||
| 35 | /// If task is idle, mark it as spawned + run_queued and return true. | 38 | /// If task is idle, mark it as spawned + run_queued and return true. |
| @@ -51,17 +54,22 @@ impl State { | |||
| 51 | self.update(|s| *s &= !STATE_SPAWNED); | 54 | self.update(|s| *s &= !STATE_SPAWNED); |
| 52 | } | 55 | } |
| 53 | 56 | ||
| 54 | /// Mark the task as run-queued if it's spawned and isn't already run-queued. Return true on success. | 57 | /// Mark the task as run-queued if it's spawned and isn't already run-queued. Run the given |
| 58 | /// function if the task was successfully marked. | ||
| 55 | #[inline(always)] | 59 | #[inline(always)] |
| 56 | pub fn run_enqueue(&self) -> bool { | 60 | pub fn run_enqueue(&self, f: impl FnOnce(Token)) { |
| 57 | self.update(|s| { | 61 | critical_section::with(|cs| { |
| 58 | if (*s & STATE_RUN_QUEUED != 0) || (*s & STATE_SPAWNED == 0) { | 62 | if self.update_with_cs(cs, |s| { |
| 59 | false | 63 | if (*s & STATE_RUN_QUEUED != 0) || (*s & STATE_SPAWNED == 0) { |
| 60 | } else { | 64 | false |
| 61 | *s |= STATE_RUN_QUEUED; | 65 | } else { |
| 62 | true | 66 | *s |= STATE_RUN_QUEUED; |
| 67 | true | ||
| 68 | } | ||
| 69 | }) { | ||
| 70 | f(cs); | ||
| 63 | } | 71 | } |
| 64 | }) | 72 | }); |
| 65 | } | 73 | } |
| 66 | 74 | ||
| 67 | /// Unmark the task as run-queued. Return whether the task is spawned. | 75 | /// Unmark the task as run-queued. Return whether the task is spawned. |
