From 1087f2ee64a5be1aedf3b702ccb5d86cc64708d9 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Thu, 11 Mar 2021 19:12:02 +0100 Subject: Added interface for cancel/reschedule Use wrapping add for marker No need to store handle to queue Remove unnecessary `SpawnHandle::new` Fix test Updated interface to follow proposal --- macros/src/codegen/module.rs | 74 +++++++++++++++++++++++++++++++++------ macros/src/codegen/timer_queue.rs | 11 +++++- macros/src/codegen/util.rs | 5 +++ 3 files changed, 79 insertions(+), 11 deletions(-) (limited to 'macros/src/codegen') diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs index 75435b5..fb028e0 100644 --- a/macros/src/codegen/module.rs +++ b/macros/src/codegen/module.rs @@ -264,15 +264,64 @@ pub fn codegen( }; let user_imports = &app.user_imports; + let tq_marker = util::mark_internal_ident(&util::timer_queue_marker_ident()); items.push(quote!( /// Holds methods related to this monotonic pub mod #m { + #[allow(unused_imports)] + use #app_path::#tq_marker; + #[allow(unused_imports)] + use #app_path::#t; #( #[allow(unused_imports)] #user_imports )* + pub struct SpawnHandle { + #[doc(hidden)] + marker: u32, + } + + // TODO: remove + impl core::fmt::Debug for SpawnHandle + { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let handle = unsafe { &#app_path::#tq as *const _ as u32 }; + f.debug_struct("SpawnHandle") + .field("marker", &self.marker) + .field("handle", &handle) + .finish() + } + } + + impl SpawnHandle { + pub fn cancel(self) -> Result<#ty, ()> { + // TODO: Actually cancel... + // &mut #app_path::#tq; + + Err(()) + } + + #[inline] + pub fn reschedule_after(self, duration: D) -> Result + where D: rtic::time::duration::Duration + rtic::time::fixed_point::FixedPoint, + D::T: Into<<#app_path::#mono_type as rtic::time::Clock>::T>, + { + self.reschedule_at(#app_path::#m::now() + duration) + } + + pub fn reschedule_at(self, instant: rtic::time::Instant<#app_path::#mono_type>) -> Result + { + let _ = instant; + + // TODO: Actually reschedule... + // &mut #app_path::#tq; + + Err(()) + } + } + #(#cfgs)* /// Spawns the task after a set duration relative to the current time /// @@ -281,7 +330,7 @@ pub fn codegen( pub fn spawn_after( duration: D #(,#args)* - ) -> Result<(), #ty> + ) -> Result where D: rtic::time::duration::Duration + rtic::time::fixed_point::FixedPoint, D::T: Into<<#app_path::#mono_type as rtic::time::Clock>::T>, { @@ -300,7 +349,7 @@ pub fn codegen( pub fn spawn_at( instant: rtic::time::Instant<#app_path::#mono_type> #(,#args)* - ) -> Result<(), #ty> { + ) -> Result { unsafe { let input = #tupled; if let Some(index) = rtic::export::interrupt::free(|_| #app_path::#fq.dequeue()) { @@ -314,13 +363,17 @@ pub fn codegen( .as_mut_ptr() .write(instant); - let nr = rtic::export::NotReady { - instant, - index, - task: #app_path::#t::#name, - }; + rtic::export::interrupt::free(|_| { + let marker = #tq_marker; + let nr = rtic::export::NotReady { + instant, + index, + task: #app_path::#t::#name, + marker, + }; + + #tq_marker = #tq_marker.wrapping_add(1); - rtic::export::interrupt::free(|_| if let Some(mono) = #app_path::#m_ident.as_mut() { #app_path::#tq.enqueue_unchecked( nr, @@ -331,9 +384,10 @@ pub fn codegen( // We can only use the timer queue if `init` has returned, and it // writes the `Some(monotonic)` we are accessing here. core::hint::unreachable_unchecked() - }); + } - Ok(()) + Ok(SpawnHandle { marker }) + }) } else { Err(input) } diff --git a/macros/src/codegen/timer_queue.rs b/macros/src/codegen/timer_queue.rs index 82d0ac9..3390551 100644 --- a/macros/src/codegen/timer_queue.rs +++ b/macros/src/codegen/timer_queue.rs @@ -9,6 +9,15 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec Vec Ident { Ident::new("interrupt", span) } +pub fn timer_queue_marker_ident() -> Ident { + let span = Span::call_site(); + Ident::new("TIMER_QUEUE_MARKER", span) +} + /// Whether `name` is an exception with configurable priority pub fn is_exception(name: &Ident) -> bool { let s = name.to_string(); -- cgit v1.2.3 From 53c407017f50d0fde17d38afed714b2fcb54194b Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Sun, 14 Mar 2021 21:27:21 +0100 Subject: Cancel and reschedule working Support cfgs in the imports Account for extern tasks --- macros/src/codegen/module.rs | 67 +++++++++++++++++++++++++++++++++------ macros/src/codegen/pre_init.rs | 12 ++++--- macros/src/codegen/timer_queue.rs | 11 +++---- 3 files changed, 70 insertions(+), 20 deletions(-) (limited to 'macros/src/codegen') diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs index fb028e0..5a594c6 100644 --- a/macros/src/codegen/module.rs +++ b/macros/src/codegen/module.rs @@ -21,6 +21,33 @@ pub fn codegen( let app_name = &app.name; let app_path = quote! {crate::#app_name}; + let all_task_names: Vec<_> = app + .software_tasks + .iter() + .map(|(name, st)| { + if !st.is_extern { + let cfgs = &st.cfgs; + quote! { + #(#cfgs)* + #[allow(unused_imports)] + use #app_path::#name as #name; + } + } else { + quote!() + } + }) + .chain(app.hardware_tasks.iter().map(|(name, ht)| { + if !ht.is_extern { + quote! { + #[allow(unused_imports)] + use #app_path::#name as #name; + } + } else { + quote!() + } + })) + .collect(); + let mut lt = None; match ctxt { Context::Init => { @@ -202,6 +229,9 @@ pub fn codegen( // Spawn caller items.push(quote!( + + #(#all_task_names)* + #(#cfgs)* /// Spawns the task directly pub fn spawn(#(#args,)*) -> Result<(), #ty> { @@ -247,6 +277,7 @@ pub fn codegen( if monotonic.args.default { items.push(quote!(pub use #m::spawn_after;)); items.push(quote!(pub use #m::spawn_at;)); + items.push(quote!(pub use #m::SpawnHandle;)); } let (enable_interrupt, pend) = if &*m_isr.to_string() == "SysTick" { @@ -269,6 +300,11 @@ pub fn codegen( items.push(quote!( /// Holds methods related to this monotonic pub mod #m { + // #( + // #[allow(unused_imports)] + // use #app_path::#all_task_names as #all_task_names; + // )* + use super::*; #[allow(unused_imports)] use #app_path::#tq_marker; #[allow(unused_imports)] @@ -297,10 +333,19 @@ pub fn codegen( impl SpawnHandle { pub fn cancel(self) -> Result<#ty, ()> { - // TODO: Actually cancel... - // &mut #app_path::#tq; - - Err(()) + rtic::export::interrupt::free(|_| unsafe { + let tq = &mut *#app_path::#tq.as_mut_ptr(); + if let Some((_task, index)) = tq.cancel_marker(self.marker) { + // Get the message + let msg = #app_path::#inputs.get_unchecked(usize::from(index)).as_ptr().read(); + // Return the index to the free queue + #app_path::#fq.split().0.enqueue_unchecked(index); + + Ok(msg) + } else { + Err(()) + } + }) } #[inline] @@ -313,12 +358,14 @@ pub fn codegen( pub fn reschedule_at(self, instant: rtic::time::Instant<#app_path::#mono_type>) -> Result { - let _ = instant; + rtic::export::interrupt::free(|_| unsafe { + let marker = #tq_marker; + #tq_marker = #tq_marker.wrapping_add(1); - // TODO: Actually reschedule... - // &mut #app_path::#tq; + let tq = &mut *#app_path::#tq.as_mut_ptr(); - Err(()) + tq.update_marker(self.marker, marker, instant, || #pend).map(|_| SpawnHandle { marker }) + }) } } @@ -374,8 +421,10 @@ pub fn codegen( #tq_marker = #tq_marker.wrapping_add(1); + let tq = unsafe { &mut *#app_path::#tq.as_mut_ptr() }; + if let Some(mono) = #app_path::#m_ident.as_mut() { - #app_path::#tq.enqueue_unchecked( + tq.enqueue_unchecked( nr, || #enable_interrupt, || #pend, diff --git a/macros/src/codegen/pre_init.rs b/macros/src/codegen/pre_init.rs index d510544..287f41a 100644 --- a/macros/src/codegen/pre_init.rs +++ b/macros/src/codegen/pre_init.rs @@ -77,12 +77,16 @@ pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec Vec); + let tq_ty = + quote!(core::mem::MaybeUninit>); items.push(quote!( #[doc(hidden)] - static mut #tq: #tq_ty = rtic::export::TimerQueue( - rtic::export::BinaryHeap( - rtic::export::iBinaryHeap::new() - ) - ); + static mut #tq: #tq_ty = core::mem::MaybeUninit::uninit(); )); let mono = util::monotonic_ident(&monotonic_name); @@ -138,7 +135,7 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec Date: Sat, 20 Mar 2021 08:38:37 +0100 Subject: Updated schedule example with all combinations --- macros/src/codegen/module.rs | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'macros/src/codegen') diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs index 5a594c6..e15aab1 100644 --- a/macros/src/codegen/module.rs +++ b/macros/src/codegen/module.rs @@ -319,18 +319,6 @@ pub fn codegen( marker: u32, } - // TODO: remove - impl core::fmt::Debug for SpawnHandle - { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - let handle = unsafe { &#app_path::#tq as *const _ as u32 }; - f.debug_struct("SpawnHandle") - .field("marker", &self.marker) - .field("handle", &handle) - .finish() - } - } - impl SpawnHandle { pub fn cancel(self) -> Result<#ty, ()> { rtic::export::interrupt::free(|_| unsafe { -- cgit v1.2.3