From b27feb061936d191f456edc22b2f89d4fc172520 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 25 Apr 2022 22:09:04 +0200 Subject: executor: fix unsoundness in InterruptExecutor::start. The initial closure is not actually called in the interrupt, so this is illegally sending non-Send futures to the interrupt. Remove the closure, and return a SendSpawner instead. --- examples/nrf/src/bin/multiprio.rs | 10 ++++------ examples/stm32f3/src/bin/multiprio.rs | 10 ++++------ examples/stm32f4/src/bin/multiprio.rs | 10 ++++------ 3 files changed, 12 insertions(+), 18 deletions(-) (limited to 'examples') diff --git a/examples/nrf/src/bin/multiprio.rs b/examples/nrf/src/bin/multiprio.rs index e69f87d85..54f6606a9 100644 --- a/examples/nrf/src/bin/multiprio.rs +++ b/examples/nrf/src/bin/multiprio.rs @@ -124,17 +124,15 @@ fn main() -> ! { let irq = interrupt::take!(SWI1_EGU1); irq.set_priority(interrupt::Priority::P6); let executor = EXECUTOR_HIGH.put(InterruptExecutor::new(irq)); - executor.start(|spawner| { - unwrap!(spawner.spawn(run_high())); - }); + let spawner = executor.start(); + unwrap!(spawner.spawn(run_high())); // Medium-priority executor: SWI0_EGU0, priority level 7 let irq = interrupt::take!(SWI0_EGU0); irq.set_priority(interrupt::Priority::P7); let executor = EXECUTOR_MED.put(InterruptExecutor::new(irq)); - executor.start(|spawner| { - unwrap!(spawner.spawn(run_med())); - }); + let spawner = executor.start(); + unwrap!(spawner.spawn(run_med())); // Low priority executor: runs in thread mode, using WFE/SEV let executor = EXECUTOR_LOW.put(Executor::new()); diff --git a/examples/stm32f3/src/bin/multiprio.rs b/examples/stm32f3/src/bin/multiprio.rs index 1c9401549..02380de72 100644 --- a/examples/stm32f3/src/bin/multiprio.rs +++ b/examples/stm32f3/src/bin/multiprio.rs @@ -124,17 +124,15 @@ fn main() -> ! { let irq = interrupt::take!(UART4); irq.set_priority(interrupt::Priority::P6); let executor = EXECUTOR_HIGH.put(InterruptExecutor::new(irq)); - executor.start(|spawner| { - unwrap!(spawner.spawn(run_high())); - }); + let spawner = executor.start(); + unwrap!(spawner.spawn(run_high())); // Medium-priority executor: SWI0_EGU0, priority level 7 let irq = interrupt::take!(UART5); irq.set_priority(interrupt::Priority::P7); let executor = EXECUTOR_MED.put(InterruptExecutor::new(irq)); - executor.start(|spawner| { - unwrap!(spawner.spawn(run_med())); - }); + let spawner = executor.start(); + unwrap!(spawner.spawn(run_med())); // Low priority executor: runs in thread mode, using WFE/SEV let executor = EXECUTOR_LOW.put(Executor::new()); diff --git a/examples/stm32f4/src/bin/multiprio.rs b/examples/stm32f4/src/bin/multiprio.rs index 1c9401549..02380de72 100644 --- a/examples/stm32f4/src/bin/multiprio.rs +++ b/examples/stm32f4/src/bin/multiprio.rs @@ -124,17 +124,15 @@ fn main() -> ! { let irq = interrupt::take!(UART4); irq.set_priority(interrupt::Priority::P6); let executor = EXECUTOR_HIGH.put(InterruptExecutor::new(irq)); - executor.start(|spawner| { - unwrap!(spawner.spawn(run_high())); - }); + let spawner = executor.start(); + unwrap!(spawner.spawn(run_high())); // Medium-priority executor: SWI0_EGU0, priority level 7 let irq = interrupt::take!(UART5); irq.set_priority(interrupt::Priority::P7); let executor = EXECUTOR_MED.put(InterruptExecutor::new(irq)); - executor.start(|spawner| { - unwrap!(spawner.spawn(run_med())); - }); + let spawner = executor.start(); + unwrap!(spawner.spawn(run_med())); // Low priority executor: runs in thread mode, using WFE/SEV let executor = EXECUTOR_LOW.put(Executor::new()); -- cgit From 2b0e8a330b0f2be7a8943a9e5acadf8fc7f92275 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Mon, 25 Apr 2022 22:19:40 +0200 Subject: examples/nrf: add self_spawn example. This serves as a compile-test of possible typecheck loops due to TAIT shenanigans. --- examples/nrf/src/bin/self_spawn.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 examples/nrf/src/bin/self_spawn.rs (limited to 'examples') diff --git a/examples/nrf/src/bin/self_spawn.rs b/examples/nrf/src/bin/self_spawn.rs new file mode 100644 index 000000000..35e73a8dd --- /dev/null +++ b/examples/nrf/src/bin/self_spawn.rs @@ -0,0 +1,24 @@ +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] + +use defmt::{info, unwrap}; +use embassy::executor::Spawner; +use embassy::time::{Duration, Timer}; +use embassy_nrf::Peripherals; + +use defmt_rtt as _; // global logger +use panic_probe as _; + +#[embassy::task(pool_size = 2)] +async fn my_task(spawner: Spawner, n: u32) { + Timer::after(Duration::from_secs(1)).await; + info!("Spawning self! {}", n); + unwrap!(spawner.spawn(my_task(spawner, n + 1))); +} + +#[embassy::main] +async fn main(spawner: Spawner, _p: Peripherals) { + info!("Hello World!"); + unwrap!(spawner.spawn(my_task(spawner, 0))); +} -- cgit