From 2c4a9dbadc9d97c6b01fd63bed27e0bce89ab9cf Mon Sep 17 00:00:00 2001 From: Gabriel Kaszewski Date: Sun, 18 Oct 2026 00:39:28 +0200 Subject: [PATCH] refactor(kernel): move SyscallOutcome/Result to syscall module, move test helpers to tests module --- crates/kernel/src/lib.rs | 112 +++--------------------- crates/kernel/src/syscall/capability.rs | 3 +- crates/kernel/src/syscall/ipc.rs | 3 +- crates/kernel/src/syscall/lifecycle.rs | 3 +- crates/kernel/src/syscall/memory.rs | 3 +- crates/kernel/src/syscall/mod.rs | 21 ++++- crates/kernel/src/syscall/simple.rs | 3 +- crates/kernel/src/tests/mod.rs | 85 ++++++++++++++++-- 8 files changed, 118 insertions(+), 115 deletions(-) diff --git a/crates/kernel/src/lib.rs b/crates/kernel/src/lib.rs index 8dc3a8a..dcbcfa0 100644 --- a/crates/kernel/src/lib.rs +++ b/crates/kernel/src/lib.rs @@ -3,6 +3,8 @@ pub mod interrupt; pub mod syscall; +pub use syscall::{SyscallOutcome, SyscallResult}; + #[cfg(test)] #[path = "tests/mod.rs"] mod tests; @@ -33,22 +35,6 @@ use types::{ time::TimeSlice, }; -pub enum SyscallOutcome { - Complete(SyscallResult), - BlockCaller(domain::thread::BlockReason), - SwitchTo(ThreadId), - TerminateCaller, -} - -pub enum SyscallResult { - Ok, - Value(usize), - Slot(CapSlot), - Message(Message), - WakeReason(domain::syscall::WakeReason), - Error(KernelError), -} - pub struct Kernel { platform: P, processes: ProcessTable, @@ -117,6 +103,14 @@ impl Kernel

