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:
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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(_));
|
||||
|
||||
@@ -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"));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user