From: Michael D. Lowis Date: Sat, 10 Sep 2022 03:41:49 +0000 (-0400) Subject: fixed linked list implementation X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=071273f0aaebe234a253bc3f14951ec89f7e42df;p=proto%2Fcerise-os.git fixed linked list implementation --- diff --git a/Kernel.c b/Kernel.c index 4e4ac38..bf6beb7 100644 --- a/Kernel.c +++ b/Kernel.c @@ -1,6 +1,8 @@ +#define _POSIX_C_SOURCE 200809L #include #include #include +#include #include #include #include @@ -67,7 +69,7 @@ static void WaitForTaskFree(Task_T* prev, Task_T* next) { if (next && prev != next) { - while (!next->stack_top) + while (!atomic_load(&next->stack_top)) { } } @@ -85,6 +87,7 @@ static void Enqueue(TaskQueue_T* queue, Task_T* task) task->next = NULL; } queue->tail = task; + task->next = NULL; if (!queue->head) { queue->head = queue->tail; @@ -96,8 +99,8 @@ static Task_T* Dequeue(TaskQueue_T* queue) Task_T* task = queue->head; if (task) { + queue->head = task->next; task->next = NULL; - queue->head = queue->head->next; if (!queue->head) { queue->tail = NULL; @@ -174,36 +177,30 @@ __asm__( " ret\n" ); -void Kernel_Yield(void) +void PickNewTask(bool requeue) { AcquireLock(); - printf("CPU %d is yielding\n", CpuID); Task_T* prev = Running[CpuID].task; Running[CpuID].task = NULL; - prev->stack_top = NULL; - Enter(prev); - printf("CPU %d is picking task\n", CpuID); + atomic_store(&prev->stack_top, NULL); + if (requeue) + { + Enter(prev); + } Running[CpuID].task = Select(); - printf("CPU %d switching to task %p\n", CpuID, Running[CpuID].task); ReleaseLock(); WaitForTaskFree(prev, Running[CpuID].task); SwapTask(prev, Running[CpuID].task); } +void Kernel_Yield(void) +{ + PickNewTask(true); +} + void Kernel_Exit(void) { - puts("exiting"); - AcquireLock(); - printf("CPU %d is yielding\n", CpuID); - Task_T* prev = Running[CpuID].task; - Running[CpuID].task = NULL; - prev->stack_top = NULL; - printf("CPU %d is picking task\n", CpuID); - Running[CpuID].task = Select(); - printf("CPU %d switching to task %p\n", CpuID, Running[CpuID].task); - ReleaseLock(); - WaitForTaskFree(prev, Running[CpuID].task); - SwapTask(prev, Running[CpuID].task); + PickNewTask(false); } static Task_T* CreateTask(void (*task_fn)(void*), void* arg, int stacksize) @@ -232,14 +229,12 @@ static Task_T* CreateTask(void (*task_fn)(void*), void* arg, int stacksize) { *(--task->stack_top) = 0xdeadbeef; // initial values for saved registers } - printf("created task %p\n", task); return task; } void Kernel_Spawn(void (*task_fn)(void*), void* arg, int stacksize) { Task_T* task = CreateTask(task_fn, arg, stacksize); - /* put task in the ready queue */ AcquireLock(); Enter(task); ReleaseLock(); @@ -247,11 +242,9 @@ void Kernel_Spawn(void (*task_fn)(void*), void* arg, int stacksize) static void CpuIdle(void* arg) { - printf("CPU %d is started\n", CpuID); while(1) { Kernel_Yield(); - printf("CPU %d is idle\n", CpuID); AcquireLock(); WaitForCondition(&ScheduleCond, &ScheduleLock, COND_WAIT_TIMEOUT_MS); ReleaseLock(); @@ -263,7 +256,6 @@ static void* CpuMain(void* arg) CpuID = (long int)arg; Running[CpuID].idle = CreateTask(CpuIdle, 0, 0); Running[CpuID].task = Running[CpuID].idle; - printf("CPU %d initializing\n", CpuID); StartTask(Running[CpuID].idle); return NULL; /* unreachable */ } @@ -308,18 +300,10 @@ void Kernel_Run(void) void task1(void* arg) { - for (int i = 0; i < 5; i++) + int* val = arg; + for (int i = 0; i < 1000; i++) { - printf("%d Hello from task 1\n", CpuID); - Kernel_Yield(); - } -} - -void task2(void* arg) -{ - for (int i = 0; i < 5; i++) - { - printf("%d Hello from task 2\n", CpuID); + printf("%d %d\n", *val, CpuID); Kernel_Yield(); } } @@ -331,12 +315,15 @@ int main(int argc, char** argv) Kernel(); - Kernel_Spawn(task1, 0, 0); - Kernel_Spawn(task2, 0, 0); + for (int i = 0; i < 100; i++) + { + int* val = malloc(sizeof(int)); + *val = i; + Kernel_Spawn(task1, val, 0); + } /* wait for all jobs to be done */ Kernel_Run(); - puts("done"); return 0; } \ No newline at end of file