mod fiber;
mod yielder;
pub use self::{fiber::FiberProc, yielder::Yielder};
use crate::{fib::FiberState, sv::Switch, thr::ThrSv};
use core::mem::ManuallyDrop;
pub union Data<I, O> {
input: ManuallyDrop<I>,
output: ManuallyDrop<O>,
_align: [u32; 0],
}
type ProcData<I, Y, R> = Data<I, FiberState<Y, R>>;
#[inline]
pub fn new_proc<Sv, I, Y, R, F>(stack_size: usize, f: F) -> FiberProc<Sv, I, Y, R, F>
where
Sv: Switch<ProcData<I, Y, R>>,
F: FnMut(I, Yielder<Sv, I, Y, R>) -> R,
F: Send + 'static,
I: Send + 'static,
Y: Send + 'static,
R: Send + 'static,
{
unsafe { FiberProc::new(stack_size, false, false, f) }
}
#[inline]
pub unsafe fn new_proc_unchecked<Sv, I, Y, R, F>(
stack_size: usize,
f: F,
) -> FiberProc<Sv, I, Y, R, F>
where
Sv: Switch<ProcData<I, Y, R>>,
F: FnMut(I, Yielder<Sv, I, Y, R>) -> R,
F: Send + 'static,
I: Send + 'static,
Y: Send + 'static,
R: Send + 'static,
{
FiberProc::new(stack_size, false, true, f)
}
#[inline]
pub fn new_proc_unprivileged<Sv, I, Y, R, F>(stack_size: usize, f: F) -> FiberProc<Sv, I, Y, R, F>
where
Sv: Switch<ProcData<I, Y, R>>,
F: FnMut(I, Yielder<Sv, I, Y, R>) -> R,
F: Send + 'static,
I: Send + 'static,
Y: Send + 'static,
R: Send + 'static,
{
unsafe { FiberProc::new(stack_size, true, false, f) }
}
#[inline]
pub unsafe fn new_proc_unprivileged_unchecked<Sv, I, Y, R, F>(
stack_size: usize,
f: F,
) -> FiberProc<Sv, I, Y, R, F>
where
Sv: Switch<ProcData<I, Y, R>>,
F: FnMut(I, Yielder<Sv, I, Y, R>) -> R,
F: Send + 'static,
I: Send + 'static,
Y: Send + 'static,
R: Send + 'static,
{
FiberProc::new(stack_size, true, true, f)
}
pub trait ThrFiberProc: ThrSv {
#[inline]
fn add_proc<F>(self, stack_size: usize, mut f: F)
where
F: FnMut(Yielder<Self::Sv, (), (), ()>),
F: Send + 'static,
Self::Sv: Switch<ProcData<(), (), ()>>,
{
self.add_fib(new_proc(stack_size, move |(), yielder| f(yielder)))
}
#[inline]
unsafe fn add_proc_unchecked<F>(self, stack_size: usize, mut f: F)
where
F: FnMut(Yielder<Self::Sv, (), (), ()>),
F: Send + 'static,
Self::Sv: Switch<ProcData<(), (), ()>>,
{
self.add_fib(new_proc_unchecked(stack_size, move |(), yielder| {
f(yielder)
}))
}
#[inline]
fn add_proc_unprivileged<F>(self, stack_size: usize, mut f: F)
where
F: FnMut(Yielder<Self::Sv, (), (), ()>),
F: Send + 'static,
Self::Sv: Switch<ProcData<(), (), ()>>,
{
self.add_fib(new_proc_unprivileged(stack_size, move |(), yielder| {
f(yielder)
}))
}
#[inline]
unsafe fn add_proc_unprivileged_unchecked<F>(self, stack_size: usize, mut f: F)
where
F: FnMut(Yielder<Self::Sv, (), (), ()>),
F: Send + 'static,
Self::Sv: Switch<ProcData<(), (), ()>>,
{
self.add_fib(new_proc_unprivileged_unchecked(
stack_size,
move |(), yielder| f(yielder),
))
}
}
impl<T: ThrSv> ThrFiberProc for T {}
impl<I, O> Data<I, O> {
fn from_input(input: I) -> Self {
Self {
input: ManuallyDrop::new(input),
}
}
fn from_output(output: O) -> Self {
Self {
output: ManuallyDrop::new(output),
}
}
unsafe fn into_input(self) -> I {
ManuallyDrop::into_inner(self.input)
}
unsafe fn into_output(self) -> O {
ManuallyDrop::into_inner(self.output)
}
}