aboutsummaryrefslogtreecommitdiff
path: root/examples/async-task.rs
diff options
context:
space:
mode:
Diffstat (limited to 'examples/async-task.rs')
-rw-r--r--examples/async-task.rs168
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);
}
}