From 6bd168d711cd6304af72a106bb98f0cbebff0742 Mon Sep 17 00:00:00 2001 From: Per Lindgren Date: Mon, 5 Oct 2020 21:57:44 +0200 Subject: spawn POC works, likely unsound --- macros/src/codegen/module.rs | 76 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 73 insertions(+), 3 deletions(-) (limited to 'macros/src/codegen/module.rs') diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs index 359c1cc..7298356 100644 --- a/macros/src/codegen/module.rs +++ b/macros/src/codegen/module.rs @@ -2,9 +2,16 @@ use proc_macro2::TokenStream as TokenStream2; use quote::quote; use rtic_syntax::{ast::App, Context}; -use crate::{check::Extra, codegen::util}; - -pub fn codegen(ctxt: Context, resources_tick: bool, app: &App, extra: &Extra) -> TokenStream2 { +// use crate::{analyze::Analysis, check::Extra, codegen::spawn_module, codegen::util}; +use crate::{analyze::Analysis, check::Extra, codegen::util}; + +pub fn codegen( + ctxt: Context, + resources_tick: bool, + app: &App, + analysis: &Analysis, + extra: &Extra, +) -> TokenStream2 { let mut items = vec![]; let mut fields = vec![]; let mut values = vec![]; @@ -318,6 +325,69 @@ pub fn codegen(ctxt: Context, resources_tick: bool, app: &App, extra: &Extra) -> } )); + // not sure if this is the right way, maybe its backwards, + // that spawn_module should put in in root + + 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; + 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); + + eprintln!("app name: {}", app.name); + eprintln!("inputs {}", &inputs); + eprintln!("task name: {}", name); + eprintln!("fq {}", fq); + eprintln!("rq {}", rq); + let app_name = &app.name; + let app_path = quote! {crate::#app_name}; + + let device = extra.device; + let enum_ = util::interrupt_ident(); + let interrupt = &analysis.interrupts.get(&priority); + let pend = { + quote!( + rtic::pend(#device::#enum_::#interrupt); + ) + }; + + eprintln!("pend {}", &pend); + + items.push(quote!( + #(#cfgs)* + pub fn spawn(#(#args,)*) -> Result<(), #ty> { + // #let_instant // do we need it? + use rtic::Mutex as _; + + let input = #tupled; + // TODO: use critical section, now we are unsafe + unsafe { + if let Some(index) = #app_path::#fq.dequeue() { + #app_path::#inputs + .get_unchecked_mut(usize::from(index)) + .as_mut_ptr() + .write(input); + + // #write_instant, do we need? + + #app_path::#rq.enqueue_unchecked((#app_path::#t::#name, index)); + + #pend + + Ok(()) + } else { + Err(input) + } + } + })); + } + if !items.is_empty() { quote!( #[allow(non_snake_case)] -- cgit v1.2.3 From aac97a2109f56784adf59cdeba25beef4f18a13a Mon Sep 17 00:00:00 2001 From: Per Lindgren Date: Mon, 5 Oct 2020 22:02:04 +0200 Subject: spawn POC works, likely unsound, cleanup --- macros/src/codegen/module.rs | 1 - 1 file changed, 1 deletion(-) (limited to 'macros/src/codegen/module.rs') diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs index 7298356..bba64bb 100644 --- a/macros/src/codegen/module.rs +++ b/macros/src/codegen/module.rs @@ -2,7 +2,6 @@ use proc_macro2::TokenStream as TokenStream2; use quote::quote; use rtic_syntax::{ast::App, Context}; -// use crate::{analyze::Analysis, check::Extra, codegen::spawn_module, codegen::util}; use crate::{analyze::Analysis, check::Extra, codegen::util}; pub fn codegen( -- cgit v1.2.3 From e8b4fa7b32cf044428971f22e01428ff9cccff3c Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Thu, 8 Oct 2020 17:33:16 +0200 Subject: Added critical sections --- macros/src/codegen/module.rs | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) (limited to 'macros/src/codegen/module.rs') diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs index bba64bb..1fd3cd4 100644 --- a/macros/src/codegen/module.rs +++ b/macros/src/codegen/module.rs @@ -350,13 +350,6 @@ pub fn codegen( let device = extra.device; let enum_ = util::interrupt_ident(); let interrupt = &analysis.interrupts.get(&priority); - let pend = { - quote!( - rtic::pend(#device::#enum_::#interrupt); - ) - }; - - eprintln!("pend {}", &pend); items.push(quote!( #(#cfgs)* @@ -365,25 +358,26 @@ pub fn codegen( use rtic::Mutex as _; let input = #tupled; - // TODO: use critical section, now we are unsafe - unsafe { - if let Some(index) = #app_path::#fq.dequeue() { + + if let Some(index) = rtic::export::interrupt::free(|_| #app_path::#fq.dequeue()) { + unsafe { #app_path::#inputs .get_unchecked_mut(usize::from(index)) .as_mut_ptr() .write(input); + } - // #write_instant, do we need? - + rtic::export::interrupt::free(|_| { #app_path::#rq.enqueue_unchecked((#app_path::#t::#name, index)); + }); - #pend + rtic::pend(#device::#enum_::#interrupt); - Ok(()) - } else { - Err(input) - } + Ok(()) + } else { + Err(input) } + })); } -- cgit v1.2.3 From 524273c96a978299b64e51a9cdcc007585a0f170 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Sun, 11 Oct 2020 18:38:38 +0200 Subject: Now with spawn/schedule from anywhere --- macros/src/codegen/module.rs | 212 ++++++++++++------------------------------- 1 file changed, 60 insertions(+), 152 deletions(-) (limited to 'macros/src/codegen/module.rs') diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs index 526bf49..979c63c 100644 --- a/macros/src/codegen/module.rs +++ b/macros/src/codegen/module.rs @@ -21,7 +21,7 @@ pub fn codegen( let mut lt = None; match ctxt { Context::Init => { - if app.uses_schedule() { + if extra.monotonic.is_some() { let m = extra.monotonic(); fields.push(quote!( @@ -67,7 +67,7 @@ pub fn codegen( Context::Idle => {} Context::HardwareTask(..) => { - if app.uses_schedule() { + if extra.monotonic.is_some() { let m = extra.monotonic(); fields.push(quote!( @@ -82,7 +82,7 @@ pub fn codegen( } Context::SoftwareTask(..) => { - if app.uses_schedule() { + if extra.monotonic.is_some() { let m = extra.monotonic(); fields.push(quote!( @@ -132,139 +132,6 @@ pub fn codegen( values.push(quote!(resources: Resources::new(#priority))); } - if ctxt.uses_schedule(app) { - let doc = "Tasks that can be `schedule`-d from this context"; - if ctxt.is_init() { - items.push(quote!( - #[doc = #doc] - #[derive(Clone, Copy)] - pub struct Schedule { - _not_send: core::marker::PhantomData<*mut ()>, - } - )); - - fields.push(quote!( - #[doc = #doc] - pub schedule: Schedule - )); - - values.push(quote!( - schedule: Schedule { _not_send: core::marker::PhantomData } - )); - } else { - lt = Some(quote!('a)); - - items.push(quote!( - #[doc = #doc] - #[derive(Clone, Copy)] - pub struct Schedule<'a> { - priority: &'a rtic::export::Priority, - } - - impl<'a> Schedule<'a> { - #[doc(hidden)] - #[inline(always)] - pub unsafe fn priority(&self) -> &rtic::export::Priority { - &self.priority - } - } - )); - - fields.push(quote!( - #[doc = #doc] - pub schedule: Schedule<'a> - )); - - values.push(quote!( - schedule: Schedule { priority } - )); - } - } - - if ctxt.uses_spawn(app) { - let doc = "Tasks that can be `spawn`-ed from this context"; - if ctxt.is_init() { - fields.push(quote!( - #[doc = #doc] - pub spawn: Spawn - )); - - items.push(quote!( - #[doc = #doc] - #[derive(Clone, Copy)] - pub struct Spawn { - _not_send: core::marker::PhantomData<*mut ()>, - } - )); - - values.push(quote!(spawn: Spawn { _not_send: core::marker::PhantomData })); - } else { - lt = Some(quote!('a)); - - fields.push(quote!( - #[doc = #doc] - pub spawn: Spawn<'a> - )); - - let mut instant_method = None; - if ctxt.is_idle() { - items.push(quote!( - #[doc = #doc] - #[derive(Clone, Copy)] - pub struct Spawn<'a> { - priority: &'a rtic::export::Priority, - } - )); - - values.push(quote!(spawn: Spawn { priority })); - } else { - let instant_field = if app.uses_schedule() { - let m = extra.monotonic(); - - needs_instant = true; - instant_method = Some(quote!( - pub unsafe fn instant(&self) -> <#m as rtic::Monotonic>::Instant { - self.instant - } - )); - Some(quote!(instant: <#m as rtic::Monotonic>::Instant,)) - } else { - None - }; - - items.push(quote!( - /// Tasks that can be spawned from this context - #[derive(Clone, Copy)] - pub struct Spawn<'a> { - #instant_field - priority: &'a rtic::export::Priority, - } - )); - - let _instant = if needs_instant { - Some(quote!(, instant)) - } else { - None - }; - values.push(quote!( - spawn: Spawn { priority #_instant } - )); - } - - items.push(quote!( - impl<'a> Spawn<'a> { - #[doc(hidden)] - #[inline(always)] - pub unsafe fn priority(&self) -> &rtic::export::Priority { - self.priority - } - - #instant_method - } - )); - } - } - if let Context::Init = ctxt { let init = &app.inits.first().unwrap(); let late_resources = util::late_resources_ident(&init.name); @@ -283,7 +150,7 @@ pub fn codegen( }; let core = if ctxt.is_init() { - if app.uses_schedule() { + if extra.monotonic.is_some() { Some(quote!(core: rtic::Peripherals,)) } else { Some(quote!(core: rtic::export::Peripherals,)) @@ -337,11 +204,6 @@ pub fn codegen( let rq = util::rq_ident(priority); let inputs = util::inputs_ident(name); - eprintln!("app name: {}", app.name); - eprintln!("inputs {}", &inputs); - eprintln!("task name: {}", name); - eprintln!("fq {}", fq); - eprintln!("rq {}", rq); let app_name = &app.name; let app_path = quote! {crate::#app_name}; @@ -349,6 +211,7 @@ pub fn codegen( let enum_ = util::interrupt_ident(); let interrupt = &analysis.interrupts.get(&priority); + // Spawn caller items.push(quote!( #(#cfgs)* pub fn spawn(#(#args,)*) -> Result<(), #ty> { @@ -357,26 +220,71 @@ pub fn codegen( let input = #tupled; - if let Some(index) = rtic::export::interrupt::free(|_| #app_path::#fq.dequeue()) { - unsafe { + unsafe { + if let Some(index) = rtic::export::interrupt::free(|_| #app_path::#fq.dequeue()) { #app_path::#inputs .get_unchecked_mut(usize::from(index)) .as_mut_ptr() .write(input); - } - rtic::export::interrupt::free(|_| { - #app_path::#rq.enqueue_unchecked((#app_path::#t::#name, index)); - }); + rtic::export::interrupt::free(|_| { + #app_path::#rq.enqueue_unchecked((#app_path::#t::#name, index)); + }); - rtic::pend(#device::#enum_::#interrupt); + rtic::pend(#device::#enum_::#interrupt); - Ok(()) - } else { - Err(input) + Ok(()) + } else { + Err(input) + } } })); + + // Schedule caller + if extra.monotonic.is_some() { + let instants = util::instants_ident(name); + + let tq = util::tq_ident(); + let m = extra.monotonic(); + let t = util::schedule_t_ident(); + + items.push(quote!( + #(#cfgs)* + pub fn schedule( + instant: <#m as rtic::Monotonic>::Instant + #(,#args)* + ) -> Result<(), #ty> { + unsafe { + use rtic::Mutex as _; + + let input = #tupled; + if let Some(index) = rtic::export::interrupt::free(|_| #app_path::#fq.dequeue()) { + #app_path::#inputs + .get_unchecked_mut(usize::from(index)) + .as_mut_ptr() + .write(input); + + #app_path::#instants + .get_unchecked_mut(usize::from(index)) + .as_mut_ptr() + .write(instant); + + let nr = rtic::export::NotReady { + instant, + index, + task: #app_path::#t::#name, + }; + + rtic::export::interrupt::free(|_| #app_path::#tq.enqueue_unchecked(nr)); + + Ok(()) + } else { + Err(input) + } + } + })); + } } if !items.is_empty() { -- cgit v1.2.3 From 5b8e6a22ab68e316e11641dedf5b39e20878c7b7 Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Sun, 11 Oct 2020 19:41:57 +0200 Subject: Fixing examples and tests, modules now import user imports correctly Fmt Correct syntax crate UI test fix Fix build script Cleanup More cleanup --- macros/src/codegen/module.rs | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'macros/src/codegen/module.rs') diff --git a/macros/src/codegen/module.rs b/macros/src/codegen/module.rs index 979c63c..e3b0ed9 100644 --- a/macros/src/codegen/module.rs +++ b/macros/src/codegen/module.rs @@ -21,9 +21,7 @@ pub fn codegen( let mut lt = None; match ctxt { Context::Init => { - if extra.monotonic.is_some() { - let m = extra.monotonic(); - + if let Some(m) = extra.monotonic { fields.push(quote!( /// System start time = `Instant(0 /* cycles */)` pub start: <#m as rtic::Monotonic>::Instant @@ -67,9 +65,7 @@ pub fn codegen( Context::Idle => {} Context::HardwareTask(..) => { - if extra.monotonic.is_some() { - let m = extra.monotonic(); - + if let Some(m) = extra.monotonic { fields.push(quote!( /// Time at which this handler started executing pub start: <#m as rtic::Monotonic>::Instant @@ -82,9 +78,7 @@ pub fn codegen( } Context::SoftwareTask(..) => { - if extra.monotonic.is_some() { - let m = extra.monotonic(); - + if let Some(m) = extra.monotonic { fields.push(quote!( /// The time at which this task was scheduled to run pub scheduled: <#m as rtic::Monotonic>::Instant @@ -242,11 +236,10 @@ pub fn codegen( })); // Schedule caller - if extra.monotonic.is_some() { + if let Some(m) = extra.monotonic { let instants = util::instants_ident(name); let tq = util::tq_ident(); - let m = extra.monotonic(); let t = util::schedule_t_ident(); items.push(quote!( @@ -288,10 +281,16 @@ pub fn codegen( } if !items.is_empty() { + let user_imports = &app.user_imports; + quote!( #[allow(non_snake_case)] #[doc = #doc] pub mod #name { + #( + #[allow(unused_imports)] + #user_imports + )* #(#items)* } ) -- cgit v1.2.3