aboutsummaryrefslogtreecommitdiff
path: root/macros/src/codegen/dispatchers.rs
diff options
context:
space:
mode:
Diffstat (limited to 'macros/src/codegen/dispatchers.rs')
-rw-r--r--macros/src/codegen/dispatchers.rs294
1 files changed, 132 insertions, 162 deletions
diff --git a/macros/src/codegen/dispatchers.rs b/macros/src/codegen/dispatchers.rs
index 60b8626e..fdeb6155 100644
--- a/macros/src/codegen/dispatchers.rs
+++ b/macros/src/codegen/dispatchers.rs
@@ -8,181 +8,151 @@ use crate::{analyze::Analysis, check::Extra, codegen::util};
pub fn codegen(app: &App, analysis: &Analysis, extra: &Extra) -> Vec<TokenStream2> {
let mut items = vec![];
- for (&receiver, dispatchers) in &analysis.channels {
- let interrupts = &analysis.interrupts[&receiver];
+ let interrupts = &analysis.interrupts;
+
+ for (&level, channel) in &analysis.channels {
+ let mut stmts = vec![];
+
+ let variants = channel
+ .tasks
+ .iter()
+ .map(|name| {
+ let cfgs = &app.software_tasks[name].cfgs;
+
+ quote!(
+ #(#cfgs)*
+ #name
+ )
+ })
+ .collect::<Vec<_>>();
+
+ let doc = format!(
+ "Software tasks to be dispatched at priority level {}",
+ level,
+ );
+ let t = util::spawn_t_ident(level);
+ items.push(quote!(
+ #[allow(non_camel_case_types)]
+ #[derive(Clone, Copy)]
+ #[doc = #doc]
+ enum #t {
+ #(#variants,)*
+ }
+ ));
+
+ let n = util::capacity_typenum(channel.capacity, true);
+ let rq = util::rq_ident(level);
+ let (rq_ty, rq_expr, section) = {
+ (
+ quote!(rtic::export::SCRQ<#t, #n>),
+ quote!(rtic::export::Queue(unsafe {
+ rtic::export::iQueue::u8_sc()
+ })),
+ util::link_section("bss"),
+ )
+ };
+
+ let doc = format!(
+ "Queue of tasks ready to be dispatched at priority level {}",
+ level
+ );
+ items.push(quote!(
+ #[doc = #doc]
+ #section
+ static mut #rq: #rq_ty = #rq_expr;
+ ));
+
+ if let Some(ceiling) = channel.ceiling {
+ items.push(quote!(
+ struct #rq<'a> {
+ priority: &'a rtic::export::Priority,
+ }
+ ));
- for (&level, channels) in dispatchers {
- let mut stmts = vec![];
+ items.push(util::impl_mutex(
+ extra,
+ &[],
+ false,
+ &rq,
+ rq_ty,
+ ceiling,
+ quote!(&mut #rq),
+ ));
+ }
- for (&sender, channel) in channels {
- let cfg_sender = util::cfg_core(sender, app.args.cores);
+ 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);
- let variants = channel
- .tasks
- .iter()
- .map(|name| {
- let cfgs = &app.software_tasks[name].cfgs;
+ let (let_instant, instant) = if app.uses_schedule() {
+ let instants = util::instants_ident(name);
- quote!(
- #(#cfgs)*
- #name
- )
- })
- .collect::<Vec<_>>();
-
- let doc = format!(
- "Software tasks spawned from core #{} to be dispatched at priority level {} by core #{}",
- sender, level, receiver,
- );
- let t = util::spawn_t_ident(receiver, level, sender);
- items.push(quote!(
- #[allow(non_camel_case_types)]
- #[derive(Clone, Copy)]
- #[doc = #doc]
- enum #t {
- #(#variants,)*
- }
- ));
-
- let n = util::capacity_typenum(channel.capacity, true);
- let rq = util::rq_ident(receiver, level, sender);
- let (rq_attr, rq_ty, rq_expr, section) = if sender == receiver {
(
- cfg_sender.clone(),
- quote!(rtic::export::SCRQ<#t, #n>),
- quote!(rtic::export::Queue(unsafe {
- rtic::export::iQueue::u8_sc()
- })),
- util::link_section("bss", sender),
+ quote!(
+ let instant =
+ #instants.get_unchecked(usize::from(index)).as_ptr().read();
+ ),
+ quote!(, instant),
)
} else {
- let shared = if cfg!(feature = "heterogeneous") {
- Some(quote!(#[rtic::export::shared]))
- } else {
- None
- };
-
- (
- shared,
- quote!(rtic::export::MCRQ<#t, #n>),
- quote!(rtic::export::Queue(rtic::export::iQueue::u8())),
- None,
- )
+ (quote!(), quote!())
};
- let doc = format!(
- "Queue of tasks sent by core #{} ready to be dispatched by core #{} at priority level {}",
- sender,
- receiver,
- level
- );
- items.push(quote!(
- #[doc = #doc]
- #rq_attr
- #section
- static mut #rq: #rq_ty = #rq_expr;
- ));
-
- if let Some(ceiling) = channel.ceiling {
- items.push(quote!(
- #cfg_sender
- struct #rq<'a> {
- priority: &'a rtic::export::Priority,
- }
- ));
-
- items.push(util::impl_mutex(
- extra,
- &[],
- cfg_sender.as_ref(),
- false,
- &rq,
- rq_ty,
- ceiling,
- quote!(&mut #rq),
- ));
- }
-
- let arms = channel
- .tasks
- .iter()
- .map(|name| {
- let task = &app.software_tasks[name];
- let cfgs = &task.cfgs;
- let fq = util::fq_ident(name, sender);
- let inputs = util::inputs_ident(name, sender);
- let (_, tupled, pats, _) = util::regroup_inputs(&task.inputs);
-
- let (let_instant, instant) = if app.uses_schedule(receiver) {
- let instants = util::instants_ident(name, sender);
-
- (
- quote!(
- let instant =
- #instants.get_unchecked(usize::from(index)).as_ptr().read();
- ),
- quote!(, instant),
- )
- } else {
- (quote!(), quote!())
- };
-
- let locals_new = if task.locals.is_empty() {
- quote!()
- } else {
- quote!(#name::Locals::new(),)
- };
+ let locals_new = if task.locals.is_empty() {
+ quote!()
+ } else {
+ quote!(#name::Locals::new(),)
+ };
- quote!(
- #(#cfgs)*
- #t::#name => {
- let #tupled =
- #inputs.get_unchecked(usize::from(index)).as_ptr().read();
- #let_instant
- #fq.split().0.enqueue_unchecked(index);
- let priority = &rtic::export::Priority::new(PRIORITY);
- crate::#name(
- #locals_new
- #name::Context::new(priority #instant)
- #(,#pats)*
- )
- }
+ quote!(
+ #(#cfgs)*
+ #t::#name => {
+ let #tupled =
+ #inputs.get_unchecked(usize::from(index)).as_ptr().read();
+ #let_instant
+ #fq.split().0.enqueue_unchecked(index);
+ let priority = &rtic::export::Priority::new(PRIORITY);
+ crate::#name(
+ #locals_new
+ #name::Context::new(priority #instant)
+ #(,#pats)*
)
- })
- .collect::<Vec<_>>();
-
- stmts.push(quote!(
- while let Some((task, index)) = #rq.split().1.dequeue() {
- match task {
- #(#arms)*
- }
}
- ));
- }
-
- let doc = format!(
- "Interrupt handler used by core #{} to dispatch tasks at priority {}",
- receiver, level
- );
- let cfg_receiver = util::cfg_core(receiver, app.args.cores);
- let section = util::link_section("text", receiver);
- let interrupt = util::suffixed(&interrupts[&level].to_string(), receiver);
- items.push(quote!(
- #[allow(non_snake_case)]
- #[doc = #doc]
- #[no_mangle]
- #cfg_receiver
- #section
- unsafe fn #interrupt() {
- /// The priority of this interrupt handler
- const PRIORITY: u8 = #level;
-
- rtic::export::run(PRIORITY, || {
- #(#stmts)*
- });
+ )
+ })
+ .collect::<Vec<_>>();
+
+ stmts.push(quote!(
+ while let Some((task, index)) = #rq.split().1.dequeue() {
+ match task {
+ #(#arms)*
}
- ));
- }
+ }
+ ));
+
+ let doc = format!("Interrupt handler to dispatch tasks at priority {}", level);
+ let section = util::link_section("text");
+ let interrupt = util::suffixed(&interrupts[&level].to_string());
+ items.push(quote!(
+ #[allow(non_snake_case)]
+ #[doc = #doc]
+ #[no_mangle]
+ #section
+ unsafe fn #interrupt() {
+ /// The priority of this interrupt handler
+ const PRIORITY: u8 = #level;
+
+ rtic::export::run(PRIORITY, || {
+ #(#stmts)*
+ });
+ }
+ ));
}
items