summaryrefslogtreecommitdiff
path: root/Source/Kernel/TaskManager
diff options
context:
space:
mode:
authorAlexis211 <alexis211@gmail.com>2009-10-16 17:35:50 +0200
committerAlexis211 <alexis211@gmail.com>2009-10-16 17:35:50 +0200
commit4d5348a49f54d95c0271c8f9c4ef01c005d6b74b (patch)
treebf993a94f618982a511f6eb5f71b21abe6521c0d /Source/Kernel/TaskManager
parent6e87493b8cd156388b075ecace376126a8875283 (diff)
downloadMelon-4d5348a49f54d95c0271c8f9c4ef01c005d6b74b.tar.gz
Melon-4d5348a49f54d95c0271c8f9c4ef01c005d6b74b.zip
We now use a temporary stack in task management for :
- deleting current thread whe it finishes - doing everything that goes with that
Diffstat (limited to 'Source/Kernel/TaskManager')
-rw-r--r--Source/Kernel/TaskManager/Process.class.cpp2
-rw-r--r--Source/Kernel/TaskManager/Task.ns.cpp52
-rw-r--r--Source/Kernel/TaskManager/Thread.class.cpp3
-rw-r--r--Source/Kernel/TaskManager/Thread.class.h2
4 files changed, 38 insertions, 21 deletions
diff --git a/Source/Kernel/TaskManager/Process.class.cpp b/Source/Kernel/TaskManager/Process.class.cpp
index 6b07e7a..2706986 100644
--- a/Source/Kernel/TaskManager/Process.class.cpp
+++ b/Source/Kernel/TaskManager/Process.class.cpp
@@ -64,7 +64,7 @@ void Process::exit() {
iter->v()->close(false);
delete iter->v();
}
- delete m_fileDescriptors;
+ delete m_fileDescriptors; //Will recursively delete whole list
m_state = P_FINISHED;
}
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*);