feat(kernel): shared ABI decoder+proofs, no-panic gate, syscall storm, kani on shrunk kernel
This commit is contained in:
@@ -57,6 +57,14 @@ impl Endpoint {
|
||||
self.waiting_receivers.pop()
|
||||
}
|
||||
|
||||
pub fn senders(&self) -> impl Iterator<Item = ThreadId> + '_ {
|
||||
self.waiting_senders.iter()
|
||||
}
|
||||
|
||||
pub fn receivers(&self) -> impl Iterator<Item = ThreadId> + '_ {
|
||||
self.waiting_receivers.iter()
|
||||
}
|
||||
|
||||
pub fn is_sender(&self, thread: ThreadId) -> bool {
|
||||
self.waiting_senders.contains(thread)
|
||||
}
|
||||
@@ -82,7 +90,7 @@ impl Endpoint {
|
||||
}
|
||||
}
|
||||
|
||||
pub const MAX_ENDPOINTS: usize = 256;
|
||||
pub const MAX_ENDPOINTS: usize = if cfg!(kani) { 2 } else { 256 };
|
||||
|
||||
pub struct EndpointTable {
|
||||
endpoints: [Option<Endpoint>; MAX_ENDPOINTS],
|
||||
@@ -98,10 +106,14 @@ impl EndpointTable {
|
||||
}
|
||||
|
||||
pub fn create(&mut self, owner: ProcessId) -> Option<EndpointId> {
|
||||
let idx = (0..MAX_ENDPOINTS)
|
||||
.find(|&i| self.endpoints[i].is_none() && self.generations.is_usable(i))?;
|
||||
let generations = &self.generations;
|
||||
let (idx, slot) = self
|
||||
.endpoints
|
||||
.iter_mut()
|
||||
.enumerate()
|
||||
.find(|(i, s)| s.is_none() && generations.is_usable(*i))?;
|
||||
let id = EndpointId::from_raw(idx as u16);
|
||||
self.endpoints[idx] = Some(Endpoint::new(id, owner));
|
||||
*slot = Some(Endpoint::new(id, owner));
|
||||
Some(id)
|
||||
}
|
||||
|
||||
@@ -111,6 +123,10 @@ impl EndpointTable {
|
||||
self.generations.current(id.raw() as usize)
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> impl Iterator<Item = &Endpoint> {
|
||||
self.endpoints.iter().flatten()
|
||||
}
|
||||
|
||||
pub fn ids_owned_by(&self, owner: ProcessId) -> impl Iterator<Item = EndpointId> + '_ {
|
||||
self.endpoints
|
||||
.iter()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use types::id::ThreadId;
|
||||
|
||||
pub const MAX_WAITERS: usize = 16;
|
||||
pub const MAX_WAITERS: usize = if cfg!(kani) { 2 } else { 16 };
|
||||
|
||||
/// Bounded FIFO of blocked threads. Order is preserved across pops and
|
||||
/// removals, so no waiter can be overtaken.
|
||||
@@ -21,13 +21,13 @@ impl<const N: usize> WaitQueue<N> {
|
||||
if self.len == N || self.contains(thread) {
|
||||
return None;
|
||||
}
|
||||
self.entries[self.len] = Some(thread);
|
||||
*self.entries.get_mut(self.len)? = Some(thread);
|
||||
self.len += 1;
|
||||
Some(())
|
||||
}
|
||||
|
||||
pub fn pop(&mut self) -> Option<ThreadId> {
|
||||
let head = self.entries[0]?;
|
||||
let head = self.entries.first().copied().flatten()?;
|
||||
self.close_gap(0);
|
||||
Some(head)
|
||||
}
|
||||
@@ -45,20 +45,33 @@ impl<const N: usize> WaitQueue<N> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> impl Iterator<Item = ThreadId> + '_ {
|
||||
self.entries.iter().take(self.len).flatten().copied()
|
||||
}
|
||||
|
||||
pub fn contains(&self, thread: ThreadId) -> bool {
|
||||
self.entries[..self.len].contains(&Some(thread))
|
||||
self.entries
|
||||
.iter()
|
||||
.take(self.len)
|
||||
.any(|e| *e == Some(thread))
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len == 0
|
||||
}
|
||||
|
||||
/// Removes entry `i`, shifting later entries forward to keep order.
|
||||
fn close_gap(&mut self, i: usize) {
|
||||
for j in i..self.len - 1 {
|
||||
self.entries[j] = self.entries[j + 1];
|
||||
for j in i..self.len.saturating_sub(1) {
|
||||
let next = self.entries.get(j + 1).copied().flatten();
|
||||
if let Some(e) = self.entries.get_mut(j) {
|
||||
*e = next;
|
||||
}
|
||||
}
|
||||
self.len = self.len.saturating_sub(1);
|
||||
if let Some(last) = self.entries.get_mut(self.len) {
|
||||
*last = None;
|
||||
}
|
||||
self.len -= 1;
|
||||
self.entries[self.len] = None;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user