diff --git a/core/irq_pit.S b/core/irq_pit.S index 6684618..ac7b935 100644 --- a/core/irq_pit.S +++ b/core/irq_pit.S @@ -2,7 +2,7 @@ .text -.extern selectNextThread +.extern switchKthread .globl pit_handler .type pit_handler, @function @@ -21,7 +21,7 @@ pit_handler: // already got eflags, cs and eip on stack thanks to CPU outb %al, $0x20 pushl %esp - call selectNextThread + call switchKthread movl %eax,%esp /* Restore the CPU context */ diff --git a/core/kthread.c b/core/kthread.c index 8ae0978..d645e0f 100644 --- a/core/kthread.c +++ b/core/kthread.c @@ -1,12 +1,19 @@ +#include "assert.h" #include "kthread.h" #include "list.h" #include "alloc.h" #include "klibc.h" +#include "vga.h" static struct kthread *currentThread; -void _kthread_exit(){ - //TODO +void kthread_exit(){ + struct kthread *current = currentThread; + struct kthread *next = selectNextKthread(); + if (next == current) + assert("cannot exit thread"); + currentThread = next; + cpu_context_exit_to(next->cpuState, (cpu_kstate_function_arg1_t *)deleteKthread, (uint32_t)current); return; } @@ -41,7 +48,7 @@ struct kthread *createKthread(const char *name, cpu_kstate_function_arg1_t func, if(cpu_kstate_init(&thread->cpuState, (cpu_kstate_function_arg1_t *)func, (vaddr_t)args, thread->stackAddr, thread->stackSize, - (cpu_kstate_function_arg1_t *)_kthread_exit, 0)) + (cpu_kstate_function_arg1_t *)kthread_exit, 0)) goto free_mem; list_add_tail(currentThread, thread); @@ -59,9 +66,15 @@ void deleteKthread(struct kthread *thread){ free((void *)thread); } -struct cpu_state *selectNextThread(struct cpu_state *prevCpu){ - currentThread->cpuState = prevCpu; +struct kthread *selectNextKthread(){ struct kthread *nextThread = currentThread->next; + return nextThread; +} + +struct cpu_state *switchKthread(struct cpu_state *prevCpu){ + currentThread->cpuState = prevCpu; + struct kthread *nextThread = selectNextKthread(); + printStringDetails(nextThread->name, RED, BLACK, 40, VGA_HEIGHT - 1); currentThread = nextThread; return nextThread->cpuState; } diff --git a/core/kthread.h b/core/kthread.h index 178fb82..8313c34 100644 --- a/core/kthread.h +++ b/core/kthread.h @@ -17,10 +17,12 @@ struct kthread { int kthreadSetup(vaddr_t mainStack, size_t mainStackSize); +void kthread_exit(); struct kthread *createKthread(const char *name, cpu_kstate_function_arg1_t func, void *args); void deleteKthread(struct kthread *thread); -struct cpu_state *selectNextThread(struct cpu_state *prev_cpu); +struct kthread *selectNextKthread(); +struct cpu_state *switchKthread(struct cpu_state *prevCpu); diff --git a/core/main.c b/core/main.c index d80cb44..d4d1627 100644 --- a/core/main.c +++ b/core/main.c @@ -28,15 +28,11 @@ void cpuid(int code, uint32_t *a, uint32_t *d) void idleThread(void *arg){ (void)arg; + int count = 0; while(1) - printf("."); + printIntDetails(count++, GREEN, BLACK, 0, VGA_HEIGHT - 1); } -void dashThread(void *arg){ - (void)arg; - while(1) - printf("-"); -} // Multiboot information available here : // https://www.gnu.org/software/grub/manual/multiboot/multiboot.html#kernel_002ec @@ -124,15 +120,13 @@ void kmain(unsigned long magic, unsigned long addr) allocInit(); kthreadSetup(_stack_bottom, (_stack_top - _stack_bottom + 1)); createKthread("idle", idleThread, NULL); - createKthread("dash", dashThread, NULL); irqSetRoutine(IRQ_TIMER, pit_handler); #ifdef RUN_TEST run_test(); #endif + printf("\nSystem init done\n"); - int count = 0; - while (1) { - printIntDetails(count++, GREEN, BLACK, 0, VGA_HEIGHT - 1); - } - printf("exiting\n"); + // There is no real caller behind this point + // So finish this by ourself + kthread_exit(); }