diff options
Diffstat (limited to 'src/kernel/syscall.C')
-rw-r--r-- | src/kernel/syscall.C | 73 |
1 files changed, 44 insertions, 29 deletions
diff --git a/src/kernel/syscall.C b/src/kernel/syscall.C index 985d9c0ab..0a8e644a0 100644 --- a/src/kernel/syscall.C +++ b/src/kernel/syscall.C @@ -42,6 +42,10 @@ #include <kernel/intmsghandler.H> #include <sys/sync.h> +namespace KernelIpc +{ + void send(uint64_t i_q, msg_t * i_msg); +}; extern "C" void kernel_execute_decrementer() @@ -308,44 +312,55 @@ namespace Systemcalls void MsgSend(task_t* t) { - MessageQueue* mq = (MessageQueue*) TASK_GETARG0(t); + uint64_t q_handle = TASK_GETARG0(t); msg_t* m = (msg_t*) TASK_GETARG1(t); - if ((NULL == mq) || (NULL == m)) + if(((q_handle >> 32) & MSGQ_TYPE_IPC) != 0) { - printkd("NULL pointer for message queue (%p) or message (%p).\n", - mq, m); - TASK_SETRTN(t, -EINVAL); - return; + // IPC message + KernelIpc::send(q_handle, m); } + else + { - m->__reserved__async = 0; // set to async msg. + MessageQueue* mq = reinterpret_cast<MessageQueue*>(q_handle); - if (m->type >= MSG_FIRST_SYS_TYPE) - { - printkd("Invalid type for msg_send, type=%d.\n", m->type); - TASK_SETRTN(t, -EINVAL); - return; - } + if ((NULL == mq) || (NULL == m)) + { + printkd("NULL pointer for message queue (%p) or message (%p).\n", + mq, m); + TASK_SETRTN(t, -EINVAL); + return; + } - mq->lock.lock(); + m->__reserved__async = 0; // set to async msg. - // 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); - } + if (m->type >= MSG_FIRST_SYS_TYPE) + { + printkd("Invalid type for msg_send, type=%d.\n", m->type); + TASK_SETRTN(t, -EINVAL); + return; + } - mq->lock.unlock(); + 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); } |