summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexis211 <alexis211@gmail.com>2009-10-11 18:38:05 +0200
committerAlexis211 <alexis211@gmail.com>2009-10-11 18:38:05 +0200
commit3be1804db57e5d1ff08f46c7b7418729da631c26 (patch)
treee91e0197b3009080647f448542ff2a16c00946cb
parent244df8bd2c52db9d9c9b59b917206dafcd275ebe (diff)
downloadMelon-3be1804db57e5d1ff08f46c7b7418729da631c26.tar.gz
Melon-3be1804db57e5d1ff08f46c7b7418729da631c26.zip
Tasking now works with linked lists
-rw-r--r--Makefile3
-rw-r--r--Qemu-GDB-Debug-CMD1
-rw-r--r--Source/Kernel/Core/Sys.ns.cpp6
-rw-r--r--Source/Kernel/Core/kmain.wtf.cpp4
-rw-r--r--Source/Kernel/Devices/Floppy/FloppyController.class.cpp8
-rw-r--r--Source/Kernel/Devices/Floppy/FloppyDrive.class.cpp12
-rw-r--r--Source/Kernel/Library/SimpleList.class.h5
-rw-r--r--Source/Kernel/Makefile2
-rwxr-xr-xSource/Kernel/Melon.kebin166272 -> 574720 bytes
-rw-r--r--Source/Kernel/SyscallManager/IDT.ns.cpp4
-rw-r--r--Source/Kernel/TaskManager/Mutex.class.cpp2
-rw-r--r--Source/Kernel/TaskManager/Process.class.cpp2
-rw-r--r--Source/Kernel/TaskManager/Task.ns.cpp125
-rw-r--r--Source/Kernel/TaskManager/Task.ns.h5
-rw-r--r--Source/Kernel/TaskManager/Thread.class.cpp2
-rw-r--r--Source/Kernel/VFS/File.class.cpp4
-rw-r--r--Source/Kernel/VTManager/VirtualTerminal-kbd.proto.cpp2
17 files changed, 106 insertions, 81 deletions
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<Device*> 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<T>* last() {
+ if (m_next == 0) return this;
+ return m_next->last();
+ }
+
SimpleList<T>* delThis() {
SimpleList<T>* 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
--- a/Source/Kernel/Melon.ke
+++ b/Source/Kernel/Melon.ke
Binary files 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.", &regs);
- 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 <Library/Vector.class.h>
-#include <Library/SimpleList.class.h>
//From Task.wtf.asm
extern "C" u32int read_eip();
@@ -8,8 +7,8 @@ extern "C" u32int idle_task(void*);
namespace Task {
-Vector <Process*> processes; //TODO : use a linked list instead
-Vector <Thread*> threads;
+SimpleList <Process*> *processes = 0; //TODO : use a linked list instead
+SimpleList <Thread*> *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<finished_thread_t> *firstFinishedThread = 0;
-Thread* currentThread = NULL;
-Process* currentProcess = NULL;
-Thread* idleThread = NULL;
-u32int currentThreadId = 0;
+SimpleList <Thread*> *currentThread = 0;
+Process* currentProcess = 0;
+SimpleList<Thread*> *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<Thread*> *iter = threads; iter != 0; iter = iter->next()) {
+ if (iter->v() == idle) {
+ idleThread = iter;
+ break;
+ }
+ }
asm volatile ("sti");
}
-Thread* nextThread() {
+SimpleList<Thread*> *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<Thread*> *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<Thread*> *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<Process*> *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<Thread*> *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<Process*> *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 <TaskManager/Thread.class.h>
#include <VTManager/VirtualTerminal.proto.h>
+#include <Library/SimpleList.class.h>
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];