aboutsummaryrefslogtreecommitdiff
path: root/embassy-macros/src
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2021-02-02 05:14:52 +0100
committerDario Nieuwenhuis <[email protected]>2021-02-02 05:20:41 +0100
commitaeaa34d7a163b327643c08e299e1b40bb497c01c (patch)
tree6054344c8a7d990b910416a1002aded9ad4d10eb /embassy-macros/src
parentd098952077b8fdc8426754151bb8064214a046fa (diff)
Executor API V2.
- It's no longer possible to call run() reentrantly from within a task (soundness issue) - it's now possible to spawn Send tasks across threads (SendSpawner, #37)
Diffstat (limited to 'embassy-macros/src')
-rw-r--r--embassy-macros/src/lib.rs20
1 files changed, 15 insertions, 5 deletions
diff --git a/embassy-macros/src/lib.rs b/embassy-macros/src/lib.rs
index cb16f65aa..23f1cda99 100644
--- a/embassy-macros/src/lib.rs
+++ b/embassy-macros/src/lib.rs
@@ -11,21 +11,23 @@ use syn::spanned::Spanned;
11struct MacroArgs { 11struct MacroArgs {
12 #[darling(default)] 12 #[darling(default)]
13 pool_size: Option<usize>, 13 pool_size: Option<usize>,
14 #[darling(default)]
15 send: bool,
14} 16}
15 17
16#[proc_macro_attribute] 18#[proc_macro_attribute]
17pub fn task(args: TokenStream, item: TokenStream) -> TokenStream { 19pub fn task(args: TokenStream, item: TokenStream) -> TokenStream {
18 let args = syn::parse_macro_input!(args as syn::AttributeArgs); 20 let macro_args = syn::parse_macro_input!(args as syn::AttributeArgs);
19 let mut task_fn = syn::parse_macro_input!(item as syn::ItemFn); 21 let mut task_fn = syn::parse_macro_input!(item as syn::ItemFn);
20 22
21 let args = match MacroArgs::from_list(&args) { 23 let macro_args = match MacroArgs::from_list(&macro_args) {
22 Ok(v) => v, 24 Ok(v) => v,
23 Err(e) => { 25 Err(e) => {
24 return TokenStream::from(e.write_errors()); 26 return TokenStream::from(e.write_errors());
25 } 27 }
26 }; 28 };
27 29
28 let pool_size: usize = args.pool_size.unwrap_or(1); 30 let pool_size: usize = macro_args.pool_size.unwrap_or(1);
29 31
30 let mut fail = false; 32 let mut fail = false;
31 if task_fn.sig.asyncness.is_none() { 33 if task_fn.sig.asyncness.is_none() {
@@ -90,11 +92,16 @@ pub fn task(args: TokenStream, item: TokenStream) -> TokenStream {
90 92
91 let visibility = &task_fn.vis; 93 let visibility = &task_fn.vis;
92 task_fn.sig.ident = format_ident!("task"); 94 task_fn.sig.ident = format_ident!("task");
95 let impl_ty = if macro_args.send {
96 quote!(impl ::core::future::Future + Send + 'static)
97 } else {
98 quote!(impl ::core::future::Future + 'static)
99 };
93 100
94 let result = quote! { 101 let result = quote! {
95 #visibility fn #name(#args) -> ::embassy::executor::SpawnToken { 102 #visibility fn #name(#args) -> ::embassy::executor::SpawnToken<#impl_ty> {
96 #task_fn 103 #task_fn
97 type F = impl ::core::future::Future + 'static; 104 type F = #impl_ty;
98 static POOL: [::embassy::executor::Task<F>; #pool_size] = [::embassy::executor::Task::new(); #pool_size]; 105 static POOL: [::embassy::executor::Task<F>; #pool_size] = [::embassy::executor::Task::new(); #pool_size];
99 unsafe { ::embassy::executor::Task::spawn(&POOL, move || task(#arg_names)) } 106 unsafe { ::embassy::executor::Task::spawn(&POOL, move || task(#arg_names)) }
100 } 107 }
@@ -119,6 +126,9 @@ pub fn interrupt_declare(item: TokenStream) -> TokenStream {
119 let irq = Interrupt::#name; 126 let irq = Interrupt::#name;
120 irq.nr() as u8 127 irq.nr() as u8
121 } 128 }
129 unsafe fn steal() -> Self {
130 Self(())
131 }
122 unsafe fn __handler(&self) -> &'static ::embassy::interrupt::Handler { 132 unsafe fn __handler(&self) -> &'static ::embassy::interrupt::Handler {
123 #[export_name = #name_handler] 133 #[export_name = #name_handler]
124 static HANDLER: ::embassy::interrupt::Handler = ::embassy::interrupt::Handler::new(); 134 static HANDLER: ::embassy::interrupt::Handler = ::embassy::interrupt::Handler::new();