feat(kernel): shared ABI decoder+proofs, no-panic gate, syscall storm, kani on shrunk kernel
This commit is contained in:
@@ -5,8 +5,8 @@ use types::{
|
||||
|
||||
use super::{Scheduler, SchedulerDecision, per_core::PerCoreScheduler};
|
||||
|
||||
const MAX_CORES: usize = 8;
|
||||
const MAX_SCHEDULED_THREADS: usize = 256;
|
||||
const MAX_CORES: usize = if cfg!(kani) { 1 } else { 8 };
|
||||
const MAX_SCHEDULED_THREADS: usize = crate::thread::MAX_THREADS;
|
||||
const BALANCE_THRESHOLD: usize = 2;
|
||||
|
||||
struct ThreadPlacement {
|
||||
@@ -25,32 +25,47 @@ impl MultiCoreScheduler {
|
||||
let cores = core::array::from_fn(|i| PerCoreScheduler::new(CoreId::from_raw(i as u8)));
|
||||
Self {
|
||||
cores,
|
||||
num_cores,
|
||||
num_cores: num_cores.min(MAX_CORES as u8),
|
||||
placements: [const { None }; MAX_SCHEDULED_THREADS],
|
||||
}
|
||||
}
|
||||
|
||||
fn core(&self, core: CoreId) -> Option<&PerCoreScheduler> {
|
||||
self.active().get(core.raw() as usize)
|
||||
}
|
||||
|
||||
fn core_mut(&mut self, core: CoreId) -> Option<&mut PerCoreScheduler> {
|
||||
let n = self.num_cores as usize;
|
||||
self.cores.get_mut(..n)?.get_mut(core.raw() as usize)
|
||||
}
|
||||
|
||||
fn active(&self) -> &[PerCoreScheduler] {
|
||||
self.cores.get(..self.num_cores as usize).unwrap_or(&[])
|
||||
}
|
||||
|
||||
fn placement(&self, thread: ThreadId) -> Option<&ThreadPlacement> {
|
||||
self.placements.get(thread.raw() as usize)?.as_ref()
|
||||
}
|
||||
|
||||
/// Whether `thread` waits in some core's run queue.
|
||||
pub fn is_queued(&self, thread: ThreadId) -> bool {
|
||||
self.cores[..self.num_cores as usize]
|
||||
.iter()
|
||||
.any(|c| c.is_queued(thread))
|
||||
self.active().iter().any(|c| c.is_queued(thread))
|
||||
}
|
||||
|
||||
pub fn current(&self, core: CoreId) -> Option<ThreadId> {
|
||||
self.cores[core.raw() as usize].current()
|
||||
self.core(core)?.current()
|
||||
}
|
||||
|
||||
pub fn set_current(&mut self, core: CoreId, thread: ThreadId) {
|
||||
self.cores[core.raw() as usize].set_current(thread);
|
||||
if let Some(c) = self.core_mut(core) {
|
||||
c.set_current(thread);
|
||||
}
|
||||
}
|
||||
|
||||
/// Runs `thread` next on `core` regardless of its place in the queue.
|
||||
/// Fails if it is not queued there.
|
||||
pub fn run_now(&mut self, core: CoreId, thread: ThreadId) -> bool {
|
||||
self.cores
|
||||
.get_mut(core.raw() as usize)
|
||||
.is_some_and(|c| c.run_now(thread))
|
||||
self.core_mut(core).is_some_and(|c| c.run_now(thread))
|
||||
}
|
||||
|
||||
fn thread_count_on(&self, core: CoreId) -> usize {
|
||||
@@ -75,38 +90,49 @@ impl MultiCoreScheduler {
|
||||
|
||||
impl Scheduler for MultiCoreScheduler {
|
||||
fn add(&mut self, thread: ThreadId, priority: Priority, core: CoreId) {
|
||||
let idx = thread.raw() as usize;
|
||||
self.placements[idx] = Some(ThreadPlacement { core, priority });
|
||||
self.cores[core.raw() as usize].add(thread, priority);
|
||||
if self.core(core).is_none() {
|
||||
return;
|
||||
}
|
||||
let Some(placement) = self.placements.get_mut(thread.raw() as usize) else {
|
||||
return;
|
||||
};
|
||||
*placement = Some(ThreadPlacement { core, priority });
|
||||
if let Some(c) = self.core_mut(core) {
|
||||
c.add(thread, priority);
|
||||
}
|
||||
}
|
||||
|
||||
fn remove(&mut self, thread: ThreadId) {
|
||||
let idx = thread.raw() as usize;
|
||||
if let Some(placement) = self.placements[idx].take() {
|
||||
let core_idx = placement.core.raw() as usize;
|
||||
self.cores[core_idx].remove(thread);
|
||||
if self.cores[core_idx].current() == Some(thread) {
|
||||
self.cores[core_idx].clear_current();
|
||||
let Some(placement) = self
|
||||
.placements
|
||||
.get_mut(thread.raw() as usize)
|
||||
.and_then(Option::take)
|
||||
else {
|
||||
return;
|
||||
};
|
||||
if let Some(c) = self.core_mut(placement.core) {
|
||||
c.remove(thread);
|
||||
if c.current() == Some(thread) {
|
||||
c.clear_current();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn next(&mut self, core: CoreId) -> Option<ThreadId> {
|
||||
self.cores[core.raw() as usize].pick_next()
|
||||
self.core_mut(core)?.pick_next()
|
||||
}
|
||||
|
||||
fn tick(&mut self, core: CoreId, current: ThreadId) -> SchedulerDecision {
|
||||
let idx = current.raw() as usize;
|
||||
if let Some(placement) = &self.placements[idx] {
|
||||
let current_priority = placement.priority;
|
||||
let core_idx = core.raw() as usize;
|
||||
if let Some(highest) = self.cores[core_idx].highest_waiting_priority()
|
||||
&& highest > current_priority
|
||||
&& let Some(next) = self.cores[core_idx].pick_next()
|
||||
{
|
||||
self.cores[core_idx].add(current, current_priority);
|
||||
return SchedulerDecision::Preempt(next);
|
||||
}
|
||||
let Some(current_priority) = self.placement(current).map(|p| p.priority) else {
|
||||
return SchedulerDecision::Continue;
|
||||
};
|
||||
if let Some(c) = self.core_mut(core)
|
||||
&& let Some(highest) = c.highest_waiting_priority()
|
||||
&& highest > current_priority
|
||||
&& let Some(next) = c.pick_next()
|
||||
{
|
||||
c.add(current, current_priority);
|
||||
return SchedulerDecision::Preempt(next);
|
||||
}
|
||||
SchedulerDecision::Continue
|
||||
}
|
||||
@@ -117,13 +143,14 @@ impl Scheduler for MultiCoreScheduler {
|
||||
_ => return,
|
||||
};
|
||||
|
||||
if self.thread_count_on(busiest) > self.thread_count_on(lightest) + BALANCE_THRESHOLD {
|
||||
let busiest_idx = busiest.raw() as usize;
|
||||
if let Some((thread, priority)) = self.cores[busiest_idx].steal_lowest() {
|
||||
let lightest_idx = lightest.raw() as usize;
|
||||
self.cores[lightest_idx].add(thread, priority);
|
||||
let tid = thread.raw() as usize;
|
||||
self.placements[tid] = Some(ThreadPlacement {
|
||||
if self.thread_count_on(busiest) > self.thread_count_on(lightest) + BALANCE_THRESHOLD
|
||||
&& let Some((thread, priority)) = self.core_mut(busiest).and_then(|c| c.steal_lowest())
|
||||
{
|
||||
if let Some(c) = self.core_mut(lightest) {
|
||||
c.add(thread, priority);
|
||||
}
|
||||
if let Some(p) = self.placements.get_mut(thread.raw() as usize) {
|
||||
*p = Some(ThreadPlacement {
|
||||
core: lightest,
|
||||
priority,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user