aboutsummaryrefslogtreecommitdiff
path: root/macros/src/codegen/monotonic.rs
diff options
context:
space:
mode:
Diffstat (limited to 'macros/src/codegen/monotonic.rs')
-rw-r--r--macros/src/codegen/monotonic.rs280
1 files changed, 0 insertions, 280 deletions
diff --git a/macros/src/codegen/monotonic.rs b/macros/src/codegen/monotonic.rs
deleted file mode 100644
index 417a1d6a..00000000
--- a/macros/src/codegen/monotonic.rs
+++ /dev/null
@@ -1,280 +0,0 @@
-use crate::syntax::ast::App;
-use proc_macro2::TokenStream as TokenStream2;
-use quote::quote;
-
-use crate::{analyze::Analysis, codegen::util};
-
-/// Generates monotonic module dispatchers
-pub fn codegen(app: &App, _analysis: &Analysis) -> TokenStream2 {
- let mut monotonic_parts: Vec<_> = Vec::new();
-
- let tq_marker = util::timer_queue_marker_ident();
-
- for (_, monotonic) in &app.monotonics {
- // let instants = util::monotonic_instants_ident(name, &monotonic.ident);
- let monotonic_name = monotonic.ident.to_string();
-
- let tq = util::tq_ident(&monotonic_name);
- let m = &monotonic.ident;
- let m_ident = util::monotonic_ident(&monotonic_name);
- let m_isr = &monotonic.args.binds;
- let enum_ = util::interrupt_ident();
- let name_str = &m.to_string();
- let ident = util::monotonic_ident(name_str);
- let doc = &format!(
- "This module holds the static implementation for `{}::now()`",
- name_str
- );
-
- let (enable_interrupt, pend) = if &*m_isr.to_string() == "SysTick" {
- (
- quote!(core::mem::transmute::<_, rtic::export::SYST>(()).enable_interrupt()),
- quote!(rtic::export::SCB::set_pendst()),
- )
- } else {
- let rt_err = util::rt_err_ident();
- (
- quote!(rtic::export::NVIC::unmask(super::super::#rt_err::#enum_::#m_isr)),
- quote!(rtic::pend(super::super::#rt_err::#enum_::#m_isr)),
- )
- };
-
- let default_monotonic = if monotonic.args.default {
- quote!(
- #[doc(inline)]
- pub use #m::now;
- #[doc(inline)]
- pub use #m::delay;
- #[doc(inline)]
- pub use #m::delay_until;
- #[doc(inline)]
- pub use #m::timeout_at;
- #[doc(inline)]
- pub use #m::timeout_after;
- )
- } else {
- quote!()
- };
-
- monotonic_parts.push(quote! {
- #default_monotonic
-
- #[doc = #doc]
- #[allow(non_snake_case)]
- pub mod #m {
- /// Read the current time from this monotonic
- pub fn now() -> <super::super::#m as rtic::Monotonic>::Instant {
- rtic::export::interrupt::free(|_| {
- use rtic::Monotonic as _;
- if let Some(m) = unsafe{ &mut *super::super::#ident.get_mut() } {
- m.now()
- } else {
- <super::super::#m as rtic::Monotonic>::zero()
- }
- })
- }
-
- /// Delay
- #[inline(always)]
- #[allow(non_snake_case)]
- pub fn delay(duration: <super::super::#m as rtic::Monotonic>::Duration)
- -> DelayFuture {
- let until = now() + duration;
- DelayFuture { until, waker_storage: None }
- }
-
- /// Delay until a specific time
- #[inline(always)]
- #[allow(non_snake_case)]
- pub fn delay_until(instant: <super::super::#m as rtic::Monotonic>::Instant)
- -> DelayFuture {
- let until = instant;
- DelayFuture { until, waker_storage: None }
- }
-
- /// Delay future.
- #[allow(non_snake_case)]
- #[allow(non_camel_case_types)]
- pub struct DelayFuture {
- until: <super::super::#m as rtic::Monotonic>::Instant,
- waker_storage: Option<rtic::export::IntrusiveNode<rtic::export::WakerNotReady<super::super::#m>>>,
- }
-
- impl Drop for DelayFuture {
- fn drop(&mut self) {
- if let Some(waker_storage) = &mut self.waker_storage {
- rtic::export::interrupt::free(|_| unsafe {
- let tq = &mut *super::super::#tq.get_mut();
- tq.cancel_waker_marker(waker_storage.val.marker);
- });
- }
- }
- }
-
- impl core::future::Future for DelayFuture {
- type Output = ();
-
- fn poll(
- mut self: core::pin::Pin<&mut Self>,
- cx: &mut core::task::Context<'_>
- ) -> core::task::Poll<Self::Output> {
- let mut s = self.as_mut();
- let now = now();
- let until = s.until;
- let is_ws_none = s.waker_storage.is_none();
-
- if now >= until {
- return core::task::Poll::Ready(());
- } else if is_ws_none {
- rtic::export::interrupt::free(|_| unsafe {
- let marker = super::super::#tq_marker.get().read();
- super::super::#tq_marker.get_mut().write(marker.wrapping_add(1));
-
- let nr = s.waker_storage.insert(rtic::export::IntrusiveNode::new(rtic::export::WakerNotReady {
- waker: cx.waker().clone(),
- instant: until,
- marker,
- }));
-
- let tq = &mut *super::super::#tq.get_mut();
-
- tq.enqueue_waker(
- core::mem::transmute(nr), // Transmute the reference to static
- || #enable_interrupt,
- || #pend,
- (&mut *super::super::#m_ident.get_mut()).as_mut());
- });
- }
-
- core::task::Poll::Pending
- }
- }
-
- /// Timeout future.
- #[allow(non_snake_case)]
- #[allow(non_camel_case_types)]
- pub struct TimeoutFuture<F: core::future::Future> {
- future: F,
- until: <super::super::#m as rtic::Monotonic>::Instant,
- waker_storage: Option<rtic::export::IntrusiveNode<rtic::export::WakerNotReady<super::super::#m>>>,
- }
-
- impl<F: core::future::Future> Drop for TimeoutFuture<F> {
- fn drop(&mut self) {
- if let Some(waker_storage) = &mut self.waker_storage {
- rtic::export::interrupt::free(|_| unsafe {
- let tq = &mut *super::super::#tq.get_mut();
- tq.cancel_waker_marker(waker_storage.val.marker);
- });
- }
- }
- }
-
- /// Timeout after
- #[allow(non_snake_case)]
- #[inline(always)]
- pub fn timeout_after<F: core::future::Future>(
- future: F,
- duration: <super::super::#m as rtic::Monotonic>::Duration
- ) -> TimeoutFuture<F> {
- let until = now() + duration;
- TimeoutFuture {
- future,
- until,
- waker_storage: None,
- }
- }
-
- /// Timeout at
- #[allow(non_snake_case)]
- #[inline(always)]
- pub fn timeout_at<F: core::future::Future>(
- future: F,
- instant: <super::super::#m as rtic::Monotonic>::Instant
- ) -> TimeoutFuture<F> {
- TimeoutFuture {
- future,
- until: instant,
- waker_storage: None,
- }
- }
-
- impl<F> core::future::Future for TimeoutFuture<F>
- where
- F: core::future::Future,
- {
- type Output = Result<F::Output, super::TimeoutError>;
-
- fn poll(
- self: core::pin::Pin<&mut Self>,
- cx: &mut core::task::Context<'_>
- ) -> core::task::Poll<Self::Output> {
- // SAFETY: We don't move the underlying pinned value.
- let mut s = unsafe { self.get_unchecked_mut() };
- let future = unsafe { core::pin::Pin::new_unchecked(&mut s.future) };
- let now = now();
- let until = s.until;
- let is_ws_none = s.waker_storage.is_none();
-
- match future.poll(cx) {
- core::task::Poll::Ready(r) => {
- if let Some(waker_storage) = &mut s.waker_storage {
- rtic::export::interrupt::free(|_| unsafe {
- let tq = &mut *super::super::#tq.get_mut();
- tq.cancel_waker_marker(waker_storage.val.marker);
- });
- }
-
- return core::task::Poll::Ready(Ok(r));
- }
- core::task::Poll::Pending => {
- if now >= until {
- // Timeout
- return core::task::Poll::Ready(Err(super::TimeoutError));
- } else if is_ws_none {
- rtic::export::interrupt::free(|_| unsafe {
- let marker = super::super::#tq_marker.get().read();
- super::super::#tq_marker.get_mut().write(marker.wrapping_add(1));
-
- let nr = s.waker_storage.insert(rtic::export::IntrusiveNode::new(rtic::export::WakerNotReady {
- waker: cx.waker().clone(),
- instant: until,
- marker,
- }));
-
- let tq = &mut *super::super::#tq.get_mut();
-
- tq.enqueue_waker(
- core::mem::transmute(nr), // Transmute the reference to static
- || #enable_interrupt,
- || #pend,
- (&mut *super::super::#m_ident.get_mut()).as_mut());
- });
- }
- }
- }
-
- core::task::Poll::Pending
- }
- }
- }
- });
- }
-
- if monotonic_parts.is_empty() {
- quote!()
- } else {
- quote!(
- pub use rtic::Monotonic as _;
-
- /// Holds static methods for each monotonic.
- pub mod monotonics {
- /// A timeout error.
- #[derive(Debug)]
- pub struct TimeoutError;
-
- #(#monotonic_parts)*
- }
- )
- }
-}