diff options
| author | Dario Nieuwenhuis <[email protected]> | 2021-03-18 00:38:27 +0100 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2021-03-18 00:38:27 +0100 |
| commit | 8c2da193b88488f0995b6d83d57b7d5d61e14ffe (patch) | |
| tree | a0dfe4d9b3e6f331208f56a9e86357e87697153c | |
| parent | 5c2bf3981ed81a7e2ff6300056c671733c810566 (diff) | |
Add spawn/spawn_pool APIs to Task
| -rw-r--r-- | embassy-macros/src/lib.rs | 2 | ||||
| -rw-r--r-- | embassy/src/executor/mod.rs | 5 | ||||
| -rw-r--r-- | embassy/src/executor/raw.rs | 49 | ||||
| -rw-r--r-- | embassy/src/executor/timer_queue.rs | 2 | ||||
| -rw-r--r-- | embassy/src/interrupt.rs | 2 |
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 @@ | |||
| 1 | pub use embassy_macros::task; | 1 | pub use embassy_macros::task; |
| 2 | 2 | ||
| 3 | use atomic_polyfill::Ordering; | ||
| 4 | use core::future::Future; | ||
| 5 | use core::marker::PhantomData; | 3 | use core::marker::PhantomData; |
| 6 | use core::pin::Pin; | ||
| 7 | use core::ptr::NonNull; | 4 | use core::ptr::NonNull; |
| 8 | use core::task::{Context, Poll}; | ||
| 9 | use core::{mem, ptr}; | 5 | use core::{mem, ptr}; |
| 10 | 6 | ||
| 11 | pub mod raw; | 7 | pub mod raw; |
| @@ -15,7 +11,6 @@ mod timer_queue; | |||
| 15 | mod util; | 11 | mod util; |
| 16 | mod waker; | 12 | mod waker; |
| 17 | 13 | ||
| 18 | use self::util::UninitCell; | ||
| 19 | use crate::fmt::panic; | 14 | use crate::fmt::panic; |
| 20 | use crate::interrupt::{Interrupt, InterruptExt}; | 15 | use crate::interrupt::{Interrupt, InterruptExt}; |
| 21 | use crate::time::Alarm; | 16 | use 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 @@ | |||
| 1 | use atomic_polyfill::{AtomicPtr, Ordering}; | 1 | use atomic_polyfill::Ordering; |
| 2 | use core::cell::Cell; | 2 | use core::cell::Cell; |
| 3 | use core::cmp::min; | 3 | use core::cmp::min; |
| 4 | use core::ptr; | 4 | use 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 @@ | |||
| 1 | use core::ptr; | 1 | use core::ptr; |
| 2 | use cortex_m::peripheral::NVIC; | 2 | use cortex_m::peripheral::NVIC; |
| 3 | 3 | ||
| 4 | use atomic_polyfill::{AtomicBool, AtomicPtr, Ordering}; | 4 | use atomic_polyfill::{AtomicPtr, Ordering}; |
| 5 | 5 | ||
| 6 | pub use embassy_macros::interrupt_declare as declare; | 6 | pub use embassy_macros::interrupt_declare as declare; |
| 7 | pub use embassy_macros::interrupt_take as take; | 7 | pub use embassy_macros::interrupt_take as take; |
