第二节 抢占式调度框架
抢占式调度由时钟中断推动,现在就让调度与时钟中断关联起来,在注册响应函数时调用 axtask::on_timer_tick():
// axruntime/src/lib.rs
#[cfg(all(target_os = "none", not(test)))]
fn init_interrupt() {
... ...
axhal::irq::register_handler(TIMER_IRQ_NUM, || {
update_timer();
debug!("On timer tick!");
axtask::on_timer_tick();
});
// Enable IRQs before starting app
axhal::irq::enable_irqs();
}
// axtask/src/lib.rs
pub fn on_timer_tick() {
run_queue::RUN_QUEUE.lock().scheduler_timer_tick();
}
// axtask/src/run_queue.rs
impl AxRunQueue {
pub fn scheduler_timer_tick(&mut self) {
let curr = current();
if !curr.is_idle() && curr.task_tick() {
curr.set_preempt_pending(true);
}
}
}
每次时钟中断时,最后会调用 scheduler_timer_tick(...)
,对于当前任务,如果 task_tick
返回 true,设置抢占标志表示任务本身已经具备了被抢占的条件。当然,这只是满足了内部条件,能否真正触发抢占调度,还要看外部条件。在此之前,先来测试一下当前的功能,执行 make run LOG=trace
查看任务内部状态的变化,在几次时钟中断触发后,任务的 need_resched 被设置为 true。