aboutsummaryrefslogtreecommitdiff
path: root/src/async_util.rs
diff options
context:
space:
mode:
authorGravatar Per Lindgren <per.lindgren@ltu.se> 2020-10-26 22:06:26 +0100
committerGravatar Per Lindgren <per.lindgren@ltu.se> 2020-10-26 22:06:26 +0100
commitb163e3ec27abca9529956c4177ff64a7fa84c1bb (patch)
treee0986ad30260071ac2fb492e12dd508831acfff5 /src/async_util.rs
parent1e26a536cd6aeec4c6e1f27266c9ba044f158118 (diff)
downloadrtic-b163e3ec27abca9529956c4177ff64a7fa84c1bb.tar.gz
rtic-b163e3ec27abca9529956c4177ff64a7fa84c1bb.tar.zst
rtic-b163e3ec27abca9529956c4177ff64a7fa84c1bb.zip
library src
Diffstat (limited to 'src/async_util.rs')
-rw-r--r--src/async_util.rs74
1 files changed, 74 insertions, 0 deletions
diff --git a/src/async_util.rs b/src/async_util.rs
new file mode 100644
index 00000000..bd8882d8
--- /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<F: Future + 'static> {
+ ///
+ Idle,
+
+ ///
+ Running(F),
+
+ ///
+ Done(F::Output),
+}
+
+impl<F: Future + 'static> Task<F> {
+ ///
+ 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(_) => {}
+ }
+ }
+}