aboutsummaryrefslogtreecommitdiff
path: root/embassy-executor/src
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-executor/src')
-rw-r--r--embassy-executor/src/arch/avr.rs4
-rw-r--r--embassy-executor/src/arch/cortex_ar.rs11
-rw-r--r--embassy-executor/src/arch/cortex_m.rs4
-rw-r--r--embassy-executor/src/arch/riscv32.rs4
-rw-r--r--embassy-executor/src/arch/spin.rs4
-rw-r--r--embassy-executor/src/arch/std.rs19
-rw-r--r--embassy-executor/src/arch/wasm.rs4
-rw-r--r--embassy-executor/src/lib.rs1
-rw-r--r--embassy-executor/src/metadata.rs2
-rw-r--r--embassy-executor/src/raw/mod.rs6
-rw-r--r--embassy-executor/src/raw/run_queue.rs4
-rw-r--r--embassy-executor/src/raw/state_atomics_arm.rs2
-rw-r--r--embassy-executor/src/raw/state_critical_section.rs2
-rw-r--r--embassy-executor/src/raw/trace.rs8
-rw-r--r--embassy-executor/src/raw/waker.rs6
-rw-r--r--embassy-executor/src/raw/waker_turbo.rs4
-rw-r--r--embassy-executor/src/spawner.rs12
17 files changed, 59 insertions, 38 deletions
diff --git a/embassy-executor/src/arch/avr.rs b/embassy-executor/src/arch/avr.rs
index 70085d04d..a841afe15 100644
--- a/embassy-executor/src/arch/avr.rs
+++ b/embassy-executor/src/arch/avr.rs
@@ -10,11 +10,11 @@ mod thread {
10 pub use embassy_executor_macros::main_avr as main; 10 pub use embassy_executor_macros::main_avr as main;
11 use portable_atomic::{AtomicBool, Ordering}; 11 use portable_atomic::{AtomicBool, Ordering};
12 12
13 use crate::{raw, Spawner}; 13 use crate::{Spawner, raw};
14 14
15 static SIGNAL_WORK_THREAD_MODE: AtomicBool = AtomicBool::new(false); 15 static SIGNAL_WORK_THREAD_MODE: AtomicBool = AtomicBool::new(false);
16 16
17 #[export_name = "__pender"] 17 #[unsafe(export_name = "__pender")]
18 fn __pender(_context: *mut ()) { 18 fn __pender(_context: *mut ()) {
19 SIGNAL_WORK_THREAD_MODE.store(true, Ordering::SeqCst); 19 SIGNAL_WORK_THREAD_MODE.store(true, Ordering::SeqCst);
20 } 20 }
diff --git a/embassy-executor/src/arch/cortex_ar.rs b/embassy-executor/src/arch/cortex_ar.rs
index f9e2f3f7c..ce572738a 100644
--- a/embassy-executor/src/arch/cortex_ar.rs
+++ b/embassy-executor/src/arch/cortex_ar.rs
@@ -1,7 +1,10 @@
1#[cfg(arm_profile = "legacy")]
2compile_error!("`arch-cortex-ar` does not support the legacy ARM profile, WFE/SEV are not available.");
3
1#[cfg(feature = "executor-interrupt")] 4#[cfg(feature = "executor-interrupt")]
2compile_error!("`executor-interrupt` is not supported with `arch-cortex-ar`."); 5compile_error!("`executor-interrupt` is not supported with `arch-cortex-ar`.");
3 6
4#[export_name = "__pender"] 7#[unsafe(export_name = "__pender")]
5#[cfg(any(feature = "executor-thread", feature = "executor-interrupt"))] 8#[cfg(any(feature = "executor-thread", feature = "executor-interrupt"))]
6fn __pender(context: *mut ()) { 9fn __pender(context: *mut ()) {
7 // `context` is always `usize::MAX` created by `Executor::run`. 10 // `context` is always `usize::MAX` created by `Executor::run`.
@@ -10,7 +13,7 @@ fn __pender(context: *mut ()) {
10 #[cfg(feature = "executor-thread")] 13 #[cfg(feature = "executor-thread")]
11 // Try to make Rust optimize the branching away if we only use thread mode. 14 // Try to make Rust optimize the branching away if we only use thread mode.
12 if !cfg!(feature = "executor-interrupt") || context == THREAD_PENDER { 15 if !cfg!(feature = "executor-interrupt") || context == THREAD_PENDER {
13 cortex_ar::asm::sev(); 16 aarch32_cpu::asm::sev();
14 return; 17 return;
15 } 18 }
16} 19}
@@ -23,10 +26,10 @@ mod thread {
23 26
24 use core::marker::PhantomData; 27 use core::marker::PhantomData;
25 28
26 use cortex_ar::asm::wfe; 29 use aarch32_cpu::asm::wfe;
27 pub use embassy_executor_macros::main_cortex_ar as main; 30 pub use embassy_executor_macros::main_cortex_ar as main;
28 31
29 use crate::{raw, Spawner}; 32 use crate::{Spawner, raw};
30 33
31 /// Thread mode executor, using WFE/SEV. 34 /// Thread mode executor, using WFE/SEV.
32 /// 35 ///
diff --git a/embassy-executor/src/arch/cortex_m.rs b/embassy-executor/src/arch/cortex_m.rs
index 1c9ddd8a0..1ce96d1d5 100644
--- a/embassy-executor/src/arch/cortex_m.rs
+++ b/embassy-executor/src/arch/cortex_m.rs
@@ -1,4 +1,4 @@
1#[export_name = "__pender"] 1#[unsafe(export_name = "__pender")]
2#[cfg(any(feature = "executor-thread", feature = "executor-interrupt"))] 2#[cfg(any(feature = "executor-thread", feature = "executor-interrupt"))]
3fn __pender(context: *mut ()) { 3fn __pender(context: *mut ()) {
4 unsafe { 4 unsafe {
@@ -53,7 +53,7 @@ mod thread {
53 53
54 pub use embassy_executor_macros::main_cortex_m as main; 54 pub use embassy_executor_macros::main_cortex_m as main;
55 55
56 use crate::{raw, Spawner}; 56 use crate::{Spawner, raw};
57 57
58 /// Thread mode executor, using WFE/SEV. 58 /// Thread mode executor, using WFE/SEV.
59 /// 59 ///
diff --git a/embassy-executor/src/arch/riscv32.rs b/embassy-executor/src/arch/riscv32.rs
index 01e63a9fd..c70c1344a 100644
--- a/embassy-executor/src/arch/riscv32.rs
+++ b/embassy-executor/src/arch/riscv32.rs
@@ -10,12 +10,12 @@ mod thread {
10 10
11 pub use embassy_executor_macros::main_riscv as main; 11 pub use embassy_executor_macros::main_riscv as main;
12 12
13 use crate::{raw, Spawner}; 13 use crate::{Spawner, raw};
14 14
15 /// global atomic used to keep track of whether there is work to do since sev() is not available on RISCV 15 /// global atomic used to keep track of whether there is work to do since sev() is not available on RISCV
16 static SIGNAL_WORK_THREAD_MODE: AtomicBool = AtomicBool::new(false); 16 static SIGNAL_WORK_THREAD_MODE: AtomicBool = AtomicBool::new(false);
17 17
18 #[export_name = "__pender"] 18 #[unsafe(export_name = "__pender")]
19 fn __pender(_context: *mut ()) { 19 fn __pender(_context: *mut ()) {
20 SIGNAL_WORK_THREAD_MODE.store(true, Ordering::SeqCst); 20 SIGNAL_WORK_THREAD_MODE.store(true, Ordering::SeqCst);
21 } 21 }
diff --git a/embassy-executor/src/arch/spin.rs b/embassy-executor/src/arch/spin.rs
index 340023620..49f3356a6 100644
--- a/embassy-executor/src/arch/spin.rs
+++ b/embassy-executor/src/arch/spin.rs
@@ -9,9 +9,9 @@ mod thread {
9 9
10 pub use embassy_executor_macros::main_spin as main; 10 pub use embassy_executor_macros::main_spin as main;
11 11
12 use crate::{raw, Spawner}; 12 use crate::{Spawner, raw};
13 13
14 #[export_name = "__pender"] 14 #[unsafe(export_name = "__pender")]
15 fn __pender(_context: *mut ()) {} 15 fn __pender(_context: *mut ()) {}
16 16
17 /// Spin Executor 17 /// Spin Executor
diff --git a/embassy-executor/src/arch/std.rs b/embassy-executor/src/arch/std.rs
index b02b15988..d4057144e 100644
--- a/embassy-executor/src/arch/std.rs
+++ b/embassy-executor/src/arch/std.rs
@@ -10,9 +10,9 @@ mod thread {
10 10
11 pub use embassy_executor_macros::main_std as main; 11 pub use embassy_executor_macros::main_std as main;
12 12
13 use crate::{raw, Spawner}; 13 use crate::{Spawner, raw};
14 14
15 #[export_name = "__pender"] 15 #[unsafe(export_name = "__pender")]
16 fn __pender(context: *mut ()) { 16 fn __pender(context: *mut ()) {
17 let signaler: &'static Signaler = unsafe { std::mem::transmute(context) }; 17 let signaler: &'static Signaler = unsafe { std::mem::transmute(context) };
18 signaler.signal() 18 signaler.signal()
@@ -55,11 +55,24 @@ mod thread {
55 /// 55 ///
56 /// This function never returns. 56 /// This function never returns.
57 pub fn run(&'static mut self, init: impl FnOnce(Spawner)) -> ! { 57 pub fn run(&'static mut self, init: impl FnOnce(Spawner)) -> ! {
58 self.run_until(init, || false);
59 unreachable!()
60 }
61
62 /// Run the executor until a flag is raised.
63 ///
64 /// This function is identical to `Executor::run()` apart from offering a `done` flag to stop execution.
65 pub fn run_until(&'static mut self, init: impl FnOnce(Spawner), mut done: impl FnMut() -> bool) {
58 init(self.inner.spawner()); 66 init(self.inner.spawner());
59 67
60 loop { 68 loop {
61 unsafe { self.inner.poll() }; 69 unsafe { self.inner.poll() };
62 self.signaler.wait() 70
71 if done() {
72 break;
73 }
74
75 self.signaler.wait();
63 } 76 }
64 } 77 }
65 } 78 }
diff --git a/embassy-executor/src/arch/wasm.rs b/embassy-executor/src/arch/wasm.rs
index f9d0f935c..d2ff2fe51 100644
--- a/embassy-executor/src/arch/wasm.rs
+++ b/embassy-executor/src/arch/wasm.rs
@@ -13,9 +13,9 @@ mod thread {
13 use wasm_bindgen::prelude::*; 13 use wasm_bindgen::prelude::*;
14 14
15 use crate::raw::util::UninitCell; 15 use crate::raw::util::UninitCell;
16 use crate::{raw, Spawner}; 16 use crate::{Spawner, raw};
17 17
18 #[export_name = "__pender"] 18 #[unsafe(export_name = "__pender")]
19 fn __pender(context: *mut ()) { 19 fn __pender(context: *mut ()) {
20 let signaler: &'static WasmContext = unsafe { std::mem::transmute(context) }; 20 let signaler: &'static WasmContext = unsafe { std::mem::transmute(context) };
21 let _ = signaler.promise.then(unsafe { signaler.closure.as_mut() }); 21 let _ = signaler.promise.then(unsafe { signaler.closure.as_mut() });
diff --git a/embassy-executor/src/lib.rs b/embassy-executor/src/lib.rs
index e47b8eb9f..cffc76699 100644
--- a/embassy-executor/src/lib.rs
+++ b/embassy-executor/src/lib.rs
@@ -1,5 +1,6 @@
1#![cfg_attr(not(any(feature = "arch-std", feature = "arch-wasm")), no_std)] 1#![cfg_attr(not(any(feature = "arch-std", feature = "arch-wasm")), no_std)]
2#![allow(clippy::new_without_default)] 2#![allow(clippy::new_without_default)]
3#![allow(unsafe_op_in_unsafe_fn)]
3#![doc = include_str!("../README.md")] 4#![doc = include_str!("../README.md")]
4#![warn(missing_docs)] 5#![warn(missing_docs)]
5 6
diff --git a/embassy-executor/src/metadata.rs b/embassy-executor/src/metadata.rs
index bc0df0f83..76504ab0b 100644
--- a/embassy-executor/src/metadata.rs
+++ b/embassy-executor/src/metadata.rs
@@ -1,6 +1,6 @@
1#[cfg(feature = "metadata-name")] 1#[cfg(feature = "metadata-name")]
2use core::cell::Cell; 2use core::cell::Cell;
3use core::future::{poll_fn, Future}; 3use core::future::{Future, poll_fn};
4#[cfg(feature = "scheduler-priority")] 4#[cfg(feature = "scheduler-priority")]
5use core::sync::atomic::{AtomicU8, Ordering}; 5use core::sync::atomic::{AtomicU8, Ordering};
6use core::task::Poll; 6use core::task::Poll;
diff --git a/embassy-executor/src/raw/mod.rs b/embassy-executor/src/raw/mod.rs
index dbd70cbf4..ab845ed3b 100644
--- a/embassy-executor/src/raw/mod.rs
+++ b/embassy-executor/src/raw/mod.rs
@@ -52,7 +52,7 @@ pub use self::waker::task_from_waker;
52use super::SpawnToken; 52use super::SpawnToken;
53use crate::{Metadata, SpawnError}; 53use crate::{Metadata, SpawnError};
54 54
55#[no_mangle] 55#[unsafe(no_mangle)]
56extern "Rust" fn __embassy_time_queue_item_from_waker(waker: &Waker) -> &'static mut TimerQueueItem { 56extern "Rust" fn __embassy_time_queue_item_from_waker(waker: &Waker) -> &'static mut TimerQueueItem {
57 unsafe { task_from_waker(waker).timer_queue_item() } 57 unsafe { task_from_waker(waker).timer_queue_item() }
58} 58}
@@ -407,7 +407,7 @@ unsafe impl Sync for Pender {}
407 407
408impl Pender { 408impl Pender {
409 pub(crate) fn pend(self) { 409 pub(crate) fn pend(self) {
410 extern "Rust" { 410 unsafe extern "Rust" {
411 fn __pender(context: *mut ()); 411 fn __pender(context: *mut ());
412 } 412 }
413 unsafe { __pender(self.0) }; 413 unsafe { __pender(self.0) };
@@ -507,7 +507,7 @@ impl SyncExecutor {
507/// The pender function must be exported with the name `__pender` and have the following signature: 507/// The pender function must be exported with the name `__pender` and have the following signature:
508/// 508///
509/// ```rust 509/// ```rust
510/// #[export_name = "__pender"] 510/// #[unsafe(export_name = "__pender")]
511/// fn pender(context: *mut ()) { 511/// fn pender(context: *mut ()) {
512/// // schedule `poll()` to be called 512/// // schedule `poll()` to be called
513/// } 513/// }
diff --git a/embassy-executor/src/raw/run_queue.rs b/embassy-executor/src/raw/run_queue.rs
index b8b052310..6f2abdbd0 100644
--- a/embassy-executor/src/raw/run_queue.rs
+++ b/embassy-executor/src/raw/run_queue.rs
@@ -1,9 +1,9 @@
1use core::ptr::{addr_of_mut, NonNull}; 1use core::ptr::{NonNull, addr_of_mut};
2 2
3use cordyceps::sorted_list::Links;
4use cordyceps::Linked; 3use cordyceps::Linked;
5#[cfg(any(feature = "scheduler-priority", feature = "scheduler-deadline"))] 4#[cfg(any(feature = "scheduler-priority", feature = "scheduler-deadline"))]
6use cordyceps::SortedList; 5use cordyceps::SortedList;
6use cordyceps::sorted_list::Links;
7 7
8#[cfg(target_has_atomic = "ptr")] 8#[cfg(target_has_atomic = "ptr")]
9type TransferStack<T> = cordyceps::TransferStack<T>; 9type TransferStack<T> = cordyceps::TransferStack<T>;
diff --git a/embassy-executor/src/raw/state_atomics_arm.rs b/embassy-executor/src/raw/state_atomics_arm.rs
index b743dcc2c..f68de955f 100644
--- a/embassy-executor/src/raw/state_atomics_arm.rs
+++ b/embassy-executor/src/raw/state_atomics_arm.rs
@@ -1,4 +1,4 @@
1use core::sync::atomic::{compiler_fence, AtomicBool, AtomicU32, Ordering}; 1use core::sync::atomic::{AtomicBool, AtomicU32, Ordering, compiler_fence};
2 2
3#[derive(Clone, Copy)] 3#[derive(Clone, Copy)]
4pub(crate) struct Token(()); 4pub(crate) struct Token(());
diff --git a/embassy-executor/src/raw/state_critical_section.rs b/embassy-executor/src/raw/state_critical_section.rs
index b69a6ac66..8d7ef2892 100644
--- a/embassy-executor/src/raw/state_critical_section.rs
+++ b/embassy-executor/src/raw/state_critical_section.rs
@@ -1,7 +1,7 @@
1use core::cell::Cell; 1use core::cell::Cell;
2 2
3pub(crate) use critical_section::{with as locked, CriticalSection as Token};
4use critical_section::{CriticalSection, Mutex}; 3use critical_section::{CriticalSection, Mutex};
4pub(crate) use critical_section::{CriticalSection as Token, with as locked};
5 5
6#[cfg(target_arch = "avr")] 6#[cfg(target_arch = "avr")]
7type StateBits = u8; 7type StateBits = u8;
diff --git a/embassy-executor/src/raw/trace.rs b/embassy-executor/src/raw/trace.rs
index b3086948c..830162039 100644
--- a/embassy-executor/src/raw/trace.rs
+++ b/embassy-executor/src/raw/trace.rs
@@ -169,7 +169,7 @@ impl TaskTracker {
169} 169}
170 170
171#[cfg(feature = "trace")] 171#[cfg(feature = "trace")]
172extern "Rust" { 172unsafe extern "Rust" {
173 /// This callback is called when the executor begins polling. This will always 173 /// This callback is called when the executor begins polling. This will always
174 /// be paired with a later call to `_embassy_trace_executor_idle`. 174 /// be paired with a later call to `_embassy_trace_executor_idle`.
175 /// 175 ///
@@ -368,11 +368,7 @@ impl rtos_trace::RtosTraceOSCallbacks for crate::raw::SyncExecutor {
368 } 368 }
369 fn time() -> u64 { 369 fn time() -> u64 {
370 const fn gcd(a: u64, b: u64) -> u64 { 370 const fn gcd(a: u64, b: u64) -> u64 {
371 if b == 0 { 371 if b == 0 { a } else { gcd(b, a % b) }
372 a
373 } else {
374 gcd(b, a % b)
375 }
376 } 372 }
377 373
378 const GCD_1M: u64 = gcd(embassy_time_driver::TICK_HZ, 1_000_000); 374 const GCD_1M: u64 = gcd(embassy_time_driver::TICK_HZ, 1_000_000);
diff --git a/embassy-executor/src/raw/waker.rs b/embassy-executor/src/raw/waker.rs
index d0d7b003d..2706f0fdf 100644
--- a/embassy-executor/src/raw/waker.rs
+++ b/embassy-executor/src/raw/waker.rs
@@ -1,6 +1,6 @@
1use core::task::{RawWaker, RawWakerVTable, Waker}; 1use core::task::{RawWaker, RawWakerVTable, Waker};
2 2
3use super::{wake_task, TaskHeader, TaskRef}; 3use super::{TaskHeader, TaskRef, wake_task};
4 4
5static VTABLE: RawWakerVTable = RawWakerVTable::new(clone, wake, wake, drop); 5static VTABLE: RawWakerVTable = RawWakerVTable::new(clone, wake, wake, drop);
6 6
@@ -35,7 +35,9 @@ pub fn task_from_waker(waker: &Waker) -> TaskRef {
35 // make sure to compare vtable addresses. Doing `==` on the references 35 // make sure to compare vtable addresses. Doing `==` on the references
36 // will compare the contents, which is slower. 36 // will compare the contents, which is slower.
37 if waker.vtable() as *const _ != &VTABLE as *const _ { 37 if waker.vtable() as *const _ != &VTABLE as *const _ {
38 panic!("Found waker not created by the Embassy executor. `embassy_time::Timer` only works with the Embassy executor.") 38 panic!(
39 "Found waker not created by the Embassy executor. `embassy_time::Timer` only works with the Embassy executor."
40 )
39 } 41 }
40 // safety: our wakers are always created with `TaskRef::as_ptr` 42 // safety: our wakers are always created with `TaskRef::as_ptr`
41 unsafe { TaskRef::from_ptr(waker.data() as *const TaskHeader) } 43 unsafe { TaskRef::from_ptr(waker.data() as *const TaskHeader) }
diff --git a/embassy-executor/src/raw/waker_turbo.rs b/embassy-executor/src/raw/waker_turbo.rs
index 435a0ff7e..919bcc61a 100644
--- a/embassy-executor/src/raw/waker_turbo.rs
+++ b/embassy-executor/src/raw/waker_turbo.rs
@@ -1,7 +1,7 @@
1use core::ptr::NonNull; 1use core::ptr::NonNull;
2use core::task::Waker; 2use core::task::Waker;
3 3
4use super::{wake_task, TaskHeader, TaskRef}; 4use super::{TaskHeader, TaskRef, wake_task};
5 5
6pub(crate) unsafe fn from_task(p: TaskRef) -> Waker { 6pub(crate) unsafe fn from_task(p: TaskRef) -> Waker {
7 Waker::from_turbo_ptr(NonNull::new_unchecked(p.as_ptr() as _)) 7 Waker::from_turbo_ptr(NonNull::new_unchecked(p.as_ptr() as _))
@@ -26,7 +26,7 @@ pub fn task_from_waker(waker: &Waker) -> TaskRef {
26} 26}
27 27
28#[inline(never)] 28#[inline(never)]
29#[no_mangle] 29#[unsafe(no_mangle)]
30fn _turbo_wake(ptr: NonNull<()>) { 30fn _turbo_wake(ptr: NonNull<()>) {
31 // safety: our wakers are always created with `TaskRef::as_ptr` 31 // safety: our wakers are always created with `TaskRef::as_ptr`
32 let task = unsafe { TaskRef::from_ptr(ptr.as_ptr() as *const TaskHeader) }; 32 let task = unsafe { TaskRef::from_ptr(ptr.as_ptr() as *const TaskHeader) };
diff --git a/embassy-executor/src/spawner.rs b/embassy-executor/src/spawner.rs
index 83d896b76..b73a1e7c6 100644
--- a/embassy-executor/src/spawner.rs
+++ b/embassy-executor/src/spawner.rs
@@ -1,4 +1,4 @@
1use core::future::{poll_fn, Future}; 1use core::future::{Future, poll_fn};
2use core::marker::PhantomData; 2use core::marker::PhantomData;
3use core::mem; 3use core::mem;
4use core::sync::atomic::Ordering; 4use core::sync::atomic::Ordering;
@@ -75,7 +75,10 @@ impl core::fmt::Debug for SpawnError {
75impl core::fmt::Display for SpawnError { 75impl core::fmt::Display for SpawnError {
76 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 76 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
77 match self { 77 match self {
78 SpawnError::Busy => write!(f, "Busy - Too many instances of this task are already running. Check the `pool_size` attribute of the task."), 78 SpawnError::Busy => write!(
79 f,
80 "Busy - Too many instances of this task are already running. Check the `pool_size` attribute of the task."
81 ),
79 } 82 }
80 } 83 }
81} 84}
@@ -84,7 +87,10 @@ impl core::fmt::Display for SpawnError {
84impl defmt::Format for SpawnError { 87impl defmt::Format for SpawnError {
85 fn format(&self, f: defmt::Formatter) { 88 fn format(&self, f: defmt::Formatter) {
86 match self { 89 match self {
87 SpawnError::Busy => defmt::write!(f, "Busy - Too many instances of this task are already running. Check the `pool_size` attribute of the task."), 90 SpawnError::Busy => defmt::write!(
91 f,
92 "Busy - Too many instances of this task are already running. Check the `pool_size` attribute of the task."
93 ),
88 } 94 }
89 } 95 }
90} 96}