81 lines
2.5 KiB
C
81 lines
2.5 KiB
C
#include "assert.h"
|
|
#include "kthread.h"
|
|
#include "list.h"
|
|
#include "alloc.h"
|
|
#include "klibc.h"
|
|
#include "vga.h"
|
|
|
|
static struct kthread *currentThread;
|
|
|
|
void kthreadExit(){
|
|
struct kthread *current = currentThread;
|
|
struct kthread *next = kthreadSelectNext();
|
|
if (next == current)
|
|
assert("cannot exit thread");
|
|
currentThread = next;
|
|
cpu_context_exit_to(next->cpuState, (cpu_kstate_function_arg1_t *)kthreadDelete, (uint32_t)current);
|
|
return;
|
|
}
|
|
|
|
int kthreadSetup(vaddr_t mainStack, size_t mainStackSize){
|
|
struct kthread * current = (struct kthread *)malloc(sizeof(struct kthread));
|
|
strzcpy(current->name, "[KINIT]", KTHREAD_NAME_MAX_LENGTH);
|
|
current->stackAddr = mainStack;
|
|
current->stackSize = mainStackSize;
|
|
|
|
list_singleton(currentThread, current);
|
|
|
|
return 0;
|
|
}
|
|
|
|
struct kthread *kthreadCreate(const char *name, cpu_kstate_function_arg1_t func,
|
|
void *args)
|
|
{
|
|
struct kthread *thread = (struct kthread *)malloc(sizeof(struct kthread));
|
|
if (!thread)
|
|
return NULL;
|
|
|
|
thread->stackAddr = (vaddr_t) malloc(KTHREAD_DEFAULT_STACK_SIZE);
|
|
thread->stackSize = KTHREAD_DEFAULT_STACK_SIZE;
|
|
|
|
if(!thread->stackAddr)
|
|
goto free_mem;
|
|
|
|
if(name)
|
|
strzcpy(thread->name, name, KTHREAD_NAME_MAX_LENGTH);
|
|
else
|
|
strzcpy(thread->name, "[UNKNOW]", KTHREAD_NAME_MAX_LENGTH);
|
|
|
|
if(cpu_kstate_init(&thread->cpuState, (cpu_kstate_function_arg1_t *)func, (vaddr_t)args,
|
|
thread->stackAddr, thread->stackSize,
|
|
(cpu_kstate_function_arg1_t *)kthreadExit, 0))
|
|
goto free_mem;
|
|
|
|
list_add_tail(currentThread, thread);
|
|
return thread;
|
|
free_mem:
|
|
free((void *)thread->stackAddr);
|
|
free((void *)thread);
|
|
return NULL;
|
|
}
|
|
|
|
void kthreadDelete(struct kthread *thread){
|
|
list_delete(currentThread, thread);
|
|
|
|
free((void *)thread->stackAddr);
|
|
free((void *)thread);
|
|
}
|
|
|
|
struct kthread *kthreadSelectNext(){
|
|
struct kthread *nextThread = currentThread->next;
|
|
return nextThread;
|
|
}
|
|
|
|
struct cpu_state *switchKthread(struct cpu_state *prevCpu){
|
|
currentThread->cpuState = prevCpu;
|
|
struct kthread *nextThread = kthreadSelectNext();
|
|
printStringDetails(nextThread->name, RED, BLACK, 40, VGA_HEIGHT - 1);
|
|
currentThread = nextThread;
|
|
return nextThread->cpuState;
|
|
}
|