aboutsummaryrefslogtreecommitdiff
path: root/macros/src/codegen
diff options
context:
space:
mode:
Diffstat (limited to 'macros/src/codegen')
-rw-r--r--macros/src/codegen/assertions.rs5
-rw-r--r--macros/src/codegen/async_dispatchers.rs66
-rw-r--r--macros/src/codegen/dispatchers.rs146
-rw-r--r--macros/src/codegen/module.rs300
-rw-r--r--macros/src/codegen/monotonic.rs280
-rw-r--r--macros/src/codegen/post_init.rs20
-rw-r--r--macros/src/codegen/pre_init.rs68
-rw-r--r--macros/src/codegen/shared_resources.rs6
-rw-r--r--macros/src/codegen/software_tasks.rs179
-rw-r--r--macros/src/codegen/timer_queue.rs170
-rw-r--r--macros/src/codegen/util.rs111
11 files changed, 47 insertions, 1304 deletions
diff --git a/macros/src/codegen/assertions.rs b/macros/src/codegen/assertions.rs
index 0f8326c7..dd94aa6d 100644
--- a/macros/src/codegen/assertions.rs
+++ b/macros/src/codegen/assertions.rs
@@ -16,11 +16,6 @@ pub fn codegen(app: &App, analysis: &Analysis) -> Vec<TokenStream2> {
stmts.push(quote!(rtic::export::assert_sync::<#ty>();));
}
- for (_, monotonic) in &app.monotonics {
- let ty = &monotonic.ty;
- stmts.push(quote!(rtic::export::assert_monotonic::<#ty>();));
- }
-
let device = &app.args.device;
let chunks_name = util::priority_mask_chunks_ident();
let no_basepri_checks: Vec<_> = app
diff --git a/macros/src/codegen/async_dispatchers.rs b/macros/src/codegen/async_dispatchers.rs
index 8b0e928b..aa854d7f 100644
--- a/macros/src/codegen/async_dispatchers.rs
+++ b/macros/src/codegen/async_dispatchers.rs
@@ -7,65 +7,47 @@ use quote::quote;
pub fn codegen(app: &App, analysis: &Analysis) -> Vec<TokenStream2> {
let mut items = vec![];
- let interrupts = &analysis.interrupts_async;
+ let interrupts = &analysis.interrupts;
// Generate executor definition and priority in global scope
- for (name, task) in app.software_tasks.iter() {
- if task.is_async {
- let type_name = util::internal_task_ident(name, "F");
- let exec_name = util::internal_task_ident(name, "EXEC");
- let prio_name = util::internal_task_ident(name, "PRIORITY");
+ for (name, _) in app.software_tasks.iter() {
+ let type_name = util::internal_task_ident(name, "F");
+ let exec_name = util::internal_task_ident(name, "EXEC");
+ let prio_name = util::internal_task_ident(name, "PRIORITY");
- items.push(quote!(
- #[allow(non_camel_case_types)]
- type #type_name = impl core::future::Future + 'static;
- #[allow(non_upper_case_globals)]
- static #exec_name:
- rtic::RacyCell<rtic::export::executor::AsyncTaskExecutor<#type_name>> =
- rtic::RacyCell::new(rtic::export::executor::AsyncTaskExecutor::new());
-
- // The executors priority, this can be any value - we will overwrite it when we
- // start a task
- #[allow(non_upper_case_globals)]
- static #prio_name: rtic::RacyCell<rtic::export::Priority> =
- unsafe { rtic::RacyCell::new(rtic::export::Priority::new(0)) };
- ));
- }
+ items.push(quote!(
+ #[allow(non_camel_case_types)]
+ type #type_name = impl core::future::Future + 'static;
+ #[allow(non_upper_case_globals)]
+ static #exec_name:
+ rtic::RacyCell<rtic::export::executor::AsyncTaskExecutor<#type_name>> =
+ rtic::RacyCell::new(rtic::export::executor::AsyncTaskExecutor::new());
+
+ // The executors priority, this can be any value - we will overwrite it when we
+ // start a task
+ #[allow(non_upper_case_globals)]
+ static #prio_name: rtic::RacyCell<rtic::export::Priority> =
+ unsafe { rtic::RacyCell::new(rtic::export::Priority::new(0)) };
+ ));
}
for (&level, channel) in &analysis.channels {
- if channel
- .tasks
- .iter()
- .map(|task_name| !app.software_tasks[task_name].is_async)
- .all(|is_not_async| is_not_async)
- {
- // check if all tasks are not async, if so don't generate this.
- continue;
- }
-
let mut stmts = vec![];
let device = &app.args.device;
let enum_ = util::interrupt_ident();
let interrupt = util::suffixed(&interrupts[&level].0.to_string());
- for name in channel
- .tasks
- .iter()
- .filter(|name| app.software_tasks[*name].is_async)
- {
+ for name in channel.tasks.iter() {
let exec_name = util::internal_task_ident(name, "EXEC");
let prio_name = util::internal_task_ident(name, "PRIORITY");
- let task = &app.software_tasks[name];
+ // let task = &app.software_tasks[name];
// let cfgs = &task.cfgs;
- let (_, tupled, pats, input_types) = util::regroup_inputs(&task.inputs);
let executor_run_ident = util::executor_run_ident(name);
- let n = util::capacity_literal(channel.capacity as usize + 1);
let rq = util::rq_async_ident(name);
let (rq_ty, rq_expr) = {
(
- quote!(rtic::export::ASYNCRQ<#input_types, #n>),
+ quote!(rtic::export::ASYNCRQ<(), 2>), // TODO: This needs updating to a counter instead of a queue
quote!(rtic::export::Queue::new()),
)
};
@@ -79,13 +61,13 @@ pub fn codegen(app: &App, analysis: &Analysis) -> Vec<TokenStream2> {
stmts.push(quote!(
if !(&*#exec_name.get()).is_running() {
- if let Some(#tupled) = rtic::export::interrupt::free(|_| (&mut *#rq.get_mut()).dequeue()) {
+ if let Some(()) = rtic::export::interrupt::free(|_| (&mut *#rq.get_mut()).dequeue()) {
// The async executor needs a static priority
#prio_name.get_mut().write(rtic::export::Priority::new(PRIORITY));
let priority: &'static _ = &*#prio_name.get();
- (&mut *#exec_name.get_mut()).spawn(#name(#name::Context::new(priority) #(,#pats)*));
+ (&mut *#exec_name.get_mut()).spawn(#name(#name::Context::new(priority)));
#executor_run_ident.store(true, core::sync::atomic::Ordering::Relaxed);
}
}
diff --git a/macros/src/codegen/dispatchers.rs b/macros/src/codegen/dispatchers.rs
deleted file mode 100644
index 1a8b4042..00000000
--- a/macros/src/codegen/dispatchers.rs
+++ /dev/null
@@ -1,146 +0,0 @@
-use crate::syntax::ast::App;
-use crate::{analyze::Analysis, codegen::util};
-use proc_macro2::TokenStream as TokenStream2;
-use quote::quote;
-
-/// Generates task dispatchers
-pub fn codegen(app: &App, analysis: &Analysis) -> Vec<TokenStream2> {
- let mut items = vec![];
-
- let interrupts = &analysis.interrupts_normal;
-
- for (&level, channel) in &analysis.channels {
- if channel
- .tasks
- .iter()
- .map(|task_name| app.software_tasks[task_name].is_async)
- .all(|is_async| is_async)
- {
- // check if all tasks are async, if so don't generate this.
- continue;
- }
-
- let mut stmts = vec![];
-
- let variants = channel
- .tasks
- .iter()
- .filter(|name| !app.software_tasks[*name].is_async)
- .map(|name| {
- let cfgs = &app.software_tasks[name].cfgs;
-
- quote!(
- #(#cfgs)*
- #name
- )
- })
- .collect::<Vec<_>>();
-
- // For future use
- // let doc = format!(
- // "Software tasks to be dispatched at priority level {}",
- // level,
- // );
- let t = util::spawn_t_ident(level);
- items.push(quote!(
- #[allow(non_snake_case)]
- #[allow(non_camel_case_types)]
- #[derive(Clone, Copy)]
- // #[doc = #doc]
- #[doc(hidden)]
- pub enum #t {
- #(#variants,)*
- }
- ));
-
- let n = util::capacity_literal(channel.capacity as usize + 1);
- let rq = util::rq_ident(level);
- // let (_, _, _, input_ty) = util::regroup_inputs(inputs);
- let (rq_ty, rq_expr) = {
- (
- quote!(rtic::export::SCRQ<#t, #n>),
- quote!(rtic::export::Queue::new()),
- )
- };
-
- // For future use
- // let doc = format!(
- // "Queue of tasks ready to be dispatched at priority level {}",
- // level
- // );
- items.push(quote!(
- #[doc(hidden)]
- #[allow(non_camel_case_types)]
- #[allow(non_upper_case_globals)]
- static #rq: rtic::RacyCell<#rq_ty> = rtic::RacyCell::new(#rq_expr);
- ));
-
- let interrupt = util::suffixed(
- &interrupts
- .get(&level)
- .expect("RTIC-ICE: Unable to get interrrupt")
- .0
- .to_string(),
- );
- let arms = channel
- .tasks
- .iter()
- .map(|name| {
- let task = &app.software_tasks[name];
- let cfgs = &task.cfgs;
- let fq = util::fq_ident(name);
- let inputs = util::inputs_ident(name);
- let (_, tupled, pats, _) = util::regroup_inputs(&task.inputs);
-
- if !task.is_async {
- quote!(
- #(#cfgs)*
- #t::#name => {
- let #tupled =
- (&*#inputs
- .get())
- .get_unchecked(usize::from(index))
- .as_ptr()
- .read();
- (&mut *#fq.get_mut()).split().0.enqueue_unchecked(index);
- let priority = &rtic::export::Priority::new(PRIORITY);
- #name(
- #name::Context::new(priority)
- #(,#pats)*
- )
- }
- )
- } else {
- quote!()
- }
- })
- .collect::<Vec<_>>();
-
- stmts.push(quote!(
- while let Some((task, index)) = (&mut *#rq.get_mut()).split().1.dequeue() {
- match task {
- #(#arms)*
- }
- }
- ));
-
- let doc = format!("Interrupt handler to dispatch tasks at priority {}", level);
- let attribute = &interrupts[&level].1.attrs;
- items.push(quote!(
- #[allow(non_snake_case)]
- #[doc = #doc]
- #[no_mangle]
- #(#attribute)*
- unsafe fn #interrupt() {
- /// The priority of this interrupt handler
- const PRIORITY: u8 = #level;
-
- rtic::export::run(PRIORITY, || {
- #(#stmts)*
- });
- }
- ));
- }
-
- items
-}
diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs
index 7ac06c5c..eb0cb65b 100644
--- a/macros/src/codegen/module.rs
+++ b/macros/src/codegen/module.rs
@@ -102,33 +102,6 @@ pub fn codegen(
values.push(quote!(shared: #name::SharedResources::new(#priority)));
}
- if let Context::Init = ctxt {
- let monotonic_types: Vec<_> = app
- .monotonics
- .iter()
- .map(|(_, monotonic)| {
- let mono = &monotonic.ty;
- quote! {#mono}
- })
- .collect();
-
- let internal_monotonics_ident = util::mark_internal_name("Monotonics");
-
- items.push(quote!(
- /// Monotonics used by the system
- #[allow(non_snake_case)]
- #[allow(non_camel_case_types)]
- pub struct #internal_monotonics_ident(
- #(pub #monotonic_types),*
- );
- ));
-
- module_items.push(quote!(
- #[doc(inline)]
- pub use super::#internal_monotonics_ident as Monotonics;
- ));
- }
-
let doc = match ctxt {
Context::Idle => "Idle loop",
Context::Init => "Initialization function",
@@ -192,280 +165,45 @@ pub fn codegen(
if let Context::SoftwareTask(..) = ctxt {
let spawnee = &app.software_tasks[name];
let priority = spawnee.args.priority;
- let t = util::spawn_t_ident(priority);
let cfgs = &spawnee.cfgs;
// Store a copy of the task cfgs
task_cfgs = cfgs.clone();
- let (args, tupled, untupled, ty) = util::regroup_inputs(&spawnee.inputs);
- let args = &args;
- let tupled = &tupled;
- let fq = util::fq_ident(name);
- let rq = util::rq_ident(priority);
- let inputs = util::inputs_ident(name);
let device = &app.args.device;
let enum_ = util::interrupt_ident();
- let interrupt = if spawnee.is_async {
- &analysis
- .interrupts_async
- .get(&priority)
- .expect("RTIC-ICE: interrupt identifer not found")
- .0
- } else {
- &analysis
- .interrupts_normal
- .get(&priority)
- .expect("RTIC-ICE: interrupt identifer not found")
- .0
- };
+ let interrupt = &analysis
+ .interrupts
+ .get(&priority)
+ .expect("RTIC-ICE: interrupt identifer not found")
+ .0;
let internal_spawn_ident = util::internal_task_ident(name, "spawn");
// Spawn caller
- if spawnee.is_async {
- let rq = util::rq_async_ident(name);
- items.push(quote!(
-
- #(#cfgs)*
- /// Spawns the task directly
- #[allow(non_snake_case)]
- #[doc(hidden)]
- pub fn #internal_spawn_ident(#(#args,)*) -> Result<(), #ty> {
- let input = #tupled;
-
- unsafe {
- let r = rtic::export::interrupt::free(|_| (&mut *#rq.get_mut()).enqueue(input));
+ let rq = util::rq_async_ident(name);
+ items.push(quote!(
- if r.is_ok() {
- rtic::pend(#device::#enum_::#interrupt);
- }
+ #(#cfgs)*
+ /// Spawns the task directly
+ #[allow(non_snake_case)]
+ #[doc(hidden)]
+ pub fn #internal_spawn_ident() -> Result<(), ()> {
+ unsafe {
+ let r = rtic::export::interrupt::free(|_| (&mut *#rq.get_mut()).enqueue(()));
- r
+ if r.is_ok() {
+ rtic::pend(#device::#enum_::#interrupt);
}
- }));
- } else {
- items.push(quote!(
- #(#cfgs)*
- /// Spawns the task directly
- #[allow(non_snake_case)]
- #[doc(hidden)]
- pub fn #internal_spawn_ident(#(#args,)*) -> Result<(), #ty> {
- let input = #tupled;
-
- unsafe {
- if let Some(index) = rtic::export::interrupt::free(|_| (&mut *#fq.get_mut()).dequeue()) {
- (&mut *#inputs
- .get_mut())
- .get_unchecked_mut(usize::from(index))
- .as_mut_ptr()
- .write(input);
-
- rtic::export::interrupt::free(|_| {
- (&mut *#rq.get_mut()).enqueue_unchecked((#t::#name, index));
- });
- rtic::pend(#device::#enum_::#interrupt);
-
- Ok(())
- } else {
- Err(input)
- }
- }
-
- }));
- }
+ r
+ }
+ }));
module_items.push(quote!(
#(#cfgs)*
#[doc(inline)]
pub use super::#internal_spawn_ident as spawn;
));
-
- // Schedule caller
- if !spawnee.is_async {
- 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.ident.to_string());
- let t = util::schedule_t_ident();
- let m = &monotonic.ident;
- let m_ident = util::monotonic_ident(&monotonic_name);
- let m_isr = &monotonic.args.binds;
- let enum_ = util::interrupt_ident();
- let spawn_handle_string = format!("{}::SpawnHandle", m);
-
- 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(#rt_err::#enum_::#m_isr)),
- quote!(rtic::pend(#rt_err::#enum_::#m_isr)),
- )
- };
-
- let tq_marker = &util::timer_queue_marker_ident();
-
- let internal_spawn_handle_ident =
- util::internal_monotonics_ident(name, m, "SpawnHandle");
- let internal_spawn_at_ident = util::internal_monotonics_ident(name, m, "spawn_at");
- let internal_spawn_after_ident =
- util::internal_monotonics_ident(name, m, "spawn_after");
-
- if monotonic.args.default {
- module_items.push(quote!(
- #[doc(inline)]
- pub use #m::spawn_after;
- #[doc(inline)]
- pub use #m::spawn_at;
- #[doc(inline)]
- pub use #m::SpawnHandle;
- ));
- }
- module_items.push(quote!(
- pub mod #m {
- #[doc(inline)]
- pub use super::super::#internal_spawn_after_ident as spawn_after;
- #[doc(inline)]
- pub use super::super::#internal_spawn_at_ident as spawn_at;
- #[doc(inline)]
- pub use super::super::#internal_spawn_handle_ident as SpawnHandle;
- }
- ));
-
- items.push(quote!(
- #(#cfgs)*
- #[allow(non_snake_case)]
- #[allow(non_camel_case_types)]
- pub struct #internal_spawn_handle_ident {
- #[doc(hidden)]
- marker: u32,
- }
-
- #(#cfgs)*
- impl core::fmt::Debug for #internal_spawn_handle_ident {
- fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
- f.debug_struct(#spawn_handle_string).finish()
- }
- }
-
- #(#cfgs)*
- impl #internal_spawn_handle_ident {
- pub fn cancel(self) -> Result<#ty, ()> {
- rtic::export::interrupt::free(|_| unsafe {
- let tq = &mut *#tq.get_mut();
- if let Some((_task, index)) = tq.cancel_task_marker(self.marker) {
- // Get the message
- let msg = (&*#inputs
- .get())
- .get_unchecked(usize::from(index))
- .as_ptr()
- .read();
- // Return the index to the free queue
- (&mut *#fq.get_mut()).split().0.enqueue_unchecked(index);
-
- Ok(msg)
- } else {
- Err(())
- }
- })
- }
-
- #[inline]
- pub fn reschedule_after(
- self,
- duration: <#m as rtic::Monotonic>::Duration
- ) -> Result<Self, ()> {
- self.reschedule_at(monotonics::#m::now() + duration)
- }
-
- pub fn reschedule_at(
- self,
- instant: <#m as rtic::Monotonic>::Instant
- ) -> Result<Self, ()> {
- rtic::export::interrupt::free(|_| unsafe {
- let marker = #tq_marker.get().read();
- #tq_marker.get_mut().write(marker.wrapping_add(1));
-
- let tq = (&mut *#tq.get_mut());
-
- tq.update_task_marker(self.marker, marker, instant, || #pend).map(|_| #name::#m::SpawnHandle { marker })
- })
- }
- }
-
-
- #(#cfgs)*
- /// Spawns the task after a set duration relative to the current time
- ///
- /// This will use the time `Instant::new(0)` as baseline if called in `#[init]`,
- /// so if you use a non-resetable timer use `spawn_at` when in `#[init]`
- #[allow(non_snake_case)]
- pub fn #internal_spawn_after_ident(
- duration: <#m as rtic::Monotonic>::Duration
- #(,#args)*
- ) -> Result<#name::#m::SpawnHandle, #ty>
- {
- let instant = monotonics::#m::now();
-
- #internal_spawn_at_ident(instant + duration #(,#untupled)*)
- }
-
- #(#cfgs)*
- /// Spawns the task at a fixed time instant
- #[allow(non_snake_case)]
- pub fn #internal_spawn_at_ident(
- instant: <#m as rtic::Monotonic>::Instant
- #(,#args)*
- ) -> Result<#name::#m::SpawnHandle, #ty> {
- unsafe {
- let input = #tupled;
- if let Some(index) = rtic::export::interrupt::free(|_| (&mut *#fq.get_mut()).dequeue()) {
- (&mut *#inputs
- .get_mut())
- .get_unchecked_mut(usize::from(index))
- .as_mut_ptr()
- .write(input);
-
- (&mut *#instants
- .get_mut())
- .get_unchecked_mut(usize::from(index))
- .as_mut_ptr()
- .write(instant);
-
- rtic::export::interrupt::free(|_| {
- let marker = #tq_marker.get().read();
- let nr = rtic::export::TaskNotReady {
- task: #t::#name,
- index,
- instant,
- marker,
- };
-
- #tq_marker.get_mut().write(#tq_marker.get().read().wrapping_add(1));
-
- let tq = &mut *#tq.get_mut();
-
- tq.enqueue_task_unchecked(
- nr,
- || #enable_interrupt,
- || #pend,
- (&mut *#m_ident.get_mut()).as_mut());
-
- Ok(#name::#m::SpawnHandle { marker })
- })
- } else {
- Err(input)
- }
- }
- }
- ));
- }
- }
}
if items.is_empty() {
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)*
- }
- )
- }
-}
diff --git a/macros/src/codegen/post_init.rs b/macros/src/codegen/post_init.rs
index df5daa1e..e8183b93 100644
--- a/macros/src/codegen/post_init.rs
+++ b/macros/src/codegen/post_init.rs
@@ -1,7 +1,6 @@
use crate::syntax::ast::App;
-use proc_macro2::{Span, TokenStream as TokenStream2};
+use proc_macro2::TokenStream as TokenStream2;
use quote::quote;
-use syn::Index;
use crate::{analyze::Analysis, codegen::util};
@@ -43,23 +42,6 @@ pub fn codegen(app: &App, analysis: &Analysis) -> Vec<TokenStream2> {
}
}
- for (i, (monotonic, _)) in app.monotonics.iter().enumerate() {
- // For future use
- // let doc = format!(" RTIC internal: {}:{}", file!(), line!());
- // stmts.push(quote!(#[doc = #doc]));
-
- #[allow(clippy::cast_possible_truncation)]
- let idx = Index {
- index: i as u32,
- span: Span::call_site(),
- };
- stmts.push(quote!(monotonics.#idx.reset();));
-
- // Store the monotonic
- let name = util::monotonic_ident(&monotonic.to_string());
- stmts.push(quote!(#name.get_mut().write(Some(monotonics.#idx));));
- }
-
// Enable the interrupts -- this completes the `init`-ialization phase
stmts.push(quote!(rtic::export::interrupt::enable();));
diff --git a/macros/src/codegen/pre_init.rs b/macros/src/codegen/pre_init.rs
index ef3acba7..14926888 100644
--- a/macros/src/codegen/pre_init.rs
+++ b/macros/src/codegen/pre_init.rs
@@ -13,20 +13,6 @@ pub fn codegen(app: &App, analysis: &Analysis) -> Vec<TokenStream2> {
// Disable interrupts -- `init` must run with interrupts disabled
stmts.push(quote!(rtic::export::interrupt::disable();));
- // Populate the FreeQueue
- for (name, task) in &app.software_tasks {
- if task.is_async {
- continue;
- }
-
- let cap = task.args.capacity;
- let fq_ident = util::fq_ident(name);
-
- stmts.push(quote!(
- (0..#cap).for_each(|i| (&mut *#fq_ident.get_mut()).enqueue_unchecked(i));
- ));
- }
-
stmts.push(quote!(
// To set the variable in cortex_m so the peripherals cannot be taken multiple times
let mut core: rtic::export::Peripherals = rtic::export::Peripherals::steal().into();
@@ -42,11 +28,7 @@ pub fn codegen(app: &App, analysis: &Analysis) -> Vec<TokenStream2> {
stmts.push(quote!(let _ = #rt_err::#interrupt::#name;));
}
- let interrupt_ids = analysis
- .interrupts_normal
- .iter()
- .map(|(p, (id, _))| (p, id))
- .chain(analysis.interrupts_async.iter().map(|(p, (id, _))| (p, id)));
+ let interrupt_ids = analysis.interrupts.iter().map(|(p, (id, _))| (p, id));
// Unmask interrupts and set their priorities
for (&priority, name) in interrupt_ids.chain(app.hardware_tasks.values().filter_map(|task| {
@@ -101,53 +83,5 @@ pub fn codegen(app: &App, analysis: &Analysis) -> Vec<TokenStream2> {
);));
}
- // Initialize monotonic's interrupts
- for (_, monotonic) in &app.monotonics {
- let priority = if let Some(prio) = monotonic.args.priority {
- quote! { #prio }
- } else {
- quote! { (1 << #nvic_prio_bits) }
- };
- let binds = &monotonic.args.binds;
-
- let name = &monotonic.ident;
- let es = format!(
- "Maximum priority used by monotonic '{}' is more than supported by hardware",
- name
- );
- // Compile time assert that this priority is supported by the device
- stmts.push(quote!(
- const _: () = if (1 << #nvic_prio_bits) < #priority as usize { ::core::panic!(#es); };
- ));
-
- let mono_type = &monotonic.ty;
-
- if &*binds.to_string() == "SysTick" {
- stmts.push(quote!(
- core.SCB.set_priority(
- rtic::export::SystemHandler::SysTick,
- rtic::export::logical2hw(#priority, #nvic_prio_bits),
- );
-
- // Always enable monotonic interrupts if they should never be off
- if !<#mono_type as rtic::Monotonic>::DISABLE_INTERRUPT_ON_EMPTY_QUEUE {
- core::mem::transmute::<_, rtic::export::SYST>(())
- .enable_interrupt();
- }
- ));
- } else {
- stmts.push(quote!(
- core.NVIC.set_priority(
- #rt_err::#interrupt::#binds,
- rtic::export::logical2hw(#priority, #nvic_prio_bits),
- );
-
- // Always enable monotonic interrupts if they should never be off
- if !<#mono_type as rtic::Monotonic>::DISABLE_INTERRUPT_ON_EMPTY_QUEUE {
- rtic::export::NVIC::unmask(#rt_err::#interrupt::#binds);
- }
- ));
- }
- }
stmts
}
diff --git a/macros/src/codegen/shared_resources.rs b/macros/src/codegen/shared_resources.rs
index 66f38002..b63e7432 100644
--- a/macros/src/codegen/shared_resources.rs
+++ b/macros/src/codegen/shared_resources.rs
@@ -111,11 +111,7 @@ pub fn codegen(
};
// Computing mapping of used interrupts to masks
- let interrupt_ids = analysis
- .interrupts_normal
- .iter()
- .map(|(p, (id, _))| (p, id))
- .chain(analysis.interrupts_async.iter().map(|(p, (id, _))| (p, id)));
+ let interrupt_ids = analysis.interrupts.iter().map(|(p, (id, _))| (p, id));
let mut prio_to_masks = HashMap::new();
let device = &app.args.device;
diff --git a/macros/src/codegen/software_tasks.rs b/macros/src/codegen/software_tasks.rs
deleted file mode 100644
index f9247dae..00000000
--- a/macros/src/codegen/software_tasks.rs
+++ /dev/null
@@ -1,179 +0,0 @@
-use crate::syntax::{ast::App, Context};
-use crate::{
- analyze::Analysis,
- codegen::{local_resources_struct, module, shared_resources_struct, util},
-};
-use proc_macro2::TokenStream as TokenStream2;
-use quote::quote;
-
-pub fn codegen(
- app: &App,
- analysis: &Analysis,
-) -> (
- // mod_app_software_tasks -- free queues, buffers and `${task}Resources` constructors
- Vec<TokenStream2>,
- // root_software_tasks -- items that must be placed in the root of the crate:
- // - `${task}Locals` structs
- // - `${task}Resources` structs
- // - `${task}` modules
- Vec<TokenStream2>,
- // user_software_tasks -- the `#[task]` functions written by the user
- Vec<TokenStream2>,
-) {
- let mut mod_app = vec![];
- let mut root = vec![];
- let mut user_tasks = vec![];
-
- // Any task
- for (name, task) in app.software_tasks.iter() {
- let inputs = &task.inputs;
- let (_, _, _, input_ty) = util::regroup_inputs(inputs);
-
- let cap = task.args.capacity;
- let cap_lit = util::capacity_literal(cap as usize);
- let cap_lit_p1 = util::capacity_literal(cap as usize + 1);
-
- if !task.is_async {
- // Create free queues and inputs / instants buffers
- let fq = util::fq_ident(name);
-
- #[allow(clippy::redundant_closure)]
- let (fq_ty, fq_expr, mk_uninit): (_, _, Box<dyn Fn() -> Option<_>>) = {
- (
- quote!(rtic::export::SCFQ<#cap_lit_p1>),
- quote!(rtic::export::Queue::new()),
- Box::new(|| Some(util::link_section_uninit())),
- )
- };
-
- mod_app.push(quote!(
- // /// Queue version of a free-list that keeps track of empty slots in
- // /// the following buffers
- #[allow(non_camel_case_types)]
- #[allow(non_upper_case_globals)]
- #[doc(hidden)]
- static #fq: rtic::RacyCell<#fq_ty> = rtic::RacyCell::new(#fq_expr);
- ));
-
- let elems = &(0..cap)
- .map(|_| quote!(core::mem::MaybeUninit::uninit()))
- .collect::<Vec<_>>();
-
- for (_, monotonic) in &app.monotonics {
- let instants = util::monotonic_instants_ident(name, &monotonic.ident);
- let mono_type = &monotonic.ty;
-
- let uninit = mk_uninit();
- // For future use
- // let doc = format!(" RTIC internal: {}:{}", file!(), line!());
- mod_app.push(quote!(
- #uninit
- // /// Buffer that holds the instants associated to the inputs of a task
- // #[doc = #doc]
- #[allow(non_camel_case_types)]
- #[allow(non_upper_case_globals)]
- #[doc(hidden)]
- static #instants:
- rtic::RacyCell<[core::mem::MaybeUninit<<#mono_type as rtic::Monotonic>::Instant>; #cap_lit]> =
- rtic::RacyCell::new([#(#elems,)*]);
- ));
- }
-
- let uninit = mk_uninit();
- let inputs_ident = util::inputs_ident(name);
-
- // Buffer that holds the inputs of a task
- mod_app.push(quote!(
- #uninit
- #[allow(non_camel_case_types)]
- #[allow(non_upper_case_globals)]
- #[doc(hidden)]
- static #inputs_ident: rtic::RacyCell<[core::mem::MaybeUninit<#input_ty>; #cap_lit]> =
- rtic::RacyCell::new([#(#elems,)*]);
- ));
- }
-
- if task.is_async {
- let executor_ident = util::executor_run_ident(name);
- mod_app.push(quote!(
- #[allow(non_camel_case_types)]
- #[allow(non_upper_case_globals)]
- #[doc(hidden)]
- static #executor_ident: core::sync::atomic::AtomicBool =
- core::sync::atomic::AtomicBool::new(false);
- ));
- }
-
- let inputs = &task.inputs;
-
- // `${task}Resources`
- let mut shared_needs_lt = false;
- let mut local_needs_lt = false;
-
- // `${task}Locals`
- if !task.args.local_resources.is_empty() {
- let (item, constructor) = local_resources_struct::codegen(
- Context::SoftwareTask(name),
- &mut local_needs_lt,
- app,
- );
-
- root.push(item);
-
- mod_app.push(constructor);
- }
-
- if !task.args.shared_resources.is_empty() {
- let (item, constructor) = shared_resources_struct::codegen(
- Context::SoftwareTask(name),
- &mut shared_needs_lt,
- app,
- );
-
- root.push(item);
-
- mod_app.push(constructor);
- }
-
- if !&task.is_extern {
- let context = &task.context;
- let attrs = &task.attrs;
- let cfgs = &task.cfgs;
- let stmts = &task.stmts;
- let (async_marker, context_lifetime) = if task.is_async {
- (
- quote!(async),
- if shared_needs_lt || local_needs_lt {
- quote!(<'static>)
- } else {
- quote!()
- },
- )
- } else {
- (quote!(), quote!())
- };
-
- user_tasks.push(quote!(
- #(#attrs)*
- #(#cfgs)*
- #[allow(non_snake_case)]
- #async_marker fn #name(#context: #name::Context #context_lifetime #(,#inputs)*) {
- use rtic::Mutex as _;
- use rtic::mutex::prelude::*;
-
- #(#stmts)*
- }
- ));
- }
-
- root.push(module::codegen(
- Context::SoftwareTask(name),
- shared_needs_lt,
- local_needs_lt,
- app,
- analysis,
- ));
- }
-
- (mod_app, root, user_tasks)
-}
diff --git a/macros/src/codegen/timer_queue.rs b/macros/src/codegen/timer_queue.rs
deleted file mode 100644
index 281148d9..00000000
--- a/macros/src/codegen/timer_queue.rs
+++ /dev/null
@@ -1,170 +0,0 @@
-use crate::syntax::ast::App;
-use crate::{analyze::Analysis, codegen::util};
-use proc_macro2::TokenStream as TokenStream2;
-use quote::quote;
-
-/// Generates timer queues and timer queue handlers
-#[allow(clippy::too_many_lines)]
-pub fn codegen(app: &App, analysis: &Analysis) -> Vec<TokenStream2> {
- let mut items = vec![];
-
- if !app.monotonics.is_empty() {
- // Generate the marker counter used to track for `cancel` and `reschedule`
- let tq_marker = util::timer_queue_marker_ident();
- items.push(quote!(
- // #[doc = #doc]
- #[doc(hidden)]
- #[allow(non_camel_case_types)]
- #[allow(non_upper_case_globals)]
- static #tq_marker: rtic::RacyCell<u32> = rtic::RacyCell::new(0);
- ));
-
- let t = util::schedule_t_ident();
-
- // Enumeration of `schedule`-able tasks
- {
- let variants = app
- .software_tasks
- .iter()
- .filter(|(_, task)| !task.is_async)
- .map(|(name, task)| {
- let cfgs = &task.cfgs;
-
- quote!(
- #(#cfgs)*
- #name
- )
- })
- .collect::<Vec<_>>();
-
- // For future use
- // let doc = "Tasks that can be scheduled".to_string();
- items.push(quote!(
- // #[doc = #doc]
- #[doc(hidden)]
- #[allow(non_camel_case_types)]
- #[derive(Clone, Copy)]
- pub enum #t {
- #(#variants,)*
- }
- ));
- }
- }
-
- for (_, monotonic) in &app.monotonics {
- let monotonic_name = monotonic.ident.to_string();
- let tq = util::tq_ident(&monotonic_name);
- let t = util::schedule_t_ident();
- let mono_type = &monotonic.ty;
- let m_ident = util::monotonic_ident(&monotonic_name);
-
- // Static variables and resource proxy
- {
- // For future use
- // let doc = &format!("Timer queue for {}", monotonic_name);
- let cap: usize = app
- .software_tasks
- .iter()
- .map(|(_name, task)| task.args.capacity as usize)
- .sum();
- let n_task = util::capacity_literal(cap);
- let tq_ty = quote!(rtic::export::TimerQueue<#mono_type, #t, #n_task>);
-
- // For future use
- // let doc = format!(" RTIC internal: {}:{}", file!(), line!());
- items.push(quote!(
- #[doc(hidden)]
- #[allow(non_camel_case_types)]
- #[allow(non_upper_case_globals)]
- static #tq: rtic::RacyCell<#tq_ty> = rtic::RacyCell::new(
- rtic::export::TimerQueue {
- task_queue: rtic::export::SortedLinkedList::new_u16(),
- waker_queue: rtic::export::IntrusiveSortedLinkedList::new(),
- }
- );
- ));
-
- let mono = util::monotonic_ident(&monotonic_name);
- // For future use
- // let doc = &format!("Storage for {}", monotonic_name);
-
- items.push(quote!(
- #[doc(hidden)]
- #[allow(non_camel_case_types)]
- #[allow(non_upper_case_globals)]
- static #mono: rtic::RacyCell<Option<#mono_type>> = rtic::RacyCell::new(None);
- ));
- }
-
- // Timer queue handler
- {
- let enum_ = util::interrupt_ident();
- let rt_err = util::rt_err_ident();
-
- let arms = app
- .software_tasks
- .iter()
- .filter(|(_, task)| !task.is_async)
- .map(|(name, task)| {
- let cfgs = &task.cfgs;
- let priority = task.args.priority;
- let rq = util::rq_ident(priority);
- let rqt = util::spawn_t_ident(priority);
-
- // The interrupt that runs the task dispatcher
- let interrupt = &analysis.interrupts_normal.get(&priority).expect("RTIC-ICE: interrupt not found").0;
-
- let pend = {
- quote!(
- rtic::pend(#rt_err::#enum_::#interrupt);
- )
- };
-
- quote!(
- #(#cfgs)*
- #t::#name => {
- rtic::export::interrupt::free(|_|
- (&mut *#rq.get_mut()).split().0.enqueue_unchecked((#rqt::#name, index))
- );
-
- #pend
- }
- )
- })
- .collect::<Vec<_>>();
-
- let bound_interrupt = &monotonic.args.binds;
- let disable_isr = if &*bound_interrupt.to_string() == "SysTick" {
- quote!(core::mem::transmute::<_, rtic::export::SYST>(()).disable_interrupt())
- } else {
- quote!(rtic::export::NVIC::mask(#rt_err::#enum_::#bound_interrupt))
- };
-
- items.push(quote!(
- #[no_mangle]
- #[allow(non_snake_case)]
- unsafe fn #bound_interrupt() {
- while let Some((task, index)) = rtic::export::interrupt::free(|_|
- if let Some(mono) = (&mut *#m_ident.get_mut()).as_mut() {
- (&mut *#tq.get_mut()).dequeue(|| #disable_isr, mono)
- } else {
- // 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()
- })
- {
- match task {
- #(#arms)*
- }
- }
-
- rtic::export::interrupt::free(|_| if let Some(mono) = (&mut *#m_ident.get_mut()).as_mut() {
- mono.on_interrupt();
- });
- }
- ));
- }
- }
-
- items
-}
diff --git a/macros/src/codegen/util.rs b/macros/src/codegen/util.rs
index 151906da..61bde98f 100644
--- a/macros/src/codegen/util.rs
+++ b/macros/src/codegen/util.rs
@@ -3,20 +3,10 @@ use core::sync::atomic::{AtomicUsize, Ordering};
use crate::syntax::{ast::App, Context};
use proc_macro2::{Span, TokenStream as TokenStream2};
use quote::quote;
-use syn::{Attribute, Ident, LitInt, PatType};
+use syn::{Attribute, Ident};
const RTIC_INTERNAL: &str = "__rtic_internal";
-/// Turns `capacity` into an unsuffixed integer literal
-pub fn capacity_literal(capacity: usize) -> LitInt {
- LitInt::new(&capacity.to_string(), Span::call_site())
-}
-
-/// Identifier for the free queue
-pub fn fq_ident(task: &Ident) -> Ident {
- mark_internal_name(&format!("{}_FQ", task))
-}
-
/// Generates a `Mutex` implementation
pub fn impl_mutex(
app: &App,
@@ -60,30 +50,16 @@ pub fn impl_mutex(
)
}
-/// Generates an identifier for the `INPUTS` buffer (`spawn` & `schedule` API)
-pub fn inputs_ident(task: &Ident) -> Ident {
- mark_internal_name(&format!("{}_INPUTS", task))
-}
-
/// Generates an identifier for the `EXECUTOR_RUN` atomics (`async` API)
pub fn executor_run_ident(task: &Ident) -> Ident {
mark_internal_name(&format!("{}_EXECUTOR_RUN", task))
}
-/// Generates an identifier for the `INSTANTS` buffer (`schedule` API)
-pub fn monotonic_instants_ident(task: &Ident, monotonic: &Ident) -> Ident {
- mark_internal_name(&format!("{}_{}_INSTANTS", task, monotonic))
-}
-
pub fn interrupt_ident() -> Ident {
let span = Span::call_site();
Ident::new("interrupt", span)
}
-pub fn timer_queue_marker_ident() -> Ident {
- mark_internal_name("TIMER_QUEUE_MARKER")
-}
-
/// Whether `name` is an exception with configurable priority
pub fn is_exception(name: &Ident) -> bool {
let s = name.to_string();
@@ -106,11 +82,6 @@ pub fn mark_internal_name(name: &str) -> Ident {
Ident::new(&format!("{}_{}", RTIC_INTERNAL, name), Span::call_site())
}
-/// Generate an internal identifier for monotonics
-pub fn internal_monotonics_ident(task: &Ident, monotonic: &Ident, ident_name: &str) -> Ident {
- mark_internal_name(&format!("{}_{}_{}", task, monotonic, ident_name,))
-}
-
/// Generate an internal identifier for tasks
pub fn internal_task_ident(task: &Ident, ident_name: &str) -> Ident {
mark_internal_name(&format!("{}_{}", task, ident_name))
@@ -129,55 +100,6 @@ pub fn link_section_uninit() -> TokenStream2 {
quote!(#[link_section = #section])
}
-// Regroups the inputs of a task
-//
-// `inputs` could be &[`input: Foo`] OR &[`mut x: i32`, `ref y: i64`]
-pub fn regroup_inputs(
- inputs: &[PatType],
-) -> (
- // args e.g. &[`_0`], &[`_0: i32`, `_1: i64`]
- Vec<TokenStream2>,
- // tupled e.g. `_0`, `(_0, _1)`
- TokenStream2,
- // untupled e.g. &[`_0`], &[`_0`, `_1`]
- Vec<TokenStream2>,
- // ty e.g. `Foo`, `(i32, i64)`
- TokenStream2,
-) {
- if inputs.len() == 1 {
- let ty = &inputs[0].ty;
-
- (
- vec![quote!(_0: #ty)],
- quote!(_0),
- vec![quote!(_0)],
- quote!(#ty),
- )
- } else {
- let mut args = vec![];
- let mut pats = vec![];
- let mut tys = vec![];
-
- for (i, input) in inputs.iter().enumerate() {
- let i = Ident::new(&format!("_{}", i), Span::call_site());
- let ty = &input.ty;
-
- args.push(quote!(#i: #ty));
-
- pats.push(quote!(#i));
-
- tys.push(quote!(#ty));
- }
-
- let tupled = {
- let pats = pats.clone();
- quote!((#(#pats,)*))
- };
- let ty = quote!((#(#tys,)*));
- (args, tupled, pats, ty)
- }
-}
-
/// Get the ident for the name of the task
pub fn get_task_name(ctxt: Context, app: &App) -> Ident {
let s = match ctxt {
@@ -230,48 +152,17 @@ pub fn local_resources_ident(ctxt: Context, app: &App) -> Ident {
mark_internal_name(&s)
}
-/// Generates an identifier for a ready queue
-///
-/// There may be several task dispatchers, one for each priority level.
-/// The ready queues are SPSC queues
-pub fn rq_ident(priority: u8) -> Ident {
- mark_internal_name(&format!("P{}_RQ", priority))
-}
-
/// Generates an identifier for a ready queue, async task version
pub fn rq_async_ident(async_task_name: &Ident) -> Ident {
mark_internal_name(&format!("ASYNC_TACK_{}_RQ", async_task_name))
}
-/// Generates an identifier for the `enum` of `schedule`-able tasks
-pub fn schedule_t_ident() -> Ident {
- mark_internal_name("SCHED_T")
-}
-
-/// Generates an identifier for the `enum` of `spawn`-able tasks
-///
-/// This identifier needs the same structure as the `RQ` identifier because there's one ready queue
-/// for each of these `T` enums
-pub fn spawn_t_ident(priority: u8) -> Ident {
- mark_internal_name(&format!("P{}_T", priority))
-}
-
/// Suffixed identifier
pub fn suffixed(name: &str) -> Ident {
let span = Span::call_site();
Ident::new(name, span)
}
-/// Generates an identifier for a timer queue
-pub fn tq_ident(name: &str) -> Ident {
- mark_internal_name(&format!("TQ_{}", name))
-}
-
-/// Generates an identifier for monotonic timer storage
-pub fn monotonic_ident(name: &str) -> Ident {
- mark_internal_name(&format!("MONOTONIC_STORAGE_{}", name))
-}
-
pub fn static_shared_resource_ident(name: &Ident) -> Ident {
mark_internal_name(&format!("shared_resource_{}", name))
}