perf(kernel): kernel static all-zero -> .bss (image 812K -> 173K): domain::Slot (repr(u8) Empty=0) for tables, zero generation counters, core ids by position, pool/platform installed at boot; Option-backed Slot under kani (cbmc speed); build fails if .data > 16K

This commit is contained in:
2026-10-28 13:01:52 +01:00
parent 419b715a1f
commit a2d4a7d085
24 changed files with 320 additions and 116 deletions

View File

@@ -71,7 +71,7 @@ pub struct Kernel<P: Platform> {
irqs: IrqRoutingTable,
notifications: NotificationTable,
ipc: [syscall::IpcState; MAX_THREADS],
pending_results: [Option<SyscallResult>; MAX_THREADS],
pending_results: [domain::slot::Slot<SyscallResult>; MAX_THREADS],
/// The core each thread runs on (see smp.rs).
homes: [types::id::CoreId; MAX_THREADS],
/// The capability derivation tree as links (see captree.rs).
@@ -111,7 +111,7 @@ impl<P: Platform> Kernel<P> {
irqs: IrqRoutingTable::new(),
notifications: NotificationTable::new(),
ipc: [syscall::IpcState::EMPTY; MAX_THREADS],
pending_results: [const { None }; MAX_THREADS],
pending_results: [const { domain::slot::Slot::Empty }; MAX_THREADS],
homes: [types::id::CoreId::from_raw(0); MAX_THREADS],
tree: domain::capability::tree::CapTree::new(),
heap_cursors: [0; MAX_PROCESSES],
@@ -127,6 +127,12 @@ impl<P: Platform> Kernel<P> {
self.platform = platform;
}
/// Hands over the user pool, for a kernel placed without one (so its
/// static is all zero, see the adapter); before anything is allocated.
pub fn install_pool(&mut self, pool_base: PhysicalAddress, pool_pages: usize) {
self.frames.set_pool(pool_base, pool_pages);
}
pub fn boot(
&mut self,
priority: Priority,

View File

@@ -148,7 +148,7 @@ impl<P: Platform> Kernel<P> {
return SyscallOutcome::Complete(SyscallResult::Error(KernelError::EndpointFull));
}
if let Some(s) = self.ipc_mut(tid) {
s.outgoing = Some(out);
s.outgoing.set(out);
}
let reason = if is_call {
BlockReason::Calling(ep)

View File

@@ -42,7 +42,7 @@ pub(crate) struct Outgoing {
/// Per-thread IPC bookkeeping.
#[derive(Debug, Clone, Copy, Default)]
pub struct IpcState {
pub(crate) outgoing: Option<Outgoing>,
pub(crate) outgoing: domain::slot::Slot<Outgoing>,
/// The caller this thread owes a reply to.
pub(crate) reply_to: Option<ThreadRef>,
/// Callers it kept to answer later (`SaveReply`).
@@ -55,7 +55,7 @@ pub(crate) const SAVED: usize = types::bounded::SavedReply::MAX as usize + 1;
impl IpcState {
pub const EMPTY: Self = Self {
outgoing: None,
outgoing: domain::slot::Slot::Empty,
reply_to: None,
saved: [None; SAVED],
bound: None,
@@ -73,7 +73,7 @@ impl<P: Platform> Kernel<P> {
pub(crate) fn set_pending_result(&mut self, tid: ThreadId, result: Option<SyscallResult>) {
if let Some(r) = self.pending_results.get_mut(tid.raw() as usize) {
*r = result;
*r = result.into();
}
}

View File

@@ -126,7 +126,7 @@ impl<P: Platform> Kernel<P> {
/// 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;
s.outgoing = domain::slot::Slot::Empty;
}
self.wake(tid, SyscallResult::Error(error));
}

View File

@@ -256,7 +256,7 @@ impl World {
"{t:?} blocked sending but not queued"
);
assert!(
ipc.outgoing.is_some(),
ipc.outgoing.is_full(),
"{t:?} queued sender without a message"
);
}
@@ -287,7 +287,7 @@ impl World {
}
ThreadState::Ready | ThreadState::Running(_) | ThreadState::Dead => {
assert!(!in_any_queue, "{t:?} runnable but queued on an IPC object");
assert!(ipc.outgoing.is_none());
assert!(!ipc.outgoing.is_full());
}
}
let blocked = matches!(state, ThreadState::Blocked(_));

View File

@@ -194,7 +194,7 @@ impl Kernel<MockPlatform> {
};
match state {
ThreadState::Blocked(BlockReason::Sending(e) | BlockReason::Calling(e)) => {
if in_endpoint(e) != Some((true, false)) || ipc.outgoing.is_none() {
if in_endpoint(e) != Some((true, false)) || !ipc.outgoing.is_full() {
return Err(format!("{t:?} blocked sending but not queued"));
}
}
@@ -225,7 +225,7 @@ impl Kernel<MockPlatform> {
}
}
_ => {
if ipc.outgoing.is_some() {
if ipc.outgoing.is_full() {
return Err(format!("{t:?} runnable with a queued message"));
}
}