From 4b3f928f6720c26c14571036b45b04f2e8458f41 Mon Sep 17 00:00:00 2001 From: Mathieu Maret Date: Sun, 3 May 2020 14:45:26 +0200 Subject: [PATCH] kthreadMsleep implementation wip --- core/kthread.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++---- core/kthread.h | 13 +++++++++ core/main.c | 19 ++++++++++--- drivers/pit.c | 1 + 4 files changed, 98 insertions(+), 8 deletions(-) diff --git a/core/kthread.c b/core/kthread.c index 768378d..ec8b889 100644 --- a/core/kthread.c +++ b/core/kthread.c @@ -17,7 +17,9 @@ void kthreadExit() struct kthread *next = kthreadSelectNext(); if (next == current) assert("cannot exit thread"); - currentThread = next; + currentThread->state = EXITING; + currentThread = next; + currentThread->state = RUNNING; cpu_context_exit_to(next->cpuState, (cpu_kstate_function_arg1_t *)kthreadDelete, (uint32_t)current); restore_IRQs(flags); @@ -43,7 +45,7 @@ struct kthread *kthreadCreate(const char *name, cpu_kstate_function_arg1_t func, return NULL; thread->stackAddr = (vaddr_t)malloc(KTHREAD_DEFAULT_STACK_SIZE); - printf("Alloc stask at 0x%x strcut at 0x%x\n", thread->stackAddr, thread); + printf("Alloc stask at 0x%x struct at 0x%x\n", thread->stackAddr, thread); thread->stackSize = KTHREAD_DEFAULT_STACK_SIZE; if (!thread->stackAddr) @@ -59,7 +61,11 @@ struct kthread *kthreadCreate(const char *name, cpu_kstate_function_arg1_t func, (cpu_kstate_function_arg1_t *)kthreadExit, 0)) goto free_mem; + thread->state = READY; + uint32_t flags; + disable_IRQs(flags); list_add_tail(currentThread, thread); + restore_IRQs(flags); return thread; free_mem: free((void *)thread->stackAddr); @@ -77,7 +83,15 @@ void kthreadDelete(struct kthread *thread) struct kthread *kthreadSelectNext() { - struct kthread *nextThread = currentThread->next; + struct kthread *nextThread; + int idx; + list_foreach(currentThread->next, nextThread, idx) + { + if (nextThread->state == READY) { + return nextThread; + } + } + assert("Cannot find next thread\n"); return nextThread; } @@ -86,21 +100,70 @@ struct cpu_state *kthreadSwitch(struct cpu_state *prevCpu) uint32_t flags; disable_IRQs(flags); currentThread->cpuState = prevCpu; + currentThread->state = READY; struct kthread *nextThread = kthreadSelectNext(); printStringDetails(nextThread->name, RED, BLACK, 40, VGA_HEIGHT - 1); - currentThread = nextThread; + currentThread = nextThread; + currentThread->state = RUNNING; restore_IRQs(flags); return nextThread->cpuState; } +int kthreadOnJieffiesTick() +{ + struct kthread *nextThread; + int idx; + uint32_t flags; + disable_IRQs(flags); + list_foreach(currentThread, nextThread, idx) + { + if (nextThread->state == SLEEPING) { + nextThread->jiffiesSleeping--; + if (!nextThread->jiffiesSleeping) { + nextThread->state = READY; + } + } + } + restore_IRQs(flags); + return 0; +} + int kthreadYield() { uint32_t flags; disable_IRQs(flags); struct kthread *next = kthreadSelectNext(); struct kthread *current = currentThread; - currentThread = next; + if (current == next) { + restore_IRQs(flags); + return 0; + } + current->state = READY; + currentThread = next; + currentThread->state = RUNNING; cpu_context_switch(¤t->cpuState, next->cpuState); restore_IRQs(flags); return 0; } + +int kthreadMsleep(unsigned long msec) +{ + uint32_t flags; + disable_IRQs(flags); + struct kthread *next = kthreadSelectNext(); + struct kthread *current = currentThread; + assert(next != current); + current->state = SLEEPING; + current->jiffiesSleeping = msecs_to_jiffies(msec); + assert(next->state == READY); + currentThread = next; + currentThread->state = RUNNING; + cpu_context_switch(¤t->cpuState, next->cpuState); + restore_IRQs(flags); + return 0; +} + +struct kthread *getCurrenThread() +{ + return currentThread; +} diff --git a/core/kthread.h b/core/kthread.h index 2317af4..21048ba 100644 --- a/core/kthread.h +++ b/core/kthread.h @@ -6,11 +6,21 @@ #define KTHREAD_NAME_MAX_LENGTH 32 #define KTHREAD_DEFAULT_STACK_SIZE PAGE_SIZE + +typedef enum { + RUNNING, + READY, + SLEEPING, + EXITING +} kthread_state; + struct kthread { char name[KTHREAD_NAME_MAX_LENGTH]; struct cpu_state *cpuState; + kthread_state state; vaddr_t stackAddr; size_t stackSize; + unsigned long jiffiesSleeping; struct kthread *next; struct kthread *prev; }; @@ -25,3 +35,6 @@ struct kthread *kthreadSelectNext(); struct cpu_state *kthreadSwitch(struct cpu_state *prevCpu); int kthreadYield(); +int kthreadMsleep(unsigned long msec); +int kthreadOnJieffiesTick(); +struct kthread *getCurrenThread(); diff --git a/core/main.c b/core/main.c index 5305d8e..eed2156 100644 --- a/core/main.c +++ b/core/main.c @@ -26,8 +26,20 @@ void idleThread(void *arg) { (void)arg; - while (1) - printIntDetails((jiffies/HZ), GREEN, BLACK, 0, VGA_HEIGHT - 1); + while (1) { + printIntDetails((jiffies / HZ), GREEN, BLACK, 0, VGA_HEIGHT - 1); + //kthreadYield(); + } +} + +void sleepThread(void *arg){ + (void)arg; + int secSleep = 0; + while (1){ + printf("Sleeping loop %d\n", secSleep); + secSleep++; + kthreadMsleep(1000); + } } // Multiboot information available here : @@ -114,7 +126,8 @@ void kmain(unsigned long magic, unsigned long addr) serialSetup(115200); allocSetup(); kthreadSetup(_stack_bottom, (_stack_top - _stack_bottom + 1)); - kthreadCreate("idle", idleThread, NULL); + kthreadCreate("idle ", idleThread, NULL); + kthreadCreate("sleep", sleepThread, NULL); irqSetRoutine(IRQ_TIMER, pit_handler); #ifdef RUN_TEST run_test(); diff --git a/drivers/pit.c b/drivers/pit.c index b79469a..bcd491a 100644 --- a/drivers/pit.c +++ b/drivers/pit.c @@ -20,5 +20,6 @@ int pitSetup(unsigned int freq) struct cpu_state *pitIrqHandler(struct cpu_state *prevCpu) { __atomic_add_fetch(&jiffies, 1, __ATOMIC_RELAXED); + kthreadOnJieffiesTick(); return kthreadSwitch(prevCpu); }