aboutsummaryrefslogtreecommitdiff
path: root/macros/src/codegen/resources.rs
diff options
context:
space:
mode:
Diffstat (limited to 'macros/src/codegen/resources.rs')
-rw-r--r--macros/src/codegen/resources.rs58
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,