use domain::memory::page_pool::PagePool; use domain::resource::Resource; use domain::scheduler::Scheduler; use domain::thread::ThreadState; use platform::Platform; use types::{ address::PhysicalAddress, bounded::{CapSlot, Priority}, id::{EndpointId, IrqId, ProcessId, ThreadId}, permission::PermissionSet, time::TimeSlice, }; use crate::Kernel; use super::mock_platform::MockPlatform; pub fn test_kernel() -> Kernel { let mock = MockPlatform::new(1); let pool = PagePool::new(PhysicalAddress::from_raw(0x8000_0000), 1024); Kernel::new(mock, pool) } pub fn kernel_with_process() -> (Kernel, ProcessId) { let mut kernel = test_kernel(); let (pid, _tid) = kernel .boot(Priority::new(16).unwrap(), TimeSlice::new(100)) .unwrap(); (kernel, pid) } impl Kernel { pub fn spawn_thread_for_test( &mut self, pid: ProcessId, priority: Priority, time_slice: TimeSlice, ) -> ThreadId { let tid = self.threads.spawn(pid, priority, time_slice, None).expect("spawn"); let _ = self.processes.get_mut(pid).map(|p| p.add_thread(tid)); let core = self.platform.core_id(); self.scheduler.add(tid, priority, core); tid } pub fn register_irq_for_test(&mut self, irq: IrqId, thread: ThreadId) { let _ = self.irqs.register(irq, thread); } pub fn block_thread_for_test( &mut self, tid: ThreadId, reason: domain::thread::BlockReason, ) { let core = self.platform.core_id(); if let Ok(t) = self.threads.get_mut(tid) { if matches!(t.state(), ThreadState::Ready) { let _ = t.set_running(core); } let _ = t.block(reason); } self.scheduler.remove(tid); } pub fn switch_to_thread_for_test(&mut self, tid: ThreadId) { let core = self.platform.core_id(); if let Some(current) = self.scheduler.current(core) { if current == tid { return; } if let Ok(t) = self.threads.get_mut(current) { if matches!(t.state(), ThreadState::Running(_)) { let priority = t.priority(); let _ = t.preempt(); self.scheduler.add(current, priority, core); } } } if let Ok(t) = self.threads.get(tid) { if matches!(t.state(), ThreadState::Ready) { self.scheduler.next(core); let _ = self.threads.get_mut(tid).map(|t| t.set_running(core)); } } } pub fn create_endpoint_for_test(&mut self) -> EndpointId { self.endpoints.create().expect("create endpoint") } pub fn grant_cap_for_test( &mut self, pid: ProcessId, resource: Resource, permissions: PermissionSet, ) -> CapSlot { self.grant_cap(pid, resource, permissions).expect("grant cap") } }