64 lines
2.1 KiB
Rust
64 lines
2.1 KiB
Rust
use domain::scheduler::{Scheduler, SchedulerDecision};
|
|
use platform::Platform;
|
|
use types::id::{CoreId, IrqId, ThreadId};
|
|
|
|
use crate::Kernel;
|
|
|
|
impl<P: Platform> Kernel<P> {
|
|
pub fn handle_tick(&mut self, core: CoreId) -> SchedulerDecision {
|
|
let current_tid = match self.scheduler.current(core) {
|
|
Some(tid) => tid,
|
|
None => return SchedulerDecision::Continue,
|
|
};
|
|
|
|
let thread = match self.threads.get_mut(current_tid) {
|
|
Ok(t) => t,
|
|
Err(_) => return SchedulerDecision::Continue,
|
|
};
|
|
|
|
let expired = thread.time_slice_mut().tick();
|
|
if expired {
|
|
thread.time_slice_mut().reset();
|
|
let priority = thread.priority();
|
|
if thread.preempt().is_err() {
|
|
return SchedulerDecision::Continue;
|
|
}
|
|
self.scheduler.add(current_tid, priority, core);
|
|
match self.scheduler.next(core) {
|
|
Some(next) => {
|
|
if self.threads.get_mut(next).and_then(|t| t.set_running(core)).is_ok() {
|
|
SchedulerDecision::Preempt(next)
|
|
} else {
|
|
let _ = self.threads.get_mut(current_tid).map(|t| t.set_running(core));
|
|
SchedulerDecision::Continue
|
|
}
|
|
}
|
|
None => {
|
|
let _ = self.threads.get_mut(current_tid).map(|t| t.set_running(core));
|
|
SchedulerDecision::Continue
|
|
}
|
|
}
|
|
} else {
|
|
self.scheduler.tick(core, current_tid)
|
|
}
|
|
}
|
|
|
|
pub fn handle_interrupt(&mut self, irq: IrqId) -> Option<ThreadId> {
|
|
self.platform.mask_irq(irq);
|
|
|
|
let tid = self.irqs.owner(irq)?;
|
|
let thread = self.threads.get_mut(tid).ok()?;
|
|
|
|
if !matches!(thread.state(), domain::thread::ThreadState::Blocked(_)) {
|
|
return None;
|
|
}
|
|
|
|
let priority = thread.priority();
|
|
let core = self.platform.core_id();
|
|
let _ = thread.unblock();
|
|
self.scheduler.add(tid, priority, core);
|
|
|
|
Some(tid)
|
|
}
|
|
}
|