From 015b6bbce4fa93a58458bd72a5f7168d746f1e37 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Wed, 30 Dec 2020 00:56:32 +0100 Subject: Ensure timers always yield at least once. This prevents a task that's constantly running late from monopolizing the CPU. Add executor_fairness_test example showcasing it. --- examples/src/bin/executor_fairness_test.rs | 74 ++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 examples/src/bin/executor_fairness_test.rs (limited to 'examples/src') diff --git a/examples/src/bin/executor_fairness_test.rs b/examples/src/bin/executor_fairness_test.rs new file mode 100644 index 000000000..9b2c1bd26 --- /dev/null +++ b/examples/src/bin/executor_fairness_test.rs @@ -0,0 +1,74 @@ +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] + +#[path = "../example_common.rs"] +mod example_common; +use example_common::*; + +use core::task::Poll; +use cortex_m_rt::entry; +use defmt::panic; +use embassy::executor::{task, Executor}; +use embassy::time::{Duration, Instant, Timer}; +use embassy::util::Forever; +use embassy_nrf::pac; +use embassy_nrf::{interrupt, rtc}; +use nrf52840_hal::clocks; + +#[task] +async fn run1() { + loop { + info!("DING DONG"); + Timer::after(Duration::from_ticks(16000)).await; + } +} + +#[task] +async fn run2() { + loop { + Timer::at(Instant::from_ticks(0)).await; + } +} + +#[task] +async fn run3() { + futures::future::poll_fn(|cx| { + cx.waker().wake_by_ref(); + Poll::<()>::Pending + }) + .await; +} + +static RTC: Forever> = Forever::new(); +static ALARM: Forever> = Forever::new(); +static EXECUTOR: Forever = Forever::new(); + +#[entry] +fn main() -> ! { + info!("Hello World!"); + + let p = unwrap!(embassy_nrf::pac::Peripherals::take()); + + clocks::Clocks::new(p.CLOCK) + .enable_ext_hfosc() + .set_lfclk_src_external(clocks::LfOscConfiguration::NoExternalNoBypass) + .start_lfclk(); + + let rtc = RTC.put(rtc::RTC::new(p.RTC1, interrupt::take!(RTC1))); + rtc.start(); + + unsafe { embassy::time::set_clock(rtc) }; + + let alarm = ALARM.put(rtc.alarm0()); + let executor = EXECUTOR.put(Executor::new_with_alarm(alarm, cortex_m::asm::sev)); + + unwrap!(executor.spawn(run1())); + unwrap!(executor.spawn(run2())); + unwrap!(executor.spawn(run3())); + + loop { + executor.run(); + cortex_m::asm::wfe(); + } +} -- cgit