diff options
Diffstat (limited to 'arm9/lib')
-rw-r--r-- | arm9/lib/include/OS_init.h | 1 | ||||
-rw-r--r-- | arm9/lib/include/OS_message.h | 28 | ||||
-rw-r--r-- | arm9/lib/src/OS_message.c | 123 |
3 files changed, 152 insertions, 0 deletions
diff --git a/arm9/lib/include/OS_init.h b/arm9/lib/include/OS_init.h index 499c9f6c..ea1fa66b 100644 --- a/arm9/lib/include/OS_init.h +++ b/arm9/lib/include/OS_init.h @@ -24,6 +24,7 @@ #include "OS_interrupt.h" #include "OS_reset.h" #include "OS_exception.h" +#include "OS_message.h" void OS_Init(void); diff --git a/arm9/lib/include/OS_message.h b/arm9/lib/include/OS_message.h new file mode 100644 index 00000000..2dc26d50 --- /dev/null +++ b/arm9/lib/include/OS_message.h @@ -0,0 +1,28 @@ +#ifndef POKEDIAMOND_OS_MESSAGE_H +#define POKEDIAMOND_OS_MESSAGE_H + +#include "nitro/types.h" +#include "OS_thread.h" + +typedef void *OSMessage; + +typedef struct OSMessageQueue +{ + OSThreadQueue queueSend; + OSThreadQueue queueReceive; + OSMessage *msgArray; + s32 msgCount; + s32 firstIndex; + s32 usedCount; +} OSMessageQueue; + +#define OS_MESSAGE_NOBLOCK 0 +#define OS_MESSAGE_BLOCK 1 + +void OS_InitMessageQueue(OSMessageQueue *mq, OSMessage *msgArray, s32 msgCount); +BOOL OS_SendMessage(OSMessageQueue *mq, OSMessage msg, s32 flags); +BOOL OS_ReceiveMessage(OSMessageQueue *mq, OSMessage *msg, s32 flags); +BOOL OS_JamMessage(OSMessageQueue *mq, OSMessage msg, s32 flags); +BOOL OS_ReadMessage(OSMessageQueue *mq, OSMessage *msg, s32 flags); + +#endif //POKEDIAMOND_OS_MESSAGE_H diff --git a/arm9/lib/src/OS_message.c b/arm9/lib/src/OS_message.c new file mode 100644 index 00000000..9f7beb8e --- /dev/null +++ b/arm9/lib/src/OS_message.c @@ -0,0 +1,123 @@ +#include "OS_message.h" +#include "function_target.h" +#include "OS_system.h" + +ARM_FUNC void OS_InitMessageQueue(OSMessageQueue *mq, OSMessage *msgArray, s32 msgCount) +{ + OS_InitThreadQueue(&mq->queueSend); + OS_InitThreadQueue(&mq->queueReceive); + mq->msgArray = msgArray; + mq->msgCount = msgCount; + mq->firstIndex = 0; + mq->usedCount = 0; +} + +ARM_FUNC BOOL OS_SendMessage(OSMessageQueue *mq, OSMessage msg, s32 flags) +{ + OSIntrMode enabled = OS_DisableInterrupts(); + + while (mq->msgCount <= mq->usedCount) + { + if (!(flags & OS_MESSAGE_BLOCK)) + { + (void)OS_RestoreInterrupts(enabled); + return FALSE; + } + else + { + OS_SleepThread(&mq->queueSend); + } + } + + s32 lastIndex = (mq->firstIndex + mq->usedCount) % mq->msgCount; + mq->msgArray[lastIndex] = msg; + mq->usedCount++; + + OS_WakeupThread(&mq->queueReceive); + + (void)OS_RestoreInterrupts(enabled); + return TRUE; +} + +ARM_FUNC BOOL OS_ReceiveMessage(OSMessageQueue *mq, OSMessage *msg, s32 flags) +{ + OSIntrMode enabled = OS_DisableInterrupts(); + + while (mq->usedCount == 0) + { + if (!(flags & OS_MESSAGE_BLOCK)) + { + (void)OS_RestoreInterrupts(enabled); + return FALSE; + } + else + { + OS_SleepThread(&mq->queueReceive); + } + } + + if (msg != NULL) + { + *msg = mq->msgArray[mq->firstIndex]; + } + mq->firstIndex = (mq->firstIndex + 1) % mq->msgCount; + mq->usedCount--; + + OS_WakeupThread(&mq->queueSend); + + (void)OS_RestoreInterrupts(enabled); + return TRUE; +} + +ARM_FUNC BOOL OS_JamMessage(OSMessageQueue *mq, OSMessage msg, s32 flags) +{ + OSIntrMode enabled = OS_DisableInterrupts(); + + while (mq->msgCount <= mq->usedCount) + { + if (!(flags & OS_MESSAGE_BLOCK)) + { + (void)OS_RestoreInterrupts(enabled); + return FALSE; + } + else + { + OS_SleepThread(&mq->queueSend); + } + } + + mq->firstIndex = (mq->firstIndex + mq->msgCount - 1) % mq->msgCount; + mq->msgArray[mq->firstIndex] = msg; + mq->usedCount++; + + OS_WakeupThread(&mq->queueReceive); + + (void)OS_RestoreInterrupts(enabled); + return TRUE; +} + +ARM_FUNC BOOL OS_ReadMessage(OSMessageQueue *mq, OSMessage *msg, s32 flags) +{ + OSIntrMode enabled = OS_DisableInterrupts(); + + while (mq->usedCount == 0) + { + if (!(flags & OS_MESSAGE_BLOCK)) + { + (void)OS_RestoreInterrupts(enabled); + return FALSE; + } + else + { + OS_SleepThread(&mq->queueReceive); + } + } + + if (msg != NULL) + { + *msg = mq->msgArray[mq->firstIndex]; + } + + (void)OS_RestoreInterrupts(enabled); + return TRUE; +} |