Add spawn/spawn_pool APIs to Task
This commit is contained in:
parent
5c2bf3981e
commit
8c2da193b8
5 changed files with 36 additions and 24 deletions
|
@ -105,7 +105,7 @@ pub fn task(args: TokenStream, item: TokenStream) -> TokenStream {
|
||||||
type F = #impl_ty;
|
type F = #impl_ty;
|
||||||
const NEW_TASK: Task<F> = Task::new();
|
const NEW_TASK: Task<F> = Task::new();
|
||||||
static POOL: [Task<F>; #pool_size] = [NEW_TASK; #pool_size];
|
static POOL: [Task<F>; #pool_size] = [NEW_TASK; #pool_size];
|
||||||
unsafe { Task::spawn(&POOL, move || task(#arg_names)) }
|
unsafe { Task::spawn_pool(&POOL, move || task(#arg_names)) }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
result.into()
|
result.into()
|
||||||
|
|
|
@ -1,11 +1,7 @@
|
||||||
pub use embassy_macros::task;
|
pub use embassy_macros::task;
|
||||||
|
|
||||||
use atomic_polyfill::Ordering;
|
|
||||||
use core::future::Future;
|
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
use core::pin::Pin;
|
|
||||||
use core::ptr::NonNull;
|
use core::ptr::NonNull;
|
||||||
use core::task::{Context, Poll};
|
|
||||||
use core::{mem, ptr};
|
use core::{mem, ptr};
|
||||||
|
|
||||||
pub mod raw;
|
pub mod raw;
|
||||||
|
@ -15,7 +11,6 @@ mod timer_queue;
|
||||||
mod util;
|
mod util;
|
||||||
mod waker;
|
mod waker;
|
||||||
|
|
||||||
use self::util::UninitCell;
|
|
||||||
use crate::fmt::panic;
|
use crate::fmt::panic;
|
||||||
use crate::interrupt::{Interrupt, InterruptExt};
|
use crate::interrupt::{Interrupt, InterruptExt};
|
||||||
use crate::time::Alarm;
|
use crate::time::Alarm;
|
||||||
|
|
|
@ -87,23 +87,10 @@ impl<F: Future + 'static> Task<F> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn spawn(pool: &'static [Self], future: impl FnOnce() -> F) -> SpawnToken<F> {
|
pub fn spawn_pool(pool: &'static [Self], future: impl FnOnce() -> F) -> SpawnToken<F> {
|
||||||
for task in pool {
|
for task in pool {
|
||||||
let state = STATE_SPAWNED | STATE_RUN_QUEUED;
|
if task.spawn_allocate() {
|
||||||
if task
|
return unsafe { task.spawn_initialize(future) };
|
||||||
.raw
|
|
||||||
.state
|
|
||||||
.compare_exchange(0, state, Ordering::AcqRel, Ordering::Acquire)
|
|
||||||
.is_ok()
|
|
||||||
{
|
|
||||||
// Initialize the task
|
|
||||||
task.raw.poll_fn.write(Self::poll);
|
|
||||||
task.future.write(future());
|
|
||||||
|
|
||||||
return SpawnToken {
|
|
||||||
raw_task: Some(NonNull::new_unchecked(&task.raw as *const TaskHeader as _)),
|
|
||||||
phantom: PhantomData,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,6 +100,36 @@ impl<F: Future + 'static> Task<F> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn spawn(&'static self, future: impl FnOnce() -> F) -> SpawnToken<F> {
|
||||||
|
if self.spawn_allocate() {
|
||||||
|
unsafe { self.spawn_initialize(future) }
|
||||||
|
} else {
|
||||||
|
SpawnToken {
|
||||||
|
raw_task: None,
|
||||||
|
phantom: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn spawn_allocate(&'static self) -> bool {
|
||||||
|
let state = STATE_SPAWNED | STATE_RUN_QUEUED;
|
||||||
|
self.raw
|
||||||
|
.state
|
||||||
|
.compare_exchange(0, state, Ordering::AcqRel, Ordering::Acquire)
|
||||||
|
.is_ok()
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn spawn_initialize(&'static self, future: impl FnOnce() -> F) -> SpawnToken<F> {
|
||||||
|
// Initialize the task
|
||||||
|
self.raw.poll_fn.write(Self::poll);
|
||||||
|
self.future.write(future());
|
||||||
|
|
||||||
|
return SpawnToken {
|
||||||
|
raw_task: Some(NonNull::new_unchecked(&self.raw as *const TaskHeader as _)),
|
||||||
|
phantom: PhantomData,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
unsafe fn poll(p: NonNull<TaskHeader>) {
|
unsafe fn poll(p: NonNull<TaskHeader>) {
|
||||||
let this = &*(p.as_ptr() as *const Task<F>);
|
let this = &*(p.as_ptr() as *const Task<F>);
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use atomic_polyfill::{AtomicPtr, Ordering};
|
use atomic_polyfill::Ordering;
|
||||||
use core::cell::Cell;
|
use core::cell::Cell;
|
||||||
use core::cmp::min;
|
use core::cmp::min;
|
||||||
use core::ptr;
|
use core::ptr;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use core::ptr;
|
use core::ptr;
|
||||||
use cortex_m::peripheral::NVIC;
|
use cortex_m::peripheral::NVIC;
|
||||||
|
|
||||||
use atomic_polyfill::{AtomicBool, AtomicPtr, Ordering};
|
use atomic_polyfill::{AtomicPtr, Ordering};
|
||||||
|
|
||||||
pub use embassy_macros::interrupt_declare as declare;
|
pub use embassy_macros::interrupt_declare as declare;
|
||||||
pub use embassy_macros::interrupt_take as take;
|
pub use embassy_macros::interrupt_take as take;
|
||||||
|
|
Loading…
Reference in a new issue