summaryrefslogtreecommitdiff
path: root/src/stem/task/task.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/stem/task/task.c')
-rw-r--r--src/stem/task/task.c245
1 files changed, 0 insertions, 245 deletions
diff --git a/src/stem/task/task.c b/src/stem/task/task.c
deleted file mode 100644
index 804adc2..0000000
--- a/src/stem/task/task.c
+++ /dev/null
@@ -1,245 +0,0 @@
-#include "task.h"
-#include <core/sys.h>
-#include <core/monitor.h>
-#include <mem/mem.h>
-#include "timer.h"
-
-#define KSTACKSIZE 0x8000
-
-//Static routines for handling threads exiting and all cleanup
-static void thread_exit_stackJmp(uint32_t reason);
-static void thread_exit2(uint32_t reason);
-static void thread_delete(struct thread *th);
-static void process_delete(struct process *pr);
-
-//From task_.asm
-extern uint32_t read_eip();
-extern void task_idle(void*);
-
-static uint32_t thread_runnable(struct thread *th);
-
-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];
-
-void tasking_init() {
- cli();
- kernel_process = kmalloc(sizeof(struct process)); //This process must be hidden to users
- kernel_process->pid = kernel_process->uid = kernel_process->threads = 0;
- kernel_process->privilege = PL_KERNEL;
- kernel_process->parent = kernel_process;
- kernel_process->pagedir = kernel_pagedir;
- kernel_process->next = 0;
- current_thread = 0;
- idle_thread = thread_new(kernel_process, task_idle, 0);
- threads = 0; //Do not include idle thread in threads
- sti();
- monitor_write("Tasking set up\n");
-}
-
-static struct thread *thread_next() {
- if (current_thread == 0 || current_thread == idle_thread) current_thread = threads;
- struct thread *ret = current_thread;
- while (1) {
- ret = ret->next;
- if (ret == 0) ret = threads;
- if (thread_runnable(ret)) {
- return ret;
- }
- if (ret == current_thread) return idle_thread;
- }
-}
-
-void tasking_switch() {
- if (threads == 0) PANIC("No more threads to run !");
- asm volatile("cli");
-
- uint32_t esp, ebp, eip;
-
- asm volatile("mov %%esp, %0" : "=r"(esp));
- asm volatile("mov %%ebp, %0" : "=r"(ebp));
- eip = read_eip();
-
- if (eip == 0x12345) {
- return;
- }
-
- if (current_thread != 0) {
- current_thread->esp = esp;
- current_thread->ebp = ebp;
- current_thread->eip = eip;
- }
-
- current_thread = thread_next();
-
- asm volatile(" \
- mov %0, %%ebp; \
- mov %1, %%esp; \
- mov %2, %%ecx; \
- mov $0x12345, %%eax; \
- jmp *%%ecx;"
- : : "r"(current_thread->ebp), "r"(current_thread->esp), "r"(current_thread->eip));
-}
-
-void tasking_updateKernelPagetable(uint32_t idx, struct page_table *table, uint32_t tablephysical) {
- if (idx < 896) return;
- struct process* it = processes;
- while (it != 0) {
- it->pagedir->tables[idx] = table;
- it->pagedir->tablesPhysical[idx] = tablephysical;
- it = it->next;
- }
-}
-
-uint32_t tasking_handleException(struct registers *regs) {
- if (current_thread == 0) return 0; //No tasking yet
- monitor_write("\n(task.c:99) Unhandled 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(" at "); monitor_writeHex(regs->eip);
- monitor_write(" >>> Thread exiting.\n");
- thread_exit_stackJmp(EX_TH_EXCEPTION);
- PANIC("This should never have happened. Please report this.");
-}
-
-void thread_sleep(uint32_t msecs) {
- if (current_thread == 0) return;
- current_thread->state = TS_SLEEPING;
- current_thread->timeWait = timer_time() + msecs;
- asm volatile("int $64" : : "a"(1));
-}
-
-void thread_exit2(uint32_t reason) { //See EX_TH_* defines in task.h
- /*
- * if reason == EX_TH_NORMAL, it is just one thread exiting because it has to
- * if reason == EX_TH_EXCEPTION, it is just one thread exiting because of an exception
- * if reason is none of the two cases above, it is the whole process exiting (with error code = reason)
- */
- struct thread *th = current_thread;
- 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();
- tasking_switch();
-}
-
-void thread_exit_stackJmp(uint32_t reason) {
- uint32_t *stack;
- cli();
- stack = tasking_tmpStack + 0x4000;
- stack--; *stack = reason;
- stack--; *stack = 0;
- asm volatile(" \
- mov %0, %%esp; \
- mov %1, %%ebp; \
- mov %2, %%ecx; \
- mov %3, %%cr3; \
- jmp *%%ecx;" : :
- "r"(stack), "r"(stack), "r"(thread_exit2), "r"(kernel_pagedir->physicalAddr));
-}
-
-void thread_exit() {
- thread_exit_stackJmp(EX_TH_NORMAL);
-}
-
-void process_exit(uint32_t retval) {
- if (retval == EX_TH_NORMAL || retval == EX_TH_EXCEPTION) retval = EX_PR_EXCEPTION;
- thread_exit_stackJmp(retval);
-}
-
-static uint32_t thread_runnable(struct thread *t) {
- if (t->state == TS_RUNNING) return 1;
- if (t->state == TS_SLEEPING && timer_time() >= t->timeWait) return 1;
- return 0;
-}
-
-static void thread_run(struct thread *thread, thread_entry entry_point, void *data) {
- pagedir_switch(thread->process->pagedir); //TODO : take into account privilege level
- asm volatile("sti");
- entry_point(data);
- thread_exit(0);
-}
-
-struct thread *thread_new(struct process *proc, thread_entry entry_point, void *data) {
- struct thread *t = kmalloc(sizeof(struct thread));
- t->process = proc;
- proc->threads++;
- t->kernelStack_addr = kmalloc(KSTACKSIZE);
- t->kernelStack_size = KSTACKSIZE;
-
- uint32_t *stack = (uint32_t*)((size_t)t->kernelStack_addr + t->kernelStack_size);
-
- //Pass parameters
- stack--; *stack = (uint32_t)data;
- stack--; *stack = (uint32_t)entry_point;
- stack--; *stack = (uint32_t)t;
- stack--; *stack = 0;
- t->esp = (uint32_t)stack;
- t->ebp = t->esp + 8;
- t->eip = (uint32_t)thread_run;
-
- t->state = TS_RUNNING;
-
- if (threads == 0) {
- threads = t;
- } else {
- struct thread *i = threads;
- while (i->next != 0) i = i->next;
- i->next = t;
- }
- return t;
-}
-
-struct process *process_new(struct process* parent, uint32_t uid, uint32_t privilege) {
- struct process* p = kmalloc(sizeof(struct process));
- p->pid = (nextpid++);
- p->uid = uid;
- p->threads = 0;
- p->privilege = privilege;
- p->parent = parent;
- p->pagedir = pagedir_new();
- p->next = processes;
- processes = p;
- return p;
-}
-
-static void thread_delete(struct thread *th) {
- kfree(th->kernelStack_addr);
- 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;
- }
- 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) {
- while (it->next->process == pr) thread_delete(it->next);
- it = it->next;
- }
- 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;
- }
- kfree(pr);
-}