#[cfg(all(not(feature = "chili"), not(feature = "rayon"), feature = "parallel"))]
compile_error!("You must enable `chili` or `rayon` feature if you want to use `parallel` feature");
#[cfg(all(feature = "chili", feature = "rayon"))]
compile_error!("You must enable `chili` or `rayon` feature, not both");
#[cfg(feature = "chili")]
mod par_chili {
use std::{cell::RefCell, mem::transmute};
use chili::Scope;
thread_local! {
static SCOPE: RefCell<Option<&'static mut Scope<'static>>> = Default::default();
}
#[inline]
fn join_scoped<A, B, RA, RB>(scope: &mut Scope<'_>, oper_a: A, oper_b: B) -> (RA, RB)
where
A: Send + FnOnce() -> RA,
B: Send + FnOnce() -> RB,
RA: Send,
RB: Send,
{
scope.join(
|scope| {
let old_scope = SCOPE.take();
SCOPE.set(Some(unsafe { transmute::<&mut Scope, &mut Scope>(scope) }));
let ra = oper_a();
SCOPE.set(old_scope);
ra
},
|scope| {
let old_scope = SCOPE.take();
SCOPE.set(Some(unsafe { transmute::<&mut Scope, &mut Scope>(scope) }));
let rb = oper_b();
SCOPE.set(old_scope);
rb
},
)
}
#[inline]
pub fn join<A, B, RA, RB>(oper_a: A, oper_b: B) -> (RA, RB)
where
A: Send + FnOnce() -> RA,
B: Send + FnOnce() -> RB,
RA: Send,
RB: Send,
{
let old_scope: Option<&mut Scope<'_>> = SCOPE.take();
match old_scope {
Some(scope) => {
let (ra, rb) = join_scoped(scope, oper_a, oper_b);
SCOPE.set(Some(scope));
(ra, rb)
}
None => join_scoped(&mut Scope::global(), oper_a, oper_b),
}
}
}
pub fn join<A, B, RA, RB>(oper_a: A, oper_b: B) -> (RA, RB)
where
A: Send + FnOnce() -> RA,
B: Send + FnOnce() -> RB,
RA: Send,
RB: Send,
{
#[cfg(feature = "chili")]
let (ra, rb) = par_chili::join(oper_a, oper_b);
#[cfg(feature = "rayon")]
let (ra, rb) = rayon::join(oper_a, oper_b);
#[cfg(not(feature = "parallel"))]
let (ra, rb) = (oper_a(), oper_b());
(ra, rb)
}