diff options
Diffstat (limited to 'Source/Kernel/TaskManager')
-rw-r--r-- | Source/Kernel/TaskManager/Process.class.cpp | 9 | ||||
-rw-r--r-- | Source/Kernel/TaskManager/Task.ns.cpp | 31 | ||||
-rw-r--r-- | Source/Kernel/TaskManager/Task.ns.h | 2 | ||||
-rw-r--r-- | Source/Kernel/TaskManager/Thread.class.cpp | 3 |
4 files changed, 39 insertions, 6 deletions
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 <Process*> processes; //TODO : use a linked list instead Vector <Thread*> 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 } |