Skip to content

Commit f049a3c

Browse files
committed
Add local spawner - also seems to have broken some pac resolution thing
1 parent bcfa2db commit f049a3c

File tree

3 files changed

+105
-37
lines changed

3 files changed

+105
-37
lines changed

rtic-macros/src/codegen/module.rs

Lines changed: 94 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::marker::PhantomData;
2+
13
use crate::syntax::{ast::App, Context};
24
use crate::{analyze::Analysis, codegen::bindings::interrupt_mod, codegen::util};
35
use proc_macro2::TokenStream as TokenStream2;
@@ -112,36 +114,6 @@ pub fn codegen(ctxt: Context, app: &App, analysis: &Analysis) -> TokenStream2 {
112114
let internal_context_name = util::internal_task_ident(name, "Context");
113115
let exec_name = util::internal_task_ident(name, "EXEC");
114116

115-
items.push(quote!(
116-
#(#cfgs)*
117-
/// Execution context
118-
#[allow(non_snake_case)]
119-
#[allow(non_camel_case_types)]
120-
pub struct #internal_context_name<'a> {
121-
#[doc(hidden)]
122-
__rtic_internal_p: ::core::marker::PhantomData<&'a ()>,
123-
#(#fields,)*
124-
}
125-
126-
#(#cfgs)*
127-
impl<'a> #internal_context_name<'a> {
128-
#[inline(always)]
129-
#[allow(missing_docs)]
130-
pub unsafe fn new(#core) -> Self {
131-
#internal_context_name {
132-
__rtic_internal_p: ::core::marker::PhantomData,
133-
#(#values,)*
134-
}
135-
}
136-
}
137-
));
138-
139-
module_items.push(quote!(
140-
#(#cfgs)*
141-
#[doc(inline)]
142-
pub use super::#internal_context_name as Context;
143-
));
144-
145117
if let Context::SoftwareTask(t) = ctxt {
146118
let spawnee = &app.software_tasks[name];
147119
let priority = spawnee.args.priority;
@@ -212,21 +184,112 @@ pub fn codegen(ctxt: Context, app: &App, analysis: &Analysis) -> TokenStream2 {
212184
}
213185
));
214186

215-
if is_local_task {
187+
if !is_local_task {
216188
module_items.push(quote!(
217189
#(#cfgs)*
218190
#[doc(inline)]
219191
pub use super::#internal_spawn_ident as spawn;
220192
));
221193
}
222194

195+
let local_tasks_on_same_executor: Vec<_> = app
196+
.software_tasks
197+
.iter()
198+
//.filter(|(_, t)| t.args.is_local_task && t.args.priority == priority)
199+
.map(|(_, t)| t)
200+
.collect();
201+
202+
if !local_tasks_on_same_executor.is_empty() {
203+
fields.push(quote! {
204+
/// Used to spawn tasks on the same executor
205+
///
206+
/// This is useful for tasks that take args which are !Send/!Sync.
207+
///
208+
/// NOTE: This only works with tasks marked `is_local_task = true`
209+
/// and which have the same priority and thus will run on the
210+
/// same executor.
211+
pub local_spawner: LocalSpawner
212+
});
213+
let tasks = local_tasks_on_same_executor
214+
.iter()
215+
.map(|task| {
216+
// Copied mostly from software_tasks.rs
217+
let context = &task.context;
218+
let attrs = &task.attrs;
219+
let cfgs = &task.cfgs;
220+
let inputs = &task.inputs;
221+
let lifetime = if task.is_bottom {
222+
quote!('static)
223+
} else {
224+
quote!('a)
225+
};
226+
let generics = if task.is_bottom {
227+
quote!()
228+
} else {
229+
quote!(<'a>)
230+
};
231+
let input_vals = inputs.iter().map(|i| &i.pat).collect::<Vec<_>>();
232+
quote! {
233+
#(#attrs)*
234+
#(#cfgs)*
235+
#[allow(non_snake_case)]
236+
fn #name #generics(&self #(,#inputs)*) {
237+
// SAFETY: This is safe to call since this can only be called
238+
// from the same executor
239+
unsafe { #internal_spawn_ident(#(#input_vals,)*) } // <-- TODO strip the types
240+
}
241+
}
242+
})
243+
.collect::<Vec<_>>();
244+
values.push(quote!(local_spawner: LocalSpawner { _p: PhantomData }));
245+
module_items.push(quote! {
246+
struct LocalSpawner {
247+
_p: PhantomData<*mut ()>,
248+
}
249+
250+
impl LocalSpawner {
251+
#(#tasks)*
252+
}
253+
});
254+
}
255+
223256
module_items.push(quote!(
224257
#(#cfgs)*
225258
#[doc(inline)]
226259
pub use super::#internal_waker_ident as waker;
227260
));
228261
}
229262

263+
items.push(quote!(
264+
#(#cfgs)*
265+
/// Execution context
266+
#[allow(non_snake_case)]
267+
#[allow(non_camel_case_types)]
268+
pub struct #internal_context_name<'a> {
269+
#[doc(hidden)]
270+
__rtic_internal_p: ::core::marker::PhantomData<&'a ()>,
271+
#(#fields,)*
272+
}
273+
274+
#(#cfgs)*
275+
impl<'a> #internal_context_name<'a> {
276+
#[inline(always)]
277+
#[allow(missing_docs)]
278+
pub unsafe fn new(#core) -> Self {
279+
#internal_context_name {
280+
__rtic_internal_p: ::core::marker::PhantomData,
281+
#(#values,)*
282+
}
283+
}
284+
}
285+
));
286+
287+
module_items.push(quote!(
288+
#(#cfgs)*
289+
#[doc(inline)]
290+
pub use super::#internal_context_name as Context;
291+
));
292+
230293
if items.is_empty() {
231294
quote!()
232295
} else {

rtic-macros/src/codegen/software_tasks.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,16 @@ pub fn codegen(app: &App, analysis: &Analysis) -> TokenStream2 {
3737
let cfgs = &task.cfgs;
3838
let stmts = &task.stmts;
3939
let inputs = &task.inputs;
40-
let lifetime = if task.is_bottom { quote!('static) } else { quote!('a) };
41-
let generics = if task.is_bottom { quote!() } else { quote!(<'a>) };
40+
let lifetime = if task.is_bottom {
41+
quote!('static)
42+
} else {
43+
quote!('a)
44+
};
45+
let generics = if task.is_bottom {
46+
quote!()
47+
} else {
48+
quote!(<'a>)
49+
};
4250

4351
user_tasks.push(quote!(
4452
#(#attrs)*
@@ -47,9 +55,6 @@ pub fn codegen(app: &App, analysis: &Analysis) -> TokenStream2 {
4755
async fn #name #generics(#context: #name::Context<#lifetime> #(,#inputs)*) {
4856
use rtic::Mutex as _;
4957
use rtic::mutex::prelude::*;
50-
mod local_spawn {
51-
//#tasks_with_same_prio
52-
}
5358

5459
#(#stmts)*
5560
}

rtic-macros/src/syntax.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use indexmap::{IndexMap, IndexSet};
77
use proc_macro2::TokenStream as TokenStream2;
88
use syn::Ident;
99

10-
use crate::syntax::ast::App;
10+
use crate::syntax::ast::{App, SoftwareTask};
1111

1212
mod accessors;
1313
pub mod analyze;

0 commit comments

Comments
 (0)