kthreadMsleep implementation wip
This commit is contained in:
parent
f7525f9e76
commit
4b3f928f67
@ -17,7 +17,9 @@ void kthreadExit()
|
||||
struct kthread *next = kthreadSelectNext();
|
||||
if (next == current)
|
||||
assert("cannot exit thread");
|
||||
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->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;
|
||||
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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
15
core/main.c
15
core/main.c
@ -26,8 +26,20 @@
|
||||
void idleThread(void *arg)
|
||||
{
|
||||
(void)arg;
|
||||
while (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 :
|
||||
@ -115,6 +127,7 @@ void kmain(unsigned long magic, unsigned long addr)
|
||||
allocSetup();
|
||||
kthreadSetup(_stack_bottom, (_stack_top - _stack_bottom + 1));
|
||||
kthreadCreate("idle ", idleThread, NULL);
|
||||
kthreadCreate("sleep", sleepThread, NULL);
|
||||
irqSetRoutine(IRQ_TIMER, pit_handler);
|
||||
#ifdef RUN_TEST
|
||||
run_test();
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user