From b9a988061e8220c5ef2406f5cd2221bf3f1b435d Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Fri, 9 Oct 2009 16:29:05 +0200 Subject: Exiting from a thread now works without hanging everything. --- Source/Kernel/Core/Sys.ns.cpp | 2 +- Source/Kernel/Core/kmain.wtf.cpp | 6 +++--- Source/Kernel/Melon.ke | Bin 165137 -> 165231 bytes Source/Kernel/MemoryManager/PageAlloc.ns.cpp | 2 +- Source/Kernel/Shell/KernelShell.class.cpp | 5 ++++- Source/Kernel/SyscallManager/IDT.ns.cpp | 2 +- Source/Kernel/TaskManager/Process.class.cpp | 9 ++++---- Source/Kernel/TaskManager/Task.ns.cpp | 31 +++++++++++++++++++++++++++ Source/Kernel/TaskManager/Task.ns.h | 2 ++ Source/Kernel/TaskManager/Thread.class.cpp | 3 +-- 10 files changed, 49 insertions(+), 13 deletions(-) (limited to 'Source') diff --git a/Source/Kernel/Core/Sys.ns.cpp b/Source/Kernel/Core/Sys.ns.cpp index c3561f2..a54c387 100644 --- a/Source/Kernel/Core/Sys.ns.cpp +++ b/Source/Kernel/Core/Sys.ns.cpp @@ -125,7 +125,7 @@ void halt() { asm volatile("cli"); Log::close(); String message("MELON SEZ : KTHXBYE, U CAN NAOW TURNZ OFF UR COMPUTER."); - SimpleVT vt(3, message.size() + 16, 6, 0); + SimpleVT vt(3, message.size() + 16, 7, 6); vt.map(); vt << "\n\t" << message; while (1) asm volatile("cli"); diff --git a/Source/Kernel/Core/kmain.wtf.cpp b/Source/Kernel/Core/kmain.wtf.cpp index 924cfc2..f1efc70 100644 --- a/Source/Kernel/Core/kmain.wtf.cpp +++ b/Source/Kernel/Core/kmain.wtf.cpp @@ -75,8 +75,8 @@ void kmain(multiboot_info_t* mbd, u32int magic) { melonLogoVT->map(1); //Create a VT for logging what kernel does - SimpleVT *kvt = new ScrollableVT(5, 69, 10, KVT_FGCOLOR, KVT_BGCOLOR); - kvt->map(20); + SimpleVT *kvt = new ScrollableVT(3, 69, 10, KVT_FGCOLOR, KVT_BGCOLOR); + kvt->map(22); INFO(kvt); *kvt << "Lower ram : " << (s32int)mbd->mem_lower << "k, upper : " << (s32int)mbd->mem_upper << "k.\n"; INFO(kvt); *kvt << "Placement address : " << (u32int)Mem::placementAddress << "\n"; @@ -131,7 +131,7 @@ void kmain(multiboot_info_t* mbd, u32int magic) { Log::log(KL_STATUS, "kmain : Kernel shell launched"); while (KernelShell::getInstances() > 0) { - Task::currentThread->sleep(10); + Task::currentThread->sleep(100); } Log::log(KL_STATUS, "kmain : All kernel shells finished. Halting."); diff --git a/Source/Kernel/Melon.ke b/Source/Kernel/Melon.ke index 2f43146..4517c24 100755 Binary files a/Source/Kernel/Melon.ke and b/Source/Kernel/Melon.ke differ diff --git a/Source/Kernel/MemoryManager/PageAlloc.ns.cpp b/Source/Kernel/MemoryManager/PageAlloc.ns.cpp index ac2969e..34d4f74 100644 --- a/Source/Kernel/MemoryManager/PageAlloc.ns.cpp +++ b/Source/Kernel/MemoryManager/PageAlloc.ns.cpp @@ -52,7 +52,7 @@ void* alloc(u32int* phys) { if (p == 0) { //THIS SHOULD NEVER HAPPEN PANIC("Cached free page does not exist."); } else if (p->frame == 0) { - PANIC("Cached free page is not mapped to a frame."); + PhysMem::allocFrame(p, true, false); } else { *phys = (p->frame * 0x1000); } diff --git a/Source/Kernel/Shell/KernelShell.class.cpp b/Source/Kernel/Shell/KernelShell.class.cpp index 5d78953..8e7bebb 100644 --- a/Source/Kernel/Shell/KernelShell.class.cpp +++ b/Source/Kernel/Shell/KernelShell.class.cpp @@ -14,7 +14,7 @@ u32int shellRun(void* ks) { } KernelShell::KernelShell(DirectoryNode* cwd) { - m_vt = new ScrollableVT(10, 76, 200, SHELL_FGCOLOR, SHELL_BGCOLOR); + m_vt = new ScrollableVT(12, 76, 200, SHELL_FGCOLOR, SHELL_BGCOLOR); ((ScrollableVT*)m_vt)->map(9); Kbd::setFocus(m_vt); m_cwd = cwd; @@ -76,6 +76,9 @@ u32int KernelShell::run() { Sys::halt(); } else if (tokens[0] == "panic") { PANIC("This is what happens when you say 'panic'."); + } else if (tokens[0] == "exit") { + if (tokens.size() == 1) return 0; + return tokens[1].toInt(); } else if (tokens[0] != "" or tokens.size() != 1) { u32int i = 0; bool found = false; diff --git a/Source/Kernel/SyscallManager/IDT.ns.cpp b/Source/Kernel/SyscallManager/IDT.ns.cpp index dc40747..36c584d 100644 --- a/Source/Kernel/SyscallManager/IDT.ns.cpp +++ b/Source/Kernel/SyscallManager/IDT.ns.cpp @@ -74,7 +74,7 @@ extern "C" void interrupt_handler(registers_t regs) { doSwitch = doSwitch or Task::IRQwakeup(regs.int_no - 32); } if (regs.int_no == 66) { //This syscall signals to kernel that thread ended. - Task::currentThread->finish(regs.eax); + Task::currentThreadExits(regs.eax); } if (doSwitch) Task::doSwitch(); //DO NEVER COUNT ON COMMING BACK FROM HERE } diff --git a/Source/Kernel/TaskManager/Process.class.cpp b/Source/Kernel/TaskManager/Process.class.cpp index 5a707cd..236d13a 100644 --- a/Source/Kernel/TaskManager/Process.class.cpp +++ b/Source/Kernel/TaskManager/Process.class.cpp @@ -56,10 +56,10 @@ u32int Process::stackAlloc() { } void Process::exit() { - while (!m_threads.empty()) { - delete m_threads.back(); - m_threads.pop(); + for (u32int i = 0; i < m_threads.size(); i++) { + delete m_threads[i]; } + m_threads.clear(); for (u32int i = 0; i < m_fileDescriptors.size(); i++) { m_fileDescriptors[i]->close(false); delete m_fileDescriptors[i]; @@ -74,7 +74,6 @@ void Process::registerThread(Thread* t) { } void Process::threadFinishes(Thread* thread, u32int retval) { - delete thread; // If it is the main thread of the process, or if it pagefaulted if (thread == m_threads[0] or retval == E_PAGEFAULT) { exit(); @@ -84,8 +83,10 @@ void Process::threadFinishes(Thread* thread, u32int retval) { if (m_threads[i] == thread) { m_threads[i] = m_threads.back(); m_threads.pop(); + break; } } + delete thread; } } diff --git a/Source/Kernel/TaskManager/Task.ns.cpp b/Source/Kernel/TaskManager/Task.ns.cpp index b430f24..a32c8c0 100644 --- a/Source/Kernel/TaskManager/Task.ns.cpp +++ b/Source/Kernel/TaskManager/Task.ns.cpp @@ -10,6 +10,12 @@ namespace Task { Vector processes; //TODO : use a linked list instead Vector threads; +struct finished_thread_t { //Forms a linked list + Thread* thread; + u32int errcode; + finished_thread_t *next; +} *firstFinishedThread = 0; + Thread* currentThread = NULL; Process* currentProcess = NULL; Thread* idleThread = NULL; @@ -29,11 +35,28 @@ void initialize(String cmdline, VirtualTerminal *vt) { } Thread* nextThread() { + //Clean up finished threads + while (firstFinishedThread != 0) { + DEBUG_HEX((u32int)firstFinishedThread); + if (firstFinishedThread->thread == currentThread) break; + firstFinishedThread->thread->finish(firstFinishedThread->errcode); + finished_thread_t* t = firstFinishedThread; + firstFinishedThread = t->next; + delete t; + } + for (u32int i = 0; i < threads.size(); i++) { + if (threads[i] == currentThread) { + currentThreadId = i; + } + } + + //Find next thread u32int nid = currentThreadId; while (1) { nid++; if (nid >= threads.size()) nid = 0; if (threads[nid]->runnable() and threads[nid] != idleThread) { + if (firstFinishedThread != 0 and firstFinishedThread->thread == threads[nid]) return idleThread; currentThreadId = nid; return threads[nid]; } @@ -104,6 +127,14 @@ Process* getKernelProcess() { return processes[0]; } +void currentThreadExits(u32int errcode) { + finished_thread_t *t = new finished_thread_t; + t->thread = currentThread; + t->errcode = errcode; + t->next = firstFinishedThread; + firstFinishedThread = t; +} + void registerThread(Thread* t) { unregisterThread(t); //...// threads.push(t); diff --git a/Source/Kernel/TaskManager/Task.ns.h b/Source/Kernel/TaskManager/Task.ns.h index 634d103..a41eaf7 100644 --- a/Source/Kernel/TaskManager/Task.ns.h +++ b/Source/Kernel/TaskManager/Task.ns.h @@ -17,6 +17,8 @@ namespace Task { void allocKernelPageTable(u32int id, page_table_t *table, u32int tablePhys); Process* getKernelProcess(); //Returns first registered process + void currentThreadExits(u32int errcode); //Syscall called when a thread finishes + //These are used by the constructors/destructors of Thread and Process void registerThread(Thread* t); void unregisterThread(Thread* t); diff --git a/Source/Kernel/TaskManager/Thread.class.cpp b/Source/Kernel/TaskManager/Thread.class.cpp index 43884d7..93a2cd3 100644 --- a/Source/Kernel/TaskManager/Thread.class.cpp +++ b/Source/Kernel/TaskManager/Thread.class.cpp @@ -33,10 +33,9 @@ Thread::Thread(Process* process, thread_entry_t entry_point, void* data) { } Thread::~Thread() { - if (Task::currentThread == this) Task::currentThread = (Thread*)0xFFFFFFFF; //Signal that current thread is invalid + Task::unregisterThread(this); if (m_isKernel) PageAlloc::free((void*)m_kernelStackFrame); - Task::unregisterThread(this); //Don't unregister thread in process, it has probably already been done } -- cgit v1.2.3