diff --git a/examples/destructure.rs b/examples/destructure.rs index 6019c225cc..13e0891317 100644 --- a/examples/destructure.rs +++ b/examples/destructure.rs @@ -46,10 +46,12 @@ mod app { } // De-structure-ing syntax + + // TODO: hide priority field (or re-use priority from first resource) #[task(shared = [&a, &b, &c])] fn bar(cx: bar::Context) { - let bar::SharedResources { a, b, c } = cx.shared; + let bar::SharedResources { a, b, c, priority } = cx.shared; - hprintln!("bar: a = {}, b = {}, c = {}", a, b, c).unwrap(); + hprintln!("bar: a = {}, b = {}, c = {}, p = {:?}", a, b, c, priority).unwrap(); } } diff --git a/macros/src/codegen/hardware_tasks.rs b/macros/src/codegen/hardware_tasks.rs index e6192e2c00..8532176e50 100644 --- a/macros/src/codegen/hardware_tasks.rs +++ b/macros/src/codegen/hardware_tasks.rs @@ -72,6 +72,8 @@ pub fn codegen( Context::HardwareTask(name), &mut shared_needs_lt, app, + analysis, + extra, ); root.push(item); diff --git a/macros/src/codegen/idle.rs b/macros/src/codegen/idle.rs index d653931655..09a955988c 100644 --- a/macros/src/codegen/idle.rs +++ b/macros/src/codegen/idle.rs @@ -35,8 +35,13 @@ pub fn codegen( let name = &idle.name; if !idle.args.shared_resources.is_empty() { - let (item, constructor) = - shared_resources_struct::codegen(Context::Idle, &mut shared_needs_lt, app); + let (item, constructor) = shared_resources_struct::codegen( + Context::Idle, + &mut shared_needs_lt, + app, + analysis, + extra, + ); root_idle.push(item); mod_app.push(constructor); diff --git a/macros/src/codegen/shared_resources.rs b/macros/src/codegen/shared_resources.rs index 87cd8f1952..b27c827c23 100644 --- a/macros/src/codegen/shared_resources.rs +++ b/macros/src/codegen/shared_resources.rs @@ -104,34 +104,5 @@ pub fn codegen( }) }; - let manual = "Manual Codegen".to_string(); - - let to_gen = quote! { - - #[doc = #manual] - impl<'a> rtic::Mutex for __rtic_internal_fooSharedResources<'a> { - type T = __rtic_internal_fooShared; - #[inline(always)] - fn lock( - &mut self, - f: impl FnOnce(&mut __rtic_internal_fooShared) -> RTIC_INTERNAL_R, - ) -> RTIC_INTERNAL_R { - /// Priority ceiling - const CEILING: u8 = 1u8; - unsafe { - rtic::export::lock( - &mut __rtic_internal_fooShared::new(), - self.priority(), - CEILING, - lm3s6965::NVIC_PRIO_BITS, - f, - ) - } - } - } - }; - - mod_app.push(to_gen); - (mod_app, mod_resources) } diff --git a/macros/src/codegen/shared_resources_struct.rs b/macros/src/codegen/shared_resources_struct.rs index ece5ff9793..d4184d0bcd 100644 --- a/macros/src/codegen/shared_resources_struct.rs +++ b/macros/src/codegen/shared_resources_struct.rs @@ -1,11 +1,17 @@ use proc_macro2::TokenStream as TokenStream2; use quote::quote; -use rtic_syntax::{ast::App, Context}; +use rtic_syntax::{analyze::Ownership, ast::App, Context}; -use crate::codegen::util; +use crate::{analyze::Analysis, check::Extra, codegen::util}; /// Generate shared resources structs -pub fn codegen(ctxt: Context, needs_lt: &mut bool, app: &App) -> (TokenStream2, TokenStream2) { +pub fn codegen( + ctxt: Context, + needs_lt: &mut bool, + app: &App, + analysis: &Analysis, + extra: &Extra, +) -> (TokenStream2, TokenStream2) { let mut lt = None; let resources = match ctxt { @@ -22,6 +28,7 @@ pub fn codegen(ctxt: Context, needs_lt: &mut bool, app: &App) -> (TokenStream2, // Lock-all api related let mut fields_mut = vec![]; let mut values_mut = vec![]; + let mut max_ceiling = 0; for (name, access) in resources { let res = app.shared_resources.get(name).expect("UNREACHABLE"); @@ -59,7 +66,6 @@ pub fn codegen(ctxt: Context, needs_lt: &mut bool, app: &App) -> (TokenStream2, values.push(quote!( #(#cfgs)* #name: shared_resources::#name::new(priority) - )); // Lock-all related @@ -74,6 +80,15 @@ pub fn codegen(ctxt: Context, needs_lt: &mut bool, app: &App) -> (TokenStream2, )); + let ceiling = match analysis.ownerships.get(name) { + Some(Ownership::Owned { priority }) => *priority, + Some(Ownership::CoOwned { priority }) => *priority, + Some(Ownership::Contended { ceiling }) => *ceiling, + None => 0, + }; + + max_ceiling = std::cmp::max(ceiling, max_ceiling); + // continue as the value has been filled, continue; } @@ -150,6 +165,18 @@ pub fn codegen(ctxt: Context, needs_lt: &mut bool, app: &App) -> (TokenStream2, } else { Some(quote!(priority: &#lt rtic::export::Priority)) }; + + // Generate code for the lock-all API + let lock_all = util::impl_mutex( + extra, + &vec![], // TODO: what cfg should go here? + false, // resource proxy at top level (not in shared_resources) + &ident, + quote!(#ident_mut), + max_ceiling, + quote!(&mut #ident_mut::new()), + ); + let implementations = quote!( impl<#lt> #ident<#lt> { #[inline(always)] @@ -175,6 +202,8 @@ pub fn codegen(ctxt: Context, needs_lt: &mut bool, app: &App) -> (TokenStream2, } } } + + #lock_all ); (item, implementations) diff --git a/macros/src/codegen/software_tasks.rs b/macros/src/codegen/software_tasks.rs index 1669a3fb1e..c8ea305954 100644 --- a/macros/src/codegen/software_tasks.rs +++ b/macros/src/codegen/software_tasks.rs @@ -112,6 +112,8 @@ pub fn codegen( Context::SoftwareTask(name), &mut shared_needs_lt, app, + analysis, + extra, ); root.push(item); diff --git a/src/export.rs b/src/export.rs index 48a7d06ec4..89d1e18ba5 100644 --- a/src/export.rs +++ b/src/export.rs @@ -69,6 +69,9 @@ impl Barrier { } // Newtype over `Cell` that forbids mutation through a shared reference +// Debug is convenient for debugging the RTIC framework +// but Priority should not be user-facing +#[derive(Debug)] pub struct Priority { inner: Cell, }