Files
k-os/crates/domain/src/scheduler/per_core.rs
Gabriel Kaszewski 76f10ff1f1 feat(kernel): seL4-style IPC, notifications, status ABI
- badges + Mint, Call/Reply/ReplyRecv w/ gen-checked reply slot
- cap transfer (1/msg, copy, needs Delegate, rechecked at delivery)
- notifications: signal/wait/poll/bind, irq -> notification routing
- WaitAny/WaitForInterrupt removed; a0=status, ErrorCode
- libkos: single ecall primitive, compat wrappers + typed new api
- fix: trap return clobbered user t0 on every trap
- fix: wait queues FIFO, delegate keeps badge, fault cap checked
- docs/ipc.md spec, ipc tests, ipc fuzz, kani ntfn + waitqueue
2026-10-26 20:27:38 +01:00

79 lines
1.8 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 is_queued(&self, thread: ThreadId) -> bool {
self.queue.contains(thread)
}
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()
}
}