refactor(kernel): split syscall.rs into per-tier modules (simple, memory, lifecycle, capability, ipc)
This commit is contained in:
128
crates/kernel/src/syscall/lifecycle.rs
Normal file
128
crates/kernel/src/syscall/lifecycle.rs
Normal file
@@ -0,0 +1,128 @@
|
||||
use platform::Platform;
|
||||
|
||||
use crate::{Kernel, SyscallOutcome, SyscallResult};
|
||||
|
||||
impl<P: Platform> Kernel<P> {
|
||||
pub(crate) fn handle_spawn_thread(
|
||||
&mut self,
|
||||
pid: types::id::ProcessId,
|
||||
_entry: types::address::EntryPoint,
|
||||
_stack: types::address::StackPointer,
|
||||
) -> SyscallOutcome {
|
||||
use domain::scheduler::Scheduler;
|
||||
|
||||
let priority = types::bounded::Priority::new(16)
|
||||
.unwrap_or_else(|| unreachable!());
|
||||
let time_slice = types::time::TimeSlice::new(100);
|
||||
|
||||
let tid = match self.threads.spawn(pid, priority, time_slice, None) {
|
||||
Ok(t) => t,
|
||||
Err(e) => return SyscallOutcome::Complete(SyscallResult::Error(e)),
|
||||
};
|
||||
|
||||
if let Err(e) = self.processes.get_mut(pid).and_then(|p| p.add_thread(tid)) {
|
||||
let _ = self.threads.destroy(tid);
|
||||
return SyscallOutcome::Complete(SyscallResult::Error(e));
|
||||
}
|
||||
|
||||
let core = self.platform.core_id();
|
||||
self.scheduler.add(tid, priority, core);
|
||||
SyscallOutcome::Complete(SyscallResult::Value(tid.raw() as usize))
|
||||
}
|
||||
|
||||
pub(crate) fn handle_create_process(
|
||||
&mut self,
|
||||
caller_pid: types::id::ProcessId,
|
||||
create_cap: types::bounded::CapSlot,
|
||||
_image: types::address::DataRef,
|
||||
) -> SyscallOutcome {
|
||||
use domain::scheduler::Scheduler;
|
||||
|
||||
if let Err(e) = self.check_cap(caller_pid, create_cap, types::permission::Permission::Execute) {
|
||||
return SyscallOutcome::Complete(SyscallResult::Error(e));
|
||||
}
|
||||
|
||||
let new_pid = match self.processes.create(
|
||||
domain::capability::CapabilityTable::new(),
|
||||
None,
|
||||
) {
|
||||
Ok(p) => p,
|
||||
Err(e) => return SyscallOutcome::Complete(SyscallResult::Error(e)),
|
||||
};
|
||||
|
||||
self.process_memory[new_pid.raw() as usize] =
|
||||
Some(domain::memory::process_memory::ProcessMemory::new(new_pid, 1024));
|
||||
|
||||
let priority = types::bounded::Priority::new(16)
|
||||
.unwrap_or_else(|| unreachable!());
|
||||
let time_slice = types::time::TimeSlice::new(100);
|
||||
|
||||
let tid = match self.threads.spawn(new_pid, priority, time_slice, None) {
|
||||
Ok(t) => t,
|
||||
Err(e) => {
|
||||
let _ = self.processes.destroy(new_pid);
|
||||
return SyscallOutcome::Complete(SyscallResult::Error(e));
|
||||
}
|
||||
};
|
||||
|
||||
if let Err(e) = self.processes.get_mut(new_pid).and_then(|p| p.add_thread(tid)) {
|
||||
let _ = self.threads.destroy(tid);
|
||||
let _ = self.processes.destroy(new_pid);
|
||||
return SyscallOutcome::Complete(SyscallResult::Error(e));
|
||||
}
|
||||
|
||||
let core = self.platform.core_id();
|
||||
self.scheduler.add(tid, priority, core);
|
||||
|
||||
let slot = match self.grant_cap(
|
||||
caller_pid,
|
||||
domain::resource::Resource::Process(new_pid),
|
||||
types::permission::PermissionSet::empty()
|
||||
.with(types::permission::Permission::Execute)
|
||||
.with(types::permission::Permission::Read),
|
||||
) {
|
||||
Ok(s) => s,
|
||||
Err(e) => return SyscallOutcome::Complete(SyscallResult::Error(e)),
|
||||
};
|
||||
|
||||
SyscallOutcome::Complete(SyscallResult::Slot(slot))
|
||||
}
|
||||
|
||||
pub(crate) fn handle_kill(
|
||||
&mut self,
|
||||
caller_pid: types::id::ProcessId,
|
||||
process_cap: types::bounded::CapSlot,
|
||||
) -> SyscallOutcome {
|
||||
let target_pid = match self.check_cap(caller_pid, process_cap, types::permission::Permission::Execute) {
|
||||
Ok(cap) => match cap.resource() {
|
||||
domain::resource::Resource::Process(pid) => *pid,
|
||||
_ => return SyscallOutcome::Complete(SyscallResult::Error(
|
||||
domain::error::KernelError::PermissionDenied {
|
||||
slot: process_cap,
|
||||
needed: types::permission::Permission::Execute,
|
||||
},
|
||||
)),
|
||||
},
|
||||
Err(e) => return SyscallOutcome::Complete(SyscallResult::Error(e)),
|
||||
};
|
||||
|
||||
let thread_ids: [Option<types::id::ThreadId>; 4] = {
|
||||
match self.processes.get(target_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(e) => return SyscallOutcome::Complete(SyscallResult::Error(e)),
|
||||
}
|
||||
};
|
||||
|
||||
self.cleanup_threads(&thread_ids);
|
||||
|
||||
let _ = self.processes.destroy(target_pid);
|
||||
self.process_memory[target_pid.raw() as usize] = None;
|
||||
SyscallOutcome::Complete(SyscallResult::Ok)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user