aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2021-03-18 00:38:27 +0100
committerDario Nieuwenhuis <[email protected]>2021-03-18 00:38:27 +0100
commit8c2da193b88488f0995b6d83d57b7d5d61e14ffe (patch)
treea0dfe4d9b3e6f331208f56a9e86357e87697153c
parent5c2bf3981ed81a7e2ff6300056c671733c810566 (diff)
Add spawn/spawn_pool APIs to Task
-rw-r--r--embassy-macros/src/lib.rs2
-rw-r--r--embassy/src/executor/mod.rs5
-rw-r--r--embassy/src/executor/raw.rs49
-rw-r--r--embassy/src/executor/timer_queue.rs2
-rw-r--r--embassy/src/interrupt.rs2
5 files changed, 36 insertions, 24 deletions
diff --git a/embassy-macros/src/lib.rs b/embassy-macros/src/lib.rs
index f207497d5..0bc5f0035 100644
--- a/embassy-macros/src/lib.rs
+++ b/embassy-macros/src/lib.rs
@@ -105,7 +105,7 @@ pub fn task(args: TokenStream, item: TokenStream) -> TokenStream {
105 type F = #impl_ty; 105 type F = #impl_ty;
106 const NEW_TASK: Task<F> = Task::new(); 106 const NEW_TASK: Task<F> = Task::new();
107 static POOL: [Task<F>; #pool_size] = [NEW_TASK; #pool_size]; 107 static POOL: [Task<F>; #pool_size] = [NEW_TASK; #pool_size];
108 unsafe { Task::spawn(&POOL, move || task(#arg_names)) } 108 unsafe { Task::spawn_pool(&POOL, move || task(#arg_names)) }
109 } 109 }
110 }; 110 };
111 result.into() 111 result.into()
diff --git a/embassy/src/executor/mod.rs b/embassy/src/executor/mod.rs
index 8b23264de..fedff73e2 100644
--- a/embassy/src/executor/mod.rs
+++ b/embassy/src/executor/mod.rs
@@ -1,11 +1,7 @@
1pub use embassy_macros::task; 1pub use embassy_macros::task;
2 2
3use atomic_polyfill::Ordering;
4use core::future::Future;
5use core::marker::PhantomData; 3use core::marker::PhantomData;
6use core::pin::Pin;
7use core::ptr::NonNull; 4use core::ptr::NonNull;
8use core::task::{Context, Poll};
9use core::{mem, ptr}; 5use core::{mem, ptr};
10 6
11pub mod raw; 7pub mod raw;
@@ -15,7 +11,6 @@ mod timer_queue;
15mod util; 11mod util;
16mod waker; 12mod waker;
17 13
18use self::util::UninitCell;
19use crate::fmt::panic; 14use crate::fmt::panic;
20use crate::interrupt::{Interrupt, InterruptExt}; 15use crate::interrupt::{Interrupt, InterruptExt};
21use crate::time::Alarm; 16use crate::time::Alarm;
diff --git a/embassy/src/executor/raw.rs b/embassy/src/executor/raw.rs
index edc6d8053..7e981b084 100644
--- a/embassy/src/executor/raw.rs
+++ b/embassy/src/executor/raw.rs
@@ -87,23 +87,10 @@ impl<F: Future + 'static> Task<F> {
87 } 87 }
88 } 88 }
89 89
90 pub unsafe fn spawn(pool: &'static [Self], future: impl FnOnce() -> F) -> SpawnToken<F> { 90 pub fn spawn_pool(pool: &'static [Self], future: impl FnOnce() -> F) -> SpawnToken<F> {
91 for task in pool { 91 for task in pool {
92 let state = STATE_SPAWNED | STATE_RUN_QUEUED; 92 if task.spawn_allocate() {
93 if task 93 return unsafe { task.spawn_initialize(future) };
94 .raw
95 .state
96 .compare_exchange(0, state, Ordering::AcqRel, Ordering::Acquire)
97 .is_ok()
98 {
99 // Initialize the task
100 task.raw.poll_fn.write(Self::poll);
101 task.future.write(future());
102
103 return SpawnToken {
104 raw_task: Some(NonNull::new_unchecked(&task.raw as *const TaskHeader as _)),
105 phantom: PhantomData,
106 };
107 } 94 }
108 } 95 }
109 96
@@ -113,6 +100,36 @@ impl<F: Future + 'static> Task<F> {
113 } 100 }
114 } 101 }
115 102
103 pub fn spawn(&'static self, future: impl FnOnce() -> F) -> SpawnToken<F> {
104 if self.spawn_allocate() {
105 unsafe { self.spawn_initialize(future) }
106 } else {
107 SpawnToken {
108 raw_task: None,
109 phantom: PhantomData,
110 }
111 }
112 }
113
114 fn spawn_allocate(&'static self) -> bool {
115 let state = STATE_SPAWNED | STATE_RUN_QUEUED;
116 self.raw
117 .state
118 .compare_exchange(0, state, Ordering::AcqRel, Ordering::Acquire)
119 .is_ok()
120 }
121
122 unsafe fn spawn_initialize(&'static self, future: impl FnOnce() -> F) -> SpawnToken<F> {
123 // Initialize the task
124 self.raw.poll_fn.write(Self::poll);
125 self.future.write(future());
126
127 return SpawnToken {
128 raw_task: Some(NonNull::new_unchecked(&self.raw as *const TaskHeader as _)),
129 phantom: PhantomData,
130 };
131 }
132
116 unsafe fn poll(p: NonNull<TaskHeader>) { 133 unsafe fn poll(p: NonNull<TaskHeader>) {
117 let this = &*(p.as_ptr() as *const Task<F>); 134 let this = &*(p.as_ptr() as *const Task<F>);
118 135
diff --git a/embassy/src/executor/timer_queue.rs b/embassy/src/executor/timer_queue.rs
index a6939f110..76bc27ad4 100644
--- a/embassy/src/executor/timer_queue.rs
+++ b/embassy/src/executor/timer_queue.rs
@@ -1,4 +1,4 @@
1use atomic_polyfill::{AtomicPtr, Ordering}; 1use atomic_polyfill::Ordering;
2use core::cell::Cell; 2use core::cell::Cell;
3use core::cmp::min; 3use core::cmp::min;
4use core::ptr; 4use core::ptr;
diff --git a/embassy/src/interrupt.rs b/embassy/src/interrupt.rs
index 013e722e6..a4285a9fe 100644
--- a/embassy/src/interrupt.rs
+++ b/embassy/src/interrupt.rs
@@ -1,7 +1,7 @@
1use core::ptr; 1use core::ptr;
2use cortex_m::peripheral::NVIC; 2use cortex_m::peripheral::NVIC;
3 3
4use atomic_polyfill::{AtomicBool, AtomicPtr, Ordering}; 4use atomic_polyfill::{AtomicPtr, Ordering};
5 5
6pub use embassy_macros::interrupt_declare as declare; 6pub use embassy_macros::interrupt_declare as declare;
7pub use embassy_macros::interrupt_take as take; 7pub use embassy_macros::interrupt_take as take;