use crate::pool::Pool;
use crate::track::Track;
#[cfg(feature = "parallel")]
pub(crate) fn in_pool(pool: &Pool) -> bool {
pool.inner().current_thread_index().is_some()
}
#[cfg(not(feature = "parallel"))]
pub(crate) fn in_pool(_pool: &Pool) -> bool {
false
}
#[cfg(feature = "parallel")]
pub(crate) fn unpin_worker(pool: &Pool) {
if let Some(worker) = pool.inner().current_thread_index() {
pool.awake.unpin_member(worker);
}
}
#[cfg(feature = "parallel")]
pub(crate) fn run_tasks<F: Fn(usize) + Sync>(pool: &Pool, tasks: usize, track: &Track, task: F) {
if in_pool(pool) {
join_tree(0, tasks, &task);
} else {
track.note_install();
pool.inner().install(|| join_tree(0, tasks, &task));
}
}
#[cfg(feature = "parallel")]
fn join_tree<F: Fn(usize) + Sync>(lo: usize, hi: usize, task: &F) {
if hi - lo == 1 {
task(lo);
} else {
let mid = lo + (hi - lo) / 2;
rayon::join(|| join_tree(lo, mid, task), || join_tree(mid, hi, task));
}
}
#[cfg(not(feature = "parallel"))]
pub(crate) fn run_tasks<F: Fn(usize) + Sync>(_pool: &Pool, tasks: usize, _track: &Track, task: F) {
for k in 0..tasks {
task(k);
}
}
#[cfg(feature = "parallel")]
pub(crate) fn enter<R: Send>(pool: &Pool, track: &Track, f: impl FnOnce() -> R + Send) -> R {
if in_pool(pool) {
f()
} else {
track.note_install();
pool.inner().install(f)
}
}
#[cfg(feature = "parallel")]
pub(crate) fn broadcast(pool: &Pool, track: &Track, budget: usize, f: impl Fn(usize) + Sync) {
track.note_install();
pool.inner().broadcast(|ctx| {
let i = ctx.index();
if i < budget {
let _live = track.task();
f(i);
}
});
}