pub mod prelude;
mod number;
mod routine;
mod task;
mod token;
mod tokens;
pub use self::number::ThreadNumber;
pub use self::routine::{RoutineFuture, RoutineStack, RoutineStreamRing,
RoutineStreamUnit};
pub use self::task::{init, TaskCell};
pub use self::token::ThreadToken;
pub use self::tokens::ThreadTokens;
pub use drone_core_macros::thread_local;
static mut CURRENT: usize = 0;
#[inline(always)]
pub fn current<T: Thread>() -> &'static T {
unsafe { (*T::all()).get_unchecked(CURRENT) }
}
pub trait Thread: Sized + Sync + 'static {
fn all() -> *mut [Self];
fn routines(&self) -> &RoutineStack;
fn routines_mut(&mut self) -> &mut RoutineStack;
fn task(&self) -> &TaskCell;
fn preempted(&mut self) -> &mut usize;
#[inline(always)]
fn routine<G>(&self, g: G)
where
G: Generator<Yield = (), Return = ()>,
G: Send + 'static,
{
self.routines().push(g);
}
#[inline(always)]
fn routine_fn<F>(&self, f: F)
where
F: FnOnce(),
F: Send + 'static,
{
self.routines().push(|| {
if false {
yield;
}
f()
});
}
#[inline(always)]
fn future<G, T, E>(&self, g: G) -> RoutineFuture<T, E>
where
G: Generator<Yield = (), Return = Result<T, E>>,
G: Send + 'static,
T: Send + 'static,
E: Send + 'static,
{
RoutineFuture::new(self, g)
}
#[inline(always)]
fn future_fn<F, T, E>(&self, f: F) -> RoutineFuture<T, E>
where
F: FnOnce() -> Result<T, E>,
F: Send + 'static,
T: Send + 'static,
E: Send + 'static,
{
RoutineFuture::new(self, || {
if false {
yield;
}
f()
})
}
#[inline(always)]
fn stream<G, E, O>(&self, overflow: O, g: G) -> RoutineStreamUnit<E>
where
G: Generator<Yield = Option<()>, Return = Result<Option<()>, E>>,
O: Fn() -> Result<(), E>,
G: Send + 'static,
E: Send + 'static,
O: Send + 'static,
{
RoutineStreamUnit::new(self, g, overflow)
}
#[inline(always)]
fn stream_skip<G, E>(&self, g: G) -> RoutineStreamUnit<E>
where
G: Generator<Yield = Option<()>, Return = Result<Option<()>, E>>,
G: Send + 'static,
E: Send + 'static,
{
RoutineStreamUnit::new(self, g, || Ok(()))
}
#[inline(always)]
fn stream_ring<G, T, E, O>(
&self,
capacity: usize,
overflow: O,
g: G,
) -> RoutineStreamRing<T, E>
where
G: Generator<Yield = Option<T>, Return = Result<Option<T>, E>>,
O: Fn(T) -> Result<(), E>,
G: Send + 'static,
T: Send + 'static,
E: Send + 'static,
O: Send + 'static,
{
RoutineStreamRing::new(self, capacity, g, overflow)
}
#[inline(always)]
fn stream_ring_skip<G, T, E>(
&self,
capacity: usize,
g: G,
) -> RoutineStreamRing<T, E>
where
G: Generator<Yield = Option<T>, Return = Result<Option<T>, E>>,
G: Send + 'static,
T: Send + 'static,
E: Send + 'static,
{
RoutineStreamRing::new(self, capacity, g, |_| Ok(()))
}
#[inline(always)]
fn stream_ring_overwrite<G, T, E>(
&self,
capacity: usize,
g: G,
) -> RoutineStreamRing<T, E>
where
G: Generator<Yield = Option<T>, Return = Result<Option<T>, E>>,
G: Send + 'static,
T: Send + 'static,
E: Send + 'static,
{
RoutineStreamRing::new_overwrite(self, capacity, g)
}
}