aboutsummaryrefslogtreecommitdiff
path: root/embassy-executor
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-executor')
-rw-r--r--embassy-executor/CHANGELOG.md4
-rw-r--r--embassy-executor/Cargo.toml100
-rw-r--r--embassy-executor/README.md2
-rw-r--r--embassy-executor/gen_config.py6
-rw-r--r--embassy-executor/src/arch/avr.rs72
-rw-r--r--embassy-executor/src/arch/riscv32.rs2
-rw-r--r--embassy-executor/src/fmt.rs3
-rw-r--r--embassy-executor/src/lib.rs6
-rw-r--r--embassy-executor/src/raw/mod.rs39
-rw-r--r--embassy-executor/src/raw/timer_queue.rs12
-rw-r--r--embassy-executor/tests/test.rs16
11 files changed, 218 insertions, 44 deletions
diff --git a/embassy-executor/CHANGELOG.md b/embassy-executor/CHANGELOG.md
index 5c6749230..77c64fd8e 100644
--- a/embassy-executor/CHANGELOG.md
+++ b/embassy-executor/CHANGELOG.md
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7 7
8## Unreleased 8## Unreleased
9 9
10## 0.5.0 - 2024-01-11
11
12- Updated to `embassy-time-driver 0.1`, `embassy-time-queue-driver 0.1`, compatible with `embassy-time v0.3` and higher.
13
10## 0.4.0 - 2023-12-05 14## 0.4.0 - 2023-12-05
11 15
12- Removed `arch-xtensa`. Use the executor provided by the HAL crate (`esp-hal`, `esp32s3-hal`, etc...) instead. 16- Removed `arch-xtensa`. Use the executor provided by the HAL crate (`esp-hal`, `esp32s3-hal`, etc...) instead.
diff --git a/embassy-executor/Cargo.toml b/embassy-executor/Cargo.toml
index ec5aca46d..431165cee 100644
--- a/embassy-executor/Cargo.toml
+++ b/embassy-executor/Cargo.toml
@@ -1,10 +1,11 @@
1[package] 1[package]
2name = "embassy-executor" 2name = "embassy-executor"
3version = "0.4.0" 3version = "0.5.0"
4edition = "2021" 4edition = "2021"
5license = "MIT OR Apache-2.0" 5license = "MIT OR Apache-2.0"
6description = "async/await executor designed for embedded usage" 6description = "async/await executor designed for embedded usage"
7repository = "https://github.com/embassy-rs/embassy" 7repository = "https://github.com/embassy-rs/embassy"
8documentation = "https://docs.embassy.dev/embassy-executor"
8categories = [ 9categories = [
9 "embedded", 10 "embedded",
10 "no-std", 11 "no-std",
@@ -14,7 +15,7 @@ categories = [
14[package.metadata.embassy_docs] 15[package.metadata.embassy_docs]
15src_base = "https://github.com/embassy-rs/embassy/blob/embassy-executor-v$VERSION/embassy-executor/src/" 16src_base = "https://github.com/embassy-rs/embassy/blob/embassy-executor-v$VERSION/embassy-executor/src/"
16src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-executor/src/" 17src_base_git = "https://github.com/embassy-rs/embassy/blob/$COMMIT/embassy-executor/src/"
17features = ["nightly", "defmt"] 18features = ["defmt"]
18flavors = [ 19flavors = [
19 { name = "std", target = "x86_64-unknown-linux-gnu", features = ["arch-std", "executor-thread"] }, 20 { name = "std", target = "x86_64-unknown-linux-gnu", features = ["arch-std", "executor-thread"] },
20 { name = "wasm", target = "wasm32-unknown-unknown", features = ["arch-wasm", "executor-thread"] }, 21 { name = "wasm", target = "wasm32-unknown-unknown", features = ["arch-wasm", "executor-thread"] },
@@ -25,7 +26,7 @@ flavors = [
25[package.metadata.docs.rs] 26[package.metadata.docs.rs]
26default-target = "thumbv7em-none-eabi" 27default-target = "thumbv7em-none-eabi"
27targets = ["thumbv7em-none-eabi"] 28targets = ["thumbv7em-none-eabi"]
28features = ["nightly", "defmt", "arch-cortex-m", "executor-thread", "executor-interrupt"] 29features = ["defmt", "arch-cortex-m", "executor-thread", "executor-interrupt"]
29 30
30[dependencies] 31[dependencies]
31defmt = { version = "0.3", optional = true } 32defmt = { version = "0.3", optional = true }
@@ -33,11 +34,13 @@ log = { version = "0.4.14", optional = true }
33rtos-trace = { version = "0.1.2", optional = true } 34rtos-trace = { version = "0.1.2", optional = true }
34 35
35embassy-executor-macros = { version = "0.4.0", path = "../embassy-executor-macros" } 36embassy-executor-macros = { version = "0.4.0", path = "../embassy-executor-macros" }
36embassy-time = { version = "0.2", path = "../embassy-time", optional = true} 37embassy-time-driver = { version = "0.1.0", path = "../embassy-time-driver", optional = true }
38embassy-time-queue-driver = { version = "0.1.0", path = "../embassy-time-queue-driver", optional = true }
37critical-section = "1.1" 39critical-section = "1.1"
38 40
39# needed for riscv 41document-features = "0.2.7"
40# remove when https://github.com/rust-lang/rust/pull/114499 is merged 42
43# needed for AVR
41portable-atomic = { version = "1.5", optional = true } 44portable-atomic = { version = "1.5", optional = true }
42 45
43# arch-cortex-m dependencies 46# arch-cortex-m dependencies
@@ -47,72 +50,137 @@ cortex-m = { version = "0.7.6", optional = true }
47wasm-bindgen = { version = "0.2.82", optional = true } 50wasm-bindgen = { version = "0.2.82", optional = true }
48js-sys = { version = "0.3", optional = true } 51js-sys = { version = "0.3", optional = true }
49 52
53# arch-avr dependencies
54avr-device = { version = "0.5.3", optional = true }
55
50[dev-dependencies] 56[dev-dependencies]
51critical-section = { version = "1.1", features = ["std"] } 57critical-section = { version = "1.1", features = ["std"] }
52 58
53 59
54[features] 60[features]
55 61
56# Architecture 62## Enable nightly-only features
63nightly = ["embassy-executor-macros/nightly"]
64
65# Enables turbo wakers, which requires patching core. Not surfaced in the docs by default due to
66# being an complicated advanced and undocumented feature.
67# See: https://github.com/embassy-rs/embassy/pull/1263
68turbowakers = []
69
70## Use the executor-integrated `embassy-time` timer queue.
71integrated-timers = ["dep:embassy-time-driver", "dep:embassy-time-queue-driver"]
72
73#! ### Architecture
57_arch = [] # some arch was picked 74_arch = [] # some arch was picked
75## std
58arch-std = ["_arch", "critical-section/std"] 76arch-std = ["_arch", "critical-section/std"]
77## Cortex-M
59arch-cortex-m = ["_arch", "dep:cortex-m"] 78arch-cortex-m = ["_arch", "dep:cortex-m"]
60arch-riscv32 = ["_arch", "dep:portable-atomic"] 79## RISC-V 32
80arch-riscv32 = ["_arch"]
81## WASM
61arch-wasm = ["_arch", "dep:wasm-bindgen", "dep:js-sys"] 82arch-wasm = ["_arch", "dep:wasm-bindgen", "dep:js-sys"]
83## AVR
84arch-avr = ["_arch", "dep:portable-atomic", "dep:avr-device"]
62 85
63# Enable the thread-mode executor (using WFE/SEV in Cortex-M, WFI in other embedded archs) 86#! ### Executor
87
88## Enable the thread-mode executor (using WFE/SEV in Cortex-M, WFI in other embedded archs)
64executor-thread = [] 89executor-thread = []
65# Enable the interrupt-mode executor (available in Cortex-M only) 90## Enable the interrupt-mode executor (available in Cortex-M only)
66executor-interrupt = [] 91executor-interrupt = []
67 92
68# Enable nightly-only features 93#! ### Task Arena Size
69nightly = ["embassy-executor-macros/nightly"] 94#! Sets the [task arena](#task-arena) size. Necessary if you’re not using `nightly`.
70 95#!
71turbowakers = [] 96#! <details>
72 97#! <summary>Preconfigured Task Arena Sizes:</summary>
73integrated-timers = ["dep:embassy-time"] 98#! <!-- rustdoc requires the following blank line for the feature list to render correctly! -->
99#!
74 100
75# BEGIN AUTOGENERATED CONFIG FEATURES 101# BEGIN AUTOGENERATED CONFIG FEATURES
76# Generated by gen_config.py. DO NOT EDIT. 102# Generated by gen_config.py. DO NOT EDIT.
103## 64
77task-arena-size-64 = [] 104task-arena-size-64 = []
105## 128
78task-arena-size-128 = [] 106task-arena-size-128 = []
107## 192
79task-arena-size-192 = [] 108task-arena-size-192 = []
109## 256
80task-arena-size-256 = [] 110task-arena-size-256 = []
111## 320
81task-arena-size-320 = [] 112task-arena-size-320 = []
113## 384
82task-arena-size-384 = [] 114task-arena-size-384 = []
115## 512
83task-arena-size-512 = [] 116task-arena-size-512 = []
117## 640
84task-arena-size-640 = [] 118task-arena-size-640 = []
119## 768
85task-arena-size-768 = [] 120task-arena-size-768 = []
121## 1024
86task-arena-size-1024 = [] 122task-arena-size-1024 = []
123## 1280
87task-arena-size-1280 = [] 124task-arena-size-1280 = []
125## 1536
88task-arena-size-1536 = [] 126task-arena-size-1536 = []
127## 2048
89task-arena-size-2048 = [] 128task-arena-size-2048 = []
129## 2560
90task-arena-size-2560 = [] 130task-arena-size-2560 = []
131## 3072
91task-arena-size-3072 = [] 132task-arena-size-3072 = []
133## 4096 (default)
92task-arena-size-4096 = [] # Default 134task-arena-size-4096 = [] # Default
135## 5120
93task-arena-size-5120 = [] 136task-arena-size-5120 = []
137## 6144
94task-arena-size-6144 = [] 138task-arena-size-6144 = []
139## 8192
95task-arena-size-8192 = [] 140task-arena-size-8192 = []
141## 10240
96task-arena-size-10240 = [] 142task-arena-size-10240 = []
143## 12288
97task-arena-size-12288 = [] 144task-arena-size-12288 = []
145## 16384
98task-arena-size-16384 = [] 146task-arena-size-16384 = []
147## 20480
99task-arena-size-20480 = [] 148task-arena-size-20480 = []
149## 24576
100task-arena-size-24576 = [] 150task-arena-size-24576 = []
151## 32768
101task-arena-size-32768 = [] 152task-arena-size-32768 = []
153## 40960
102task-arena-size-40960 = [] 154task-arena-size-40960 = []
155## 49152
103task-arena-size-49152 = [] 156task-arena-size-49152 = []
157## 65536
104task-arena-size-65536 = [] 158task-arena-size-65536 = []
159## 81920
105task-arena-size-81920 = [] 160task-arena-size-81920 = []
161## 98304
106task-arena-size-98304 = [] 162task-arena-size-98304 = []
163## 131072
107task-arena-size-131072 = [] 164task-arena-size-131072 = []
165## 163840
108task-arena-size-163840 = [] 166task-arena-size-163840 = []
167## 196608
109task-arena-size-196608 = [] 168task-arena-size-196608 = []
169## 262144
110task-arena-size-262144 = [] 170task-arena-size-262144 = []
171## 327680
111task-arena-size-327680 = [] 172task-arena-size-327680 = []
173## 393216
112task-arena-size-393216 = [] 174task-arena-size-393216 = []
175## 524288
113task-arena-size-524288 = [] 176task-arena-size-524288 = []
177## 655360
114task-arena-size-655360 = [] 178task-arena-size-655360 = []
179## 786432
115task-arena-size-786432 = [] 180task-arena-size-786432 = []
181## 1048576
116task-arena-size-1048576 = [] 182task-arena-size-1048576 = []
117 183
118# END AUTOGENERATED CONFIG FEATURES 184# END AUTOGENERATED CONFIG FEATURES
185
186#! </details>
diff --git a/embassy-executor/README.md b/embassy-executor/README.md
index 80ecfc71a..aa9d59907 100644
--- a/embassy-executor/README.md
+++ b/embassy-executor/README.md
@@ -22,7 +22,7 @@ Tasks are allocated from the arena when spawned for the first time. If the task
22The arena size can be configured in two ways: 22The arena size can be configured in two ways:
23 23
24- Via Cargo features: enable a Cargo feature like `task-arena-size-8192`. Only a selection of values 24- Via Cargo features: enable a Cargo feature like `task-arena-size-8192`. Only a selection of values
25 is available, check `Cargo.toml` for the list. 25 is available, see [Task Area Sizes](#task-arena-size) for reference.
26- Via environment variables at build time: set the variable named `EMBASSY_EXECUTOR_TASK_ARENA_SIZE`. For example 26- Via environment variables at build time: set the variable named `EMBASSY_EXECUTOR_TASK_ARENA_SIZE`. For example
27 `EMBASSY_EXECUTOR_TASK_ARENA_SIZE=4321 cargo build`. You can also set them in the `[env]` section of `.cargo/config.toml`. 27 `EMBASSY_EXECUTOR_TASK_ARENA_SIZE=4321 cargo build`. You can also set them in the `[env]` section of `.cargo/config.toml`.
28 Any value can be set, unlike with Cargo features. 28 Any value can be set, unlike with Cargo features.
diff --git a/embassy-executor/gen_config.py b/embassy-executor/gen_config.py
index e427d29f4..cf32bd530 100644
--- a/embassy-executor/gen_config.py
+++ b/embassy-executor/gen_config.py
@@ -45,6 +45,12 @@ things = ""
45for f in features: 45for f in features:
46 name = f["name"].replace("_", "-") 46 name = f["name"].replace("_", "-")
47 for val in f["vals"]: 47 for val in f["vals"]:
48 things += f"## {val}"
49 if val == f["default"]:
50 things += " (default)\n"
51 else:
52 things += "\n"
53
48 things += f"{name}-{val} = []" 54 things += f"{name}-{val} = []"
49 if val == f["default"]: 55 if val == f["default"]:
50 things += " # Default" 56 things += " # Default"
diff --git a/embassy-executor/src/arch/avr.rs b/embassy-executor/src/arch/avr.rs
new file mode 100644
index 000000000..70085d04d
--- /dev/null
+++ b/embassy-executor/src/arch/avr.rs
@@ -0,0 +1,72 @@
1#[cfg(feature = "executor-interrupt")]
2compile_error!("`executor-interrupt` is not supported with `arch-avr`.");
3
4#[cfg(feature = "executor-thread")]
5pub use thread::*;
6#[cfg(feature = "executor-thread")]
7mod thread {
8 use core::marker::PhantomData;
9
10 pub use embassy_executor_macros::main_avr as main;
11 use portable_atomic::{AtomicBool, Ordering};
12
13 use crate::{raw, Spawner};
14
15 static SIGNAL_WORK_THREAD_MODE: AtomicBool = AtomicBool::new(false);
16
17 #[export_name = "__pender"]
18 fn __pender(_context: *mut ()) {
19 SIGNAL_WORK_THREAD_MODE.store(true, Ordering::SeqCst);
20 }
21
22 /// avr Executor
23 pub struct Executor {
24 inner: raw::Executor,
25 not_send: PhantomData<*mut ()>,
26 }
27
28 impl Executor {
29 /// Create a new Executor.
30 pub fn new() -> Self {
31 Self {
32 inner: raw::Executor::new(core::ptr::null_mut()),
33 not_send: PhantomData,
34 }
35 }
36
37 /// Run the executor.
38 ///
39 /// The `init` closure is called with a [`Spawner`] that spawns tasks on
40 /// this executor. Use it to spawn the initial task(s). After `init` returns,
41 /// the executor starts running the tasks.
42 ///
43 /// To spawn more tasks later, you may keep copies of the [`Spawner`] (it is `Copy`),
44 /// for example by passing it as an argument to the initial tasks.
45 ///
46 /// This function requires `&'static mut self`. This means you have to store the
47 /// Executor instance in a place where it'll live forever and grants you mutable
48 /// access. There's a few ways to do this:
49 ///
50 /// - a [StaticCell](https://docs.rs/static_cell/latest/static_cell/) (safe)
51 /// - a `static mut` (unsafe)
52 /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe)
53 ///
54 /// This function never returns.
55 pub fn run(&'static mut self, init: impl FnOnce(Spawner)) -> ! {
56 init(self.inner.spawner());
57
58 loop {
59 unsafe {
60 avr_device::interrupt::disable();
61 if !SIGNAL_WORK_THREAD_MODE.swap(false, Ordering::SeqCst) {
62 avr_device::interrupt::enable();
63 avr_device::asm::sleep();
64 } else {
65 avr_device::interrupt::enable();
66 self.inner.poll();
67 }
68 }
69 }
70 }
71 }
72}
diff --git a/embassy-executor/src/arch/riscv32.rs b/embassy-executor/src/arch/riscv32.rs
index c56f502d3..01e63a9fd 100644
--- a/embassy-executor/src/arch/riscv32.rs
+++ b/embassy-executor/src/arch/riscv32.rs
@@ -6,9 +6,9 @@ pub use thread::*;
6#[cfg(feature = "executor-thread")] 6#[cfg(feature = "executor-thread")]
7mod thread { 7mod thread {
8 use core::marker::PhantomData; 8 use core::marker::PhantomData;
9 use core::sync::atomic::{AtomicBool, Ordering};
9 10
10 pub use embassy_executor_macros::main_riscv as main; 11 pub use embassy_executor_macros::main_riscv as main;
11 use portable_atomic::{AtomicBool, Ordering};
12 12
13 use crate::{raw, Spawner}; 13 use crate::{raw, Spawner};
14 14
diff --git a/embassy-executor/src/fmt.rs b/embassy-executor/src/fmt.rs
index 78e583c1c..2ac42c557 100644
--- a/embassy-executor/src/fmt.rs
+++ b/embassy-executor/src/fmt.rs
@@ -1,5 +1,5 @@
1#![macro_use] 1#![macro_use]
2#![allow(unused_macros)] 2#![allow(unused)]
3 3
4use core::fmt::{Debug, Display, LowerHex}; 4use core::fmt::{Debug, Display, LowerHex};
5 5
@@ -229,7 +229,6 @@ impl<T, E> Try for Result<T, E> {
229 } 229 }
230} 230}
231 231
232#[allow(unused)]
233pub(crate) struct Bytes<'a>(pub &'a [u8]); 232pub(crate) struct Bytes<'a>(pub &'a [u8]);
234 233
235impl<'a> Debug for Bytes<'a> { 234impl<'a> Debug for Bytes<'a> {
diff --git a/embassy-executor/src/lib.rs b/embassy-executor/src/lib.rs
index 4c6900a6d..6a2e493a2 100644
--- a/embassy-executor/src/lib.rs
+++ b/embassy-executor/src/lib.rs
@@ -3,6 +3,9 @@
3#![doc = include_str!("../README.md")] 3#![doc = include_str!("../README.md")]
4#![warn(missing_docs)] 4#![warn(missing_docs)]
5 5
6//! ## Feature flags
7#![doc = document_features::document_features!(feature_label = r#"<span class="stab portability"><code>{feature}</code></span>"#)]
8
6// This mod MUST go first, so that the others see its macros. 9// This mod MUST go first, so that the others see its macros.
7pub(crate) mod fmt; 10pub(crate) mod fmt;
8 11
@@ -20,9 +23,10 @@ macro_rules! check_at_most_one {
20 check_at_most_one!(@amo [$($f)*] [$($f)*] []); 23 check_at_most_one!(@amo [$($f)*] [$($f)*] []);
21 }; 24 };
22} 25}
23check_at_most_one!("arch-cortex-m", "arch-riscv32", "arch-std", "arch-wasm",); 26check_at_most_one!("arch-avr", "arch-cortex-m", "arch-riscv32", "arch-std", "arch-wasm",);
24 27
25#[cfg(feature = "_arch")] 28#[cfg(feature = "_arch")]
29#[cfg_attr(feature = "arch-avr", path = "arch/avr.rs")]
26#[cfg_attr(feature = "arch-cortex-m", path = "arch/cortex_m.rs")] 30#[cfg_attr(feature = "arch-cortex-m", path = "arch/cortex_m.rs")]
27#[cfg_attr(feature = "arch-riscv32", path = "arch/riscv32.rs")] 31#[cfg_attr(feature = "arch-riscv32", path = "arch/riscv32.rs")]
28#[cfg_attr(feature = "arch-std", path = "arch/std.rs")] 32#[cfg_attr(feature = "arch-std", path = "arch/std.rs")]
diff --git a/embassy-executor/src/raw/mod.rs b/embassy-executor/src/raw/mod.rs
index b16a1c7c3..d9ea5c005 100644
--- a/embassy-executor/src/raw/mod.rs
+++ b/embassy-executor/src/raw/mod.rs
@@ -30,9 +30,7 @@ use core::ptr::NonNull;
30use core::task::{Context, Poll}; 30use core::task::{Context, Poll};
31 31
32#[cfg(feature = "integrated-timers")] 32#[cfg(feature = "integrated-timers")]
33use embassy_time::driver::{self, AlarmHandle}; 33use embassy_time_driver::AlarmHandle;
34#[cfg(feature = "integrated-timers")]
35use embassy_time::Instant;
36#[cfg(feature = "rtos-trace")] 34#[cfg(feature = "rtos-trace")]
37use rtos_trace::trace; 35use rtos_trace::trace;
38 36
@@ -50,7 +48,7 @@ pub(crate) struct TaskHeader {
50 poll_fn: SyncUnsafeCell<Option<unsafe fn(TaskRef)>>, 48 poll_fn: SyncUnsafeCell<Option<unsafe fn(TaskRef)>>,
51 49
52 #[cfg(feature = "integrated-timers")] 50 #[cfg(feature = "integrated-timers")]
53 pub(crate) expires_at: SyncUnsafeCell<Instant>, 51 pub(crate) expires_at: SyncUnsafeCell<u64>,
54 #[cfg(feature = "integrated-timers")] 52 #[cfg(feature = "integrated-timers")]
55 pub(crate) timer_queue_item: timer_queue::TimerQueueItem, 53 pub(crate) timer_queue_item: timer_queue::TimerQueueItem,
56} 54}
@@ -123,7 +121,7 @@ impl<F: Future + 'static> TaskStorage<F> {
123 poll_fn: SyncUnsafeCell::new(None), 121 poll_fn: SyncUnsafeCell::new(None),
124 122
125 #[cfg(feature = "integrated-timers")] 123 #[cfg(feature = "integrated-timers")]
126 expires_at: SyncUnsafeCell::new(Instant::from_ticks(0)), 124 expires_at: SyncUnsafeCell::new(0),
127 #[cfg(feature = "integrated-timers")] 125 #[cfg(feature = "integrated-timers")]
128 timer_queue_item: timer_queue::TimerQueueItem::new(), 126 timer_queue_item: timer_queue::TimerQueueItem::new(),
129 }, 127 },
@@ -164,7 +162,7 @@ impl<F: Future + 'static> TaskStorage<F> {
164 this.raw.state.despawn(); 162 this.raw.state.despawn();
165 163
166 #[cfg(feature = "integrated-timers")] 164 #[cfg(feature = "integrated-timers")]
167 this.raw.expires_at.set(Instant::MAX); 165 this.raw.expires_at.set(u64::MAX);
168 } 166 }
169 Poll::Pending => {} 167 Poll::Pending => {}
170 } 168 }
@@ -328,7 +326,7 @@ pub(crate) struct SyncExecutor {
328impl SyncExecutor { 326impl SyncExecutor {
329 pub(crate) fn new(pender: Pender) -> Self { 327 pub(crate) fn new(pender: Pender) -> Self {
330 #[cfg(feature = "integrated-timers")] 328 #[cfg(feature = "integrated-timers")]
331 let alarm = unsafe { unwrap!(driver::allocate_alarm()) }; 329 let alarm = unsafe { unwrap!(embassy_time_driver::allocate_alarm()) };
332 330
333 Self { 331 Self {
334 run_queue: RunQueue::new(), 332 run_queue: RunQueue::new(),
@@ -377,18 +375,19 @@ impl SyncExecutor {
377 /// Same as [`Executor::poll`], plus you must only call this on the thread this executor was created. 375 /// Same as [`Executor::poll`], plus you must only call this on the thread this executor was created.
378 pub(crate) unsafe fn poll(&'static self) { 376 pub(crate) unsafe fn poll(&'static self) {
379 #[cfg(feature = "integrated-timers")] 377 #[cfg(feature = "integrated-timers")]
380 driver::set_alarm_callback(self.alarm, Self::alarm_callback, self as *const _ as *mut ()); 378 embassy_time_driver::set_alarm_callback(self.alarm, Self::alarm_callback, self as *const _ as *mut ());
381 379
382 #[allow(clippy::never_loop)] 380 #[allow(clippy::never_loop)]
383 loop { 381 loop {
384 #[cfg(feature = "integrated-timers")] 382 #[cfg(feature = "integrated-timers")]
385 self.timer_queue.dequeue_expired(Instant::now(), wake_task_no_pend); 383 self.timer_queue
384 .dequeue_expired(embassy_time_driver::now(), wake_task_no_pend);
386 385
387 self.run_queue.dequeue_all(|p| { 386 self.run_queue.dequeue_all(|p| {
388 let task = p.header(); 387 let task = p.header();
389 388
390 #[cfg(feature = "integrated-timers")] 389 #[cfg(feature = "integrated-timers")]
391 task.expires_at.set(Instant::MAX); 390 task.expires_at.set(u64::MAX);
392 391
393 if !task.state.run_dequeue() { 392 if !task.state.run_dequeue() {
394 // If task is not running, ignore it. This can happen in the following scenario: 393 // If task is not running, ignore it. This can happen in the following scenario:
@@ -418,7 +417,7 @@ impl SyncExecutor {
418 // If this is already in the past, set_alarm might return false 417 // If this is already in the past, set_alarm might return false
419 // In that case do another poll loop iteration. 418 // In that case do another poll loop iteration.
420 let next_expiration = self.timer_queue.next_expiration(); 419 let next_expiration = self.timer_queue.next_expiration();
421 if driver::set_alarm(self.alarm, next_expiration.as_ticks()) { 420 if embassy_time_driver::set_alarm(self.alarm, next_expiration) {
422 break; 421 break;
423 } 422 }
424 } 423 }
@@ -568,8 +567,8 @@ pub fn wake_task_no_pend(task: TaskRef) {
568struct TimerQueue; 567struct TimerQueue;
569 568
570#[cfg(feature = "integrated-timers")] 569#[cfg(feature = "integrated-timers")]
571impl embassy_time::queue::TimerQueue for TimerQueue { 570impl embassy_time_queue_driver::TimerQueue for TimerQueue {
572 fn schedule_wake(&'static self, at: Instant, waker: &core::task::Waker) { 571 fn schedule_wake(&'static self, at: u64, waker: &core::task::Waker) {
573 let task = waker::task_from_waker(waker); 572 let task = waker::task_from_waker(waker);
574 let task = task.header(); 573 let task = task.header();
575 unsafe { 574 unsafe {
@@ -580,7 +579,16 @@ impl embassy_time::queue::TimerQueue for TimerQueue {
580} 579}
581 580
582#[cfg(feature = "integrated-timers")] 581#[cfg(feature = "integrated-timers")]
583embassy_time::timer_queue_impl!(static TIMER_QUEUE: TimerQueue = TimerQueue); 582embassy_time_queue_driver::timer_queue_impl!(static TIMER_QUEUE: TimerQueue = TimerQueue);
583
584#[cfg(all(feature = "rtos-trace", feature = "integrated-timers"))]
585const fn gcd(a: u64, b: u64) -> u64 {
586 if b == 0 {
587 a
588 } else {
589 gcd(b, a % b)
590 }
591}
584 592
585#[cfg(feature = "rtos-trace")] 593#[cfg(feature = "rtos-trace")]
586impl rtos_trace::RtosTraceOSCallbacks for Executor { 594impl rtos_trace::RtosTraceOSCallbacks for Executor {
@@ -589,7 +597,8 @@ impl rtos_trace::RtosTraceOSCallbacks for Executor {
589 } 597 }
590 #[cfg(feature = "integrated-timers")] 598 #[cfg(feature = "integrated-timers")]
591 fn time() -> u64 { 599 fn time() -> u64 {
592 Instant::now().as_micros() 600 const GCD_1M: u64 = gcd(embassy_time_driver::TICK_HZ, 1_000_000);
601 embassy_time_driver::now() * (1_000_000 / GCD_1M) / (embassy_time_driver::TICK_HZ / GCD_1M)
593 } 602 }
594 #[cfg(not(feature = "integrated-timers"))] 603 #[cfg(not(feature = "integrated-timers"))]
595 fn time() -> u64 { 604 fn time() -> u64 {
diff --git a/embassy-executor/src/raw/timer_queue.rs b/embassy-executor/src/raw/timer_queue.rs
index 59a3b43f5..94a5f340b 100644
--- a/embassy-executor/src/raw/timer_queue.rs
+++ b/embassy-executor/src/raw/timer_queue.rs
@@ -1,7 +1,5 @@
1use core::cmp::min; 1use core::cmp::min;
2 2
3use embassy_time::Instant;
4
5use super::TaskRef; 3use super::TaskRef;
6use crate::raw::util::SyncUnsafeCell; 4use crate::raw::util::SyncUnsafeCell;
7 5
@@ -30,7 +28,7 @@ impl TimerQueue {
30 28
31 pub(crate) unsafe fn update(&self, p: TaskRef) { 29 pub(crate) unsafe fn update(&self, p: TaskRef) {
32 let task = p.header(); 30 let task = p.header();
33 if task.expires_at.get() != Instant::MAX { 31 if task.expires_at.get() != u64::MAX {
34 if task.state.timer_enqueue() { 32 if task.state.timer_enqueue() {
35 task.timer_queue_item.next.set(self.head.get()); 33 task.timer_queue_item.next.set(self.head.get());
36 self.head.set(Some(p)); 34 self.head.set(Some(p));
@@ -38,18 +36,18 @@ impl TimerQueue {
38 } 36 }
39 } 37 }
40 38
41 pub(crate) unsafe fn next_expiration(&self) -> Instant { 39 pub(crate) unsafe fn next_expiration(&self) -> u64 {
42 let mut res = Instant::MAX; 40 let mut res = u64::MAX;
43 self.retain(|p| { 41 self.retain(|p| {
44 let task = p.header(); 42 let task = p.header();
45 let expires = task.expires_at.get(); 43 let expires = task.expires_at.get();
46 res = min(res, expires); 44 res = min(res, expires);
47 expires != Instant::MAX 45 expires != u64::MAX
48 }); 46 });
49 res 47 res
50 } 48 }
51 49
52 pub(crate) unsafe fn dequeue_expired(&self, now: Instant, on_task: impl Fn(TaskRef)) { 50 pub(crate) unsafe fn dequeue_expired(&self, now: u64, on_task: impl Fn(TaskRef)) {
53 self.retain(|p| { 51 self.retain(|p| {
54 let task = p.header(); 52 let task = p.header();
55 if task.expires_at.get() <= now { 53 if task.expires_at.get() <= now {
diff --git a/embassy-executor/tests/test.rs b/embassy-executor/tests/test.rs
index 0dbd391e8..348cc7dc4 100644
--- a/embassy-executor/tests/test.rs
+++ b/embassy-executor/tests/test.rs
@@ -1,4 +1,4 @@
1#![cfg_attr(feature = "nightly", feature(type_alias_impl_trait))] 1#![cfg_attr(feature = "nightly", feature(impl_trait_in_assoc_type))]
2 2
3use std::boxed::Box; 3use std::boxed::Box;
4use std::future::poll_fn; 4use std::future::poll_fn;
@@ -135,3 +135,17 @@ fn executor_task_self_wake_twice() {
135 ] 135 ]
136 ) 136 )
137} 137}
138
139#[test]
140fn executor_task_cfg_args() {
141 // simulate cfg'ing away argument c
142 #[task]
143 async fn task1(a: u32, b: u32, #[cfg(any())] c: u32) {
144 let (_, _) = (a, b);
145 }
146
147 #[task]
148 async fn task2(a: u32, b: u32, #[cfg(all())] c: u32) {
149 let (_, _, _) = (a, b, c);
150 }
151}