diff options
| author | Dario Nieuwenhuis <[email protected]> | 2023-11-14 22:32:48 +0100 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2023-11-15 18:43:27 +0100 |
| commit | bef9b7a8539c3dddb1cf6ab46db161f1ca56b1a1 (patch) | |
| tree | 6d15736eec0029c13093bee120bd2189aa9537ac /embassy-executor/src/raw/state_critical_section.rs | |
| parent | 50a983fd9b8f10fa5153757593e9f8cfccc902ac (diff) | |
executor: remove atomic-polyfill.
Diffstat (limited to 'embassy-executor/src/raw/state_critical_section.rs')
| -rw-r--r-- | embassy-executor/src/raw/state_critical_section.rs | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/embassy-executor/src/raw/state_critical_section.rs b/embassy-executor/src/raw/state_critical_section.rs new file mode 100644 index 000000000..c3cc1b0b7 --- /dev/null +++ b/embassy-executor/src/raw/state_critical_section.rs | |||
| @@ -0,0 +1,93 @@ | |||
| 1 | use core::cell::Cell; | ||
| 2 | |||
| 3 | use critical_section::Mutex; | ||
| 4 | |||
| 5 | /// Task is spawned (has a future) | ||
| 6 | pub(crate) const STATE_SPAWNED: u32 = 1 << 0; | ||
| 7 | /// Task is in the executor run queue | ||
| 8 | pub(crate) const STATE_RUN_QUEUED: u32 = 1 << 1; | ||
| 9 | /// Task is in the executor timer queue | ||
| 10 | #[cfg(feature = "integrated-timers")] | ||
| 11 | pub(crate) const STATE_TIMER_QUEUED: u32 = 1 << 2; | ||
| 12 | |||
| 13 | pub(crate) struct State { | ||
| 14 | state: Mutex<Cell<u32>>, | ||
| 15 | } | ||
| 16 | |||
| 17 | impl State { | ||
| 18 | pub const fn new() -> State { | ||
| 19 | Self { | ||
| 20 | state: Mutex::new(Cell::new(0)), | ||
| 21 | } | ||
| 22 | } | ||
| 23 | |||
| 24 | fn update<R>(&self, f: impl FnOnce(&mut u32) -> R) -> R { | ||
| 25 | critical_section::with(|cs| { | ||
| 26 | let s = self.state.borrow(cs); | ||
| 27 | let mut val = s.get(); | ||
| 28 | let r = f(&mut val); | ||
| 29 | s.set(val); | ||
| 30 | r | ||
| 31 | }) | ||
| 32 | } | ||
| 33 | |||
| 34 | /// If task is idle, mark it as spawned + run_queued and return true. | ||
| 35 | #[inline(always)] | ||
| 36 | pub fn spawn(&self) -> bool { | ||
| 37 | self.update(|s| { | ||
| 38 | if *s == 0 { | ||
| 39 | *s = STATE_SPAWNED | STATE_RUN_QUEUED; | ||
| 40 | true | ||
| 41 | } else { | ||
| 42 | false | ||
| 43 | } | ||
| 44 | }) | ||
| 45 | } | ||
| 46 | |||
| 47 | /// Unmark the task as spawned. | ||
| 48 | #[inline(always)] | ||
| 49 | pub fn despawn(&self) { | ||
| 50 | self.update(|s| *s &= !STATE_SPAWNED); | ||
| 51 | } | ||
| 52 | |||
| 53 | /// Mark the task as run-queued if it's spawned and isn't already run-queued. Return true on success. | ||
| 54 | #[inline(always)] | ||
| 55 | pub fn run_enqueue(&self) -> bool { | ||
| 56 | self.update(|s| { | ||
| 57 | if (*s & STATE_RUN_QUEUED != 0) || (*s & STATE_SPAWNED == 0) { | ||
| 58 | false | ||
| 59 | } else { | ||
| 60 | *s |= STATE_RUN_QUEUED; | ||
| 61 | true | ||
| 62 | } | ||
| 63 | }) | ||
| 64 | } | ||
| 65 | |||
| 66 | /// Unmark the task as run-queued. Return whether the task is spawned. | ||
| 67 | #[inline(always)] | ||
| 68 | pub fn run_dequeue(&self) -> bool { | ||
| 69 | self.update(|s| { | ||
| 70 | let ok = *s & STATE_SPAWNED != 0; | ||
| 71 | *s &= !STATE_RUN_QUEUED; | ||
| 72 | ok | ||
| 73 | }) | ||
| 74 | } | ||
| 75 | |||
| 76 | /// Mark the task as timer-queued. Return whether it was newly queued (i.e. not queued before) | ||
| 77 | #[cfg(feature = "integrated-timers")] | ||
| 78 | #[inline(always)] | ||
| 79 | pub fn timer_enqueue(&self) -> bool { | ||
| 80 | self.update(|s| { | ||
| 81 | let ok = *s & STATE_TIMER_QUEUED == 0; | ||
| 82 | *s |= STATE_TIMER_QUEUED; | ||
| 83 | ok | ||
| 84 | }) | ||
| 85 | } | ||
| 86 | |||
| 87 | /// Unmark the task as timer-queued. | ||
| 88 | #[cfg(feature = "integrated-timers")] | ||
| 89 | #[inline(always)] | ||
| 90 | pub fn timer_dequeue(&self) { | ||
| 91 | self.update(|s| *s &= !STATE_TIMER_QUEUED); | ||
| 92 | } | ||
| 93 | } | ||
