aboutsummaryrefslogtreecommitdiff
path: root/macros/src/codegen/software_tasks.rs
blob: 6bd2a71f11fb87fd6f3e04a6ca270c398787f181 (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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
use proc_macro2::TokenStream as TokenStream2;
use quote::quote;
use rtic_syntax::{ast::App, Context};

use crate::{
    analyze::Analysis,
    check::Extra,
    codegen::{local_resources_struct, module, shared_resources_struct, util},
};

pub fn codegen(
    app: &App,
    analysis: &Analysis,
    extra: &Extra,
) -> (
    // mod_app_software_tasks -- free queues, buffers and `${task}Resources` constructors
    Vec<TokenStream2>,
    // root_software_tasks -- items that must be placed in the root of the crate:
    // - `${task}Locals` structs
    // - `${task}Resources` structs
    // - `${task}` modules
    Vec<TokenStream2>,
    // user_software_tasks -- the `#[task]` functions written by the user
    Vec<TokenStream2>,
) {
    let mut mod_app = vec![];
    let mut root = vec![];
    let mut user_tasks = vec![];

    for (name, task) in &app.software_tasks {
        let inputs = &task.inputs;
        let (_, _, _, input_ty) = util::regroup_inputs(inputs);

        let cap = task.args.capacity;
        let cap_lit = util::capacity_literal(cap as usize);
        let cap_lit_p1 = util::capacity_literal(cap as usize + 1);

        // Create free queues and inputs / instants buffers
        let fq = util::fq_ident(name);

        #[allow(clippy::redundant_closure)]
        let (fq_ty, fq_expr, mk_uninit): (_, _, Box<dyn Fn() -> Option<_>>) = {
            (
                quote!(rtic::export::SCFQ<#cap_lit_p1>),
                quote!(rtic::export::Queue::new()),
                Box::new(|| Some(util::link_section_uninit())),
            )
        };
        mod_app.push(quote!(
            // /// Queue version of a free-list that keeps track of empty slots in
            // /// the following buffers
            #[allow(non_camel_case_types)]
            #[allow(non_upper_case_globals)]
            #[doc(hidden)]
            static #fq: rtic::RacyCell<#fq_ty> = rtic::RacyCell::new(#fq_expr);
        ));

        let elems = &(0..cap)
            .map(|_| quote!(core::mem::MaybeUninit::uninit()))
            .collect::<Vec<_>>();

        for (_, monotonic) in &app.monotonics {
            let instants = util::monotonic_instants_ident(name, &monotonic.ident);
            let mono_type = &monotonic.ty;
            let cfgs = &monotonic.cfgs;

            let uninit = mk_uninit();
            // For future use
            // let doc = format!(" RTIC internal: {}:{}", file!(), line!());
            mod_app.push(quote!(
                #uninit
                // /// Buffer that holds the instants associated to the inputs of a task
                // #[doc = #doc]
                #[allow(non_camel_case_types)]
                #[allow(non_upper_case_globals)]
                #[doc(hidden)]
                #(#cfgs)*
                static #instants:
                    rtic::RacyCell<[core::mem::MaybeUninit<<#mono_type as rtic::Monotonic>::Instant>; #cap_lit]> =
                    rtic::RacyCell::new([#(#elems,)*]);
            ));
        }

        let uninit = mk_uninit();
        let inputs_ident = util::inputs_ident(name);
        mod_app.push(quote!(
            #uninit
            // /// Buffer that holds the inputs of a task
            #[allow(non_camel_case_types)]
            #[allow(non_upper_case_globals)]
            #[doc(hidden)]
            static #inputs_ident: rtic::RacyCell<[core::mem::MaybeUninit<#input_ty>; #cap_lit]> =
                rtic::RacyCell::new([#(#elems,)*]);
        ));

        // `${task}Resources`
        let mut shared_needs_lt = false;
        let mut local_needs_lt = false;

        // `${task}Locals`
        if !task.args.local_resources.is_empty() {
            let (item, constructor) = local_resources_struct::codegen(
                Context::SoftwareTask(name),
                &mut local_needs_lt,
                app,
            );

            root.push(item);

            mod_app.push(constructor);
        }

        if !task.args.shared_resources.is_empty() {
            let (item, constructor) = shared_resources_struct::codegen(
                Context::SoftwareTask(name),
                &mut shared_needs_lt,
                app,
            );

            root.push(item);

            mod_app.push(constructor);
        }

        if !&task.is_extern {
            let context = &task.context;
            let attrs = &task.attrs;
            let cfgs = &task.cfgs;
            let stmts = &task.stmts;
            let user_task_doc = format!(" User SW task {name}");
            user_tasks.push(quote!(
                #[doc = #user_task_doc]
                #(#attrs)*
                #(#cfgs)*
                #[allow(non_snake_case)]
                fn #name(#context: #name::Context #(,#inputs)*) {
                    use rtic::Mutex as _;
                    use rtic::mutex::prelude::*;

                    #(#stmts)*
                }
            ));
        }

        root.push(module::codegen(
            Context::SoftwareTask(name),
            shared_needs_lt,
            local_needs_lt,
            app,
            analysis,
            extra,
        ));
    }

    (mod_app, root, user_tasks)
}
> 2022-01-10[ci] update lockfile (#2351)Gravatar Fred K. Schott 1-116/+116 2022-01-10Update instructions for the monorepo (#2274)Gravatar Caleb Jasik 1-5/+12 2022-01-10Fix Astro Preview Pathing Issues (#2338)Gravatar Jonathan Neal 5-144/+150 2022-01-10[ci] collect statsGravatar FredKSchott 1-0/+1 2022-01-09[ci] collect statsGravatar FredKSchott 1-0/+1 2022-01-08[ci] update lockfile (#2344)Gravatar Fred K. Schott 1-33/+33 2022-01-08Fix sitemap.xml page urls (#2335)Gravatar Jonathan Neal 4-4/+8 2022-01-08[ci] collect statsGravatar FredKSchott 1-0/+1 2022-01-07Create .git-blame-ignore-revs (#2254)Gravatar Jonathan Neal 2-0/+8 2022-01-07Fix issue with plugins running twice in dev and build (#2323)Gravatar Jonathan Neal 2-2/+5 2022-01-07[ci] yarn formatGravatar matthewp 1-8/+8 2022-01-07[ci] release (#2339)astro@0.22.9Gravatar github-actions[bot] 28-39/+40 2022-01-07[ci] yarn formatGravatar matthewp 3-7/+8 2022-01-07Handle loading the Code package in the static build (#2337)Gravatar Matthew Phillips 8-4/+87 2022-01-07[ci] update lockfile (#2334)Gravatar Fred K. Schott 1-154/+154 2022-01-07[ci] yarn formatGravatar matthewp 1-8/+8 2022-01-07[ci] release (#2333)astro@0.22.8Gravatar github-actions[bot] 28-39/+40 2022-01-07[ci] collect statsGravatar FredKSchott 1-0/+1 2022-01-06[ci] yarn formatGravatar matthewp 4-54/+54 2022-01-06[ci] update lockfile (#2327)Gravatar Fred K. Schott 1-58/+64 2022-01-06Fix subpath support regressions (#2330)Gravatar Matthew Phillips 12-22/+566 2022-01-06[ci] yarn formatGravatar natemoo-re 1-2/+2 2022-01-06Added "IntelliSense for TypeScript" (#2326)astro@0.22.7Gravatar Morritz 1-0/+17 2022-01-06[ci] collect statsGravatar FredKSchott 1-0/+1 2022-01-06[ci] yarn formatGravatar FredKSchott 1-8/+8 2022-01-05[ci] release (#2320)Gravatar github-actions[bot] 31-54/+46 2022-01-05chore: update compiler (#2324)Gravatar Nate Moore 3-5/+10