use alloc::{sync::Arc, vec::Vec};
use crate::{
processor::this_processor_id,
sched::{schedule::pelt::SchedAvg, task::Task},
space::mm::MmStruct,
time::sched_clock::sched_clock,
};
mod pelt;
bitflags::bitflags! {
#[derive(Clone, Copy)]
struct SchedClassFlags: u32 {
const ENQUEUE_WAKEUP = 0b0000_0001;
const DEQUEUE_SLEEP = 0b0000_0010;
}
}
#[allow(unused)]
trait SchedClass {
fn next(&self) -> Option<impl SchedClass>;
fn enqueue_task(&self, rq: &Rq, tsk: Arc<Task>, flags: SchedClassFlags);
fn dequeue_task(&self, rq: &Rq, tsk: Arc<Task>, flags: SchedClassFlags);
fn yield_task(&self, rq: &Rq);
fn check_preempt_curr(&self, rq: &Rq, tsk: Arc<Task>, flags: SchedClassFlags);
fn pick_next_task(&self, rq: &Rq, prev_tsk: Arc<Task>) -> Arc<Task>;
fn put_prev_task(&self, rq: &Rq, prev_tsk: Arc<Task>);
fn set_curr_task(&self, rq: &Rq, next_tsk: Arc<Task>);
fn task_tick(&self, rq: &Rq);
fn update_curr(&self, rq: &Rq);
}
#[repr(align(64))]
#[allow(unused)]
struct Rq {
cpu: usize,
nr_running: usize,
clock: u64,
sched_avg: SchedAvg,
curr: Arc<Task>,
}
impl Rq {
#[allow(unused)]
fn init(cpu: usize, curr: Arc<Task>) -> Self {
Self { cpu, nr_running: 0, clock: sched_clock(), sched_avg: SchedAvg::new(), curr }
}
}
static mut RUNQUEUES: Vec<Rq> = Vec::new();
fn __schedule(_preempt: bool) {
let cpu = this_processor_id();
let rq = unsafe { &RUNQUEUES[cpu] };
let _prev = rq.curr.clone();
}
pub(crate) fn sched_init() {}
pub(crate) fn sched_init_cpu() {}
pub(crate) fn schedule_ipi() {
sched_clock();
let rq = unsafe { &mut RUNQUEUES[0] };
rq.sched_avg.update_load_avg(sched_clock(), 1024, 2, 1);
}
pub fn schedule() {
let mm = MmStruct::create().unwrap();
mm.switch_mm();
}
pub fn rq_load_avg(cpu: usize) -> u64 {
let rq = unsafe { &RUNQUEUES[cpu] };
rq.sched_avg.load_avg()
}
pub fn rq_runnable_avg(cpu: usize) -> u64 {
let rq = unsafe { &RUNQUEUES[cpu] };
rq.sched_avg.runnable_avg()
}
pub fn rq_util_avg(cpu: usize) -> u64 {
let rq = unsafe { &RUNQUEUES[cpu] };
rq.sched_avg.util_avg()
}