]> git.mdlowis.com Git - proto/cerise-os.git/commitdiff
added heap
authorMichael D. Lowis <mike@mdlowis.com>
Mon, 12 Sep 2022 03:48:46 +0000 (23:48 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Mon, 12 Sep 2022 03:48:46 +0000 (23:48 -0400)
Kernel.c

index bf6beb7e532653e146283e485bd20c1adc770d41..3d56af7ccc2004ef5ef7e784d49fdbcba466d81a 100644 (file)
--- a/Kernel.c
+++ b/Kernel.c
@@ -3,6 +3,7 @@
 #include <stdlib.h>
 #include <stdbool.h>
 #include <stdatomic.h>
+#include <string.h>
 #include <unistd.h>
 #include <pthread.h>
 #include <assert.h>
 
 */
 
-#define COND_WAIT_TIMEOUT_MS 100u
+#define COND_WAIT_TIMEOUT_MS    100u
+#define WORD_SIZE               sizeof(void*)
+#define WORD_ALIGN(x)           (((x) + WORD_SIZE) & ~(WORD_SIZE))
 
 typedef struct Task_T {
     volatile long* stack_top; // top of tasks's stack
     long* stack_base;         // allocated memory for stack
     struct Task_T* next;      // pointer to next task
+    long* heap_beg;
+    long* heap_ptr;
+    long* heap_end;
 } Task_T;
 
 typedef struct {
@@ -203,7 +209,17 @@ void Kernel_Exit(void)
     PickNewTask(false);
 }
 
-static Task_T* CreateTask(void (*task_fn)(void*), void* arg, int stacksize)
+static void* TaskAllocate(Task_T* task, size_t sz)
+{
+    sz = WORD_ALIGN(sz);
+    size_t free_sz = (size_t)task->heap_end - (size_t)task->heap_ptr;
+    assert(sz <= free_sz);
+    void* ptr = task->heap_ptr;
+    task->heap_ptr = (void*)((size_t)task->heap_end + sz);
+    return ptr;
+}
+
+static Task_T* CreateTask(void (*task_fn)(void*), void* arg, long int argsz, long int stacksz, long int heapsz)
 {
     AcquireLock();
     Task_T* task = Dequeue(&DeadQueue);
@@ -214,27 +230,36 @@ static Task_T* CreateTask(void (*task_fn)(void*), void* arg, int stacksize)
         task = calloc(1, sizeof(Task_T));
     }
 
-    /* allocate stack */
-    if (stacksize == 0)
+    /* create the task's heap and copy the argument onto the tasks heap */
+    task->heap_beg = malloc(WORD_ALIGN(heapsz));
+    task->heap_ptr = task->heap_beg;
+    task->heap_end = (void*)((size_t)task->heap_beg + heapsz);
+    void* newarg = TaskAllocate(task, argsz);
+    memcpy(newarg, arg, argsz);
+
+    /* allocate stack (default size of 32768) */
+    if (stacksz == 0)
     {
-        stacksize = 32768;
+        stacksz = 32768;
     }
-    task->stack_base = realloc(task->stack_base, stacksize);
+    task->stack_base = realloc(task->stack_base, stacksz);
 
-    task->stack_top  = &task->stack_base[stacksize/sizeof(long)-1]; // top of stack
+    /* populate the initial context on the stack so SwapTasks works */
+    task->stack_top  = &task->stack_base[stacksz / sizeof(long)-1]; // top of stack
     *(--task->stack_top) = (long)Kernel_Exit; // coroutine cleanup
     *(--task->stack_top) = (long)task_fn;     // user's function to run (rop style!)
-    *(--task->stack_top) = (long)arg;         // user's function argument (rdi)
+    *(--task->stack_top) = (long)newarg;      // user's function argument (rdi)
     for (int saved = 0; saved < 6; saved++)
     {
         *(--task->stack_top) = 0xdeadbeef; // initial values for saved registers
     }
+
     return task;
 }
 
-void Kernel_Spawn(void (*task_fn)(void*), void* arg, int stacksize)
+void Kernel_Spawn(void (*task_fn)(void*), void* arg, long int argsz, long int stacksz, long int heapsz)
 {
-    Task_T* task = CreateTask(task_fn, arg, stacksize);
+    Task_T* task = CreateTask(task_fn, arg, argsz, stacksz, heapsz);
     AcquireLock();
     Enter(task);
     ReleaseLock();
@@ -254,7 +279,7 @@ static void CpuIdle(void* arg)
 static void* CpuMain(void* arg)
 {
     CpuID = (long int)arg;
-    Running[CpuID].idle = CreateTask(CpuIdle, 0, 0);
+    Running[CpuID].idle = CreateTask(CpuIdle, 0, 0, 0, 0);
     Running[CpuID].task = Running[CpuID].idle;
     StartTask(Running[CpuID].idle);
     return NULL; /* unreachable */
@@ -319,7 +344,7 @@ int main(int argc, char** argv)
     {
         int* val = malloc(sizeof(int));
         *val = i;
-        Kernel_Spawn(task1, val, 0);
+        Kernel_Spawn(task1, &i, sizeof(int), 0, sizeof(int));
     }
 
     /* wait for all jobs to be done */