diff options
Diffstat (limited to 'macros/src/codegen/resources.rs')
-rw-r--r-- | macros/src/codegen/resources.rs | 58 |
1 files changed, 45 insertions, 13 deletions
diff --git a/macros/src/codegen/resources.rs b/macros/src/codegen/resources.rs index fa52b86d..53523696 100644 --- a/macros/src/codegen/resources.rs +++ b/macros/src/codegen/resources.rs @@ -4,13 +4,20 @@ use rtic_syntax::{analyze::Ownership, ast::App}; use crate::{analyze::Analysis, check::Extra, codegen::util}; -/// Generates `static [mut]` variables and resource proxies +/// Generates `static` variables and resource proxies +/// Early resources are stored in `RacyCell<T>` +/// Late resource are stored in `RacyCell<MaybeUninit<T>>` +/// +/// Safety: +/// - RacyCell<T> access is `unsafe`. +/// - RacyCell<MaybeUninit> is always written to before user access, thus +// the generated code for user access can safely `assume_init`. pub fn codegen( app: &App, analysis: &Analysis, extra: &Extra, ) -> ( - // mod_app -- the `static [mut]` variables behind the proxies + // mod_app -- the `static` variables behind the proxies Vec<TokenStream2>, // mod_resources -- the `resources` module TokenStream2, @@ -24,35 +31,50 @@ pub fn codegen( let mangled_name = util::mark_internal_ident(&name); { + // TODO: do we really need this in the single core case + // late resources in `util::link_section_uninit` let section = if expr.is_none() { util::link_section_uninit(true) } else { None }; + // resource type and assigned value let (ty, expr) = if let Some(expr) = expr { - (quote!(#ty), quote!(#expr)) + // early resource + ( + quote!(rtic::RacyCell<#ty>), + quote!(rtic::RacyCell::new(#expr)), + ) } else { + // late resource ( - quote!(core::mem::MaybeUninit<#ty>), - quote!(core::mem::MaybeUninit::uninit()), + quote!(rtic::RacyCell<core::mem::MaybeUninit<#ty>>), + quote!(rtic::RacyCell::new(core::mem::MaybeUninit::uninit())), ) }; let attrs = &res.attrs; + + // let doc = format!(" RTIC internal: {}:{}", file!(), line!()); mod_app.push(quote!( #[allow(non_upper_case_globals)] + // #[doc = #doc] #[doc(hidden)] #(#attrs)* #(#cfgs)* #section - static mut #mangled_name: #ty = #expr; + static #mangled_name: #ty = #expr; )); } let r_prop = &res.properties; + // let doc = format!(" RTIC internal: {}:{}", file!(), line!()); + if !r_prop.task_local && !r_prop.lock_free { mod_resources.push(quote!( + // #[doc = #doc] + #[doc(hidden)] #[allow(non_camel_case_types)] #(#cfgs)* pub struct #name<'a> { @@ -73,15 +95,23 @@ pub fn codegen( } )); - let ptr = if expr.is_none() { - quote!( - #(#cfgs)* - #mangled_name.as_mut_ptr() + let (ptr, _doc) = if expr.is_none() { + // late resource + ( + quote!( + #(#cfgs)* + #mangled_name.get_mut_unchecked().as_mut_ptr() + ), + "late", ) } else { - quote!( - #(#cfgs)* - &mut #mangled_name + // early resource + ( + quote!( + #(#cfgs)* + #mangled_name.get_mut_unchecked() + ), + "early", ) }; @@ -92,6 +122,8 @@ pub fn codegen( None => 0, }; + // let doc = format!(" RTIC internal ({} resource): {}:{}", doc, file!(), line!()); + mod_app.push(util::impl_mutex( extra, cfgs, |