Skip to content

Commit bcfa2db

Browse files
committed
Try to add spawn-local
1 parent 300ad99 commit bcfa2db

File tree

5 files changed

+51
-15
lines changed

5 files changed

+51
-15
lines changed

rtic-macros/src/codegen/module.rs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ pub fn codegen(ctxt: Context, app: &App, analysis: &Analysis) -> TokenStream2 {
142142
pub use super::#internal_context_name as Context;
143143
));
144144

145-
if let Context::SoftwareTask(..) = ctxt {
145+
if let Context::SoftwareTask(t) = ctxt {
146146
let spawnee = &app.software_tasks[name];
147147
let priority = spawnee.args.priority;
148148
let cfgs = &spawnee.cfgs;
@@ -163,13 +163,21 @@ pub fn codegen(ctxt: Context, app: &App, analysis: &Analysis) -> TokenStream2 {
163163
let (input_args, input_tupled, input_untupled, input_ty) =
164164
util::regroup_inputs(&spawnee.inputs);
165165

166+
let is_local_task = app.software_tasks[t].args.is_local_task;
167+
let unsafety = if is_local_task {
168+
// local tasks are only safe to call from the same executor
169+
quote! { unsafe }
170+
} else {
171+
quote! {}
172+
};
173+
166174
// Spawn caller
167175
items.push(quote!(
168176
#(#cfgs)*
169177
/// Spawns the task directly
170178
#[allow(non_snake_case)]
171179
#[doc(hidden)]
172-
pub fn #internal_spawn_ident(#(#input_args,)*) -> ::core::result::Result<(), #input_ty> {
180+
pub #unsafety fn #internal_spawn_ident(#(#input_args,)*) -> ::core::result::Result<(), #input_ty> {
173181
// SAFETY: If `try_allocate` succeeds one must call `spawn`, which we do.
174182
unsafe {
175183
let exec = rtic::export::executor::AsyncTaskExecutor::#from_ptr_n_args(#name, &#exec_name);
@@ -204,11 +212,13 @@ pub fn codegen(ctxt: Context, app: &App, analysis: &Analysis) -> TokenStream2 {
204212
}
205213
));
206214

207-
module_items.push(quote!(
208-
#(#cfgs)*
209-
#[doc(inline)]
210-
pub use super::#internal_spawn_ident as spawn;
211-
));
215+
if is_local_task {
216+
module_items.push(quote!(
217+
#(#cfgs)*
218+
#[doc(inline)]
219+
pub use super::#internal_spawn_ident as spawn;
220+
));
221+
}
212222

213223
module_items.push(quote!(
214224
#(#cfgs)*

rtic-macros/src/codegen/software_tasks.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ pub fn codegen(app: &App, analysis: &Analysis) -> TokenStream2 {
4747
async fn #name #generics(#context: #name::Context<#lifetime> #(,#inputs)*) {
4848
use rtic::Mutex as _;
4949
use rtic::mutex::prelude::*;
50+
mod local_spawn {
51+
//#tasks_with_same_prio
52+
}
5053

5154
#(#stmts)*
5255
}

rtic-macros/src/syntax/analyze.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -285,13 +285,16 @@ pub(crate) fn app(app: &App) -> Result<Analysis, syn::Error> {
285285
for (name, spawnee) in &app.software_tasks {
286286
let spawnee_prio = spawnee.args.priority;
287287

288+
// TODO: What is this?
288289
let channel = channels.entry(spawnee_prio).or_default();
289290
channel.tasks.insert(name.clone());
290291

291-
// All inputs are send as we do not know from where they may be spawned.
292-
spawnee.inputs.iter().for_each(|input| {
293-
send_types.insert(input.ty.clone());
294-
});
292+
if !spawnee.args.is_local_task {
293+
// All inputs are send as we do not know from where they may be spawned.
294+
spawnee.inputs.iter().for_each(|input| {
295+
send_types.insert(input.ty.clone());
296+
});
297+
}
295298
}
296299

297300
// No channel should ever be empty

rtic-macros/src/syntax/ast.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,12 @@ pub struct SoftwareTaskArgs {
256256

257257
/// Shared resources that can be accessed from this context
258258
pub shared_resources: SharedResources,
259+
260+
/// Local tasks
261+
///
262+
/// Local tasks can only be spawned from the same executor.
263+
/// However they do not require Send and Sync
264+
pub is_local_task: bool,
259265
}
260266

261267
impl Default for SoftwareTaskArgs {
@@ -264,6 +270,7 @@ impl Default for SoftwareTaskArgs {
264270
priority: 0,
265271
local_resources: LocalResources::new(),
266272
shared_resources: SharedResources::new(),
273+
is_local_task: false,
267274
}
268275
}
269276
}

rtic-macros/src/syntax/parse.rs

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,7 @@ mod util;
88

99
use proc_macro2::TokenStream as TokenStream2;
1010
use syn::{
11-
braced,
12-
parse::{self, Parse, ParseStream, Parser},
13-
token::Brace,
14-
Attribute, Ident, Item, LitInt, Meta, Token,
11+
braced, parse::{self, Parse, ParseStream, Parser}, token::Brace, Attribute, Ident, Item, LitBool, LitInt, Meta, Token
1512
};
1613

1714
use crate::syntax::{
@@ -197,6 +194,7 @@ fn task_args(tokens: TokenStream2) -> parse::Result<Either<HardwareTaskArgs, Sof
197194
let mut shared_resources = None;
198195
let mut local_resources = None;
199196
let mut prio_span = None;
197+
let mut is_local_task = None;
200198

201199
loop {
202200
if input.is_empty() {
@@ -277,6 +275,19 @@ fn task_args(tokens: TokenStream2) -> parse::Result<Either<HardwareTaskArgs, Sof
277275
local_resources = Some(util::parse_local_resources(input)?);
278276
}
279277

278+
"is_local_task" => {
279+
if is_local_task.is_some() {
280+
return Err(parse::Error::new(
281+
ident.span(),
282+
"argument appears more than once",
283+
));
284+
}
285+
286+
let lit: LitBool = input.parse()?;
287+
288+
is_local_task = Some(lit.value);
289+
}
290+
280291
_ => {
281292
return Err(parse::Error::new(ident.span(), "unexpected argument"));
282293
}
@@ -291,6 +302,7 @@ fn task_args(tokens: TokenStream2) -> parse::Result<Either<HardwareTaskArgs, Sof
291302
}
292303
let shared_resources = shared_resources.unwrap_or_default();
293304
let local_resources = local_resources.unwrap_or_default();
305+
let is_local_task = is_local_task.unwrap_or(false);
294306

295307
Ok(if let Some(binds) = binds {
296308
// Hardware tasks can't run at anything lower than 1
@@ -317,6 +329,7 @@ fn task_args(tokens: TokenStream2) -> parse::Result<Either<HardwareTaskArgs, Sof
317329
priority,
318330
shared_resources,
319331
local_resources,
332+
is_local_task,
320333
})
321334
})
322335
})

0 commit comments

Comments
 (0)