From 37a1ebfc27cfb85e1527507722dc580cd5d7855f Mon Sep 17 00:00:00 2001 From: Yury Popov Date: Tue, 28 May 2019 00:25:43 +0300 Subject: [PATCH] Fix process exit handling --- src/kernlib/include/list.hpp | 3 +++ src/process/include/processmanager.hpp | 3 ++- src/process/process.cpp | 33 ++++++++++++-------------- src/process/processmanager.cpp | 10 +++++++- 4 files changed, 29 insertions(+), 20 deletions(-) diff --git a/src/kernlib/include/list.hpp b/src/kernlib/include/list.hpp index 4af3755..c1b3358 100644 --- a/src/kernlib/include/list.hpp +++ b/src/kernlib/include/list.hpp @@ -20,6 +20,9 @@ class List { } return items[count++]; } + void remove(size_t idx) { + Memory::copy(items + idx, items + idx + 1, sizeof(Item) * ((--count) - idx)); + } void add(const Item &item) { insert() = item; } diff --git a/src/process/include/processmanager.hpp b/src/process/include/processmanager.hpp index 298451f..9368f20 100644 --- a/src/process/include/processmanager.hpp +++ b/src/process/include/processmanager.hpp @@ -29,7 +29,8 @@ class ProcessManager { static bool FaultHandler(uint8_t intr, uint32_t code, Interrupts::CallbackRegs *regs); public: - uint64_t RegisterProcess(Process *process); + uint64_t registerProcess(Process *process); + void exitProcess(Process *process, int code); void queueThread(Process *process, Thread *thread); void dequeueThread(Thread *thread); Process *currentProcess(); diff --git a/src/process/process.cpp b/src/process/process.cpp index fc033e6..099971b 100644 --- a/src/process/process.cpp +++ b/src/process/process.cpp @@ -77,26 +77,22 @@ PTE* Process::addPage(uintptr_t vaddr, void* paddr, uint8_t flags) { pagetable = static_cast(Pagetable::alloc()); addPage(uintptr_t(pagetable), pagetable, 5); } - PTE pte = pagetable[ptx]; - if (!pte.present) { - pagetable[ptx] = pte = PTE(Pagetable::alloc(), 7); - addPage(pte.getUintPtr(), pte.getPtr(), 5); + if (!pagetable[ptx].present) { + pagetable[ptx] = PTE(Pagetable::alloc(), 7); + addPage(pagetable[ptx].getUintPtr(), pagetable[ptx].getPtr(), 5); } - PTE *pde = pte.getPTE(); - pte = pde[pdx]; - if (!pte.present) { - pde[pdx] = pte = PTE(Pagetable::alloc(), 7); - addPage(pte.getUintPtr(), pte.getPtr(), 5); + PTE *pde = pagetable[ptx].getPTE(); + if (!pde[pdx].present) { + pde[pdx] = PTE(Pagetable::alloc(), 7); + addPage(pde[pdx].getUintPtr(), pde[pdx].getPtr(), 5); } - PTE *pdpe = pte.getPTE(); - pte = pdpe[pdpx]; - if (!pte.present) { - pdpe[pdpx] = pte = PTE(Pagetable::alloc(), 7); - addPage(pte.getUintPtr(), pte.getPtr(), 5); + PTE *pdpe = pde[pdx].getPTE(); + if (!pdpe[pdpx].present) { + pdpe[pdpx] = PTE(Pagetable::alloc(), 7); + addPage(pdpe[pdpx].getUintPtr(), pdpe[pdpx].getPtr(), 5); } - PTE *pml4e = pte.getPTE(); - flags |= 1; - pml4e[pml4x] = PTE(paddr, flags); + PTE *pml4e = pdpe[pdpx].getPTE(); + pml4e[pml4x] = PTE(paddr, flags | 1); return &pml4e[pml4x]; } @@ -329,7 +325,7 @@ void Process::startup() { Thread *thread = new Thread(); thread->regs.rip = entry; thread->regs.rflags = 0; - id = (ProcessManager::getManager())->RegisterProcess(this); + id = (ProcessManager::getManager())->registerProcess(this); addThread(thread, false); } @@ -338,6 +334,7 @@ void Process::exit(int code) { for (size_t i = 0; i < threads.getCount(); i++) { ProcessManager::getManager()->dequeueThread(threads[i]); } + ProcessManager::getManager()->exitProcess(this, code); delete this; } diff --git a/src/process/processmanager.cpp b/src/process/processmanager.cpp index 9c38621..032e4c2 100644 --- a/src/process/processmanager.cpp +++ b/src/process/processmanager.cpp @@ -104,7 +104,7 @@ bool ProcessManager::HandleFault(uint8_t intr, uint32_t code, Interrupts::Callba return true; } -uint64_t ProcessManager::RegisterProcess(Process *process) { +uint64_t ProcessManager::registerProcess(Process *process) { Mutex::CriticalLock lock(processSwitchMutex); uint64_t pid = 1; for (size_t i = 0; i < processes.getCount(); i++) { @@ -114,6 +114,14 @@ uint64_t ProcessManager::RegisterProcess(Process *process) { return pid; } +void ProcessManager::exitProcess(Process *process, int code) { + (void)code; // TODO: handle + Mutex::CriticalLock lock(processSwitchMutex); + for (size_t i = processes.getCount(); i > 0; i--) { + if (processes[i-1] == process) processes.remove(i-1); + } +} + void ProcessManager::queueThread(Process *process, Thread *thread) { QueuedThread *q = new QueuedThread(); q->process = process;