From 9520a1a101b264abe700c3f7753f5f55bba4c681 Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Sat, 17 Oct 2009 16:40:56 +0200 Subject: Each thread now has a kernel stack and an user stack --- Source/Kernel/TaskManager/Process.class.cpp | 4 +++- Source/Kernel/TaskManager/Thread.class.cpp | 37 ++++++++++++++++------------- Source/Kernel/TaskManager/Thread.class.h | 8 +++++-- 3 files changed, 30 insertions(+), 19 deletions(-) (limited to 'Source/Kernel/TaskManager') diff --git a/Source/Kernel/TaskManager/Process.class.cpp b/Source/Kernel/TaskManager/Process.class.cpp index d7fba80..cf8f00a 100644 --- a/Source/Kernel/TaskManager/Process.class.cpp +++ b/Source/Kernel/TaskManager/Process.class.cpp @@ -25,7 +25,8 @@ Process* Process::createKernel(String cmdline, VirtualTerminal *vt) { t->m_process = p; t->m_state = T_RUNNING; t->m_isKernel = true; - t->m_kernelStackFrame = 0; + t->m_kernelStack.addr = 0; + t->m_kernelStack.size = 0; p->registerThread(t); Task::registerProcess(p); @@ -43,6 +44,7 @@ Process::Process(String cmdline, u32int uid) { m_vt = Task::currProcess()->getVirtualTerminal(); //Create page directory and user heap m_pagedir = new PageDirectory(kernelPageDirectory); + m_pagedir->switchTo(); m_userHeap = new Heap(); u32int heapIdxSize = PhysMem::total() * 16 + 0x10000; m_userHeap->create(USERHEAPSTART, USERHEAPINITSIZE + heapIdxSize, heapIdxSize, m_pagedir, true, true); diff --git a/Source/Kernel/TaskManager/Thread.class.cpp b/Source/Kernel/TaskManager/Thread.class.cpp index 20d6cd4..6d62474 100644 --- a/Source/Kernel/TaskManager/Thread.class.cpp +++ b/Source/Kernel/TaskManager/Thread.class.cpp @@ -14,35 +14,40 @@ Thread::Thread() { //Private constructor, does nothing Thread::Thread(thread_entry_t entry_point, void* data, bool iskernel) { if (iskernel) { - m_isKernel = true; - u32int tmp; - m_kernelStackFrame = (u32int)PageAlloc::alloc(&tmp); - m_process = Task::getKernelProcess(); - setup(entry_point, data, m_kernelStackFrame + 0x1000); //A kernel stack always is 1 frame, meaning 0x1000 bytes + setup(Task::getKernelProcess(), entry_point, data, true); } else { - m_isKernel = false; - m_process = Task::currProcess(); - setup(entry_point, data, (u32int)(m_process->heap().alloc(STACKSIZE)) + STACKSIZE); + setup(Task::currProcess(), entry_point, data, false); } } Thread::Thread(Process* process, thread_entry_t entry_point, void* data) { - m_isKernel = false; - m_process = process; - setup(entry_point, data, (u32int)(m_process->heap().alloc(STACKSIZE)) + STACKSIZE); + setup(process, entry_point, data, false); } Thread::~Thread() { Task::unregisterThread(this); - if (m_isKernel) { - PageAlloc::free((void*)m_kernelStackFrame); - } + Mem::kfree(m_kernelStack.addr); + if (!m_isKernel) m_process->heap().free(m_userStack.addr); //Don't unregister thread in process, it has probably already been done } -void Thread::setup(thread_entry_t entry_point, void* data, u32int esp) { +void Thread::setup(Process* process, thread_entry_t entry_point, void* data, bool isKernel) { + DEBUG("new Thread :: setup"); + m_isKernel = isKernel; + m_process = process; + m_kernelStack.addr = Mem::kalloc(STACKSIZE); + m_kernelStack.size = STACKSIZE; + + if (m_isKernel) { + m_userStack.size = 0; + m_userStack.addr = 0; + } else { + m_userStack.addr = m_process->heap().alloc(STACKSIZE); + m_userStack.size = STACKSIZE; + } + u32int* stack = (u32int*)((u32int)(m_kernelStack.addr) + m_kernelStack.size); + //Pass function parameters for runThread() - u32int *stack = (u32int*)esp; stack--; *stack = (u32int)entry_point; //Push entry point (function parameter) stack--; diff --git a/Source/Kernel/TaskManager/Thread.class.h b/Source/Kernel/TaskManager/Thread.class.h index 369f62f..9c8fa26 100644 --- a/Source/Kernel/TaskManager/Thread.class.h +++ b/Source/Kernel/TaskManager/Thread.class.h @@ -13,6 +13,7 @@ typedef u32int(*thread_entry_t)(void*); class Thread { friend class Process; //This might be useful + friend void runThread(Thread*, void*, thread_entry_t); private: Thread(); //Creates a thread without initializing anything. Used by Process::createKernel(); @@ -27,9 +28,12 @@ class Thread { } waitfor; bool m_isKernel; //Says if stack is in kernel pagedir, and if thread should run in ring 0 - u32int m_kernelStackFrame; //Used for allocating and freeing a frame used as a stack + struct { + void* addr; + u32int size; + } m_userStack, m_kernelStack; - void setup(thread_entry_t entry_point, void* data, u32int esp); //Sets up stack, called by both constructors + void setup(Process* process, thread_entry_t entry_point, void* data, bool isKernel); public: Thread(thread_entry_t entry_point, void* data, bool iskernel = false); //Assumes process is current process, or is kprocess if isk -- cgit v1.2.3