use crate::{
constants::{MIN_WORKER_STACK, SLEEP_MULTIPLIER, WORKER_MULTIPLIER, WORKER_STACK},
modules::errors::RuntimeError,
};
use std::sync::atomic::{AtomicUsize, Ordering};
static WORKERS_PER_CORE: AtomicUsize = AtomicUsize::new(WORKER_MULTIPLIER);
static SLEEP_THREADS_PER_CORE: AtomicUsize = AtomicUsize::new(SLEEP_MULTIPLIER);
static STACK: AtomicUsize = AtomicUsize::new(WORKER_STACK);
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) struct Tuning {
workers_per_core: usize,
sleep_threads_per_core: usize,
worker_stack: usize,
}
impl Tuning {
pub(crate) const fn new() -> Self {
Self {
workers_per_core: WORKER_MULTIPLIER,
sleep_threads_per_core: SLEEP_MULTIPLIER,
worker_stack: WORKER_STACK,
}
}
pub(crate) fn set_workers_per_core(&mut self, count: usize) {
self.workers_per_core = count;
}
pub(crate) fn set_sleep_threads_per_core(&mut self, count: usize) {
self.sleep_threads_per_core = count;
}
pub(crate) fn set_worker_stack(&mut self, bytes: usize) {
self.worker_stack = bytes;
}
pub(crate) fn check(&self) -> Result<(), RuntimeError> {
match self.workers_per_core == 0
|| self.sleep_threads_per_core == 0
|| self.worker_stack < MIN_WORKER_STACK
{
true => Err(RuntimeError::BadArgument),
false => Ok(()),
}
}
}
pub(crate) fn apply(tuning: Tuning) {
WORKERS_PER_CORE.store(tuning.workers_per_core, Ordering::Release);
SLEEP_THREADS_PER_CORE.store(tuning.sleep_threads_per_core, Ordering::Release);
STACK.store(tuning.worker_stack, Ordering::Release);
}
#[inline(always)]
pub(crate) fn workers_per_core() -> usize {
WORKERS_PER_CORE.load(Ordering::Acquire)
}
#[inline(always)]
pub(crate) fn sleep_threads_per_core() -> usize {
SLEEP_THREADS_PER_CORE.load(Ordering::Acquire)
}
#[inline(always)]
pub(crate) fn worker_stack() -> usize {
STACK.load(Ordering::Acquire)
}