1use std::num::NonZeroUsize;
2use std::thread;
3
4use loam_time::par::{ChunkSource, Executor};
5
6pub struct ScopedThreads {
7 threads: usize,
8}
9
10impl Default for ScopedThreads {
11 fn default() -> Self {
12 Self {
13 threads: thread::available_parallelism().map_or(1, NonZeroUsize::get),
14 }
15 }
16}
17
18impl Executor for ScopedThreads {
19 fn parallelism(&self) -> usize {
20 self.threads
21 }
22
23 fn for_each_chunk(&self, workers: usize, chunks: &(dyn ChunkSource + Sync)) {
24 let workers = workers.clamp(1, self.threads);
25 thread::scope(|scope| {
26 for _ in 1..workers {
27 scope.spawn(|| while chunks.run_next() {});
28 }
29 while chunks.run_next() {}
30 });
31 }
32}
33
34pub fn install() {
35 if loam_time::par::install(Box::new(ScopedThreads::default())).is_err() {
36 tracing::debug!("a parallel executor was already installed");
37 }
38}