kthreadMsleep implementation wip

This commit is contained in:
Mathieu Maret 2020-05-03 14:45:26 +02:00
parent f7525f9e76
commit 4b3f928f67
4 changed files with 98 additions and 8 deletions

View File

@ -17,7 +17,9 @@ void kthreadExit()
struct kthread *next = kthreadSelectNext(); struct kthread *next = kthreadSelectNext();
if (next == current) if (next == current)
assert("cannot exit thread"); assert("cannot exit thread");
currentThread->state = EXITING;
currentThread = next; currentThread = next;
currentThread->state = RUNNING;
cpu_context_exit_to(next->cpuState, (cpu_kstate_function_arg1_t *)kthreadDelete, cpu_context_exit_to(next->cpuState, (cpu_kstate_function_arg1_t *)kthreadDelete,
(uint32_t)current); (uint32_t)current);
restore_IRQs(flags); restore_IRQs(flags);
@ -43,7 +45,7 @@ struct kthread *kthreadCreate(const char *name, cpu_kstate_function_arg1_t func,
return NULL; return NULL;
thread->stackAddr = (vaddr_t)malloc(KTHREAD_DEFAULT_STACK_SIZE); 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; thread->stackSize = KTHREAD_DEFAULT_STACK_SIZE;
if (!thread->stackAddr) 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)) (cpu_kstate_function_arg1_t *)kthreadExit, 0))
goto free_mem; goto free_mem;
thread->state = READY;
uint32_t flags;
disable_IRQs(flags);
list_add_tail(currentThread, thread); list_add_tail(currentThread, thread);
restore_IRQs(flags);
return thread; return thread;
free_mem: free_mem:
free((void *)thread->stackAddr); free((void *)thread->stackAddr);
@ -77,7 +83,15 @@ void kthreadDelete(struct kthread *thread)
struct kthread *kthreadSelectNext() 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; return nextThread;
} }
@ -86,21 +100,70 @@ struct cpu_state *kthreadSwitch(struct cpu_state *prevCpu)
uint32_t flags; uint32_t flags;
disable_IRQs(flags); disable_IRQs(flags);
currentThread->cpuState = prevCpu; currentThread->cpuState = prevCpu;
currentThread->state = READY;
struct kthread *nextThread = kthreadSelectNext(); struct kthread *nextThread = kthreadSelectNext();
printStringDetails(nextThread->name, RED, BLACK, 40, VGA_HEIGHT - 1); printStringDetails(nextThread->name, RED, BLACK, 40, VGA_HEIGHT - 1);
currentThread = nextThread; currentThread = nextThread;
currentThread->state = RUNNING;
restore_IRQs(flags); restore_IRQs(flags);
return nextThread->cpuState; 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() int kthreadYield()
{ {
uint32_t flags; uint32_t flags;
disable_IRQs(flags); disable_IRQs(flags);
struct kthread *next = kthreadSelectNext(); struct kthread *next = kthreadSelectNext();
struct kthread *current = currentThread; struct kthread *current = currentThread;
if (current == next) {
restore_IRQs(flags);
return 0;
}
current->state = READY;
currentThread = next; currentThread = next;
currentThread->state = RUNNING;
cpu_context_switch(&current->cpuState, next->cpuState); cpu_context_switch(&current->cpuState, next->cpuState);
restore_IRQs(flags); restore_IRQs(flags);
return 0; 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(&current->cpuState, next->cpuState);
restore_IRQs(flags);
return 0;
}
struct kthread *getCurrenThread()
{
return currentThread;
}

View File

@ -6,11 +6,21 @@
#define KTHREAD_NAME_MAX_LENGTH 32 #define KTHREAD_NAME_MAX_LENGTH 32
#define KTHREAD_DEFAULT_STACK_SIZE PAGE_SIZE #define KTHREAD_DEFAULT_STACK_SIZE PAGE_SIZE
typedef enum {
RUNNING,
READY,
SLEEPING,
EXITING
} kthread_state;
struct kthread { struct kthread {
char name[KTHREAD_NAME_MAX_LENGTH]; char name[KTHREAD_NAME_MAX_LENGTH];
struct cpu_state *cpuState; struct cpu_state *cpuState;
kthread_state state;
vaddr_t stackAddr; vaddr_t stackAddr;
size_t stackSize; size_t stackSize;
unsigned long jiffiesSleeping;
struct kthread *next; struct kthread *next;
struct kthread *prev; struct kthread *prev;
}; };
@ -25,3 +35,6 @@ struct kthread *kthreadSelectNext();
struct cpu_state *kthreadSwitch(struct cpu_state *prevCpu); struct cpu_state *kthreadSwitch(struct cpu_state *prevCpu);
int kthreadYield(); int kthreadYield();
int kthreadMsleep(unsigned long msec);
int kthreadOnJieffiesTick();
struct kthread *getCurrenThread();

View File

@ -26,8 +26,20 @@
void idleThread(void *arg) void idleThread(void *arg)
{ {
(void)arg; (void)arg;
while (1) while (1) {
printIntDetails((jiffies / HZ), GREEN, BLACK, 0, VGA_HEIGHT - 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 : // Multiboot information available here :
@ -115,6 +127,7 @@ void kmain(unsigned long magic, unsigned long addr)
allocSetup(); allocSetup();
kthreadSetup(_stack_bottom, (_stack_top - _stack_bottom + 1)); 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); irqSetRoutine(IRQ_TIMER, pit_handler);
#ifdef RUN_TEST #ifdef RUN_TEST
run_test(); run_test();

View File

@ -20,5 +20,6 @@ int pitSetup(unsigned int freq)
struct cpu_state *pitIrqHandler(struct cpu_state *prevCpu) struct cpu_state *pitIrqHandler(struct cpu_state *prevCpu)
{ {
__atomic_add_fetch(&jiffies, 1, __ATOMIC_RELAXED); __atomic_add_fetch(&jiffies, 1, __ATOMIC_RELAXED);
kthreadOnJieffiesTick();
return kthreadSwitch(prevCpu); return kthreadSwitch(prevCpu);
} }