diff options
Diffstat (limited to 'examples/async-task.rs')
-rw-r--r-- | examples/async-task.rs | 168 |
1 files changed, 12 insertions, 156 deletions
diff --git a/examples/async-task.rs b/examples/async-task.rs index a91dfc67..00fe581c 100644 --- a/examples/async-task.rs +++ b/examples/async-task.rs @@ -2,10 +2,6 @@ #![no_std] #![feature(type_alias_impl_trait)] -use core::future::Future; -use core::pin::Pin; -use core::task::{Context, Poll, Waker}; - use cortex_m_semihosting::{debug, hprintln}; use panic_semihosting as _; use systick_monotonic::*; @@ -25,9 +21,7 @@ mod app { pub type AppDuration = <Systick<100> as rtic::Monotonic>::Duration; #[shared] - struct Shared { - s: u32, - } + struct Shared {} #[local] struct Local {} @@ -39,8 +33,11 @@ mod app { fn init(cx: init::Context) -> (Shared, Local, init::Monotonics) { hprintln!("init").unwrap(); + normal_task::spawn().ok(); + async_task::spawn().ok(); + ( - Shared { s: 0 }, + Shared {}, Local {}, init::Monotonics(Systick::new(cx.core.SYST, 12_000_000)), ) @@ -55,156 +52,15 @@ mod app { } } - #[task(priority = 2)] - async fn task(cx: task::Context) { - hprintln!("delay long time").ok(); - - let fut = Delay::spawn(2500.millis()); - - hprintln!("we have just created the future").ok(); - fut.await; - hprintln!("long delay done").ok(); - - hprintln!("delay short time").ok(); - delay(500.millis()).await; - hprintln!("short delay done").ok(); - - hprintln!("test timeout").ok(); - let res = timeout(NeverEndingFuture {}, 1.secs()).await; - hprintln!("timeout done: {:?}", res).ok(); - - hprintln!("test timeout 2").ok(); - let res = timeout(delay(500.millis()), 1.secs()).await; - hprintln!("timeout done 2: {:?}", res).ok(); - - debug::exit(debug::EXIT_SUCCESS); - } - - #[task(capacity = 12)] - fn delay_handler(_: delay_handler::Context, waker: Waker) { - waker.wake(); - } -} - -// Delay - -pub struct Delay { - until: crate::app::AppInstant, -} - -impl Delay { - pub fn spawn(duration: crate::app::AppDuration) -> Self { - let until = crate::app::monotonics::now() + duration; - - Delay { until } - } -} - -#[inline(always)] -pub fn delay(duration: crate::app::AppDuration) -> Delay { - Delay::spawn(duration) -} - -impl Future for Delay { - type Output = (); - - fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { - let s = self.as_mut(); - let now = crate::app::monotonics::now(); - - hprintln!(" poll Delay").ok(); - - if now >= s.until { - Poll::Ready(()) - } else { - let waker = cx.waker().clone(); - crate::app::delay_handler::spawn_after(s.until - now, waker).ok(); - - Poll::Pending - } - } -} - -//============= -// Timeout future - -#[derive(Copy, Clone, Debug)] -pub struct TimeoutError; - -pub struct Timeout<F: Future> { - future: F, - until: crate::app::AppInstant, - cancel_handle: Option<crate::app::delay_handler::SpawnHandle>, -} - -impl<F> Timeout<F> -where - F: Future, -{ - pub fn timeout(future: F, duration: crate::app::AppDuration) -> Self { - let until = crate::app::monotonics::now() + duration; - Self { - future, - until, - cancel_handle: None, - } - } -} - -#[inline(always)] -pub fn timeout<F: Future>(future: F, duration: crate::app::AppDuration) -> Timeout<F> { - Timeout::timeout(future, duration) -} - -impl<F> Future for Timeout<F> -where - F: Future, -{ - type Output = Result<F::Output, TimeoutError>; - - fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> { - let now = crate::app::monotonics::now(); - - // SAFETY: We don't move the underlying pinned value. - let mut s = unsafe { self.get_unchecked_mut() }; - let future = unsafe { Pin::new_unchecked(&mut s.future) }; - - hprintln!(" poll Timeout").ok(); - - match future.poll(cx) { - Poll::Ready(r) => { - if let Some(ch) = s.cancel_handle.take() { - ch.cancel().ok(); - } - - Poll::Ready(Ok(r)) - } - Poll::Pending => { - if now >= s.until { - Poll::Ready(Err(TimeoutError)) - } else if s.cancel_handle.is_none() { - let waker = cx.waker().clone(); - let sh = crate::app::delay_handler::spawn_after(s.until - now, waker) - .expect("Internal RTIC bug, this should never fail"); - s.cancel_handle = Some(sh); - - Poll::Pending - } else { - Poll::Pending - } - } - } + #[task] + fn normal_task(_cx: normal_task::Context) { + hprintln!("hello from normal").ok(); } -} - -pub struct NeverEndingFuture {} -impl Future for NeverEndingFuture { - type Output = (); + #[task] + async fn async_task(_cx: async_task::Context) { + hprintln!("hello from async").ok(); - fn poll(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Self::Output> { - // Never finish - hprintln!(" polling NeverEndingFuture").ok(); - Poll::Pending + debug::exit(debug::EXIT_SUCCESS); } } |