summaryrefslogtreecommitdiff
path: root/Source/Kernel
diff options
context:
space:
mode:
authorAlexis211 <alexis211@gmail.com>2009-10-09 16:29:05 +0200
committerAlexis211 <alexis211@gmail.com>2009-10-09 16:29:05 +0200
commitb9a988061e8220c5ef2406f5cd2221bf3f1b435d (patch)
tree7d523347e555a7555740d7b0ceffbeb35c32d1e6 /Source/Kernel
parent92abedffec913fe7337117403c5e07185356c81b (diff)
downloadMelon-b9a988061e8220c5ef2406f5cd2221bf3f1b435d.tar.gz
Melon-b9a988061e8220c5ef2406f5cd2221bf3f1b435d.zip
Exiting from a thread now works without hanging everything.
Diffstat (limited to 'Source/Kernel')
-rw-r--r--Source/Kernel/Core/Sys.ns.cpp2
-rw-r--r--Source/Kernel/Core/kmain.wtf.cpp6
-rwxr-xr-xSource/Kernel/Melon.kebin165137 -> 165231 bytes
-rw-r--r--Source/Kernel/MemoryManager/PageAlloc.ns.cpp2
-rw-r--r--Source/Kernel/Shell/KernelShell.class.cpp5
-rw-r--r--Source/Kernel/SyscallManager/IDT.ns.cpp2
-rw-r--r--Source/Kernel/TaskManager/Process.class.cpp9
-rw-r--r--Source/Kernel/TaskManager/Task.ns.cpp31
-rw-r--r--Source/Kernel/TaskManager/Task.ns.h2
-rw-r--r--Source/Kernel/TaskManager/Thread.class.cpp3
10 files changed, 49 insertions, 13 deletions
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
--- a/Source/Kernel/Melon.ke
+++ b/Source/Kernel/Melon.ke
Binary files 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 <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
}