diff options
-rwxr-xr-x | Source/Kernel/Melon.ke | bin | 613280 -> 609378 bytes | |||
-rw-r--r-- | Source/Kernel/MemoryManager/Heap.class.cpp | 20 | ||||
-rw-r--r-- | Source/Kernel/MemoryManager/Heap.class.h | 28 | ||||
-rw-r--r-- | Source/Kernel/MemoryManager/PageDirectory.class.cpp | 2 | ||||
-rw-r--r-- | Source/Kernel/MemoryManager/PhysMem.ns.cpp | 5 | ||||
-rw-r--r-- | Source/Kernel/SyscallManager/IDT.ns.cpp | 4 | ||||
-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 |
12 files changed, 96 insertions, 47 deletions
diff --git a/Source/Kernel/Melon.ke b/Source/Kernel/Melon.ke Binary files differindex da8d78d..326bd23 100755 --- a/Source/Kernel/Melon.ke +++ b/Source/Kernel/Melon.ke diff --git a/Source/Kernel/MemoryManager/Heap.class.cpp b/Source/Kernel/MemoryManager/Heap.class.cpp index f5bbe0a..7331cd0 100644 --- a/Source/Kernel/MemoryManager/Heap.class.cpp +++ b/Source/Kernel/MemoryManager/Heap.class.cpp @@ -1,7 +1,7 @@ #include "Heap.class.h" #include <MemoryManager/PageDirectory.class.h> -Heap::Heap() { +Heap::Heap() : m_mutex(MUTEX_FALSE) { m_usable = false; m_index.data = 0; m_index.size = 0; @@ -12,6 +12,8 @@ Heap::~Heap() { } void Heap::create(u32int start, u32int size, u32int idxsize, PageDirectory* pagedir, bool user, bool rw) { + if (m_usable) return; + if (start & 0x0FFF) start = (start & 0xFFFFF000) + 0x1000; if (size & 0x0FFF) size = (size & 0xFFFFF000) + 0x1000; m_start = start + idxsize; //m_start is start of real data, start is start of index. @@ -42,6 +44,8 @@ void Heap::create(u32int start, u32int size, u32int idxsize, PageDirectory* page m_usable = true; m_free = (m_end - m_start); + + m_mutex.unlock(); } void Heap::expand(u32int quantity) { @@ -113,6 +117,8 @@ void Heap::contract() { //Automatically work out how much we can contract } void *Heap::alloc(u32int sz, bool no_expand) { + m_mutex.waitLock(); + u32int newsize = sz + sizeof(heap_header_t) + sizeof(heap_footer_t); u32int iterator = 0; while (iterator < m_index.size) { @@ -120,8 +126,12 @@ void *Heap::alloc(u32int sz, bool no_expand) { iterator++; } if (iterator == m_index.size) { //No hole is big enough - if (no_expand) return 0; + if (no_expand) { + m_mutex.unlock(); + return 0; + } expand((sz & 0xFFFFF000) + 0x1000); + m_mutex.unlock(); return alloc(sz, true); //Recurse call } @@ -152,6 +162,8 @@ void *Heap::alloc(u32int sz, bool no_expand) { m_free -= loc->size; + m_mutex.unlock(); + return (void*)((u32int)loc + sizeof(heap_header_t)); } @@ -162,6 +174,8 @@ void Heap::free(void *ptr) { heap_footer_t *footer = (heap_footer_t*)((u32int)header + header->size - sizeof(heap_footer_t)); if (header->magic != HEAP_MAGIC or footer->magic != HEAP_MAGIC) return; + m_mutex.waitLock(); + m_free += header->size; //Unify left @@ -192,4 +206,6 @@ void Heap::free(void *ptr) { header->size >= 0x2000 and (m_end - m_start > HEAP_MIN_SIZE)) { contract(); } + + m_mutex.unlock(); } diff --git a/Source/Kernel/MemoryManager/Heap.class.h b/Source/Kernel/MemoryManager/Heap.class.h index a1feaa1..930a589 100644 --- a/Source/Kernel/MemoryManager/Heap.class.h +++ b/Source/Kernel/MemoryManager/Heap.class.h @@ -2,6 +2,7 @@ #define DEF_HEAP_CLASS_H #include <Core/common.wtf.h> +#include <TaskManager/Mutex.class.h> //Heap minimum size : 2M #define HEAP_MIN_SIZE 0x00200000 @@ -33,6 +34,8 @@ class Heap { heap_index_t m_index; PageDirectory* m_pagedir; + Mutex m_mutex; + void insertIntoIndex(heap_header_t *e); u32int findIndexEntry(heap_header_t *e); void removeFromIndex(u32int idx); @@ -41,20 +44,35 @@ class Heap { void expand(u32int quantity); void contract(); //Quantity is automatically calculated - public: Heap(); ~Heap(); - bool usable() { return m_usable; } - void create(u32int start, u32int size, u32int idxsize, PageDirectory* pagedir, bool user, bool rw); void* alloc(u32int sz, bool no_expand = false); void free(void* ptr); - u32int size() { return m_end - m_start; } - u32int free() { return m_free; } + bool usable() { + m_mutex.waitLock(); + bool ret = m_usable; + m_mutex.unlock(); + return ret; + } + + u32int size() { + m_mutex.waitLock(); + u32int ret = m_end - m_start; + m_mutex.unlock(); + return ret; + } + + u32int free() { + m_mutex.waitLock(); + u32int ret = m_free; + m_mutex.unlock(); + return ret; + } }; diff --git a/Source/Kernel/MemoryManager/PageDirectory.class.cpp b/Source/Kernel/MemoryManager/PageDirectory.class.cpp index 2c8507f..13fbc36 100644 --- a/Source/Kernel/MemoryManager/PageDirectory.class.cpp +++ b/Source/Kernel/MemoryManager/PageDirectory.class.cpp @@ -43,7 +43,6 @@ PageDirectory::PageDirectory(PageDirectory* other) { } PageDirectory::~PageDirectory() { - PageAlloc::free((void*)tablesPhysical); for (int i = 0; i < 768; i++) { //Only free addresses below 0xC0000000, upper is kernel space if (tables[i] != 0) { for (int j = 0; j < 1024; j++) { @@ -52,6 +51,7 @@ PageDirectory::~PageDirectory() { PageAlloc::free((void*)tables[i]); } } + PageAlloc::free((void*)tablesPhysical); } page_t *PageDirectory::getPage(u32int address, bool make) { diff --git a/Source/Kernel/MemoryManager/PhysMem.ns.cpp b/Source/Kernel/MemoryManager/PhysMem.ns.cpp index 1794106..382e8a4 100644 --- a/Source/Kernel/MemoryManager/PhysMem.ns.cpp +++ b/Source/Kernel/MemoryManager/PhysMem.ns.cpp @@ -61,8 +61,9 @@ void freeFrame(page_t *page) { if (page->frame == 0) { return; } else { - if (page->frame >= 0x100) //First 1M are reserved (system) - frames->clearBit(page->frame / 0x1000); + if (page->frame >= 0x100) { //First 1M are reserved (system) + frames->clearBit(page->frame); + } page->frame = 0; } } diff --git a/Source/Kernel/SyscallManager/IDT.ns.cpp b/Source/Kernel/SyscallManager/IDT.ns.cpp index 1a62d88..fcab741 100644 --- a/Source/Kernel/SyscallManager/IDT.ns.cpp +++ b/Source/Kernel/SyscallManager/IDT.ns.cpp @@ -74,9 +74,9 @@ 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::currentThreadExits(regs.eax); + Task::currentThreadExits(regs.eax); //DO NOT COUNT ON COMMING BACK FROM HERE } - if (doSwitch) Task::doSwitch(); //DO NEVER COUNT ON COMMING BACK FROM HERE + if (doSwitch) Task::doSwitch(); //DO NOT COUNT ON COMMING BACK FROM HERE EITHER } namespace IDT { 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*); |