use std::{num::NonZeroUsize, thread::available_parallelism};
#[repr(C)]
#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Default, Hash)]
pub enum ThreadingPolicy {
Single,
#[default]
Adaptive,
AdaptiveReserve(NonZeroUsize),
Fixed(NonZeroUsize),
}
impl ThreadingPolicy {
pub fn thread_count(&self, width: u32, height: u32) -> usize {
match self {
ThreadingPolicy::Single => 1,
ThreadingPolicy::Adaptive => {
((width * height / (256 * 256)) as usize).clamp(1, Self::available_parallelism(6))
}
ThreadingPolicy::AdaptiveReserve(reserve) => {
let reserve = reserve.get();
let max_threads = {
let max_threads = Self::available_parallelism(1);
if max_threads <= reserve {
1
} else {
max_threads
}
};
((width * height / (256 * 256)) as usize)
.clamp(1, max_threads.min(max_threads - reserve))
}
ThreadingPolicy::Fixed(fixed) => fixed.get(),
}
}
fn available_parallelism(min: usize) -> usize {
available_parallelism()
.unwrap_or_else(|_| NonZeroUsize::new(1).unwrap())
.get()
.max(min)
}
}