[Zion] Add a proc/thread cleanup thread for future use.
This commit is contained in:
parent
8e4cd1562f
commit
cb590c96b8
|
@ -34,6 +34,7 @@ add_executable(zion
|
|||
object/reply_port.cpp
|
||||
object/semaphore.cpp
|
||||
object/thread.cpp
|
||||
scheduler/cleanup.cpp
|
||||
scheduler/context_switch.s
|
||||
scheduler/jump_user_space.s
|
||||
scheduler/process_manager.cpp
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "memory/kernel_vmm.h"
|
||||
#include "memory/paging_util.h"
|
||||
#include "object/process.h"
|
||||
#include "scheduler/process_manager.h"
|
||||
#include "scheduler/scheduler.h"
|
||||
|
||||
#define K_THREAD_DEBUG 0
|
||||
|
@ -64,6 +65,10 @@ void Thread::Start(uint64_t entry, uint64_t arg1, uint64_t arg2) {
|
|||
}
|
||||
|
||||
void Thread::Init() {
|
||||
if (is_kernel_) {
|
||||
((void (*)(void*))rip_)(reinterpret_cast<void*>(arg1_));
|
||||
panic("Returned from kernel thread.");
|
||||
}
|
||||
#if K_THREAD_DEBUG
|
||||
dbgln("Thread start.", pid(), id_);
|
||||
#endif
|
||||
|
@ -86,6 +91,7 @@ void Thread::Exit() {
|
|||
panic("Thread::Exit called from [{}.{}] on [{}.{}]", curr_thread->pid(),
|
||||
curr_thread->tid(), pid(), tid());
|
||||
}
|
||||
gProcMan->CleanupThread(curr_thread);
|
||||
Cleanup();
|
||||
process_.CheckState();
|
||||
gScheduler->Yield();
|
||||
|
|
|
@ -45,6 +45,8 @@ class Thread : public KernelObject, public glcr::IntrusiveListNode<Thread> {
|
|||
|
||||
uint8_t* FxData() { return fx_data_; }
|
||||
|
||||
void SetKernel() { is_kernel_ = true; }
|
||||
|
||||
// Switches the thread's state to runnable and enqueues it.
|
||||
void Start(uint64_t entry, uint64_t arg1, uint64_t arg2);
|
||||
|
||||
|
@ -75,6 +77,7 @@ class Thread : public KernelObject, public glcr::IntrusiveListNode<Thread> {
|
|||
Process& process_;
|
||||
uint64_t id_;
|
||||
State state_ = CREATED;
|
||||
bool is_kernel_ = false;
|
||||
|
||||
// Startup Context for the thread.
|
||||
uint64_t rsp_;
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
#include "scheduler/cleanup.h"
|
||||
|
||||
void ProcessCleanup::CleanupLoop() {
|
||||
while (true) {
|
||||
while (process_list_.empty() && thread_list_.empty()) {
|
||||
semaphore_.Wait();
|
||||
}
|
||||
// TODO: I think we need to protect these lists with a mutex as well.
|
||||
while (!process_list_.empty()) {
|
||||
auto proc = process_list_.PopFront();
|
||||
dbgln("CLEANUP Proc {}", proc->id());
|
||||
}
|
||||
while (!thread_list_.empty()) {
|
||||
auto thread = thread_list_.PopFront();
|
||||
dbgln("CLEANUP Thread {}.{}", thread->pid(), thread->tid());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessCleanup::CleanupProcess(glcr::RefPtr<Process> process) {
|
||||
process_list_.PushBack(process);
|
||||
semaphore_.Signal();
|
||||
}
|
||||
void ProcessCleanup::CleanupThread(glcr::RefPtr<Thread> thread) {
|
||||
thread_list_.PushBack(thread);
|
||||
semaphore_.Signal();
|
||||
}
|
||||
|
||||
void CleanupThreadEntry(ProcessCleanup* cleanup) {
|
||||
cleanup->CleanupLoop();
|
||||
UNREACHABLE;
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
#pragma once
|
||||
|
||||
#include <glacier/container/linked_list.h>
|
||||
#include <glacier/memory/ref_ptr.h>
|
||||
|
||||
#include "object/process.h"
|
||||
#include "object/semaphore.h"
|
||||
#include "object/thread.h"
|
||||
|
||||
class ProcessCleanup {
|
||||
public:
|
||||
ProcessCleanup() {}
|
||||
|
||||
void CleanupLoop();
|
||||
|
||||
void CleanupProcess(glcr::RefPtr<Process> process);
|
||||
void CleanupThread(glcr::RefPtr<Thread> thread);
|
||||
|
||||
private:
|
||||
Semaphore semaphore_;
|
||||
glcr::LinkedList<glcr::RefPtr<Thread>> thread_list_;
|
||||
glcr::LinkedList<glcr::RefPtr<Process>> process_list_;
|
||||
};
|
||||
|
||||
void CleanupThreadEntry(ProcessCleanup* cleanup);
|
|
@ -19,3 +19,21 @@ Process& ProcessManager::FromId(uint64_t pid) {
|
|||
}
|
||||
return *proc_map_.at(pid);
|
||||
}
|
||||
|
||||
void ProcessManager::InitCleanup() {
|
||||
auto cleanup_thread = FromId(0).CreateThread();
|
||||
cleanup_thread->SetKernel();
|
||||
cleanup_thread->Start(reinterpret_cast<uint64_t>(CleanupThreadEntry),
|
||||
reinterpret_cast<uint64_t>(&gProcMan->cleanup), 0);
|
||||
}
|
||||
|
||||
void ProcessManager::CleanupProcess(uint64_t pid) {
|
||||
if (!proc_map_.Contains(pid)) {
|
||||
panic("Bad proc access {}, have {} processes", pid, proc_map_.size());
|
||||
}
|
||||
cleanup.CleanupProcess(proc_map_.at(pid));
|
||||
}
|
||||
|
||||
void ProcessManager::CleanupThread(glcr::RefPtr<Thread> thread) {
|
||||
cleanup.CleanupThread(thread);
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <glacier/memory/ref_ptr.h>
|
||||
|
||||
#include "object/process.h"
|
||||
#include "scheduler/cleanup.h"
|
||||
|
||||
class ProcessManager {
|
||||
public:
|
||||
|
@ -16,8 +17,14 @@ class ProcessManager {
|
|||
|
||||
Process& FromId(uint64_t id);
|
||||
|
||||
void InitCleanup();
|
||||
|
||||
void CleanupProcess(uint64_t pid);
|
||||
void CleanupThread(glcr::RefPtr<Thread> thread);
|
||||
|
||||
private:
|
||||
glcr::HashMap<uint64_t, glcr::RefPtr<Process>> proc_map_;
|
||||
ProcessCleanup cleanup;
|
||||
};
|
||||
|
||||
extern ProcessManager* gProcMan;
|
||||
|
|
|
@ -2,12 +2,14 @@
|
|||
|
||||
#include "capability/capability.h"
|
||||
#include "debug/debug.h"
|
||||
#include "scheduler/cleanup.h"
|
||||
#include "scheduler/process_manager.h"
|
||||
#include "scheduler/scheduler.h"
|
||||
|
||||
z_err_t ProcessExit(ZProcessExitReq* req) {
|
||||
auto curr_thread = gScheduler->CurrentThread();
|
||||
dbgln("Exit code: {}", static_cast<glcr::ErrorCode>(req->code));
|
||||
gProcMan->CleanupProcess(curr_thread->pid());
|
||||
curr_thread->process().Exit();
|
||||
panic("Returned from thread exit");
|
||||
return glcr::UNIMPLEMENTED;
|
||||
|
|
|
@ -53,6 +53,7 @@ extern "C" void zion() {
|
|||
dbgln("[boot] Init scheduler.");
|
||||
ProcessManager::Init();
|
||||
Scheduler::Init();
|
||||
gProcMan->InitCleanup();
|
||||
|
||||
dbgln("[boot] Loading sys init program.");
|
||||
LoadInitProgram();
|
||||
|
|
Loading…
Reference in New Issue