From 9014869a79862416e6401a80151c49e0d16183ab Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Fri, 16 Sep 2022 16:12:13 -0400 Subject: [PATCH] started adding message passing scaffolding --- Kernel.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 72 insertions(+), 10 deletions(-) diff --git a/Kernel.c b/Kernel.c index f513923..30f1c5f 100644 --- a/Kernel.c +++ b/Kernel.c @@ -24,14 +24,23 @@ #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 -- 2.54.0