summaryrefslogtreecommitdiff
path: root/arm9/lib
diff options
context:
space:
mode:
Diffstat (limited to 'arm9/lib')
-rw-r--r--arm9/lib/include/OS_init.h1
-rw-r--r--arm9/lib/include/OS_message.h28
-rw-r--r--arm9/lib/src/OS_message.c123
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;
+}