summaryrefslogtreecommitdiff
path: root/src/kernel/task
diff options
context:
space:
mode:
authorAlexis211 <alexis211@gmail.com>2010-09-10 18:46:00 +0200
committerAlexis211 <alexis211@gmail.com>2010-09-10 18:46:00 +0200
commitaba6ed4b91aff5d914be11704e34de75bfd4d003 (patch)
tree3d5cf90e9ccad09d352c6a61e90027ef552dd87f /src/kernel/task
parent5fc3baaa17a6ffb34490bb8accb86f53ef3d6d15 (diff)
downloadTCE-aba6ed4b91aff5d914be11704e34de75bfd4d003.tar.gz
TCE-aba6ed4b91aff5d914be11704e34de75bfd4d003.zip
Each thread has its own stack. Added simple unit tests for kmalloc,kfree
Found a bug in heap_contract (not sure) but didn't fix it.
Diffstat (limited to 'src/kernel/task')
-rw-r--r--src/kernel/task/idt.c8
-rw-r--r--src/kernel/task/syscall.c2
-rw-r--r--src/kernel/task/task.c29
-rw-r--r--src/kernel/task/task.h5
4 files changed, 22 insertions, 22 deletions
diff --git a/src/kernel/task/idt.c b/src/kernel/task/idt.c
index 6aa16e0..be5d152 100644
--- a/src/kernel/task/idt.c
+++ b/src/kernel/task/idt.c
@@ -75,11 +75,9 @@ static struct irq_waiter {
void idt_isrHandler(struct registers regs) {
if ((regs.int_no == 14 && paging_fault(&regs) != 0) || regs.int_no != 14) {
if (tasking_handleException(&regs) == 0) {
- monitor_write("\n >> >> SOMETHING BAD HAPPENNED << <<\n");
- monitor_write("Unhandled exception ");
- monitor_writeHex(regs.int_no);
- monitor_write(" @"); monitor_writeHex(regs.eip);
- monitor_put('\n');
+ monitor_write("\nREALLY BAD THIS TIME\t\tUnhandled exception\t#");
+ monitor_writeDec(regs.int_no);
+ monitor_write("\t@"); monitor_writeHex(regs.eip);
PANIC("Unhandled Exception");
}
}
diff --git a/src/kernel/task/syscall.c b/src/kernel/task/syscall.c
index 41cd0ea..b490987 100644
--- a/src/kernel/task/syscall.c
+++ b/src/kernel/task/syscall.c
@@ -35,7 +35,7 @@ CALL2(send_msg, send_msg_sc);
CALL2(process_setheapseg, proc_setheap_sc);
static void thread_new_sc(struct registers* r) {
- thread_new(current_thread->process, (thread_entry)r->ebx, (void*)r->ecx);
+ thread_new(current_thread->process, (thread_entry)r->ebx, (void*)r->ecx, (void*)r->edx);
}
int_callback syscalls[NUMBER_OF_SYSCALLS] = {
diff --git a/src/kernel/task/task.c b/src/kernel/task/task.c
index 7153d85..b8a72ce 100644
--- a/src/kernel/task/task.c
+++ b/src/kernel/task/task.c
@@ -39,7 +39,7 @@ void tasking_init() {
kernel_process->pagedir = kernel_pagedir;
kernel_process->next = 0;
current_thread = 0;
- idle_thread = thread_new(kernel_process, task_idle, 0);
+ idle_thread = thread_new(kernel_process, task_idle, 0, 0);
kernel_process->threads = idle_thread;
sti();
monitor_write("[Tasking] ");
@@ -99,15 +99,15 @@ void tasking_switch() {
Ends the thread for most exceptions, ends the whole process for page faults. */
uint32_t tasking_handleException(struct registers *regs) {
if (current_thread == 0) return 0; //No tasking yet
- NL; WHERE; monitor_write("Unhandled exception : ");
+ NL; WHERE; monitor_write("exception:`");
char *exception_messages[] = {"Division By Zero","Debug","Non Maskable Interrupt","Breakpoint",
"Into Detected Overflow","Out of Bounds","Invalid Opcode","No Coprocessor", "Double Fault",
"Coprocessor Segment Overrun","Bad TSS","Segment Not Present","Stack Fault","General Protection Fault",
"Page Fault","Unknown Interrupt","Coprocessor Fault","Alignment Check","Machine Check"};
monitor_write(exception_messages[regs->int_no]);
- monitor_write(" eip:"); monitor_writeHex(regs->eip);
+ monitor_write("'\teip:"); monitor_writeHex(regs->eip);
if (regs->eip >= 0xE0000000) {
- monitor_write("\n Exception stack trace :");
+ monitor_write("\n Exception stack trace :\n");
stack_trace(regs->ebp);
PANIC("Kernel error'd.");
}
@@ -194,10 +194,10 @@ void process_exit(uint32_t retval) {
/* For internal use only. This is called when a newly created thread first runs
(its address is the value given for EIP).
It switches to user mode if necessary and calls the entry point. */
-static void thread_run(struct thread *thread, thread_entry entry_point, void *data) {
+static void thread_run(void* u_esp, struct thread *thread, thread_entry entry_point, void *data) {
pagedir_switch(thread->process->pagedir);
if (thread->process->privilege >= PL_SERVICE) { //User mode !
- uint32_t *stack = (uint32_t*)(thread->userStack_seg->start + thread->userStack_seg->len);
+ uint32_t *stack = u_esp;
stack--; *stack = (uint32_t)data;
stack--; *stack = 0;
@@ -239,16 +239,13 @@ static void thread_run(struct thread *thread, thread_entry entry_point, void *da
/* Creates a new thread for given process.
Allocates a kernel stack and a user stack if necessary.
Sets up the kernel stack for values to be passed to thread_run. */
-struct thread *thread_new(struct process *proc, thread_entry entry_point, void *data) {
+struct thread *thread_new(struct process *proc, thread_entry entry_point, void *data, void *u_esp) {
struct thread *t = kmalloc(sizeof(struct thread));
t->process = proc;
t->next = 0;
proc->thread_count++;
- if (proc->privilege >= PL_SERVICE) { //We are running in user mode
- proc->stacksBottom -= USER_STACK_SIZE;
- t->userStack_seg = seg_map(simpleseg_make(proc->stacksBottom, USER_STACK_SIZE, 1), proc->pagedir, 0);
- }
+ if (u_esp == 0) u_esp = (void*)proc->stack;
t->kernelStack_addr = kmalloc(KSTACKSIZE);
t->kernelStack_size = KSTACKSIZE;
@@ -259,6 +256,7 @@ struct thread *thread_new(struct process *proc, thread_entry entry_point, void *
stack--; *stack = (uint32_t)data;
stack--; *stack = (uint32_t)entry_point;
stack--; *stack = (uint32_t)t;
+ stack--; *stack = (uint32_t)u_esp;
stack--; *stack = 0;
t->esp = (uint32_t)stack;
t->ebp = t->esp + 8;
@@ -287,9 +285,15 @@ struct process *process_new(struct process* parent, uint32_t uid, uint32_t privi
p->parent = parent;
p->pagedir = pagedir_new();
p->next = processes;
- p->stacksBottom = 0xDF000000;
p->heapseg = 0;
+ p->stack = 0;
+ if (p->privilege >= PL_SERVICE) { //We are running in user mode
+ size_t stacksBottom = 0xDF000000;
+ seg_map(simpleseg_make(stacksBottom, USER_STACK_SIZE, 1), p->pagedir, 0);
+ p->stack = stacksBottom + USER_STACK_SIZE - 4;
+ }
+
p->next_objdesc = 0;
p->objects = 0;
struct object* o = obj_new(p);
@@ -318,7 +322,6 @@ static void thread_delete(struct thread *th) {
if (current_thread == th) current_thread = 0;
th->process->thread_count--;
kfree(th->kernelStack_addr);
- if (th->userStack_seg != 0) seg_unmap(th->userStack_seg);
kfree(th);
}
diff --git a/src/kernel/task/task.h b/src/kernel/task/task.h
index 0a95e57..171a9fd 100644
--- a/src/kernel/task/task.h
+++ b/src/kernel/task/task.h
@@ -26,7 +26,7 @@ struct process {
uint32_t pid, uid, privilege, thread_count;
struct process *parent;
struct page_directory *pagedir;
- size_t stacksBottom;
+ size_t stack;
struct obj_descriptor *objects;
uint32_t next_objdesc;
@@ -44,7 +44,6 @@ struct thread {
uint32_t timeWait;
void* kernelStack_addr;
uint32_t kernelStack_size;
- struct segment_map *userStack_seg;
struct thread *next, *queue_next; //queue_next is used in sched.c
};
@@ -59,7 +58,7 @@ uint32_t tasking_handleException(struct registers *regs);
void thread_goInactive(); //Blocks the current thread. it is then waked up by another thread or a system event.
void thread_wakeUp(struct thread *t);
int proc_priv(); //Returns current privilege level
-struct thread * thread_new(struct process *proc, thread_entry entry_point, void *data);
+struct thread * thread_new(struct process *proc, thread_entry entry_point, void *data, void *u_esp);
struct process* process_new(struct process *parent, uint32_t uid, uint32_t privilege);
void thread_exit(); //syscall