]> git.mdlowis.com Git - proto/cerise-os.git/commitdiff
fixed linked list implementation
authorMichael D. Lowis <mike@mdlowis.com>
Sat, 10 Sep 2022 03:41:49 +0000 (23:41 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Sat, 10 Sep 2022 03:41:49 +0000 (23:41 -0400)
Kernel.c

index 4e4ac38c9dc4234dc2aeccd780de691e3f0b43be..bf6beb7e532653e146283e485bd20c1adc770d41 100644 (file)
--- a/Kernel.c
+++ b/Kernel.c
@@ -1,6 +1,8 @@
+#define _POSIX_C_SOURCE 200809L
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdbool.h>
+#include <stdatomic.h>
 #include <unistd.h>
 #include <pthread.h>
 #include <assert.h>
@@ -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