kthread: implement exit

This commit is contained in:
Mathieu Maret 2020-04-23 23:40:16 +02:00
parent c1b13bc3f4
commit de14e795d6
4 changed files with 29 additions and 20 deletions

View File

@ -2,7 +2,7 @@
.text .text
.extern selectNextThread .extern switchKthread
.globl pit_handler .globl pit_handler
.type pit_handler, @function .type pit_handler, @function
@ -21,7 +21,7 @@ pit_handler: // already got eflags, cs and eip on stack thanks to CPU
outb %al, $0x20 outb %al, $0x20
pushl %esp pushl %esp
call selectNextThread call switchKthread
movl %eax,%esp movl %eax,%esp
/* Restore the CPU context */ /* Restore the CPU context */

View File

@ -1,12 +1,19 @@
#include "assert.h"
#include "kthread.h" #include "kthread.h"
#include "list.h" #include "list.h"
#include "alloc.h" #include "alloc.h"
#include "klibc.h" #include "klibc.h"
#include "vga.h"
static struct kthread *currentThread; static struct kthread *currentThread;
void _kthread_exit(){ void kthread_exit(){
//TODO 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; 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, if(cpu_kstate_init(&thread->cpuState, (cpu_kstate_function_arg1_t *)func, (vaddr_t)args,
thread->stackAddr, thread->stackSize, thread->stackAddr, thread->stackSize,
(cpu_kstate_function_arg1_t *)_kthread_exit, 0)) (cpu_kstate_function_arg1_t *)kthread_exit, 0))
goto free_mem; goto free_mem;
list_add_tail(currentThread, thread); list_add_tail(currentThread, thread);
@ -59,9 +66,15 @@ void deleteKthread(struct kthread *thread){
free((void *)thread); free((void *)thread);
} }
struct cpu_state *selectNextThread(struct cpu_state *prevCpu){ struct kthread *selectNextKthread(){
currentThread->cpuState = prevCpu;
struct kthread *nextThread = currentThread->next; 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; currentThread = nextThread;
return nextThread->cpuState; return nextThread->cpuState;
} }

View File

@ -17,10 +17,12 @@ struct kthread {
int kthreadSetup(vaddr_t mainStack, size_t mainStackSize); int kthreadSetup(vaddr_t mainStack, size_t mainStackSize);
void kthread_exit();
struct kthread *createKthread(const char *name, cpu_kstate_function_arg1_t func, struct kthread *createKthread(const char *name, cpu_kstate_function_arg1_t func,
void *args); void *args);
void deleteKthread(struct kthread *thread); 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);

View File

@ -28,15 +28,11 @@ void cpuid(int code, uint32_t *a, uint32_t *d)
void idleThread(void *arg){ void idleThread(void *arg){
(void)arg; (void)arg;
int count = 0;
while(1) while(1)
printf("."); printIntDetails(count++, GREEN, BLACK, 0, VGA_HEIGHT - 1);
} }
void dashThread(void *arg){
(void)arg;
while(1)
printf("-");
}
// Multiboot information available here : // Multiboot information available here :
// https://www.gnu.org/software/grub/manual/multiboot/multiboot.html#kernel_002ec // 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(); allocInit();
kthreadSetup(_stack_bottom, (_stack_top - _stack_bottom + 1)); kthreadSetup(_stack_bottom, (_stack_top - _stack_bottom + 1));
createKthread("idle", idleThread, NULL); createKthread("idle", idleThread, NULL);
createKthread("dash", dashThread, NULL);
irqSetRoutine(IRQ_TIMER, pit_handler); irqSetRoutine(IRQ_TIMER, pit_handler);
#ifdef RUN_TEST #ifdef RUN_TEST
run_test(); run_test();
#endif #endif
printf("\nSystem init done\n");
int count = 0; // There is no real caller behind this point
while (1) { // So finish this by ourself
printIntDetails(count++, GREEN, BLACK, 0, VGA_HEIGHT - 1); kthread_exit();
}
printf("exiting\n");
} }