- SlotGenerations per table, never wraps, retires exhausted slots - caps to dead/reused process, endpoint, region rejected - endpoints owned, die w/ owner, waiters woken w/ error - DropCap syscall + libkos wrapper - irq table bounds-checked, routes dropped w/ thread - self-kill terminates caller, exit_thread full cleanup - sched run_now: switch to named thread, not queue head - lifetime tests, fuzz kills/recreates, kani gen proofs
75 lines
1.7 KiB
Rust
75 lines
1.7 KiB
Rust
use super::priority_queue::PriorityQueue;
|
|
use types::bounded::Priority;
|
|
use types::id::{CoreId, ThreadId};
|
|
|
|
pub struct PerCoreScheduler {
|
|
core: CoreId,
|
|
queue: PriorityQueue,
|
|
current: Option<ThreadId>,
|
|
}
|
|
|
|
impl PerCoreScheduler {
|
|
pub fn new(core: CoreId) -> Self {
|
|
Self {
|
|
core,
|
|
queue: PriorityQueue::new(),
|
|
current: None,
|
|
}
|
|
}
|
|
|
|
pub fn core(&self) -> CoreId {
|
|
self.core
|
|
}
|
|
|
|
pub fn current(&self) -> Option<ThreadId> {
|
|
self.current
|
|
}
|
|
|
|
pub fn add(&mut self, thread: ThreadId, priority: Priority) {
|
|
self.queue.add(thread, priority);
|
|
}
|
|
|
|
pub fn remove(&mut self, thread: ThreadId) {
|
|
self.queue.remove(thread);
|
|
}
|
|
|
|
pub fn pick_next(&mut self) -> Option<ThreadId> {
|
|
let (thread, _priority) = self.queue.pop_highest()?;
|
|
self.current = Some(thread);
|
|
Some(thread)
|
|
}
|
|
|
|
/// Takes `thread` out of the run queue and makes it current.
|
|
pub fn run_now(&mut self, thread: ThreadId) -> bool {
|
|
if !self.queue.remove(thread) {
|
|
return false;
|
|
}
|
|
self.current = Some(thread);
|
|
true
|
|
}
|
|
|
|
pub fn clear_current(&mut self) {
|
|
self.current = None;
|
|
}
|
|
|
|
pub fn set_current(&mut self, thread: ThreadId) {
|
|
self.current = Some(thread);
|
|
}
|
|
|
|
pub fn highest_waiting_priority(&self) -> Option<Priority> {
|
|
self.queue.highest_priority()
|
|
}
|
|
|
|
pub fn steal_lowest(&mut self) -> Option<(ThreadId, Priority)> {
|
|
self.queue.steal_lowest()
|
|
}
|
|
|
|
pub fn len(&self) -> usize {
|
|
self.queue.len()
|
|
}
|
|
|
|
pub fn is_empty(&self) -> bool {
|
|
self.queue.is_empty()
|
|
}
|
|
}
|