summaryrefslogtreecommitdiffstats
path: root/src/kernel/syscall.C
diff options
context:
space:
mode:
authorPatrick Williams <iawillia@us.ibm.com>2010-06-24 15:51:29 -0500
committerPatrick Williams <iawillia@us.ibm.com>2010-06-24 15:51:29 -0500
commit8085c7634979f38c1b152d0a35b98c2447ce497a (patch)
tree844b3527d7b1e8770540f77d1f95c59254aaca60 /src/kernel/syscall.C
parentf760d7d1b0a7872228870b84ebfa85ab9999eb54 (diff)
downloadtalos-hostboot-8085c7634979f38c1b152d0a35b98c2447ce497a.tar.gz
talos-hostboot-8085c7634979f38c1b152d0a35b98c2447ce497a.zip
Add messaging
Diffstat (limited to 'src/kernel/syscall.C')
-rw-r--r--src/kernel/syscall.C154
1 files changed, 154 insertions, 0 deletions
diff --git a/src/kernel/syscall.C b/src/kernel/syscall.C
index d3cff262c..b969745ca 100644
--- a/src/kernel/syscall.C
+++ b/src/kernel/syscall.C
@@ -7,6 +7,7 @@
#include <kernel/console.H>
#include <kernel/pagemgr.H>
#include <kernel/usermutex.H>
+#include <kernel/msg.H>
extern "C"
void kernel_execute_decrementer()
@@ -31,6 +32,14 @@ namespace Systemcalls
void MutexDestroy(task_t*);
void MutexLockCont(task_t*);
void MutexUnlockCont(task_t*);
+ void MsgQCreate(task_t*);
+ void MsgQDestroy(task_t*);
+ void MsgQRegisterRoot(task_t*);
+ void MsgQResolveRoot(task_t*);
+ void MsgSend(task_t*);
+ void MsgSendRecv(task_t*);
+ void MsgRespond(task_t*);
+ void MsgWait(task_t*);
syscall syscalls[] =
{
@@ -43,6 +52,16 @@ namespace Systemcalls
&MutexDestroy,
&MutexLockCont,
&MutexUnlockCont,
+
+ &MsgQCreate,
+ &MsgQDestroy,
+ &MsgQRegisterRoot,
+ &MsgQResolveRoot,
+
+ &MsgSend,
+ &MsgSendRecv,
+ &MsgRespond,
+ &MsgWait,
};
};
@@ -169,4 +188,139 @@ namespace Systemcalls
m->lock.unlock();
TASK_SETRTN(t, 0);
}
+
+ void MsgQCreate(task_t* t)
+ {
+ TASK_SETRTN(t, (uint64_t) new MessageQueue());
+ }
+
+ void MsgQDestroy(task_t* t)
+ {
+ MessageQueue* mq = (MessageQueue*) TASK_GETARG0(t);
+ if (NULL != mq)
+ delete mq;
+ TASK_SETRTN(t, 0);
+ }
+
+ static MessageQueue* msgQRoot = NULL;
+
+ void MsgQRegisterRoot(task_t* t)
+ {
+ msgQRoot = (MessageQueue*) TASK_GETARG0(t);
+ TASK_SETRTN(t, 0);
+ }
+
+ void MsgQResolveRoot(task_t* t)
+ {
+ TASK_SETRTN(t, (uint64_t) msgQRoot);
+ }
+
+ void MsgSend(task_t* t)
+ {
+ MessageQueue* mq = (MessageQueue*) TASK_GETARG0(t);
+ msg_t* m = (msg_t*) TASK_GETARG1(t);
+ m->__reserved__async = 0; // set to async msg.
+
+ mq->lock.lock();
+
+ // Get waiting (server) task.
+ task_t* waiter = mq->waiting.remove();
+ if (NULL == waiter) // None found, add to 'messages' queue.
+ {
+ MessagePending* mp = new MessagePending();
+ mp->key = m;
+ mp->task = t;
+ mq->messages.insert(mp);
+ }
+ else // Add waiter back to its scheduler.
+ {
+ TASK_SETRTN(waiter, (uint64_t) m);
+ waiter->cpu->scheduler->addTask(waiter);
+ }
+
+ mq->lock.unlock();
+ TASK_SETRTN(t, 0);
+ }
+
+ void MsgSendRecv(task_t* t)
+ {
+ MessageQueue* mq = (MessageQueue*) TASK_GETARG0(t);
+ msg_t* m = (msg_t*) TASK_GETARG1(t);
+ m->__reserved__async = 1; // set to sync msg.
+
+ mq->lock.lock();
+ MessagePending* mp = new MessagePending();
+ mp->key = m;
+ mp->task = t;
+
+ // Get waiting (server) task.
+ task_t* waiter = mq->waiting.remove();
+ if (NULL == waiter) // None found, add to 'messages' queue.
+ {
+ mq->messages.insert(mp);
+ }
+ else // Context switch to waiter.
+ {
+ TASK_SETRTN(waiter, (uint64_t) m);
+ mq->responses.insert(mp);
+ waiter->cpu = t->cpu;
+ TaskManager::setCurrentTask(waiter);
+ }
+
+ mq->lock.unlock();
+ TASK_SETRTN(t,0);
+ }
+
+ void MsgRespond(task_t* t)
+ {
+ MessageQueue* mq = (MessageQueue*) TASK_GETARG0(t);
+ msg_t* m = (msg_t*) TASK_GETARG1(t);
+
+ mq->lock.lock();
+ MessagePending* mp = mq->responses.find(m);
+ if (NULL != mp)
+ {
+ task_t* waiter = mp->task;
+
+ mq->responses.erase(mp);
+ delete mp;
+
+ waiter->cpu = t->cpu;
+ TaskManager::setCurrentTask(waiter);
+ t->cpu->scheduler->addTask(t);
+
+ TASK_SETRTN(t,0);
+ }
+ else
+ {
+ TASK_SETRTN(t, -1);
+ }
+ mq->lock.unlock();
+ }
+
+ void MsgWait(task_t* t)
+ {
+ MessageQueue* mq = (MessageQueue*) TASK_GETARG0(t);
+
+ mq->lock.lock();
+ MessagePending* mp = mq->messages.remove();
+
+ if (NULL == mp)
+ {
+ mq->waiting.insert(t);
+ t->cpu->scheduler->setNextRunnable();
+ }
+ else
+ {
+ msg_t* m = mp->key;
+ if (m->__reserved__async)
+ mq->responses.insert(mp);
+ else
+ delete mp;
+ TASK_SETRTN(t, (uint64_t) m);
+ }
+ mq->lock.unlock();
+ }
+
+
};
OpenPOWER on IntegriCloud