[Zion] Add a ProcessWait syscall.

This commit is contained in:
Drew Galbraith 2023-12-01 11:36:27 -08:00
parent 642fc4d80d
commit d9a4be6555
8 changed files with 29 additions and 8 deletions

View File

@ -10,6 +10,7 @@ z_err_t SysCall1(uint64_t code, const void* req);
SYS1(ProcessExit, uint64_t, code);
SYS5(ProcessSpawn, z_cap_t, proc_cap, z_cap_t, bootstrap_cap, z_cap_t*,
new_proc_cap, z_cap_t*, new_vmas_cap, z_cap_t*, new_bootstrap_cap);
SYS2(ProcessWait, z_cap_t, proc_cap, z_err_t*, exit_code);
SYS2(ThreadCreate, z_cap_t, proc_cap, z_cap_t*, thread_cap);
SYS4(ThreadStart, z_cap_t, thread_cap, uint64_t, entry, uint64_t, arg1,

View File

@ -12,6 +12,7 @@ typedef uint64_t z_err_t;
// Process Calls.
const uint64_t kZionProcessExit = 0x1;
const uint64_t kZionProcessSpawn = 0x2;
const uint64_t kZionProcessWait = 0x3;
// Thread Calls.
const uint64_t kZionThreadCreate = 0x10;

View File

@ -79,7 +79,7 @@ extern "C" void interrupt_divide_by_zero(InterruptFrame* frame) {
StackUnwind(frame->rbp);
if (IsUserSpace(frame->rip)) {
gScheduler->CurrentProcess().Exit();
gScheduler->CurrentProcess().Exit(glcr::INTERNAL);
UNREACHABLE
}
panic("DIV0");
@ -91,7 +91,7 @@ extern "C" void interrupt_invalid_opcode(InterruptFrame* frame) {
StackUnwind(frame->rbp);
if (IsUserSpace(frame->rip)) {
gScheduler->CurrentProcess().Exit();
gScheduler->CurrentProcess().Exit(glcr::INTERNAL);
UNREACHABLE
}
panic("INVALID OPCODE");
@ -117,7 +117,7 @@ extern "C" void interrupt_protection_fault(InterruptFrame* frame) {
StackUnwind(frame->rbp);
if (IsUserSpace(frame->rip)) {
gScheduler->CurrentProcess().Exit();
gScheduler->CurrentProcess().Exit(glcr::INTERNAL);
UNREACHABLE
}
panic("GP");
@ -159,7 +159,7 @@ extern "C" void interrupt_page_fault(InterruptFrame* frame) {
StackUnwind(frame->rbp);
if (IsUserSpace(frame->rip)) {
gScheduler->CurrentProcess().Exit();
gScheduler->CurrentProcess().Exit(glcr::INTERNAL);
UNREACHABLE
}
@ -170,7 +170,7 @@ extern "C" void isr_fpe_fault();
extern "C" void interrupt_fpe_fault(InterruptFrame* frame) {
dbgln("Floating point exception.");
if (IsUserSpace(frame->rip)) {
gScheduler->CurrentProcess().Exit();
gScheduler->CurrentProcess().Exit(glcr::INTERNAL);
UNREACHABLE
}
panic("Floating point exception");

View File

@ -59,10 +59,11 @@ uint64_t Process::AddExistingCapability(const glcr::RefPtr<Capability>& cap) {
return caps_.AddExistingCapability(cap);
}
void Process::Exit() {
void Process::Exit(uint64_t exit_code) {
// TODO: Check this state elsewhere to ensure that we don't for instance
// create a running thread on a finished process.
state_ = CLEANUP;
exit_code_ = exit_code;
for (uint64_t i = 0; i < threads_.size(); i++) {
if (!threads_[i]->IsDying()) {

View File

@ -57,10 +57,11 @@ class Process : public KernelObject {
uint64_t AddExistingCapability(const glcr::RefPtr<Capability>& cap);
State GetState() { return state_; }
uint64_t exit_code() { return exit_code_; }
// This stops all of the processes threads (they will no longer be scheduled)
// and flags the process for cleanup.
void Exit();
void Exit(uint64_t code);
// This *should not* be called from a thread that belongs to this process.
// Rather it should be called from the cleanup thread.
@ -76,6 +77,7 @@ class Process : public KernelObject {
uint64_t id_;
glcr::RefPtr<AddressSpace> vmas_;
State state_;
uint64_t exit_code_ = -1;
uint64_t next_thread_id_ = 0;

View File

@ -9,7 +9,7 @@
z_err_t ProcessExit(ZProcessExitReq* req) {
auto curr_thread = gScheduler->CurrentThread();
dbgln("Exit code: {}", static_cast<glcr::ErrorCode>(req->code));
curr_thread->process().Exit();
curr_thread->process().Exit(req->code);
panic("Returned from thread exit");
return glcr::UNIMPLEMENTED;
}
@ -39,3 +39,17 @@ z_err_t ProcessSpawn(ZProcessSpawnReq* req) {
return glcr::OK;
}
z_err_t ProcessWait(ZProcessWaitReq* req) {
auto& curr_proc = gScheduler->CurrentProcess();
auto cap = curr_proc.GetCapability(req->proc_cap);
RET_ERR(ValidateCapability<Process>(cap, kZionPerm_Read));
auto proc = cap->obj<Process>();
if (proc->id() == curr_proc.id()) {
return glcr::INVALID_ARGUMENT;
}
proc->GetThread(0)->Wait();
*req->exit_code = proc->exit_code();
return glcr::OK;
}

View File

@ -4,3 +4,4 @@
z_err_t ProcessExit(ZProcessExitReq* req);
z_err_t ProcessSpawn(ZProcessSpawnReq* req);
z_err_t ProcessWait(ZProcessWaitReq* req);

View File

@ -53,6 +53,7 @@ extern "C" z_err_t SyscallHandler(uint64_t call_id, void* req) {
// syscall/process.h
CASE(ProcessExit);
CASE(ProcessSpawn);
CASE(ProcessWait);
// syscall/thread.h
CASE(ThreadCreate);
CASE(ThreadStart);