diff options
author | Alex AUVOLAT <alexis211@gmail.com> | 2012-05-04 20:06:37 +0200 |
---|---|---|
committer | Alex AUVOLAT <alexis211@gmail.com> | 2012-05-04 20:06:37 +0200 |
commit | 277e4af4fa9e80816c809542d792ee6bebb7f202 (patch) | |
tree | 9abb7f207d185909427137e4861b81c057de1259 /src/kernel/task | |
parent | e9683297bf480f9590b0e5796f4520fb430e2e03 (diff) | |
download | TCE-277e4af4fa9e80816c809542d792ee6bebb7f202.tar.gz TCE-277e4af4fa9e80816c809542d792ee6bebb7f202.zip |
Migration to C++!
Diffstat (limited to 'src/kernel/task')
-rw-r--r-- | src/kernel/task/idt.cpp (renamed from src/kernel/task/idt.c) | 28 | ||||
-rw-r--r-- | src/kernel/task/idt.h | 2 | ||||
-rw-r--r-- | src/kernel/task/sched.cpp (renamed from src/kernel/task/sched.c) | 16 | ||||
-rw-r--r-- | src/kernel/task/sched.h | 4 | ||||
-rw-r--r-- | src/kernel/task/syscall.c | 45 | ||||
-rw-r--r-- | src/kernel/task/syscall.cpp | 50 | ||||
-rw-r--r-- | src/kernel/task/task.cpp (renamed from src/kernel/task/task.c) | 61 | ||||
-rw-r--r-- | src/kernel/task/task.h | 29 | ||||
-rw-r--r-- | src/kernel/task/timer.cpp (renamed from src/kernel/task/timer.c) | 10 |
9 files changed, 130 insertions, 115 deletions
diff --git a/src/kernel/task/idt.c b/src/kernel/task/idt.cpp index aed5ea8..ebc092d 100644 --- a/src/kernel/task/idt.c +++ b/src/kernel/task/idt.cpp @@ -2,12 +2,14 @@ #include <core/monitor.h> #include <core/sys.h> #include <mem/paging.h> -#include <mem/mem.h> +#include <lib/cpp.h> #include "task.h" #include "syscall.h" #include <stdlib_common.h> +extern "C" { + extern void isr0(); extern void isr1(); extern void isr2(); @@ -60,20 +62,22 @@ extern void irq15(); extern void syscall64(); -extern void idt_flush(int32_t ptr); +} + +extern "C" void idt_flush(int32_t ptr); -struct idt_entry idt_entries[256]; -struct idt_ptr idt_ptr; +idt_entry idt_entries[256]; +idt_ptr idt_ptr; static int_callback irq_handlers[16] = {0}; static struct irq_waiter { struct thread *thread; - struct irq_waiter *next; + irq_waiter *next; } *irq_wakeup[16] = {0}; /* Called in idt_.asm when an exception fires (interrupt 0 to 31). Tries to handle the exception, panics if fails. */ -void idt_isrHandler(struct registers regs) { +extern "C" void idt_isrHandler(registers regs) { if ((regs.int_no == 14 && paging_fault(®s) != 0) || regs.int_no != 14) { if (tasking_handleException(®s) == 0) { monitor_write("\nREALLY BAD THIS TIME\t\tUnhandled exception\t#"); @@ -86,14 +90,14 @@ void idt_isrHandler(struct registers regs) { /* Called in idt_.asm when an IRQ fires (interrupt 32 to 47) Possibly wakes up a thread that was waiting, possibly calls a handler. */ -void idt_irqHandler(struct registers regs) { +extern "C" void idt_irqHandler(registers regs) { uint32_t doSwitch = (regs.err_code == 0); //IRQ0 = timer if (regs.err_code > 7) { outb(0xA0, 0x20); } outb(0x20, 0x20); while (irq_wakeup[regs.err_code] != 0) { - struct irq_waiter *tmp = irq_wakeup[regs.err_code]; + irq_waiter *tmp = irq_wakeup[regs.err_code]; thread_wakeUp(tmp->thread); irq_wakeup[regs.err_code] = tmp->next; kfree(tmp); @@ -107,7 +111,7 @@ void idt_irqHandler(struct registers regs) { /* Called in idt_.asm on a system call (interrupt 64). Calls the correct syscall handler (if any). */ -void idt_syscallHandler(struct registers regs) { +extern "C" void idt_syscallHandler(registers regs) { if (regs.eax < NUMBER_OF_SYSCALLS && syscalls[regs.eax] != 0) { syscalls[regs.eax](®s); } @@ -125,10 +129,10 @@ static void idt_setGate(uint8_t num, uint32_t base, uint16_t sel, uint8_t flags) /* Remaps the IRQs. Sets up the IDT. */ void idt_init() { - idt_ptr.limit = (sizeof(struct idt_entry) * 256) - 1; + idt_ptr.limit = (sizeof(idt_entry) * 256) - 1; idt_ptr.base = (uint32_t)&idt_entries; - memset((uint8_t*)&idt_entries, 0, sizeof(struct idt_entry) * 256); + memset((uint8_t*)&idt_entries, 0, sizeof(idt_entry) * 256); //Remap the IRQ table outb(0x20, 0x11); @@ -209,7 +213,7 @@ void idt_handleIrq(int number, int_callback func) { /* Tells the IRQ handler to wake up the current thread when specified IRQ fires. */ void idt_waitIrq(int number) { if (number < 16 && number >= 0 && proc_priv() <= PL_KERNEL) { - struct irq_waiter *tmp = kmalloc(sizeof(struct irq_waiter)); + irq_waiter *tmp = new irq_waiter(); tmp->thread = current_thread; tmp->next = irq_wakeup[number]; irq_wakeup[number] = tmp; diff --git a/src/kernel/task/idt.h b/src/kernel/task/idt.h index 1ac03e2..849418e 100644 --- a/src/kernel/task/idt.h +++ b/src/kernel/task/idt.h @@ -29,7 +29,7 @@ struct registers { uint32_t eip, cs, eflags, useresp, ss; // Pushed by the processor automatically. }; -typedef void (*int_callback)(struct registers*); +typedef void (*int_callback)(registers*); void idt_init(); void idt_handleIrq(int number, int_callback func); //Set IRQ handler diff --git a/src/kernel/task/sched.c b/src/kernel/task/sched.cpp index aa41d5b..e773e97 100644 --- a/src/kernel/task/sched.c +++ b/src/kernel/task/sched.cpp @@ -6,12 +6,12 @@ #define PRIORITIES 3 // we have 4 priority levels #define PRIORITY(t) (t->process->privilege) //get priority for a thread -extern struct thread *idle_thread; +extern thread *idle_thread; -static struct thread *queue[PRIORITIES] = {0}, *last[PRIORITIES] = {0}; +static thread *queue[PRIORITIES] = {0}, *last[PRIORITIES] = {0}; /* For internal use only. Enqueues specified thread in specified priority queue. */ -static void sched_enqueueIn(struct thread *t, int qid) { +static void sched_enqueueIn(thread *t, int qid) { t->queue_next = 0; if (queue[qid] == 0) { queue[qid] = last[qid] = t; @@ -22,9 +22,9 @@ static void sched_enqueueIn(struct thread *t, int qid) { } /* For internal use only. Pops a thread from specified queue, if available. */ -static struct thread *sched_dequeueFrom(int qid) { +static thread *sched_dequeueFrom(int qid) { if (queue[qid] == 0) return 0; - struct thread *it = queue[qid]; + thread *it = queue[qid]; ASSERT((it->queue_next == 0 && it == last[qid]) || it != last[qid]); queue[qid] = it->queue_next; if (queue[qid] == 0) last[qid] = 0; @@ -32,14 +32,14 @@ static struct thread *sched_dequeueFrom(int qid) { } /* Used by task.c. Enqueus a thread in the corresponding priority queue. */ -void sched_enqueue(struct thread *t) { +void sched_enqueue(thread *t) { if (t == idle_thread) return; sched_enqueueIn(t, PRIORITY(t)); } /* Used by task.c. Pops a thread from the lowest priority non-empty queue. */ -struct thread *sched_dequeue() { - struct thread *it = 0; +thread *sched_dequeue() { + thread *it = 0; int i; for (i = 0; i < PRIORITIES; i++) { it = sched_dequeueFrom(i); diff --git a/src/kernel/task/sched.h b/src/kernel/task/sched.h index 1233a44..7d0dcd3 100644 --- a/src/kernel/task/sched.h +++ b/src/kernel/task/sched.h @@ -3,7 +3,7 @@ #include "task.h" -void sched_enqueue(struct thread *t); -struct thread *sched_dequeue(); +void sched_enqueue(thread *t); +thread *sched_dequeue(); #endif diff --git a/src/kernel/task/syscall.c b/src/kernel/task/syscall.c deleted file mode 100644 index bd27eba..0000000 --- a/src/kernel/task/syscall.c +++ /dev/null @@ -1,45 +0,0 @@ -#include "syscall.h" -#include "task.h" -#include <core/sys.h> - -#define CALL0(name, scname) static void scname(struct registers* r) { r->eax = name(); } -#define CALL1(name, scname) static void scname(struct registers* r) { \ - r->eax = name(r->ebx); } -#define CALL2(name, scname) static void scname(struct registers* r) { \ - r->eax = name(r->ebx, r->ecx); } -#define CALL3(name, scname) static void scname(struct registers* r) { \ - r->eax = name(r->ebx, r->ecx, r->edx); } -#define CALL0V(name, scname) static void scname(struct registers* r) { name(); } -#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(schedule, schedule_sc); -CALL1V(thread_sleep, thread_sleep_sc); -CALL1V(process_exit, process_exit_sc); -CALL1(monitor_write, printk_sc); -CALL1V(idt_waitIrq, irq_wait_sc); -CALL0(proc_priv, proc_priv_sc); -CALL1(process_sbrk, proc_sbrk_sc); -CALL1V(process_brk, proc_brk_sc); - -static void thread_new_sc(struct registers* r) { - cli(); - thread_new(current_thread->process, (thread_entry)r->ebx, (void*)r->ecx, (void*)r->edx); - sti(); -} - -int_callback syscalls[NUMBER_OF_SYSCALLS] = { - thread_exit_sc, //0 - schedule_sc, - thread_sleep_sc, - process_exit_sc, - printk_sc, - thread_new_sc, //5 - irq_wait_sc, - proc_priv_sc, - proc_sbrk_sc, - proc_brk_sc, - 0 }; diff --git a/src/kernel/task/syscall.cpp b/src/kernel/task/syscall.cpp new file mode 100644 index 0000000..6880745 --- /dev/null +++ b/src/kernel/task/syscall.cpp @@ -0,0 +1,50 @@ +#include "syscall.h" +#include "task.h" +#include "timer.h" +#include <core/monitor.h> +#include <core/sys.h> + +#define CALL0(name, scname) static void scname(registers* r) { r->eax = name(); } +#define CALL1(name, scname) static void scname(registers* r) { \ + r->eax = name(r->ebx); } +#define CALL2(name, scname) static void scname(registers* r) { \ + r->eax = name(r->ebx, r->ecx); } +#define CALL3(name, scname) static void scname(registers* r) { \ + r->eax = name(r->ebx, r->ecx, r->edx); } +#define CALL0V(name, scname) static void scname(registers* r) { name(); } +#define CALL1V(name, scname) static void scname(registers* r) { name(r->ebx); } +#define CALL2V(name, scname) static void scname(registers* r) { name(r->ebx, r->ecx); } +#define CALL3V(name, scname) static void scname(registers* r) { name(r->ebx, r->ecx, r->edx); } +#define CALL4V(name, scname) static void scname(registers* r) { name(r->ebx, r->ecx, r->edx, r->esi); } + +CALL0V(thread_exit, thread_exit_sc); +CALL0V(schedule, schedule_sc); +CALL1V(thread_sleep, thread_sleep_sc); +CALL1V(process_exit, process_exit_sc); +CALL1V(idt_waitIrq, irq_wait_sc); +CALL0(proc_priv, proc_priv_sc); +CALL1(process_sbrk, proc_sbrk_sc); +CALL1V(process_brk, proc_brk_sc); + +static void printk_sc(registers *r) { + monitor_write((char*)r->ebx); +} + +static void thread_new_sc(registers* r) { + cli(); + thread_new(current_thread->process, (thread_entry)r->ebx, (void*)r->ecx, (void*)r->edx); + sti(); +} + +int_callback syscalls[NUMBER_OF_SYSCALLS] = { + thread_exit_sc, //0 + schedule_sc, + thread_sleep_sc, + process_exit_sc, + printk_sc, + thread_new_sc, //5 + irq_wait_sc, + proc_priv_sc, + proc_sbrk_sc, + proc_brk_sc, + 0 }; diff --git a/src/kernel/task/task.c b/src/kernel/task/task.cpp index 9d98165..b7c8f45 100644 --- a/src/kernel/task/task.c +++ b/src/kernel/task/task.cpp @@ -2,7 +2,7 @@ #include "sched.h" #include <core/sys.h> #include <core/monitor.h> -#include <mem/mem.h> +#include <lib/cpp.h> #include <mem/seg.h> #include <mem/gdt.h> #include "timer.h" @@ -12,16 +12,16 @@ //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); +static void thread_delete(thread *th); +static void process_delete(process *pr); //From task_.asm -extern uint32_t read_eip(); -extern void task_idle(void*); +extern "C" uint32_t read_eip(); +extern "C" void task_idle(void*); static uint32_t nextpid = 1; -struct process *processes = 0, *kernel_process; -struct thread *current_thread = 0, *idle_thread = 0; +process *processes = 0, *kernel_process; +thread *current_thread = 0, *idle_thread = 0; uint32_t tasking_tmpStack[KSTACKSIZE]; @@ -29,7 +29,7 @@ uint32_t tasking_tmpStack[KSTACKSIZE]; Creates a kernel process and an IDLE thread in it. */ void tasking_init() { cli(); - kernel_process = kmalloc(sizeof(struct process)); //This process must be hidden to users + kernel_process = new process(); //This process must be hidden to users kernel_process->pid = kernel_process->uid = kernel_process->thread_count = 0; kernel_process->privilege = PL_KERNEL; kernel_process->parent = kernel_process; @@ -44,9 +44,9 @@ void tasking_init() { /* Called by the paging functions when a page table is allocated in the kernel space (>K_HIGHHALF_ADDR). Updates the page directories of all the processes. */ -void tasking_updateKernelPagetable(uint32_t idx, struct page_table *table, uint32_t tablephysical) { +void tasking_updateKernelPagetable(uint32_t idx, page_table *table, uint32_t tablephysical) { if (idx < FIRST_KERNEL_PAGETABLE) return; - struct process* it = processes; + process* it = processes; while (it != 0) { it->pagedir->tables[idx] = table; it->pagedir->tablesPhysical[idx] = tablephysical; @@ -94,7 +94,7 @@ void schedule() { /* Called when an exception happens. Provides a stack trace if it was in kernel land. Ends the thread for most exceptions, ends the whole process for page faults. */ -uint32_t tasking_handleException(struct registers *regs) { +uint32_t tasking_handleException(registers *regs) { if (current_thread == 0) return 0; //No tasking yet NL; WHERE; monitor_write("exception:`"); char *exception_messages[] = {"Division By Zero","Debug","Non Maskable Interrupt","Breakpoint", @@ -126,7 +126,7 @@ void thread_goInactive() { } /* Wakes up the given thread. */ -void thread_wakeUp(struct thread* t) { +void thread_wakeUp(thread* t) { if (t->state == TS_WAKEWAIT) { t->state = TS_RUNNING; sched_enqueue(t); @@ -147,9 +147,10 @@ void thread_exit2(uint32_t reason) { //See EX_TH_* defines in task.h * 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; + thread *th = current_thread; + process* pr; if (th == 0 || th->process == 0) goto retrn; - struct process *pr = th->process; + pr = th->process; if ((reason == EX_TH_NORMAL || reason == EX_TH_EXCEPTION) && pr->thread_count > 1) { thread_delete(th); } else { @@ -191,10 +192,10 @@ void process_exit(size_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(void* u_esp, struct thread *thread, thread_entry entry_point, void *data) { +static void thread_run(void* u_esp, thread *thread, thread_entry entry_point, void *data) { pagedir_switch(thread->process->pagedir); if (thread->process->privilege >= PL_USER) { //User mode ! - uint32_t *stack = u_esp; + uint32_t *stack = (uint32_t*)u_esp; stack--; *stack = (uint32_t)data; stack--; *stack = 0; @@ -230,14 +231,14 @@ static void thread_run(void* u_esp, struct thread *thread, thread_entry entry_po asm volatile("sti"); entry_point(data); } - thread_exit(0); + thread_exit(); } /* 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, void *u_esp) { - struct thread *t = kmalloc(sizeof(struct thread)); +thread *thread_new(process *proc, thread_entry entry_point, void *data, void *u_esp) { + thread *t = new thread(); t->process = proc; t->next = 0; proc->thread_count++; @@ -265,7 +266,7 @@ struct thread *thread_new(struct process *proc, thread_entry entry_point, void * if (proc->threads == 0) { proc->threads = t; } else { - struct thread *i = proc->threads; + thread *i = proc->threads; while (i->next != 0) i = i->next; i->next = t; } @@ -273,8 +274,8 @@ struct thread *thread_new(struct process *proc, thread_entry entry_point, void * } /* Creates a new process. Creates a struct process and fills it up. */ -struct process *process_new(struct process* parent, uint32_t uid, uint32_t privilege) { - struct process* p = kmalloc(sizeof(struct process)); +process *process_new(process* parent, uint32_t uid, uint32_t privilege) { + process* p = new process(); p->pid = (nextpid++); p->uid = uid; p->thread_count = 0; @@ -298,11 +299,11 @@ struct process *process_new(struct process* parent, uint32_t uid, uint32_t privi } /* Deletes given thread, freeing the stack(s). */ -static void thread_delete(struct thread *th) { +static void thread_delete(thread *th) { if (th->process->threads == th) { th->process->threads = th->next; } else { - struct thread *it = th->process->threads; + thread *it = th->process->threads; while (it) { if (it->next == th) { it->next = th->next; @@ -318,8 +319,8 @@ static void thread_delete(struct thread *th) { } /* Deletes a process. First, deletes all its threads. Also deletes the corresponding page directory. */ -static void process_delete(struct process *pr) { - struct thread *it = pr->threads; +static void process_delete(process *pr) { + thread *it = pr->threads; while (it != 0) { thread_delete(it); it = it->next; @@ -327,7 +328,7 @@ static void process_delete(struct process *pr) { if (processes == pr) { processes = pr->next; } else { - struct process *it = processes; + process *it = processes; while (it) { if (it->next == pr) { it->next = pr->next; @@ -363,7 +364,7 @@ static void process_delete(struct process *pr) { }*/ size_t process_sbrk(size_t size) { - struct process *p = current_thread->process; + process *p = current_thread->process; if (p->data == 0) return -1; ASSERT(p->data < K_HIGHHALF_ADDR); if (p->data + size >= K_HIGHHALF_ADDR) return -1; @@ -375,7 +376,7 @@ size_t process_sbrk(size_t size) { size_t end = start + size; if (end & 0x0FFF) end = (end & 0xFFFFF000) + 0x1000; - struct segment *s = simpleseg_make(start, end - start, 1); + segment *s = simpleseg_make(start, end - start, 1); if (s == 0) return -5; p->dataseg = seg_map(s, p->pagedir, 0); if (p->dataseg == 0) return -1; @@ -402,7 +403,7 @@ size_t process_sbrk(size_t size) { } void process_brk(size_t ptr) { - struct process *p = current_thread->process; + process *p = current_thread->process; ASSERT(ptr < K_HIGHHALF_ADDR); process_sbrk(ptr - p->data); diff --git a/src/kernel/task/task.h b/src/kernel/task/task.h index 63cb35a..47d7632 100644 --- a/src/kernel/task/task.h +++ b/src/kernel/task/task.h @@ -20,16 +20,17 @@ typedef void (*thread_entry)(void*); +struct thread; struct process { uint32_t pid, uid, privilege, thread_count; - struct process *parent; - struct page_directory *pagedir; + process *parent; + page_directory *pagedir; size_t stack, data; - struct segment_map *dataseg; + segment_map *dataseg; - struct process *next; //Forms a linked list - struct thread *threads; + process *next; //Forms a linked list + thread *threads; }; struct thread { @@ -40,21 +41,25 @@ struct thread { void* kernelStack_addr; uint32_t kernelStack_size; - struct thread *next, *queue_next; //queue_next is used in sched.c + thread *next, *queue_next; //queue_next is used in sched.c }; -extern struct thread *current_thread; +extern thread *current_thread; void tasking_init(); +#ifdef __cplusplus +extern "C" void schedule(); +#else void schedule(); -void tasking_updateKernelPagetable(uint32_t idx, struct page_table *table, uint32_t tablePhysical); -uint32_t tasking_handleException(struct registers *regs); +#endif +void tasking_updateKernelPagetable(uint32_t idx, page_table *table, uint32_t tablePhysical); +uint32_t tasking_handleException(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); +void thread_wakeUp(thread *t); int proc_priv(); //Returns current privilege level -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); +thread * thread_new(process *proc, thread_entry entry_point, void *data, void *u_esp); +process* process_new(process *parent, uint32_t uid, uint32_t privilege); void thread_exit(); //syscall void process_exit(size_t retval); //syscall diff --git a/src/kernel/task/timer.c b/src/kernel/task/timer.cpp index 35a94f9..05c4550 100644 --- a/src/kernel/task/timer.c +++ b/src/kernel/task/timer.cpp @@ -7,7 +7,7 @@ static uint32_t tick = 0, frequency = 0, uptime = 0; -static void timer_callback(struct registers *regs); +static void timer_callback(registers *regs); static void timer_wakeUpSleepingThreads(); /* Called by kmain. Sets up the PIT and the IRQ0 handler. */ @@ -37,7 +37,7 @@ uint32_t timer_time() { /* Called when IRQ0 fires. Updates the uptime variable. DOES NOT provoke a task switch. The task switch is called in idt.c (IRQ handler). */ -void timer_callback(struct registers *regs) { +void timer_callback(registers *regs) { tick++; if (tick == frequency) { uptime++; @@ -51,14 +51,14 @@ void timer_callback(struct registers *regs) { static struct sleeping_thread { uint32_t wakeup_time; struct thread *thread; - struct sleeping_thread *next; + sleeping_thread *next; } *sleeping_threads = 0; /* Makes the current thread sleep. */ void thread_sleep(uint32_t msecs) { if (current_thread == 0) return; // Create the sleeping_thread structure - struct sleeping_thread *sf = kmalloc(sizeof(struct sleeping_thread)), *tmp; + sleeping_thread *sf = (sleeping_thread*)kmalloc(sizeof(sleeping_thread)), *tmp; sf->wakeup_time = timer_time() + msecs; sf->thread = current_thread; //Insert it at the right place @@ -83,7 +83,7 @@ void thread_sleep(uint32_t msecs) { void timer_wakeUpSleepingThreads() { uint32_t time = timer_time(); while (sleeping_threads != 0 && sleeping_threads->wakeup_time <= time) { - struct sleeping_thread *tmp = sleeping_threads; + sleeping_thread *tmp = sleeping_threads; thread_wakeUp(tmp->thread); sleeping_threads = tmp->next; kfree(tmp); |