mod sim;
use crate::physics::Fanout;
pub(crate) const WORKERS: usize = 8;
pub(crate) struct Pool;
impl Fanout for Pool {
fn workers(&self) -> usize {
WORKERS
}
fn for_each<T, F>(&self, items: &mut [T], body: F)
where
T: Send,
F: Fn(&mut T) + Send + Sync,
{
if items.len() < 2 {
items.iter_mut().for_each(body);
return;
}
let body = &body;
std::thread::scope(|scope| {
for item in items.iter_mut() {
scope.spawn(move || body(item));
}
});
}
}
#[cfg(test)]
mod tests {
use super::*;
use alloc::vec::Vec;
#[test]
fn the_fan_out_touches_every_item_once() {
let mut items: Vec<u32> = (0..16).collect();
Pool.for_each(&mut items, |item| *item += 1);
assert_eq!(items, (1..17).collect::<Vec<u32>>());
assert_eq!(Pool.workers(), WORKERS);
}
#[test]
fn a_split_of_one_or_none_runs_on_the_calling_thread() {
let mut one = [7u32];
Pool.for_each(&mut one, |item| *item += 1);
assert_eq!(one, [8]);
let mut none: [u32; 0] = [];
Pool.for_each(&mut none, |item| *item += 1);
assert!(none.is_empty());
}
}