From b163e3ec27abca9529956c4177ff64a7fa84c1bb Mon Sep 17 00:00:00 2001 From: Per Lindgren Date: Mon, 26 Oct 2020 22:06:26 +0100 Subject: [PATCH] library src --- macros/src/codegen/software_tasks.rs | 4 ++ src/async_util.rs | 74 ++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 src/async_util.rs diff --git a/macros/src/codegen/software_tasks.rs b/macros/src/codegen/software_tasks.rs index 833e338dd5..f055428c75 100644 --- a/macros/src/codegen/software_tasks.rs +++ b/macros/src/codegen/software_tasks.rs @@ -117,6 +117,10 @@ pub fn codegen( )); } + if &task.is_async { + eprintln!("") + } + root.push(module::codegen( Context::SoftwareTask(name), needs_lt, diff --git a/src/async_util.rs b/src/async_util.rs new file mode 100644 index 0000000000..bd8882d8f4 --- /dev/null +++ b/src/async_util.rs @@ -0,0 +1,74 @@ +//! Async support for RTIC + +use core::{ + future::Future, + mem, + pin::Pin, + task::{Context, Poll, RawWaker, RawWakerVTable, Waker}, +}; + +//============= +// Waker + +/// +pub static WAKER_VTABLE: RawWakerVTable = + RawWakerVTable::new(waker_clone, waker_wake, waker_wake, waker_drop); + +unsafe fn waker_clone(p: *const ()) -> RawWaker { + RawWaker::new(p, &WAKER_VTABLE) +} + +unsafe fn waker_wake(p: *const ()) { + let f: fn() = mem::transmute(p); + f(); +} + +unsafe fn waker_drop(_: *const ()) { + // nop +} + +//============ +// Task + +/// +pub enum Task { + /// + Idle, + + /// + Running(F), + + /// + Done(F::Output), +} + +impl Task { + /// + pub const fn new() -> Self { + Self::Idle + } + + /// + pub fn spawn(&mut self, future: impl FnOnce() -> F) { + *self = Task::Running(future()); + } + + /// + pub unsafe fn poll(&mut self, wake: fn()) { + match self { + Task::Idle => {} + Task::Running(future) => { + let future = Pin::new_unchecked(future); + let waker_data: *const () = mem::transmute(wake); + let waker = Waker::from_raw(RawWaker::new(waker_data, &WAKER_VTABLE)); + let mut cx = Context::from_waker(&waker); + + match future.poll(&mut cx) { + Poll::Ready(r) => *self = Task::Done(r), + Poll::Pending => {} + }; + } + Task::Done(_) => {} + } + } +}