Newer
Older
tree-os / src / kernel / lib / task / task.c
#include <lib/task/task.h>
#include <lib/memory/alloc.h>
#include <lib/textMode/stdio.h>

#define STACK_SIZE 0xF000

Task *currentTask;

void createTask(Task *task, uint32_t mainFunction, uint32_t flags, uint32_t *pagedir) {
    void* stack = mallocTask(STACK_SIZE, task);
    task->registers.eax = 0;
    task->registers.ebx = 0;
    task->registers.ecx = 0;
    task->registers.edx = 0;
    task->registers.esi = 0;
    task->registers.edi = 0;
    task->registers.eflags = flags;
    task->registers.eip = mainFunction;
    task->registers.cr3 = (uint32_t) pagedir;
    task->registers.esp = STACK_SIZE + (uint32_t) stack;
    task->nextTask = 0;
    task->stack = stack;
}

void yield() {
    Task* last = currentTask;
    currentTask = currentTask->nextTask;
    if (currentTask == 0x00) {
        puts("No more tasks to run, halting . . .\n");
        while (1) {
            asm("hlt");
            puts("interrupt!\n");
        }
    }
    last->nextTask = 0x00;
    switchTask(&(last->registers), &(currentTask->registers));
}

void schedule(Task* task) {
    Task* test = currentTask;
    while (test->nextTask != 0x0) {
        test = test->nextTask;
        if (test->nextTask == task) {
            return; // don't schedule if the task is already in the queue
        }
    }
    test->nextTask = task;
}

void setRunningTask(Task* task) {
    currentTask = task;
}

void yields() {
    schedule(currentTask);
    yield();
}

void destroyCurrentTask() {
    freeTaskAllocations(currentTask);
    yield();
}

Task* getCurrentTask() {
    return currentTask;
}

void sendMessage(Task* task, Message* message) {
    if (task->message == 0x00) {
        task->message = message;
        return;
    }
    Message* currentMessage = task->message;
    while (currentMessage->next == 0x00) {
        currentMessage = currentMessage->next;
    }
    currentMessage->next = message;
}

Message* popMessage(Task* task) {
    Message* currentMessage = task->message;
    if (currentMessage != 0x00) {
        task->message = currentMessage->next;

    }
    return currentMessage;
}