feat(kernel): add handle_tick and handle_interrupt entry points
This commit is contained in:
@@ -1,15 +1,63 @@
|
||||
use domain::scheduler::SchedulerDecision;
|
||||
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 {
|
||||
SchedulerDecision::Continue
|
||||
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> {
|
||||
None
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user