refactor(kernel): split ipc/memory/lib/thread by concern; trim comments

This commit is contained in:
2026-10-27 13:21:53 +01:00
parent b814bd9570
commit 95dbe7b9d5
34 changed files with 1239 additions and 1231 deletions

View File

@@ -23,6 +23,7 @@ mod memory;
pub mod proofs;
mod smp;
pub mod syscall;
mod teardown;
pub use board::{BoardCaps, BoardDevice};
pub use syscall::{SyscallOutcome, SyscallResult};
@@ -37,7 +38,7 @@ use domain::{
error::KernelError,
irq::IrqRoutingTable,
memory::{RegionTable, frame::FrameTable, quota::Quota},
notification::{MAX_NOTIFICATIONS, NotificationTable},
notification::NotificationTable,
process::{MAX_PROCESSES, ProcessTable},
resource::Resource,
scheduler::{Scheduler, multi_core::MultiCoreScheduler},
@@ -96,12 +97,10 @@ impl<P: Platform> Kernel<P> {
}
}
/// Builds the kernel directly in `slot`, one table at a time, so the
/// whole structure never has to fit on the (small) boot stack.
/// Builds the kernel in place, one table at a time, to stay off the boot stack.
///
/// # Safety
/// `slot` must be valid for writes and properly aligned. Any previous
/// value is overwritten without being dropped.
/// `slot` must be valid for writes and aligned; the old value is overwritten without drop.
pub unsafe fn init_in_place(
slot: *mut Self,
platform: P,
@@ -263,123 +262,6 @@ impl<P: Platform> Kernel<P> {
}
}
pub(crate) fn destroy_process(&mut self, pid: ProcessId) {
use domain::process::MAX_THREADS_PER_PROCESS;
let thread_ids: [Option<ThreadId>; MAX_THREADS_PER_PROCESS] = match self.processes.get(pid)
{
Ok(p) => {
let mut ids = [None; MAX_THREADS_PER_PROCESS];
for (slot, tid) in ids.iter_mut().zip(p.thread_ids()) {
*slot = Some(tid);
}
ids
}
Err(_) => return,
};
self.cleanup_threads(&thread_ids);
self.delete_all_caps(pid);
self.destroy_endpoints_owned_by(pid);
self.destroy_notifications_owned_by(pid);
self.teardown_memory(pid);
let _ = self.processes.destroy(pid);
}
pub(crate) fn cleanup_threads(&mut self, thread_ids: &[Option<ThreadId>]) {
use domain::scheduler::Scheduler;
for tid in thread_ids.iter().flatten() {
self.leave_queue(*tid);
if let Some(n) = self
.ipc(*tid)
.and_then(|s| s.bound)
.and_then(|n| self.notifications.get_mut(n))
{
n.remove_thread(*tid);
}
let ipc = self.ipc_mut(*tid).map(core::mem::take).unwrap_or_default();
if let Some(caller) = ipc.reply_to {
self.release_caller(caller);
}
self.evict(*tid);
self.scheduler.remove(*tid);
self.set_pending_result(*tid, None);
let _ = self.threads.destroy(*tid);
}
}
/// Takes a blocked thread off the one queue its block reason names, so
/// nothing needs to scan every endpoint and notification.
pub(crate) fn leave_queue(&mut self, tid: ThreadId) {
use domain::thread::BlockReason::*;
let Ok(ThreadState::Blocked(reason)) = self.threads.get(tid).map(|t| *t.state()) else {
return;
};
match reason {
Sending(ep) | Calling(ep) => {
self.endpoints.get_mut(ep).map(|e| e.remove_sender(tid));
}
Receiving(ep) => {
self.endpoints.get_mut(ep).map(|e| e.remove_receiver(tid));
}
WaitingNotification(n) => {
if let Some(n) = self.notifications.get_mut(n) {
n.remove_waiter(tid);
}
}
AwaitingReply => {}
}
}
/// Destroys every endpoint `owner` created, waking anyone blocked on
/// them with an error instead of leaving them blocked forever.
pub(crate) fn destroy_endpoints_owned_by(&mut self, owner: ProcessId) {
let mut owned = [None; domain::endpoint::MAX_ENDPOINTS];
for (slot, id) in owned.iter_mut().zip(self.endpoints.ids_owned_by(owner)) {
*slot = Some(id);
}
for id in owned.into_iter().flatten() {
let Some(mut ep) = self.endpoints.destroy(id) else {
continue;
};
while let Some(tid) = ep.dequeue_sender().or_else(|| ep.dequeue_receiver()) {
self.wake_with_error(tid, KernelError::InvalidEndpoint(id));
}
}
}
/// Destroys every notification `owner` created, waking its waiters
/// with an error and unbinding its bound thread.
pub(crate) fn destroy_notifications_owned_by(&mut self, owner: ProcessId) {
let mut owned = [None; MAX_NOTIFICATIONS];
for (slot, id) in owned.iter_mut().zip(self.notifications.ids_owned_by(owner)) {
*slot = Some(id);
}
for id in owned.into_iter().flatten() {
let Some(mut n) = self.notifications.destroy(id) else {
continue;
};
if let Some(bound) = n.bound()
&& let Some(s) = self.ipc_mut(bound)
{
s.bound = None;
}
while let Some(tid) = n.pop_waiter() {
self.wake_with_error(tid, KernelError::NoSuchObject);
}
}
}
/// Makes a blocked thread runnable with `error` as its syscall result,
/// dropping whatever it was about to send.
fn wake_with_error(&mut self, tid: ThreadId, error: KernelError) {
if let Some(s) = self.ipc_mut(tid) {
s.outgoing = None;
}
self.wake(tid, SyscallResult::Error(error));
}
fn check_cap(
&self,
owner: ProcessId,