aboutsummaryrefslogtreecommitdiff
path: root/embassy-executor/src
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2024-12-17 16:27:47 +0000
committerGitHub <[email protected]>2024-12-17 16:27:47 +0000
commitc1120c7138c10a4cbdadb75d47eb23be9b65c231 (patch)
tree169419cb049bb5485ae4e93ed247063adcc1e161 /embassy-executor/src
parent2853308d8f7b845a9255bd7f68911a5214f17ca1 (diff)
parent889b419fc40f252726dbdc8a67bc4d27aa5b81f3 (diff)
Merge pull request #3573 from bugadani/enqueue
Unconditionally set `RUN_QUEUED`
Diffstat (limited to 'embassy-executor/src')
-rw-r--r--embassy-executor/src/raw/mod.rs3
-rw-r--r--embassy-executor/src/raw/state_atomics.rs15
-rw-r--r--embassy-executor/src/raw/state_atomics_arm.rs21
-rw-r--r--embassy-executor/src/raw/state_critical_section.rs9
4 files changed, 10 insertions, 38 deletions
diff --git a/embassy-executor/src/raw/mod.rs b/embassy-executor/src/raw/mod.rs
index 0ac569946..6503b556f 100644
--- a/embassy-executor/src/raw/mod.rs
+++ b/embassy-executor/src/raw/mod.rs
@@ -52,7 +52,7 @@ use super::SpawnToken;
52/// ```text 52/// ```text
53/// ┌────────────┐ ┌────────────────────────┐ 53/// ┌────────────┐ ┌────────────────────────┐
54/// ┌─►│Not spawned │◄─6┤Not spawned|Run enqueued│ 54/// ┌─►│Not spawned │◄─6┤Not spawned|Run enqueued│
55/// │ │ �│ │ 55/// │ │ ��7�►�� │
56/// │ └─────┬──────┘ └──────▲─────────────────┘ 56/// │ └─────┬──────┘ └──────▲─────────────────┘
57/// │ 1 │ 57/// │ 1 │
58/// │ │ ┌────────────┘ 58/// │ │ ┌────────────┘
@@ -76,6 +76,7 @@ use super::SpawnToken;
76/// - 4: Task exits - `TaskStorage::poll -> Poll::Ready` 76/// - 4: Task exits - `TaskStorage::poll -> Poll::Ready`
77/// - 5: A run-queued task exits - `TaskStorage::poll -> Poll::Ready` 77/// - 5: A run-queued task exits - `TaskStorage::poll -> Poll::Ready`
78/// - 6: Task is dequeued and then ignored via `State::run_dequeue` 78/// - 6: Task is dequeued and then ignored via `State::run_dequeue`
79/// - 7: A task is waken when it is not spawned - `wake_task -> State::run_enqueue`
79pub(crate) struct TaskHeader { 80pub(crate) struct TaskHeader {
80 pub(crate) state: State, 81 pub(crate) state: State,
81 pub(crate) run_queue_item: RunQueueItem, 82 pub(crate) run_queue_item: RunQueueItem,
diff --git a/embassy-executor/src/raw/state_atomics.rs b/embassy-executor/src/raw/state_atomics.rs
index 6f5266bda..bdd317b53 100644
--- a/embassy-executor/src/raw/state_atomics.rs
+++ b/embassy-executor/src/raw/state_atomics.rs
@@ -44,19 +44,8 @@ impl State {
44 /// function if the task was successfully marked. 44 /// function if the task was successfully marked.
45 #[inline(always)] 45 #[inline(always)]
46 pub fn run_enqueue(&self, f: impl FnOnce(Token)) { 46 pub fn run_enqueue(&self, f: impl FnOnce(Token)) {
47 if self 47 let prev = self.state.fetch_or(STATE_RUN_QUEUED, Ordering::AcqRel);
48 .state 48 if prev & STATE_RUN_QUEUED == 0 {
49 .fetch_update(Ordering::SeqCst, Ordering::SeqCst, |state| {
50 // If already scheduled, or if not started,
51 if (state & STATE_RUN_QUEUED != 0) || (state & STATE_SPAWNED == 0) {
52 None
53 } else {
54 // Mark it as scheduled
55 Some(state | STATE_RUN_QUEUED)
56 }
57 })
58 .is_ok()
59 {
60 locked(f); 49 locked(f);
61 } 50 }
62 } 51 }
diff --git a/embassy-executor/src/raw/state_atomics_arm.rs b/embassy-executor/src/raw/state_atomics_arm.rs
index 4896b33c5..cbda0d89d 100644
--- a/embassy-executor/src/raw/state_atomics_arm.rs
+++ b/embassy-executor/src/raw/state_atomics_arm.rs
@@ -1,4 +1,3 @@
1use core::arch::asm;
2use core::sync::atomic::{compiler_fence, AtomicBool, AtomicU32, Ordering}; 1use core::sync::atomic::{compiler_fence, AtomicBool, AtomicU32, Ordering};
3 2
4#[derive(Clone, Copy)] 3#[derive(Clone, Copy)]
@@ -67,24 +66,10 @@ impl State {
67 /// function if the task was successfully marked. 66 /// function if the task was successfully marked.
68 #[inline(always)] 67 #[inline(always)]
69 pub fn run_enqueue(&self, f: impl FnOnce(Token)) { 68 pub fn run_enqueue(&self, f: impl FnOnce(Token)) {
70 unsafe { 69 let old = self.run_queued.swap(true, Ordering::AcqRel);
71 loop {
72 let state: u32;
73 asm!("ldrex {}, [{}]", out(reg) state, in(reg) self, options(nostack));
74 70
75 if (state & STATE_RUN_QUEUED != 0) || (state & STATE_SPAWNED == 0) { 71 if !old {
76 asm!("clrex", options(nomem, nostack)); 72 locked(f);
77 return;
78 }
79
80 let outcome: usize;
81 let new_state = state | STATE_RUN_QUEUED;
82 asm!("strex {}, {}, [{}]", out(reg) outcome, in(reg) new_state, in(reg) self, options(nostack));
83 if outcome == 0 {
84 locked(f);
85 return;
86 }
87 }
88 } 73 }
89 } 74 }
90 75
diff --git a/embassy-executor/src/raw/state_critical_section.rs b/embassy-executor/src/raw/state_critical_section.rs
index 29b10f6e3..4733af278 100644
--- a/embassy-executor/src/raw/state_critical_section.rs
+++ b/embassy-executor/src/raw/state_critical_section.rs
@@ -56,12 +56,9 @@ impl State {
56 pub fn run_enqueue(&self, f: impl FnOnce(Token)) { 56 pub fn run_enqueue(&self, f: impl FnOnce(Token)) {
57 critical_section::with(|cs| { 57 critical_section::with(|cs| {
58 if self.update_with_cs(cs, |s| { 58 if self.update_with_cs(cs, |s| {
59 if (*s & STATE_RUN_QUEUED != 0) || (*s & STATE_SPAWNED == 0) { 59 let ok = *s & STATE_RUN_QUEUED == 0;
60 false 60 *s |= STATE_RUN_QUEUED;
61 } else { 61 ok
62 *s |= STATE_RUN_QUEUED;
63 true
64 }
65 }) { 62 }) {
66 f(cs); 63 f(cs);
67 } 64 }