use super::priority_queue::PriorityQueue; use types::bounded::Priority; use types::id::{CoreId, ThreadId}; pub struct PerCoreScheduler { core: CoreId, queue: PriorityQueue, current: Option, } 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 { 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 { 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 { 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() } }