diff options
Diffstat (limited to 'src/kernel/task')
-rw-r--r-- | src/kernel/task/syscall.c | 3 | ||||
-rw-r--r-- | src/kernel/task/task.c | 69 |
2 files changed, 49 insertions, 23 deletions
diff --git a/src/kernel/task/syscall.c b/src/kernel/task/syscall.c index 9a1ce81..a5142eb 100644 --- a/src/kernel/task/syscall.c +++ b/src/kernel/task/syscall.c @@ -12,6 +12,7 @@ #define CALL1V(name, scname) static void scname(struct registers* r) { name(r->ebx); } #define CALL2V(name, scname) static void scname(struct registers* r) { name(r->ebx, r->ecx); } #define CALL3V(name, scname) static void scname(struct registers* r) { name(r->ebx, r->ecx, r->edx); } +#define CALL4V(name, scname) static void scname(struct registers* r) { name(r->ebx, r->ecx, r->edx, r->esi); } CALL0V(thread_exit, thread_exit_sc); CALL0V(tasking_switch, schedule_sc); @@ -27,7 +28,7 @@ CALL1(object_owned, object_owned_sc); CALL1V(object_close, object_close_sc); CALL3(request_get, request_get_sc); CALL1(request_has, request_has_sc); -CALL3V(request_answer, request_answer_sc); +CALL4V(request_answer, request_answer_sc); CALL3(request_mapShm, request_mapShm_sc); CALL2(request, request_sc); CALL2(send_msg, send_msg_sc); diff --git a/src/kernel/task/task.c b/src/kernel/task/task.c index f10ec6f..8afc609 100644 --- a/src/kernel/task/task.c +++ b/src/kernel/task/task.c @@ -28,7 +28,7 @@ static uint32_t nextpid = 1; struct process *processes = 0, *kernel_process; struct thread *threads = 0, *current_thread = 0, *idle_thread; -uint32_t tasking_tmpStack[0x4000]; +uint32_t tasking_tmpStack[KSTACKSIZE]; void tasking_init() { cli(); @@ -54,7 +54,9 @@ static struct thread *thread_next() { if (thread_runnable(ret)) { return ret; } - if (ret == current_thread) return idle_thread; + if (ret == current_thread) { + return idle_thread; + } } } @@ -110,8 +112,17 @@ uint32_t tasking_handleException(struct registers *regs) { "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(" at "); monitor_writeHex(regs->eip); - PANIC("kk"); + monitor_write(" eip:"); monitor_writeHex(regs->eip); + if (regs->eip >= 0xE0000000) { + monitor_write("\n Stack trace :"); + uint32_t *stack = (uint32_t*)regs->ebp, i; + for (i = 0; i < 5 && stack > 0xE0000000 && stack < (regs->useresp + 0x8000); i++) { + monitor_write("\nframe@"); monitor_writeHex(stack); + monitor_write(" next:"); monitor_writeHex(stack[0]); monitor_write(" ret:"); monitor_writeHex(stack[1]); + stack = (uint32_t*)stack[0]; + } + PANIC("Kernel error'd."); + } if (regs->int_no == 14) { monitor_write("\n>>> Process exiting.\n"); thread_exit_stackJmp(EX_PR_EXCEPTION); @@ -140,7 +151,7 @@ void thread_wakeUp(struct thread* t) { } int proc_priv() { - if (current_thread == 0) return PL_UNKNOWN; + if (current_thread == 0 || current_thread->process == 0) return PL_UNKNOWN; return current_thread->process->privilege; } @@ -151,20 +162,21 @@ void thread_exit2(uint32_t reason) { //See EX_TH_* defines in task.h * if reason is none of the two cases above, it is the whole process exiting (with error code = reason) */ struct thread *th = current_thread; + if (th == 0 || th->process == 0) goto retrn; struct process *pr = th->process; if ((reason == EX_TH_NORMAL || reason == EX_TH_EXCEPTION) && pr->threads > 1) { thread_delete(th); } else { process_delete(pr); } - sti(); + retrn: tasking_switch(); } void thread_exit_stackJmp(uint32_t reason) { - uint32_t *stack; cli(); - stack = tasking_tmpStack + 0x4000; + uint32_t *stack; + stack = tasking_tmpStack + (KSTACKSIZE / 4); stack--; *stack = reason; stack--; *stack = 0; asm volatile(" \ @@ -296,36 +308,49 @@ struct process *process_new(struct process* parent, uint32_t uid, uint32_t privi } static void thread_delete(struct thread *th) { - kfree(th->kernelStack_addr); - if (th->userStack_seg != 0) seg_unmap(th->userStack_seg); - th->process->threads--; if (threads == th) { threads = th->next; } else { struct thread *it = threads; - while (it->next != th && it->next != 0) it = it->next; - if (it->next == th) it->next = th->next; + while (it) { + if (it->next == th) { + it->next = th->next; + break; + } + it = it->next; + } } + if (current_thread == th) current_thread = 0; + th->process->threads--; + kfree(th->kernelStack_addr); + if (th->userStack_seg != 0) seg_unmap(th->userStack_seg); kfree(th); } static void process_delete(struct process *pr) { - struct thread *it; - while (threads != 0 && threads->process == pr) thread_delete(threads); - it = threads; - while (it != 0 && it->next != 0) { - while (it->next != 0 && it->next->process == pr) thread_delete(it->next); - it = it->next; + struct thread *it = threads; + while (it != 0) { + if (it->process == pr) { + thread_delete(it); + it = threads; + } else { + it = it->next; + } } obj_closeall(pr); - pagedir_delete(pr->pagedir); if (processes == pr) { processes = pr->next; } else { struct process *it = processes; - while (it != 0 && it->next != pr) it = it->next; - if (it != 0 && it->next == pr) it->next = pr->next; + while (it) { + if (it->next == pr) { + it->next = pr->next; + break; + } + it = it->next; + } } + pagedir_delete(pr->pagedir); kfree(pr); } |