diff options
Diffstat (limited to 'Source/Kernel/TaskManager')
-rw-r--r-- | Source/Kernel/TaskManager/Mutex.class.cpp | 6 | ||||
-rw-r--r-- | Source/Kernel/TaskManager/Process.class.cpp | 18 | ||||
-rw-r--r-- | Source/Kernel/TaskManager/Process.class.h | 3 | ||||
-rw-r--r-- | Source/Kernel/TaskManager/Task.ns.cpp | 52 | ||||
-rw-r--r-- | Source/Kernel/TaskManager/Thread.class.cpp | 3 | ||||
-rw-r--r-- | Source/Kernel/TaskManager/Thread.class.h | 2 |
6 files changed, 49 insertions, 35 deletions
diff --git a/Source/Kernel/TaskManager/Mutex.class.cpp b/Source/Kernel/TaskManager/Mutex.class.cpp index a6c3ba8..8ba274f 100644 --- a/Source/Kernel/TaskManager/Mutex.class.cpp +++ b/Source/Kernel/TaskManager/Mutex.class.cpp @@ -13,8 +13,10 @@ bool Mutex::lock() { } void Mutex::waitLock() { - while (atomic_exchange(&m_locked, MUTEX_TRUE) == MUTEX_TRUE) - Task::currThread()->sleep(10); //Wait 10ms + while (atomic_exchange(&m_locked, MUTEX_TRUE) == MUTEX_TRUE) { + if (Task::currThread() != 0) Task::currThread()->sleep(10); //Wait 10ms + else return; + } } void Mutex::unlock() { diff --git a/Source/Kernel/TaskManager/Process.class.cpp b/Source/Kernel/TaskManager/Process.class.cpp index 2653269..2706986 100644 --- a/Source/Kernel/TaskManager/Process.class.cpp +++ b/Source/Kernel/TaskManager/Process.class.cpp @@ -60,11 +60,11 @@ void Process::exit() { 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]; + for (SimpleList<File*> *iter = m_fileDescriptors; iter != 0; iter = iter->next()) { + iter->v()->close(false); + delete iter->v(); } - m_fileDescriptors.clear(); + delete m_fileDescriptors; //Will recursively delete whole list m_state = P_FINISHED; } @@ -91,17 +91,11 @@ void Process::threadFinishes(Thread* thread, u32int retval) { } void Process::registerFileDescriptor(File* fd) { - m_fileDescriptors.push(fd); + m_fileDescriptors = m_fileDescriptors->cons(fd); } void Process::unregisterFileDescriptor(File* fd) { - for (u32int i = 0; i < m_fileDescriptors.size(); i++) { - if (m_fileDescriptors[i] == fd) { - m_fileDescriptors[i] = m_fileDescriptors.back(); - m_fileDescriptors.pop(); - break; - } - } + m_fileDescriptors = m_fileDescriptors->removeOnce(fd); } PageDirectory* Process::getPagedir() { diff --git a/Source/Kernel/TaskManager/Process.class.h b/Source/Kernel/TaskManager/Process.class.h index 65a5d8b..b975db1 100644 --- a/Source/Kernel/TaskManager/Process.class.h +++ b/Source/Kernel/TaskManager/Process.class.h @@ -3,6 +3,7 @@ #include <Library/String.class.h> #include <Library/Vector.class.h> +#include <Library/SimpleList.class.h> #include <MemoryManager/PageDirectory.class.h> #include <VTManager/VirtualTerminal.proto.h> @@ -35,7 +36,7 @@ class Process { VirtualTerminal *m_vt; Vector<Thread*> m_threads; - Vector<File*> m_fileDescriptors; + SimpleList<File*> *m_fileDescriptors; public: static Process* createKernel(String cmdline, VirtualTerminal *vt); //Also creates a Thread for what's curently happening diff --git a/Source/Kernel/TaskManager/Task.ns.cpp b/Source/Kernel/TaskManager/Task.ns.cpp index 4db05bc..66eca94 100644 --- a/Source/Kernel/TaskManager/Task.ns.cpp +++ b/Source/Kernel/TaskManager/Task.ns.cpp @@ -1,5 +1,9 @@ #include "Task.ns.h" #include <Library/Vector.class.h> +#include <MemoryManager/PhysMem.ns.h> + +#define INVALID_TASK_MAGIC 0xBEEFFEED +#define TEMP_STACK_SIZE 128 //This must be big enough so that we can call all we need to call when a task finishes //From Task.wtf.asm extern "C" u32int read_eip(); @@ -16,12 +20,7 @@ SimpleList<Thread*> *idleThread = 0; u32int nextpid = 1; -struct finished_thread_t { //Forms a linked list - Thread* thread; - u32int errcode; -}; -SimpleList<finished_thread_t> *firstFinishedThread = 0; - +u32int temp_stack[TEMP_STACK_SIZE]; //Temporary stack used for finishing current thread Thread* currThread() { return currentThread->v(); @@ -53,20 +52,15 @@ void initialize(String cmdline, VirtualTerminal *vt) { } SimpleList<Thread*> *nextThread() { - //Clean up finished threads - while (firstFinishedThread != 0) { - if (firstFinishedThread->v().thread == currentThread->v()) break; - firstFinishedThread->v().thread->finish(firstFinishedThread->v().errcode); - firstFinishedThread = firstFinishedThread->delThis(); - } - //Find next thread + if ((u32int)currentThread == INVALID_TASK_MAGIC) { + currentThread = threads; //This will happen when we come here just after current thread has finished + } SimpleList<Thread*> *iter = currentThread; while (1) { iter = iter->next(); if (iter == 0) iter = threads; if (iter->v()->runnable() and iter->v() != idleThread->v()) { - if (firstFinishedThread != 0 and firstFinishedThread->v().thread == iter->v()) return idleThread; return iter; } if (iter == currentThread) break; @@ -88,7 +82,8 @@ void doSwitch() { return; } - if ((u32int)currentThread->v() != 0xFFFFFFFF) currentThread->v()->setState(esp, ebp, eip); + //This will happen when we come here just after current thread has finished + if ((u32int)currentThread != INVALID_TASK_MAGIC) currentThread->v()->setState(esp, ebp, eip); currentThread = nextThread(); Thread* t = currentThread->v(); @@ -127,6 +122,8 @@ bool IRQwakeup(u8int irq) { } void allocKernelPageTable(u32int id, page_table_t *table, u32int tablePhys) { + kernelPageDirectory->tables[id] = table; + kernelPageDirectory->tablesPhysical[id] = tablePhys; if (id < 768) return; //this would be a BUG for (SimpleList<Process*> *iter = processes; iter != 0; iter = iter->next()) { iter->v()->getPagedir()->tables[id] = table; @@ -134,9 +131,28 @@ void allocKernelPageTable(u32int id, page_table_t *table, u32int tablePhys) { } } -void currentThreadExits(u32int errcode) { - finished_thread_t tmp = {currentThread->v(), errcode}; - firstFinishedThread = firstFinishedThread->cons(tmp); +void currThreadExitProceed(u32int errcode) { + currentThread->v()->finish(errcode); + currentThread = (SimpleList<Thread*>*)INVALID_TASK_MAGIC; + doSwitch(); //Normally never come back from here +} + +void currentThreadExits(u32int errcode) { //Call currThreadExitProceed with a working stack (we use temp_stack) + u32int* stack = &temp_stack[TEMP_STACK_SIZE]; + stack--; + *stack = errcode; + stack--; + *stack = 0; + u32int esp = (u32int)(stack), ebp = (u32int)(stack + 1), eip = (u32int)currThreadExitProceed; + + asm volatile(" \ + cli; \ + mov %0, %%ebp; \ + mov %1, %%esp; \ + mov %2, %%ecx; \ + mov %3, %%cr3; \ + jmp *%%ecx;" + : : "r"(ebp), "r"(esp), "r"(eip), "r"(kernelPageDirectory->physicalAddr)); } void registerThread(Thread* t) { diff --git a/Source/Kernel/TaskManager/Thread.class.cpp b/Source/Kernel/TaskManager/Thread.class.cpp index fd5cfd9..fe1d08e 100644 --- a/Source/Kernel/TaskManager/Thread.class.cpp +++ b/Source/Kernel/TaskManager/Thread.class.cpp @@ -34,8 +34,9 @@ Thread::Thread(Process* process, thread_entry_t entry_point, void* data) { Thread::~Thread() { Task::unregisterThread(this); - if (m_isKernel) + if (m_isKernel) { PageAlloc::free((void*)m_kernelStackFrame); + } //Don't unregister thread in process, it has probably already been done } diff --git a/Source/Kernel/TaskManager/Thread.class.h b/Source/Kernel/TaskManager/Thread.class.h index dffc84a..369f62f 100644 --- a/Source/Kernel/TaskManager/Thread.class.h +++ b/Source/Kernel/TaskManager/Thread.class.h @@ -7,7 +7,7 @@ #define T_ZOMBIE 0 #define T_RUNNING 1 #define T_SLEEPING 2 -#define T_IRQWAIT 3 //This can only happen if process->uid == 0 (root) +#define T_IRQWAIT 3 typedef u32int(*thread_entry_t)(void*); |