use crate::runtime::task::TaskId;
use crate::scheduler::data::random::RandomDataSource;
use crate::scheduler::data::DataSource;
use crate::scheduler::{Schedule, Scheduler};
use rand::rngs::OsRng;
use rand::seq::SliceRandom;
use rand::{RngCore, SeedableRng};
use rand_pcg::Pcg64Mcg;
#[derive(Debug)]
pub struct RandomScheduler {
max_iterations: usize,
rng: Pcg64Mcg,
iterations: usize,
data_source: RandomDataSource,
}
impl RandomScheduler {
pub fn new(max_iterations: usize) -> Self {
Self::new_from_seed(OsRng.next_u64(), max_iterations)
}
pub fn new_from_seed(seed: u64, max_iterations: usize) -> Self {
let rng = Pcg64Mcg::seed_from_u64(seed);
Self {
max_iterations,
rng,
iterations: 0,
data_source: RandomDataSource::initialize(seed),
}
}
}
impl Scheduler for RandomScheduler {
fn new_execution(&mut self) -> Option<Schedule> {
if self.iterations >= self.max_iterations {
None
} else {
self.iterations += 1;
Some(Schedule::new(self.data_source.reinitialize()))
}
}
fn next_task(&mut self, runnable: &[TaskId], _current: Option<TaskId>, _is_yielding: bool) -> Option<TaskId> {
Some(*runnable.choose(&mut self.rng).unwrap())
}
fn next_u64(&mut self) -> u64 {
self.data_source.next_u64()
}
}