pub trait ThreadPool: Send + Sync {
fn parallel_for<F>(&self, count: usize, f: F)
where
F: Fn(usize) + Send + Sync;
fn num_threads(&self) -> usize;
fn join<A, B, RA, RB>(&self, a: A, b: B) -> (RA, RB)
where
A: FnOnce() -> RA + Send,
B: FnOnce() -> RB + Send,
RA: Send,
RB: Send;
fn parallel_for_chunks<F>(&self, count: usize, chunk_size: usize, f: F)
where
F: Fn(usize, usize) + Send + Sync,
{
if count == 0 || chunk_size == 0 {
return;
}
let num_chunks = count.div_ceil(chunk_size);
self.parallel_for(num_chunks, |chunk_idx| {
let start = chunk_idx.saturating_mul(chunk_size);
if start >= count {
return;
}
let len = core::cmp::min(chunk_size, count - start);
f(start, len);
});
}
fn parallel_split<F>(&self, start: usize, count: usize, min_chunk_size: usize, f: &F)
where
F: Fn(usize, usize) + Send + Sync,
{
let min_chunk_size = min_chunk_size.max(1);
if count <= min_chunk_size || self.num_threads() <= 1 {
f(start, count);
} else {
let mid = count / 2;
self.join(
|| self.parallel_split(start, mid, min_chunk_size, f),
|| self.parallel_split(start.saturating_add(mid), count - mid, min_chunk_size, f),
);
}
}
}