Newer
Older
tree-os / src / kernel / task / task.c
#include <alloc.h>
#include <list.h>
#include <paging.h>
#include <stdio.h>
#include <task.h>
// one page
#define STACK_SIZE 4096
#define INTERRUPT_TASK 0x1

Task *currentTask;
ListElement *scheduledTasks = NULL;
ListElement *allTasks = NULL;
extern uint32_t *kernelPageTable;

void createTask(Task *task, uint32_t mainFunction, uint32_t flags,
                uint32_t *pagedir) {
    listAdd(&allTasks, task);
    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 = kernelPageTable;
    task->registers.esp = STACK_SIZE + (uintptr_t)stack;
    task->stack = stack;
    task->messages = NULL;
    task->ticksLeft = -1;
    task->timerTicks = -1;
}

void yield() {
    Task *last = currentTask;
    currentTask = popBeginning(&scheduledTasks);
    while (currentTask == 0) {
        currentTask = (void *)(uintptr_t)INTERRUPT_TASK;
        asm("sti");
        asm("hlt");
        currentTask = popBeginning(&scheduledTasks);
    }
    if (last == currentTask) {
        return;
    }
    switchTask(&(last->registers), &(currentTask->registers));
}

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

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

inline Task *getCurrentTask() { return currentTask; }

inline void schedule(Task *task) { listAdd(&scheduledTasks, task); }

inline void setRunningTask(Task *task) {
    currentTask = task;
    listAddSet(&allTasks, task);
}

inline ListElement *getAllTasks() { return allTasks; }