use super::worker::Worker;
use crate::util::signal::{Counter, Signal};
#[derive(Debug, Clone)]
pub struct ThreadSlot {
pub index: usize,
pub worker: Option<Worker>,
}
impl ThreadSlot {
pub fn make_worker(&mut self, counter: Counter) -> &Worker {
self.worker = Some(Worker::new(counter));
let worker = self.worker.as_ref().unwrap();
worker.spawn();
worker
}
}
#[derive(Debug)]
pub struct ThreadSlots {
capacity: usize,
slots: Vec<ThreadSlot>,
full: Signal,
}
impl ThreadSlots {
pub fn new(capacity: usize) -> Self {
let slots = (0..capacity)
.map(|index| ThreadSlot {
index,
worker: None,
})
.collect();
Self {
capacity,
slots,
full: Signal::new(false),
}
}
pub fn allocate(&mut self) -> &mut ThreadSlot {
let capacity = self.capacity;
let mut slots = self.slots.iter_mut();
let full = &self.full;
if full.value() {
let index = (rand::random::<f32>() * self.capacity as f32) as usize;
slots.nth(index).unwrap()
} else {
let slot = slots.find(|slot| slot.worker.is_none()).unwrap();
if slot.index + 1 == capacity {
full.set(true)
}
slot
}
}
}