summaryrefslogtreecommitdiffstats
path: root/src/kernel/syscall.C
diff options
context:
space:
mode:
authorPatrick Williams <iawillia@us.ibm.com>2012-02-28 16:07:46 -0600
committerA. Patrick Williams III <iawillia@us.ibm.com>2012-03-03 08:47:22 -0600
commitb3a04d1638f20bd146590dd2c8b1e6fea96faf9c (patch)
treebdea5a9739ea09438856cc0860350c3457754b6a /src/kernel/syscall.C
parentb623fb5b9feba1e5eb1808b456f6dd67bcd79cea (diff)
downloadblackbird-hostboot-b3a04d1638f20bd146590dd2c8b1e6fea96faf9c.tar.gz
blackbird-hostboot-b3a04d1638f20bd146590dd2c8b1e6fea96faf9c.zip
Add non-blocking sync msg interface.
Change-Id: I808fc55ca4706bf03df63b1a72acc87ddba20822 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/705 Tested-by: Jenkins Server Reviewed-by: Douglas R. Gilbert <dgilbert@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com> Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/kernel/syscall.C')
-rw-r--r--src/kernel/syscall.C61
1 files changed, 56 insertions, 5 deletions
diff --git a/src/kernel/syscall.C b/src/kernel/syscall.C
index f0f5b81f0..4d723852f 100644
--- a/src/kernel/syscall.C
+++ b/src/kernel/syscall.C
@@ -336,7 +336,13 @@ namespace Systemcalls
{
MessageQueue* mq = (MessageQueue*) TASK_GETARG0(t);
msg_t* m = (msg_t*) TASK_GETARG1(t);
+ MessageQueue* mq2 = (MessageQueue*) TASK_GETARG2(t);
+
m->__reserved__async = 1; // set to sync msg.
+ if (NULL != mq2) // set as pseudo-sync if secondary queue given.
+ {
+ m->__reserved__pseudosync = 1;
+ }
if (m->type >= MSG_FIRST_SYS_TYPE)
{
@@ -349,9 +355,18 @@ namespace Systemcalls
// Create pending response object.
MessagePending* mp = new MessagePending();
mp->key = m;
- mp->task = t;
- t->state = TASK_STATE_BLOCK_MSG;
- t->state_info = mq;
+ if (!m->__reserved__pseudosync) // Normal sync, add task to pending obj.
+ {
+ mp->task = t;
+ t->state = TASK_STATE_BLOCK_MSG;
+ t->state_info = mq;
+ }
+ else // Pseudo-sync, add the secondary queue instead.
+ {
+ mp->task = reinterpret_cast<task_t*>(mq2);
+ TASK_SETRTN(t, 0); // Need to give good RC for the caller, since
+ // we are returning immediately.
+ }
mq->lock.lock();
@@ -360,14 +375,22 @@ namespace Systemcalls
if (NULL == waiter) // None found, add to 'messages' queue.
{
mq->messages.insert(mp);
- // Choose next thread to execute, this one is delayed.
- t->cpu->scheduler->setNextRunnable();
+ if (!m->__reserved__pseudosync)
+ {
+ // Choose next thread to execute, this one is delayed.
+ t->cpu->scheduler->setNextRunnable();
+ } // For pseudo-sync, just keep running the current task.
}
else // Context switch to waiter.
{
TASK_SETRTN(waiter, (uint64_t) m);
mq->responses.insert(mp);
waiter->cpu = t->cpu;
+ if (m->__reserved__pseudosync) // For pseudo-sync, add this task
+ // back to scheduler.
+ {
+ t->cpu->scheduler->addTask(t);
+ }
TaskManager::setCurrentTask(waiter);
}
@@ -389,6 +412,7 @@ namespace Systemcalls
mq->lock.unlock();
delete mp;
+ // Kernel message types are handled by MessageHandler objects.
if (m->type >= MSG_FIRST_SYS_TYPE)
{
TASK_SETRTN(t,
@@ -399,6 +423,33 @@ namespace Systemcalls
t->cpu->scheduler->addTask(t);
}
}
+ // Pseudo-sync messages are handled by pushing the response onto
+ // a message queue.
+ else if (m->__reserved__pseudosync)
+ {
+ MessageQueue* mq2 = (MessageQueue*) waiter;
+ mq2->lock.lock();
+
+ // See if there is a waiting task (the original client).
+ task_t* client = mq2->waiting.remove();
+ if (NULL == client) // None found, add to queue.
+ {
+ MessagePending* mp2 = new MessagePending();
+ mp2->key = m;
+ mp2->task = t;
+ mq2->messages.insert(mp2);
+ }
+ else // Add waiting task onto its scheduler.
+ {
+ TASK_SETRTN(client, (uint64_t) m);
+ client->cpu->scheduler->addTask(client);
+ }
+
+ mq2->lock.unlock();
+ TASK_SETRTN(t, 0);
+
+ }
+ // Normal-sync messages are handled by releasing the deferred task.
else
{
waiter->cpu = t->cpu;
OpenPOWER on IntegriCloud