From 3be1804db57e5d1ff08f46c7b7418729da631c26 Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Sun, 11 Oct 2009 18:38:05 +0200 Subject: Tasking now works with linked lists --- Makefile | 3 + Qemu-GDB-Debug-CMD | 1 + Source/Kernel/Core/Sys.ns.cpp | 6 +- Source/Kernel/Core/kmain.wtf.cpp | 4 +- .../Devices/Floppy/FloppyController.class.cpp | 8 +- Source/Kernel/Devices/Floppy/FloppyDrive.class.cpp | 12 +- Source/Kernel/Library/SimpleList.class.h | 5 + Source/Kernel/Makefile | 2 +- Source/Kernel/Melon.ke | Bin 166272 -> 574720 bytes Source/Kernel/SyscallManager/IDT.ns.cpp | 4 +- Source/Kernel/TaskManager/Mutex.class.cpp | 2 +- Source/Kernel/TaskManager/Process.class.cpp | 2 +- Source/Kernel/TaskManager/Task.ns.cpp | 125 ++++++++++++--------- Source/Kernel/TaskManager/Task.ns.h | 5 +- Source/Kernel/TaskManager/Thread.class.cpp | 2 +- Source/Kernel/VFS/File.class.cpp | 4 +- .../Kernel/VTManager/VirtualTerminal-kbd.proto.cpp | 2 +- 17 files changed, 106 insertions(+), 81 deletions(-) create mode 100644 Qemu-GDB-Debug-CMD diff --git a/Makefile b/Makefile index a15bfad..1ee22b3 100644 --- a/Makefile +++ b/Makefile @@ -50,6 +50,9 @@ bochs: qemu: qemu -fda $(Floppy) -m 16 +qemu_debug: + qemu -fda $(Floppy) -m 16 -s -S & gdb Source/Kernel/Melon.ke -x Qemu-GDB-Debug-CMD + stats: echo; echo " ** Statistics for project O3S ** "; \ echo -n "Lines of code : "; \ diff --git a/Qemu-GDB-Debug-CMD b/Qemu-GDB-Debug-CMD new file mode 100644 index 0000000..24efe1e --- /dev/null +++ b/Qemu-GDB-Debug-CMD @@ -0,0 +1 @@ +target remote localhost:1234 diff --git a/Source/Kernel/Core/Sys.ns.cpp b/Source/Kernel/Core/Sys.ns.cpp index a54c387..c0218d8 100644 --- a/Source/Kernel/Core/Sys.ns.cpp +++ b/Source/Kernel/Core/Sys.ns.cpp @@ -82,8 +82,9 @@ void panic(char *message, char *file, u32int line) { void panic(char *message, registers_t *regs, char *file, u32int line) { asm volatile("cli"); - SimpleVT vt(20, 70, 7, 1); + SimpleVT vt(21, 70, 7, 1); vt.map(); + vt.write("\n"); vt << "PANIC : " << message << "\n => in " << file << " at " << (s32int)line << "\n\n"; vt << "ds=" << (u32int)regs->ds << ", eip=" << (u32int)regs->eip << ", cs=" << (u32int)regs->cs << "\n"; @@ -93,14 +94,13 @@ void panic(char *message, registers_t *regs, char *file, u32int line) { ", edx=" << (u32int)regs->edx << "\n"; vt << "int_no=" << (s32int)regs->int_no << ", err_code=" << (u32int)regs->err_code << "\n"; vt << "eflags=" << (u32int)regs->eflags << ", useresp=" << (u32int)regs->useresp << ", ss=" << (u32int)regs->ss << "\n\n"; + while (1) asm volatile("cli; hlt"); u32int *v = (u32int*)regs->ebp; for (int i = 0; i < 10; i++) { vt << "ebp=" << (u32int)v << ", value=" << (u32int)(v[1]) << "\n"; v = (u32int*)(*v); } - - while (1) asm volatile("hlt"); } //Used by ASSERT() macro (see common.wtf.h) diff --git a/Source/Kernel/Core/kmain.wtf.cpp b/Source/Kernel/Core/kmain.wtf.cpp index 66e6a8a..8b6a0de 100644 --- a/Source/Kernel/Core/kmain.wtf.cpp +++ b/Source/Kernel/Core/kmain.wtf.cpp @@ -78,7 +78,7 @@ u32int logoAnimation(void* p) { vt.putChar(y, (i + (y%3)), wat[(i + (y%3)) * melonLogoLines + y]); } } - Task::currentThread->sleep(20); + Task::currThread()->sleep(20); } return 0; } @@ -171,7 +171,7 @@ void kmain(multiboot_info_t* mbd, u32int magic) { kvt->unmap(); while (KernelShell::getInstances() > 0) { - Task::currentThread->sleep(100); + Task::currThread()->sleep(100); } Log::log(KL_STATUS, "kmain : All kernel shells finished. Halting."); diff --git a/Source/Kernel/Devices/Floppy/FloppyController.class.cpp b/Source/Kernel/Devices/Floppy/FloppyController.class.cpp index fa7a56a..146ce28 100644 --- a/Source/Kernel/Devices/Floppy/FloppyController.class.cpp +++ b/Source/Kernel/Devices/Floppy/FloppyController.class.cpp @@ -75,7 +75,7 @@ void FloppyController::dmaRelease() { //********************************************************* u32int floppyMotorTimer(void* plop) { //This will be an independant thread while(1) { - Task::currentThread->sleep(1000); //Check only every second + Task::currThread()->sleep(1000); //Check only every second Vector floppys = Dev::findDevices("block.floppy"); for (u32int i = 0; i < floppys.size(); i++) { FloppyDrive* f = (FloppyDrive*)floppys[i]; @@ -147,7 +147,7 @@ void FloppyController::setDOR() { asm volatile ("cli"); outb(m_base + FR_DOR, dor); if (m_first) { //First time we set the DOR, controller initialized - Task::currentThread->waitIRQ(m_irq); + Task::currThread()->waitIRQ(m_irq); int st0, cyl; checkInterrupt(&st0, &cyl); m_first = false; @@ -172,7 +172,7 @@ bool FloppyController::writeCmd(u8int cmd) { outb(m_base + FR_FIFO, cmd); return true; } - Task::currentThread->sleep(10); + Task::currThread()->sleep(10); } return false; } @@ -182,7 +182,7 @@ u8int FloppyController::readData() { if (0x80 & inb(m_base + FR_MSR)) { return inb(m_base + FR_FIFO); } - Task::currentThread->sleep(10); + Task::currThread()->sleep(10); } return 0; } diff --git a/Source/Kernel/Devices/Floppy/FloppyDrive.class.cpp b/Source/Kernel/Devices/Floppy/FloppyDrive.class.cpp index beaaf19..7edf24a 100644 --- a/Source/Kernel/Devices/Floppy/FloppyDrive.class.cpp +++ b/Source/Kernel/Devices/Floppy/FloppyDrive.class.cpp @@ -98,7 +98,7 @@ bool FloppyDrive::calibrate() { m_fdc->writeCmd(FC_RECALIBRATE); m_fdc->writeCmd(m_driveNumber); - Task::currentThread->waitIRQ(m_fdc->m_irq); + Task::currThread()->waitIRQ(m_fdc->m_irq); m_fdc->checkInterrupt(&st0, &cyl); asm volatile("sti"); @@ -121,7 +121,7 @@ bool FloppyDrive::setMotorState(bool on) { if (m_motorState == FS_MOTOROFF) { m_motorState = FS_MOTORON; m_fdc->setDOR(); - Task::currentThread->sleep(500); + Task::currThread()->sleep(500); } m_motorState = FS_MOTORON; } else { @@ -151,7 +151,7 @@ bool FloppyDrive::seek(u32int cyli, s32int head) { m_fdc->writeCmd(head << 2); m_fdc->writeCmd(cyl); - Task::currentThread->waitIRQ(m_fdc->m_irq); + Task::currThread()->waitIRQ(m_fdc->m_irq); m_fdc->checkInterrupt(&st0, &cyl); asm volatile("sti"); @@ -201,7 +201,7 @@ bool FloppyDrive::doTrack(u32int cyl, u8int dir) { return false; } - Task::currentThread->sleep(100); + Task::currThread()->sleep(100); asm volatile("cli"); m_fdc->writeCmd(cmd); @@ -214,7 +214,7 @@ bool FloppyDrive::doTrack(u32int cyl, u8int dir) { m_fdc->writeCmd(0x1B); m_fdc->writeCmd(0xFF); - Task::currentThread->waitIRQ(m_fdc->m_irq); + Task::currThread()->waitIRQ(m_fdc->m_irq); u8int st0, st1, st2, rcy, rhe, rse, bps; st0 = m_fdc->readData(); @@ -277,7 +277,7 @@ bool FloppyDrive::readOnly() { asm volatile("cli"); m_fdc->writeCmd(FC_SENSE_DRIVE_STATUS); m_fdc->writeCmd(m_driveNumber); - Task::currentThread->waitIRQ(m_fdc->m_irq); + Task::currThread()->waitIRQ(m_fdc->m_irq); u8int st3 = m_fdc->readData(); asm volatile("sti"); diff --git a/Source/Kernel/Library/SimpleList.class.h b/Source/Kernel/Library/SimpleList.class.h index c0ea111..770128e 100644 --- a/Source/Kernel/Library/SimpleList.class.h +++ b/Source/Kernel/Library/SimpleList.class.h @@ -27,6 +27,11 @@ class SimpleList { return m_next; } + SimpleList* last() { + if (m_next == 0) return this; + return m_next->last(); + } + SimpleList* delThis() { SimpleList* ret = m_next; Mem::kfree(this); diff --git a/Source/Kernel/Makefile b/Source/Kernel/Makefile index 9f300bc..06b4d47 100644 --- a/Source/Kernel/Makefile +++ b/Source/Kernel/Makefile @@ -5,7 +5,7 @@ CXX = g++ LD = ld LDFLAGS = -T Link.ld -Map Map.txt --oformat=elf32-i386 CFLAGS = -nostdlib -nostartfiles -nodefaultlibs -fno-builtin -fno-stack-protector -Wall -Wextra -Werror -I . -CXXFLAGS = -nostartfiles -nostdlib -fno-exceptions -fno-rtti -I . -Wall -Werror -Wno-write-strings -funsigned-char -D THIS_IS_MELON -D RANDOM_SEED=`date +%N`LL +CXXFLAGS = -nostartfiles -nostdlib -fno-exceptions -fno-rtti -I . -Wall -Werror -Wno-write-strings -funsigned-char -D THIS_IS_MELON -D RANDOM_SEED=`date +%N`LL -g ASM = nasm ASMFLAGS = -f elf diff --git a/Source/Kernel/Melon.ke b/Source/Kernel/Melon.ke index d9ddeff..95613ee 100755 Binary files a/Source/Kernel/Melon.ke and b/Source/Kernel/Melon.ke differ diff --git a/Source/Kernel/SyscallManager/IDT.ns.cpp b/Source/Kernel/SyscallManager/IDT.ns.cpp index 36c584d..1a62d88 100644 --- a/Source/Kernel/SyscallManager/IDT.ns.cpp +++ b/Source/Kernel/SyscallManager/IDT.ns.cpp @@ -63,9 +63,9 @@ extern "C" void idt_flush(u32int); extern "C" void interrupt_handler(registers_t regs) { bool doSwitch = (regs.int_no == 32 or regs.int_no >= 65); //SYSCALLS >= 65 are task-managing-related if (regs.int_no < 32) { - if ((u32int)Task::currentThread == 0xFFFFFFFF or Task::currentThread == 0) + if ((u32int)Task::currThread() == 0xFFFFFFFF or Task::currThread() == 0) PANIC_DUMP("Exception cannot be handled.", ®s); - Task::currentThread->handleException(regs, regs.int_no); + Task::currThread()->handleException(regs, regs.int_no); } else if (regs.int_no < 48) { if (regs.int_no >= 40) outb(0xA0, 0x20); diff --git a/Source/Kernel/TaskManager/Mutex.class.cpp b/Source/Kernel/TaskManager/Mutex.class.cpp index 67234d8..a6c3ba8 100644 --- a/Source/Kernel/TaskManager/Mutex.class.cpp +++ b/Source/Kernel/TaskManager/Mutex.class.cpp @@ -14,7 +14,7 @@ bool Mutex::lock() { void Mutex::waitLock() { while (atomic_exchange(&m_locked, MUTEX_TRUE) == MUTEX_TRUE) - Task::currentThread->sleep(10); //Wait 10ms + Task::currThread()->sleep(10); //Wait 10ms } void Mutex::unlock() { diff --git a/Source/Kernel/TaskManager/Process.class.cpp b/Source/Kernel/TaskManager/Process.class.cpp index 236d13a..2653269 100644 --- a/Source/Kernel/TaskManager/Process.class.cpp +++ b/Source/Kernel/TaskManager/Process.class.cpp @@ -37,7 +37,7 @@ Process::Process(String cmdline, u32int uid) { m_state = P_RUNNING; m_pagedir = new PageDirectory(kernelPageDirectory); m_uid = uid; - m_vt = Task::currentProcess->getVirtualTerminal(); + m_vt = Task::currProcess()->getVirtualTerminal(); m_stacksstart = 0xC0000000; } diff --git a/Source/Kernel/TaskManager/Task.ns.cpp b/Source/Kernel/TaskManager/Task.ns.cpp index 30610d1..66119e8 100644 --- a/Source/Kernel/TaskManager/Task.ns.cpp +++ b/Source/Kernel/TaskManager/Task.ns.cpp @@ -1,6 +1,5 @@ #include "Task.ns.h" #include -#include //From Task.wtf.asm extern "C" u32int read_eip(); @@ -8,8 +7,8 @@ extern "C" u32int idle_task(void*); namespace Task { -Vector processes; //TODO : use a linked list instead -Vector threads; +SimpleList *processes = 0; //TODO : use a linked list instead +SimpleList *threads = 0; struct finished_thread_t { //Forms a linked list Thread* thread; @@ -18,49 +17,59 @@ struct finished_thread_t { //Forms a linked list SimpleList *firstFinishedThread = 0; -Thread* currentThread = NULL; -Process* currentProcess = NULL; -Thread* idleThread = NULL; -u32int currentThreadId = 0; +SimpleList *currentThread = 0; +Process* currentProcess = 0; +SimpleList *idleThread = 0; u32int nextpid = 1; +Thread* currThread() { + return currentThread->v(); +} + +Process* currProcess() { + return currentProcess; +} + +Process* getKernelProcess() { + if (processes == 0) PANIC("kko"); + return processes->last()->v(); +} + void initialize(String cmdline, VirtualTerminal *vt) { asm volatile ("cli"); - threads.clear(); - processes.clear(); + threads = 0; + processes = 0; currentProcess = Process::createKernel(cmdline, vt); - idleThread = new Thread(idle_task, 0, true); - currentThread = threads[0]; - currentThreadId = 0; + currentThread = threads; + Thread* idle = new Thread(idle_task, 0, true); + for (SimpleList *iter = threads; iter != 0; iter = iter->next()) { + if (iter->v() == idle) { + idleThread = iter; + break; + } + } asm volatile ("sti"); } -Thread* nextThread() { +SimpleList *nextThread() { //Clean up finished threads while (firstFinishedThread != 0) { - DEBUG_HEX((u32int)firstFinishedThread); - if (firstFinishedThread->v().thread == currentThread) break; + if (firstFinishedThread->v().thread == currentThread->v()) break; firstFinishedThread->v().thread->finish(firstFinishedThread->v().errcode); firstFinishedThread = firstFinishedThread->delThis(); } - for (u32int i = 0; i < threads.size(); i++) { - if (threads[i] == currentThread) { - currentThreadId = i; - } - } - + //Find next thread - u32int nid = currentThreadId; + SimpleList *iter = currentThread; while (1) { - nid++; - if (nid >= threads.size()) nid = 0; - if (threads[nid]->runnable() and threads[nid] != idleThread) { - if (firstFinishedThread != 0 and firstFinishedThread->v().thread == threads[nid]) return idleThread; - currentThreadId = nid; - return threads[nid]; + 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 (nid == currentThreadId) break; + if (iter == currentThread) break; } return idleThread; } @@ -75,17 +84,19 @@ void doSwitch() { eip = read_eip(); - if (eip == 0x12345) + if (eip == 0x12345) { return; + } - if ((u32int)currentThread != 0xFFFFFFFF) currentThread->setState(esp, ebp, eip); + if ((u32int)currentThread->v() != 0xFFFFFFFF) currentThread->v()->setState(esp, ebp, eip); currentThread = nextThread(); - currentProcess = currentThread->getProcess(); + Thread* t = currentThread->v(); + currentProcess = t->getProcess(); - esp = currentThread->getEsp(); - ebp = currentThread->getEbp(); - eip = currentThread->getEip(); + esp = t->getEsp(); + ebp = t->getEbp(); + eip = t->getEip(); cr3 = currentProcess->getPagedir()->physicalAddr; asm volatile(" \ @@ -109,39 +120,39 @@ u32int nextPid() { bool IRQwakeup(u8int irq) { bool r = false; - for (u32int i = 0; i < threads.size(); i++) { - r = r or threads[i]->irqHappens(irq); + for (SimpleList *iter = threads; iter != 0; iter = iter->next()) { + r = r or iter->v()->irqHappens(irq); } return r; } void allocKernelPageTable(u32int id, page_table_t *table, u32int tablePhys) { if (id < 768) return; //this would be a BUG - for (u32int i = 1; i < processes.size(); i++) { - processes[i]->getPagedir()->tables[id] = table; - processes[i]->getPagedir()->tablesPhysical[id] = tablePhys; + for (SimpleList *iter = processes; iter != 0; iter = iter->next()) { + iter->v()->getPagedir()->tables[id] = table; + iter->v()->getPagedir()->tablesPhysical[id] = tablePhys; } } -Process* getKernelProcess() { - return processes[0]; -} - void currentThreadExits(u32int errcode) { - finished_thread_t tmp = {currentThread, errcode}; + finished_thread_t tmp = {currentThread->v(), errcode}; firstFinishedThread = firstFinishedThread->cons(tmp); } void registerThread(Thread* t) { unregisterThread(t); //...// - threads.push(t); + threads = threads->cons(t); } void unregisterThread(Thread* t) { - for (u32int i = 0; i < threads.size(); i++) { - if (threads[i] == t) { - threads[i] = threads.back(); - threads.pop(); + if (threads == 0) return; //Tasking not yet initialized + if (threads->v() == t) { + threads = threads->delThis(); + return; + } + for (SimpleList *iter = threads; iter->next() != 0; iter = iter->next()) { + if (iter->next()->v() == t) { + iter->delNext(); return; } } @@ -149,14 +160,18 @@ void unregisterThread(Thread* t) { void registerProcess(Process* p) { unregisterProcess(p); //...// - processes.push(p); + processes = processes->cons(p); } void unregisterProcess(Process* p) { - for (u32int i = 0; i < processes.size(); i++) { - if (processes[i] == p) { - processes[i] = processes.back(); - processes.pop(); + if (processes == 0) return; //Tasking not yet initialized + if (processes->v() == p) { + processes = processes->delThis(); + return; + } + for (SimpleList *iter = processes; iter->next() != 0; iter = iter->next()) { + if (iter->next()->v() == p) { + iter->delNext(); return; } } diff --git a/Source/Kernel/TaskManager/Task.ns.h b/Source/Kernel/TaskManager/Task.ns.h index a41eaf7..c7c3d23 100644 --- a/Source/Kernel/TaskManager/Task.ns.h +++ b/Source/Kernel/TaskManager/Task.ns.h @@ -3,10 +3,11 @@ #include #include +#include namespace Task { - extern Thread* currentThread; - extern Process* currentProcess; + Thread* currThread(); + Process* currProcess(); void initialize(String cmdline, VirtualTerminal *vt); //cmdline should be the bootloader kernel command line, if anybody needs it void doSwitch(); diff --git a/Source/Kernel/TaskManager/Thread.class.cpp b/Source/Kernel/TaskManager/Thread.class.cpp index 072a505..fd5cfd9 100644 --- a/Source/Kernel/TaskManager/Thread.class.cpp +++ b/Source/Kernel/TaskManager/Thread.class.cpp @@ -21,7 +21,7 @@ Thread::Thread(thread_entry_t entry_point, void* data, bool iskernel) { setup(entry_point, data, m_kernelStackFrame + 0x1000); //A kernel stack always is 1 frame, meaning 0x1000 bytes } else { m_isKernel = false; - m_process = Task::currentProcess; + m_process = Task::currProcess(); setup(entry_point, data, m_process->stackAlloc() + STACKSIZE); } } diff --git a/Source/Kernel/VFS/File.class.cpp b/Source/Kernel/VFS/File.class.cpp index 69b08de..fbaabbe 100644 --- a/Source/Kernel/VFS/File.class.cpp +++ b/Source/Kernel/VFS/File.class.cpp @@ -44,7 +44,7 @@ bool File::open(String filename, u8int mode, FSNode* start) { else m_file->m_writers++; - Task::currentProcess->registerFileDescriptor(this); + Task::currProcess()->registerFileDescriptor(this); m_valid = true; return true; } @@ -135,5 +135,5 @@ void File::close(bool unregisterFD) { m_file = NULL; m_position = 0; m_writable = false; - if (unregisterFD) Task::currentProcess->unregisterFileDescriptor(this); + if (unregisterFD) Task::currProcess()->unregisterFileDescriptor(this); } diff --git a/Source/Kernel/VTManager/VirtualTerminal-kbd.proto.cpp b/Source/Kernel/VTManager/VirtualTerminal-kbd.proto.cpp index ef95615..59f66a6 100644 --- a/Source/Kernel/VTManager/VirtualTerminal-kbd.proto.cpp +++ b/Source/Kernel/VTManager/VirtualTerminal-kbd.proto.cpp @@ -29,7 +29,7 @@ keypress_t VirtualTerminal::getKeypress(bool show, bool block) { } while (m_kbdbuff.empty()) - Task::currentThread->sleep(10); + Task::currThread()->sleep(10); m_kbdbuffMutex.waitLock(); keypress_t ret = m_kbdbuff[0]; -- cgit v1.2.3