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();
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(&current->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(&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_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();

View File

@ -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();

View File

@ -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);
}