]> git.mdlowis.com Git - proto/cerise-os.git/commitdiff
started adding message passing scaffolding master
authorMichael D. Lowis <mike.lowis@gentex.com>
Fri, 16 Sep 2022 20:12:13 +0000 (16:12 -0400)
committerMichael D. Lowis <mike.lowis@gentex.com>
Fri, 16 Sep 2022 20:12:13 +0000 (16:12 -0400)
Kernel.c

index f5139231bda800342d93dd197459b8d4e1262ff6..30f1c5f29158be651af301dfd976db2a8c3265c3 100644 (file)
--- a/Kernel.c
+++ b/Kernel.c
 #define WORD_ALIGN(x) \
     (((x) + WORD_SIZE) & ~(WORD_SIZE))
 
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+
 typedef long TaskID_T;
 
+struct Task_T;
+
+typedef struct {
+    struct Task_T* head;
+    struct Task_T* tail;
+} TaskQueue_T;
+
 typedef enum {
-    STATE_READY = 0,
-    STATE_RUNNING,
+    STATE_TERMINATED = 0,
+    STATE_READY,
     STATE_SEND_BLOCKED,
     STATE_RECV_BLOCKED,
-    STATE_TERMINATED
+    STATE_RUNNING,
 } TaskState_T;
 
 typedef struct Task_T {
@@ -39,12 +48,20 @@ typedef struct Task_T {
     long* heap_top;
     long* memory;
     struct Task_T* next;
+    TaskState_T state;
+
+    /* incoming messages */
+    TaskQueue_T wait_queue;
+
+    /* outgoing message */
+    TaskID_T sender;
+    long status;
+    const void* sdata;
+    size_t nsdata;
+    void* rdata;
+    size_t nrdata;
 } Task_T;
 
-typedef struct {
-    Task_T* head;
-    Task_T* tail;
-} TaskQueue_T;
 
 typedef struct {
     Task_T idle;
@@ -397,19 +414,64 @@ void* Kernel_Allocate(long sz)
     return ptr;
 }
 
-#if 0
-long Kernel_MsgSend(Task_T* task, const void* sdata, size_t nsdata, void* rdata, size_t nrdata)
+long Kernel_MsgSend(TaskID_T tid, const void* sdata, size_t nsdata, void* rdata, size_t nrdata)
 {
+    AcquireLock();
+    Task_T* receiver = &Tasks[tid];
+    Task_T* sender = &Tasks[Running[CpuID].task];
+    sender->sender = tid;
+    sender->sdata  = sdata;
+    sender->nsdata = nsdata;
+    sender->rdata  = rdata;
+    sender->nrdata = nrdata;
+    // put sender in receiver's wait queue
+
+    if (receiver->state == STATE_RECV_BLOCKED)
+    {
+        // TODO: swap tasks directly to the receiver
+        // The receiver will handle the message and yield back to sender
+        ReleaseLock();
+        //YieldTo(receiver);
+    }
+    else
+    {
+        ReleaseLock();
+        Kernel_Yield();
+    }
+    return sender->status;
 }
 
 long Kernel_MsgReceive(void* rdata, size_t nrdata)
 {
+    AcquireLock();
+    Task_T* sender = Tasks[Running[CpuID].task].wait_queue.head;
+    if (&Tasks[Running[CpuID].task].wait_queue.head)
+    {
+        memcpy(rdata, sender->sdata, MIN(nrdata, sender->nsdata));
+        ReleaseLock();
+    }
+    else
+    {
+        /* insert into wait queue and yield() */
+        ReleaseLock();
+        // yield
+    }
+    return 0;
 }
 
 long Kernel_MsgReply(long status, void* sdata, size_t nsdata)
 {
+    (void)status;
+    (void)sdata;
+    (void)nsdata;
+    // acquire lock
+    // copy response data
+    // deque sender from wait queue
+    // enqueue receiver in ready queue
+    // yield to sender
+    // release lock
+    return 0;
 }
-#endif
 
 /***************************************
     Main Routine