refactor(kernel): split syscall.rs into per-tier modules (simple, memory, lifecycle, capability, ipc)
This commit is contained in:
94
crates/kernel/src/syscall/simple.rs
Normal file
94
crates/kernel/src/syscall/simple.rs
Normal file
@@ -0,0 +1,94 @@
|
||||
use platform::Platform;
|
||||
|
||||
use crate::{Kernel, SyscallOutcome, SyscallResult};
|
||||
|
||||
impl<P: Platform> Kernel<P> {
|
||||
pub(crate) fn handle_get_time(&self) -> SyscallOutcome {
|
||||
let ticks = self.platform.current_ticks();
|
||||
SyscallOutcome::Complete(SyscallResult::Value(ticks.raw() as usize))
|
||||
}
|
||||
|
||||
pub(crate) fn handle_get_process_id(&self, pid: types::id::ProcessId) -> SyscallOutcome {
|
||||
SyscallOutcome::Complete(SyscallResult::Value(pid.raw() as usize))
|
||||
}
|
||||
|
||||
pub(crate) fn handle_yield(&mut self, caller_tid: types::id::ThreadId) -> SyscallOutcome {
|
||||
use domain::scheduler::Scheduler;
|
||||
|
||||
let core = self.platform.core_id();
|
||||
let thread = match self.threads.get_mut(caller_tid) {
|
||||
Ok(t) => t,
|
||||
Err(e) => return SyscallOutcome::Complete(SyscallResult::Error(e)),
|
||||
};
|
||||
|
||||
let priority = thread.priority();
|
||||
if thread.preempt().is_err() {
|
||||
return SyscallOutcome::Complete(SyscallResult::Ok);
|
||||
}
|
||||
|
||||
self.scheduler.add(caller_tid, priority, core);
|
||||
|
||||
match self.scheduler.next(core) {
|
||||
Some(next) if next != caller_tid => {
|
||||
if self.threads.get_mut(next).and_then(|t| t.set_running(core)).is_ok() {
|
||||
SyscallOutcome::SwitchTo(next)
|
||||
} else {
|
||||
let _ = self.threads.get_mut(caller_tid).map(|t| t.set_running(core));
|
||||
SyscallOutcome::Complete(SyscallResult::Ok)
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
let _ = self.threads.get_mut(caller_tid).map(|t| t.set_running(core));
|
||||
SyscallOutcome::Complete(SyscallResult::Ok)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn handle_exit(
|
||||
&mut self,
|
||||
_caller_tid: types::id::ThreadId,
|
||||
pid: types::id::ProcessId,
|
||||
) -> SyscallOutcome {
|
||||
let thread_ids: [Option<types::id::ThreadId>; 4] = {
|
||||
match self.processes.get(pid) {
|
||||
Ok(p) => {
|
||||
let mut ids = [None; 4];
|
||||
for (i, tid) in p.thread_ids().enumerate() {
|
||||
if i < 4 {
|
||||
ids[i] = Some(tid);
|
||||
}
|
||||
}
|
||||
ids
|
||||
}
|
||||
Err(_) => return SyscallOutcome::TerminateCaller,
|
||||
}
|
||||
};
|
||||
|
||||
self.cleanup_threads(&thread_ids);
|
||||
|
||||
let _ = self.processes.destroy(pid);
|
||||
self.process_memory[pid.raw() as usize] = None;
|
||||
SyscallOutcome::TerminateCaller
|
||||
}
|
||||
|
||||
pub(crate) fn handle_exit_thread(
|
||||
&mut self,
|
||||
caller_tid: types::id::ThreadId,
|
||||
pid: types::id::ProcessId,
|
||||
) -> SyscallOutcome {
|
||||
use domain::scheduler::Scheduler;
|
||||
|
||||
self.scheduler.remove(caller_tid);
|
||||
let _ = self.threads.destroy(caller_tid);
|
||||
|
||||
if let Ok(process) = self.processes.get_mut(pid) {
|
||||
process.remove_thread(caller_tid);
|
||||
if process.thread_ids().count() == 0 {
|
||||
let _ = self.processes.destroy(pid);
|
||||
self.process_memory[pid.raw() as usize] = None;
|
||||
}
|
||||
}
|
||||
|
||||
SyscallOutcome::TerminateCaller
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user