diff options
author | 2020-10-15 16:42:30 +0000 | |
---|---|---|
committer | 2020-10-15 16:42:30 +0000 | |
commit | 355cb82d0693fe108ac28ec8a0d77e8aab4e6e06 (patch) | |
tree | 67c0eadf6d8a98a2691b816d46a5103d159d6bbc /macros/src/codegen/spawn_body.rs | |
parent | f9303cef1cf5b2d57d26e7667289fbdccf959ea8 (diff) | |
parent | 6808cc7cdf1512a7b10dd43f268f430a676c606e (diff) | |
download | rtic-355cb82d0693fe108ac28ec8a0d77e8aab4e6e06.tar.gz rtic-355cb82d0693fe108ac28ec8a0d77e8aab4e6e06.tar.zst rtic-355cb82d0693fe108ac28ec8a0d77e8aab4e6e06.zip |
Merge #390
390: Spawn and schedule from anywhere r=AfoHT a=korken89
This PR moves RTIC to the spawn and schedule from anywhere syntax.
Notable changes:
* We do no longer support non-`Send` types.
* Some extra code is generated as any task may spawn/schedule any task. However Rust/LLVM does a great job optimizing away non used instantiations (no real code-size difference observed).
* Worst case priority inversion has increased, but it is now predictable.
Upsides:
* With this we should be able to support async/await.
* RTIC tasks can now be callbacks (spawned and scheduled).
* RTIC tasks can be stored.
Needs the following PR to land first: https://github.com/rtic-rs/rtic-syntax/pull/34
The following now works:
```rust
#[rtic::app(device = lm3s6965, monotonic = rtic::cyccnt::CYCCNT)]
mod app {
#[init]
fn init(mut cx: init::Context) -> init::LateResources {
// Init stuff...
// New spawn syntax
foo::spawn().unwrap();
// New schedule syntax
bar::schedule(now + 4_000_000.cycles()).unwrap();
init::LateResources {}
}
#[task]
fn foo(_: foo::Context) {}
#[task]
fn bar(_: bar::Context) {}
extern "C" {
fn SSI0();
}
}
```
Co-authored-by: Per Lindgren <per.lindgren@ltu.se>
Co-authored-by: Emil Fresk <emil.fresk@gmail.com>
Diffstat (limited to 'macros/src/codegen/spawn_body.rs')
-rw-r--r-- | macros/src/codegen/spawn_body.rs | 75 |
1 files changed, 0 insertions, 75 deletions
diff --git a/macros/src/codegen/spawn_body.rs b/macros/src/codegen/spawn_body.rs deleted file mode 100644 index f29393a6..00000000 --- a/macros/src/codegen/spawn_body.rs +++ /dev/null @@ -1,75 +0,0 @@ -use proc_macro2::TokenStream as TokenStream2; -use quote::quote; -use rtic_syntax::{ast::App, Context}; -use syn::Ident; - -use crate::{analyze::Analysis, check::Extra, codegen::util}; - -pub fn codegen( - spawner: Context, - name: &Ident, - app: &App, - analysis: &Analysis, - _extra: &Extra, -) -> TokenStream2 { - let spawnee = &app.software_tasks[name]; - let priority = spawnee.args.priority; - - let write_instant = if app.uses_schedule() { - let instants = util::instants_ident(name); - - Some(quote!( - #instants.get_unchecked_mut(usize::from(index)).as_mut_ptr().write(instant); - )) - } else { - None - }; - - let t = util::spawn_t_ident(priority); - let fq = util::fq_ident(name); - let rq = util::rq_ident(priority); - let (dequeue, enqueue) = if spawner.is_init() { - ( - quote!(#fq.dequeue()), - quote!(#rq.enqueue_unchecked((#t::#name, index));), - ) - } else { - ( - quote!((#fq { priority }.lock(|fq| fq.split().1.dequeue()))), - quote!((#rq { priority }.lock(|rq| { - rq.split().0.enqueue_unchecked((#t::#name, index)) - }));), - ) - }; - - let enum_ = util::interrupt_ident(); - let interrupt = &analysis.interrupts.get(&priority); - let pend = { - quote!( - rtic::pend(you_must_enable_the_rt_feature_for_the_pac_in_your_cargo_toml::#enum_::#interrupt); - ) - }; - - let (_, tupled, _, _) = util::regroup_inputs(&spawnee.inputs); - let inputs = util::inputs_ident(name); - quote!( - unsafe { - use rtic::Mutex as _; - - let input = #tupled; - if let Some(index) = #dequeue { - #inputs.get_unchecked_mut(usize::from(index)).as_mut_ptr().write(input); - - #write_instant - - #enqueue - - #pend - - Ok(()) - } else { - Err(input) - } - } - ) -} |