#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 {
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;
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