feat: SMP stage 1 (4 harts, per-hart guarded stacks, home-core affinity, IPIs, TLB shootdown, one temporary kernel lock), 4-core storm
This commit is contained in:
@@ -21,6 +21,7 @@ pub mod interrupt;
|
||||
mod memory;
|
||||
#[cfg(kani)]
|
||||
pub mod proofs;
|
||||
mod smp;
|
||||
pub mod syscall;
|
||||
|
||||
pub use board::BoardDevice;
|
||||
@@ -65,6 +66,8 @@ pub struct Kernel<P: Platform> {
|
||||
notifications: NotificationTable,
|
||||
ipc: [syscall::IpcState; MAX_THREADS],
|
||||
pending_results: [Option<SyscallResult>; MAX_THREADS],
|
||||
/// The core each thread runs on (see smp.rs).
|
||||
homes: [types::id::CoreId; MAX_THREADS],
|
||||
}
|
||||
|
||||
impl<P: Platform> Kernel<P> {
|
||||
@@ -83,6 +86,7 @@ impl<P: Platform> Kernel<P> {
|
||||
notifications: NotificationTable::new(),
|
||||
ipc: [syscall::IpcState::default(); MAX_THREADS],
|
||||
pending_results: [const { None }; MAX_THREADS],
|
||||
homes: [types::id::CoreId::from_raw(0); MAX_THREADS],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,6 +119,7 @@ impl<P: Platform> Kernel<P> {
|
||||
addr_of_mut!((*slot).notifications).write(NotificationTable::new());
|
||||
addr_of_mut!((*slot).ipc).write([syscall::IpcState::default(); MAX_THREADS]);
|
||||
addr_of_mut!((*slot).pending_results).write([const { None }; MAX_THREADS]);
|
||||
addr_of_mut!((*slot).homes).write([types::id::CoreId::from_raw(0); MAX_THREADS]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,6 +147,7 @@ impl<P: Platform> Kernel<P> {
|
||||
.insert(cap)?;
|
||||
|
||||
let core = self.platform.core_id();
|
||||
self.set_home(tid, core);
|
||||
self.scheduler.add(tid, priority, core);
|
||||
self.scheduler.next(core);
|
||||
self.threads.get_mut(tid)?.set_running(core)?;
|
||||
@@ -211,14 +217,13 @@ impl<P: Platform> Kernel<P> {
|
||||
}
|
||||
|
||||
pub fn spawn_thread_internal(&mut self, pid: ProcessId) -> Option<ThreadId> {
|
||||
use domain::scheduler::Scheduler;
|
||||
let tid = self
|
||||
.threads
|
||||
.spawn(pid, Priority::DEFAULT, TimeSlice::DEFAULT, None)
|
||||
.ok()?;
|
||||
let _ = self.processes.get_mut(pid).map(|p| p.add_thread(tid));
|
||||
let core = self.platform.core_id();
|
||||
self.scheduler.add(tid, Priority::DEFAULT, core);
|
||||
self.place(tid);
|
||||
self.make_ready(tid, Priority::DEFAULT);
|
||||
Some(tid)
|
||||
}
|
||||
|
||||
@@ -240,31 +245,6 @@ impl<P: Platform> Kernel<P> {
|
||||
self.grant_cap(to, resource, permissions)
|
||||
}
|
||||
|
||||
pub fn switch_to_thread(&mut self, tid: ThreadId) {
|
||||
use domain::scheduler::Scheduler;
|
||||
let core = self.platform.core_id();
|
||||
|
||||
if let Some(current) = self.scheduler.current(core) {
|
||||
if current == tid {
|
||||
return;
|
||||
}
|
||||
if let Ok(t) = self.threads.get_mut(current)
|
||||
&& matches!(t.state(), ThreadState::Running(_))
|
||||
{
|
||||
let priority = t.priority();
|
||||
let _ = t.preempt();
|
||||
self.scheduler.add(current, priority, core);
|
||||
}
|
||||
}
|
||||
|
||||
if let Ok(t) = self.threads.get(tid)
|
||||
&& matches!(t.state(), ThreadState::Ready)
|
||||
&& self.scheduler.run_now(core, tid)
|
||||
{
|
||||
let _ = self.threads.get_mut(tid).map(|t| t.set_running(core));
|
||||
}
|
||||
}
|
||||
|
||||
fn caller(&self) -> Result<(ThreadId, ProcessId), KernelError> {
|
||||
let core = self.platform.core_id();
|
||||
let tid = self
|
||||
@@ -311,6 +291,7 @@ impl<P: Platform> Kernel<P> {
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user