api test, all implemented, TODO hide priority?

This commit is contained in:
Per Lindgren 2021-10-18 17:39:51 +02:00 committed by Henrik Tjäder
parent 8917252dc5
commit f9d05fdad0
7 changed files with 51 additions and 36 deletions

View file

@ -46,10 +46,12 @@ mod app {
} }
// De-structure-ing syntax // De-structure-ing syntax
// TODO: hide priority field (or re-use priority from first resource)
#[task(shared = [&a, &b, &c])] #[task(shared = [&a, &b, &c])]
fn bar(cx: bar::Context) { 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();
} }
} }

View file

@ -72,6 +72,8 @@ pub fn codegen(
Context::HardwareTask(name), Context::HardwareTask(name),
&mut shared_needs_lt, &mut shared_needs_lt,
app, app,
analysis,
extra,
); );
root.push(item); root.push(item);

View file

@ -35,8 +35,13 @@ pub fn codegen(
let name = &idle.name; let name = &idle.name;
if !idle.args.shared_resources.is_empty() { if !idle.args.shared_resources.is_empty() {
let (item, constructor) = let (item, constructor) = shared_resources_struct::codegen(
shared_resources_struct::codegen(Context::Idle, &mut shared_needs_lt, app); Context::Idle,
&mut shared_needs_lt,
app,
analysis,
extra,
);
root_idle.push(item); root_idle.push(item);
mod_app.push(constructor); mod_app.push(constructor);

View file

@ -106,34 +106,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<RTIC_INTERNAL_R>(
&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) (mod_app, mod_resources)
} }

View file

@ -1,11 +1,17 @@
use proc_macro2::TokenStream as TokenStream2; use proc_macro2::TokenStream as TokenStream2;
use quote::quote; 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 /// 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 mut lt = None;
let resources = match ctxt { let resources = match ctxt {
@ -22,6 +28,7 @@ pub fn codegen(ctxt: Context, needs_lt: &mut bool, app: &App) -> (TokenStream2,
// Lock-all api related // Lock-all api related
let mut fields_mut = vec![]; let mut fields_mut = vec![];
let mut values_mut = vec![]; let mut values_mut = vec![];
let mut max_ceiling = 0;
for (name, access) in resources { for (name, access) in resources {
let res = app.shared_resources.get(name).expect("UNREACHABLE"); let res = app.shared_resources.get(name).expect("UNREACHABLE");
@ -75,6 +82,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 as the value has been filled,
continue; continue;
} }
@ -151,6 +167,18 @@ pub fn codegen(ctxt: Context, needs_lt: &mut bool, app: &App) -> (TokenStream2,
} else { } else {
Some(quote!(priority: &#lt rtic::export::Priority)) 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!( let implementations = quote!(
impl<#lt> #ident<#lt> { impl<#lt> #ident<#lt> {
#[inline(always)] #[inline(always)]
@ -176,6 +204,8 @@ pub fn codegen(ctxt: Context, needs_lt: &mut bool, app: &App) -> (TokenStream2,
} }
} }
} }
#lock_all
); );
(item, implementations) (item, implementations)

View file

@ -112,6 +112,8 @@ pub fn codegen(
Context::SoftwareTask(name), Context::SoftwareTask(name),
&mut shared_needs_lt, &mut shared_needs_lt,
app, app,
analysis,
extra,
); );
root.push(item); root.push(item);

View file

@ -70,6 +70,9 @@ impl Barrier {
} }
// Newtype over `Cell` that forbids mutation through a shared reference // 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 { pub struct Priority {
inner: Cell<u8>, inner: Cell<u8>,
} }