/*---------------------------------------------------------------------------* Project: TwlSDK - OS File: os_message.c Copyright 2003-2008 Nintendo. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Date:: $ $Rev$ $Author$ *---------------------------------------------------------------------------*/ #include #include /*---------------------------------------------------------------------------* Name: osInitMessageQueue Description: initialize message queue Arguments: mq message queue msgArray buffer for message queue msgCount max massage size for buffer Returns: None *---------------------------------------------------------------------------*/ void osInitMessageQueue(OSMessageQueue *mq, OSMessage *msgArray, s32 msgCount) { osInitThreadQueue(&mq->queueSend); osInitThreadQueue(&mq->queueReceive); mq->msgArray = msgArray; mq->msgCount = msgCount; mq->firstIndex = 0; mq->usedCount = 0; } /*---------------------------------------------------------------------------* Name: osSendMessage Description: send message to message queue Arguments: mq message queue msg massage which is sent flags whether wait or not when queue is full Returns: TRUE if send *---------------------------------------------------------------------------*/ BOOL osSendMessage(OSMessageQueue *mq, OSMessage msg, s32 flags) { OSIntrMode enabled; s32 lastIndex; enabled = osDisableInterrupts(); while (mq->msgCount <= mq->usedCount) // check for full queue { if (!(flags & OS_MESSAGE_BLOCK)) { (void)osRestoreInterrupts(enabled); return FALSE; } else { // Yield osSleepThread(&mq->queueSend); } } // Store message lastIndex = (mq->firstIndex + mq->usedCount) % mq->msgCount; mq->msgArray[lastIndex] = msg; mq->usedCount++; // Wakeup receiving threads if any osWakeupThread(&mq->queueReceive); (void)osRestoreInterrupts(enabled); return TRUE; } /*---------------------------------------------------------------------------* Name: osReceiveMessage Description: receive message from message queue Arguments: mq message queue msg massage which is received flags whether wait or not when queue is empty Returns: TRUE if reveice *---------------------------------------------------------------------------*/ BOOL osReceiveMessage(OSMessageQueue *mq, OSMessage *msg, s32 flags) { OSIntrMode enabled; enabled = osDisableInterrupts(); while (mq->usedCount == 0) // check for empty queue { if (!(flags & OS_MESSAGE_BLOCK)) { (void)osRestoreInterrupts(enabled); return FALSE; } else { // Yield osSleepThread(&mq->queueReceive); } } // Copy-out message if (msg != NULL) { *msg = mq->msgArray[mq->firstIndex]; } mq->firstIndex = (mq->firstIndex + 1) % mq->msgCount; mq->usedCount--; // Wakeup sending threads if any osWakeupThread(&mq->queueSend); (void)osRestoreInterrupts(enabled); return TRUE; } /*---------------------------------------------------------------------------* Name: osJamMessage Description: send message to message queue, cutting in the top of the queue Arguments: mq message queue msg massage which is sent flags whether wait or not when queue is full Returns: TRUE if send *---------------------------------------------------------------------------*/ BOOL osJamMessage(OSMessageQueue *mq, OSMessage msg, s32 flags) { OSIntrMode enabled; enabled = osDisableInterrupts(); while (mq->msgCount <= mq->usedCount) // check for full queue { if (!(flags & OS_MESSAGE_BLOCK)) { (void)osRestoreInterrupts(enabled); return FALSE; } else { // Yield osSleepThread(&mq->queueSend); } } // Store message at the front mq->firstIndex = (mq->firstIndex + mq->msgCount - 1) % mq->msgCount; mq->msgArray[mq->firstIndex] = msg; mq->usedCount++; // Wakeup receiving threads if any osWakeupThread(&mq->queueReceive); (void)osRestoreInterrupts(enabled); return TRUE; } /*---------------------------------------------------------------------------* Name: osReadMessage Description: read message at message queue. no change in queue not occur to switch threads. Arguments: mq message queue msg massage which is received flags whether wait or not when queue is empty Returns: TRUE if read *---------------------------------------------------------------------------*/ BOOL osReadMessage(OSMessageQueue *mq, OSMessage *msg, s32 flags) { OSIntrMode enabled; enabled = osDisableInterrupts(); while (mq->usedCount == 0) // check for empty queue { if (!(flags & OS_MESSAGE_BLOCK)) { (void)osRestoreInterrupts(enabled); return FALSE; } else { // Yield osSleepThread(&mq->queueReceive); } } // Copy-out message if (msg != NULL) { *msg = mq->msgArray[mq->firstIndex]; } (void)osRestoreInterrupts(enabled); return TRUE; }