{ self.pending_results[thread.raw() as usize].as_ref() } + pub fn free_page_count(&self) -> usize { + self.page_pool.free_count() + } + + pub fn process_exists(&self, pid: ProcessId) -> bool { + self.processes.get(pid).is_ok() + } + fn caller(&self) -> Result<(ThreadId, ProcessId), KernelError> { let core = self.platform.core_id(); let tid = self.scheduler.current(core) @@ -128,14 +122,6 @@ impl Kernel

{ } } - pub fn free_page_count(&self) -> usize { - self.page_pool.free_count() - } - - pub fn process_exists(&self, pid: ProcessId) -> bool { - self.processes.get(pid).is_ok() - } - pub(crate) fn cleanup_threads(&mut self, thread_ids: &[Option; 4]) { use domain::scheduler::Scheduler; for slot in thread_ids { @@ -184,82 +170,4 @@ impl Kernel

{ let cap = Capability::new(resource, permissions, Generation::initial()); self.processes.get_mut(to)?.capabilities_mut().insert(cap) } - - #[cfg(test)] - pub fn spawn_thread_for_test( - &mut self, - pid: ProcessId, - priority: Priority, - time_slice: TimeSlice, - ) -> ThreadId { - use domain::scheduler::Scheduler; - 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 - } - - #[cfg(test)] - pub fn register_irq_for_test(&mut self, irq: types::id::IrqId, thread: ThreadId) { - let _ = self.irqs.register(irq, thread); - } - - #[cfg(test)] - pub fn block_thread_for_test( - &mut self, - tid: ThreadId, - reason: domain::thread::BlockReason, - ) { - use domain::scheduler::Scheduler; - 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); - } - - #[cfg(test)] - pub fn switch_to_thread_for_test(&mut self, tid: ThreadId) { - use domain::scheduler::Scheduler; - 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)); - } - } - } - - #[cfg(test)] - pub fn create_endpoint_for_test(&mut self) -> types::id::EndpointId { - self.endpoints.create().expect("create endpoint") - } - - #[cfg(test)] - pub fn grant_cap_for_test( - &mut self, - pid: ProcessId, - resource: Resource, - permissions: PermissionSet, - ) -> CapSlot { - self.grant_cap(pid, resource, permissions).expect("grant cap") - } } diff --git a/crates/kernel/src/syscall/capability.rs b/crates/kernel/src/syscall/capability.rs index 3a0966b..8b1672b 100644 --- a/crates/kernel/src/syscall/capability.rs +++ b/crates/kernel/src/syscall/capability.rs @@ -1,6 +1,7 @@ use platform::Platform; -use crate::{Kernel, SyscallOutcome, SyscallResult}; +use super::{SyscallOutcome, SyscallResult}; +use crate::Kernel; impl Kernel

{ pub(crate) fn handle_delegate( diff --git a/crates/kernel/src/syscall/ipc.rs b/crates/kernel/src/syscall/ipc.rs index 2270708..14f3922 100644 --- a/crates/kernel/src/syscall/ipc.rs +++ b/crates/kernel/src/syscall/ipc.rs @@ -1,6 +1,7 @@ use platform::Platform; -use crate::{Kernel, SyscallOutcome, SyscallResult}; +use super::{SyscallOutcome, SyscallResult}; +use crate::Kernel; impl Kernel

{ pub(crate) fn handle_send( diff --git a/crates/kernel/src/syscall/lifecycle.rs b/crates/kernel/src/syscall/lifecycle.rs index fa6f905..11d2da9 100644 --- a/crates/kernel/src/syscall/lifecycle.rs +++ b/crates/kernel/src/syscall/lifecycle.rs @@ -1,6 +1,7 @@ use platform::Platform; -use crate::{Kernel, SyscallOutcome, SyscallResult}; +use super::{SyscallOutcome, SyscallResult}; +use crate::Kernel; impl Kernel

{ pub(crate) fn handle_spawn_thread( diff --git a/crates/kernel/src/syscall/memory.rs b/crates/kernel/src/syscall/memory.rs index 573c715..90e963d 100644 --- a/crates/kernel/src/syscall/memory.rs +++ b/crates/kernel/src/syscall/memory.rs @@ -1,6 +1,7 @@ use platform::Platform; -use crate::{Kernel, SyscallOutcome, SyscallResult}; +use super::{SyscallOutcome, SyscallResult}; +use crate::Kernel; impl Kernel

{ pub(crate) fn handle_request_pages( diff --git a/crates/kernel/src/syscall/mod.rs b/crates/kernel/src/syscall/mod.rs index bb53d5e..004e111 100644 --- a/crates/kernel/src/syscall/mod.rs +++ b/crates/kernel/src/syscall/mod.rs @@ -4,10 +4,27 @@ mod lifecycle; mod memory; mod simple; -use domain::syscall::Syscall; +use domain::{error::KernelError, message::Message, syscall::Syscall}; use platform::Platform; +use types::{bounded::CapSlot, id::ThreadId}; -use crate::{Kernel, SyscallOutcome, SyscallResult}; +use crate::Kernel; + +pub enum SyscallOutcome { + Complete(SyscallResult), + BlockCaller(domain::thread::BlockReason), + SwitchTo(ThreadId), + TerminateCaller, +} + +pub enum SyscallResult { + Ok, + Value(usize), + Slot(CapSlot), + Message(Message), + WakeReason(domain::syscall::WakeReason), + Error(KernelError), +} impl Kernel

{ pub fn handle_syscall(&mut self, syscall: Syscall) -> SyscallOutcome { diff --git a/crates/kernel/src/syscall/simple.rs b/crates/kernel/src/syscall/simple.rs index 3f7aef9..de453aa 100644 --- a/crates/kernel/src/syscall/simple.rs +++ b/crates/kernel/src/syscall/simple.rs @@ -1,6 +1,7 @@ use platform::Platform; -use crate::{Kernel, SyscallOutcome, SyscallResult}; +use super::{SyscallOutcome, SyscallResult}; +use crate::Kernel; impl Kernel

{ pub(crate) fn handle_get_time(&self) -> SyscallOutcome { diff --git a/crates/kernel/src/tests/mod.rs b/crates/kernel/src/tests/mod.rs index c309d3a..e81a84f 100644 --- a/crates/kernel/src/tests/mod.rs +++ b/crates/kernel/src/tests/mod.rs @@ -7,18 +7,20 @@ mod simple; mod tick; use domain::memory::page_pool::PagePool; +use domain::memory::MemoryRegion; +use domain::resource::Resource; +use domain::scheduler::Scheduler; +use domain::thread::{SavedContext, ThreadState}; use platform::Platform; use types::{ address::{EntryPoint, PhysicalAddress, StackPointer}, - bounded::Priority, - id::{CoreId, IrqId, ProcessId}, + bounded::{CapSlot, Priority}, + id::{CoreId, EndpointId, IrqId, ProcessId, ThreadId}, + permission::PermissionSet, time::{Ticks, TimerDuration, TimeSlice}, }; -use domain::memory::MemoryRegion; -use domain::thread::SavedContext; - -use crate::Kernel; +use crate::{Kernel, SyscallResult}; pub struct MockPlatform { ticks: Ticks, @@ -74,3 +76,74 @@ pub fn kernel_with_process() -> (Kernel, ProcessId) { .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") + } +}