kthreadMsleep implementation wip
This commit is contained in:
parent
f7525f9e76
commit
4b3f928f67
@ -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 = next;
|
currentThread->state = EXITING;
|
||||||
|
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;
|
||||||
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);
|
cpu_context_switch(¤t->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(¤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_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();
|
||||||
|
19
core/main.c
19
core/main.c
@ -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 :
|
||||||
@ -114,7 +126,8 @@ void kmain(unsigned long magic, unsigned long addr)
|
|||||||
serialSetup(115200);
|
serialSetup(115200);
|
||||||
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();
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user