aboutsummaryrefslogtreecommitdiff
path: root/macros/src
diff options
context:
space:
mode:
Diffstat (limited to 'macros/src')
-rw-r--r--macros/src/codegen/post_init.rs10
-rw-r--r--macros/src/codegen/resources.rs33
2 files changed, 32 insertions, 11 deletions
diff --git a/macros/src/codegen/post_init.rs b/macros/src/codegen/post_init.rs
index 96c5df80..eec633ba 100644
--- a/macros/src/codegen/post_init.rs
+++ b/macros/src/codegen/post_init.rs
@@ -17,10 +17,14 @@ pub fn codegen(app: &App, analysis: &Analysis) -> Vec<TokenStream2> {
// If it's live
let cfgs = app.late_resources[name].cfgs.clone();
if analysis.locations.get(name).is_some() {
- // Need to also include the cfgs
stmts.push(quote!(
- #(#cfgs)*
- #mangled_name.as_mut_ptr().write(late.#name);
+ // We include the cfgs
+ #(#cfgs)*
+ // Late resource is a RacyCell<MaybeUninit<T>>
+ // - `get_mut_unchecked` to obtain `MaybeUninit<T>`
+ // - `as_mut_ptr` to obtain a raw pointer to `MaybeUninit<T>`
+ // - `write` the defined value for the late resource T
+ #mangled_name.get_mut_unchecked().as_mut_ptr().write(late.#name);
));
}
}
diff --git a/macros/src/codegen/resources.rs b/macros/src/codegen/resources.rs
index fa52b86d..89f70f84 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,18 +31,26 @@ 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())),
)
};
@@ -46,7 +61,7 @@ pub fn codegen(
#(#attrs)*
#(#cfgs)*
#section
- static mut #mangled_name: #ty = #expr;
+ static #mangled_name: #ty = #expr;
));
}
@@ -74,14 +89,16 @@ pub fn codegen(
));
let ptr = if expr.is_none() {
+ // late resource
quote!(
#(#cfgs)*
- #mangled_name.as_mut_ptr()
+ &mut #mangled_name.get_mut_unchecked().assume_init()
)
} else {
+ // early resource
quote!(
#(#cfgs)*
- &mut #mangled_name
+ unsafe { #mangled_name.get_mut_unchecked() }
)
};