aboutsummaryrefslogtreecommitdiff
path: root/macros/src/codegen/schedule_body.rs
blob: 644930d7d7282426513d62add85f014277dc46fb (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
use proc_macro2::TokenStream as TokenStream2;
use quote::quote;
use rtic_syntax::{ast::App, Context};
use syn::Ident;

use crate::codegen::util;

pub fn codegen(scheduler: Context, name: &Ident, app: &App) -> TokenStream2 {
    let schedulee = &app.software_tasks[name];

    let fq = util::fq_ident(name);
    let tq = util::tq_ident();
    let (dequeue, enqueue) = if scheduler.is_init() {
        (quote!(#fq.dequeue()), quote!(#tq.enqueue_unchecked(nr);))
    } else {
        (
            quote!((#fq { priority }).lock(|fq| fq.split().1.dequeue())),
            quote!((#tq { priority }).lock(|tq| tq.enqueue_unchecked(nr));),
        )
    };

    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 (_, tupled, _, _) = util::regroup_inputs(&schedulee.inputs);
    let inputs = util::inputs_ident(name);
    let t = util::schedule_t_ident();
    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

                let nr = rtic::export::NotReady {
                    instant,
                    index,
                    task: #t::#name,
                };

                #enqueue

                Ok(())
            } else {
                Err(input)
            }
        }
    )
}