The following example demonstrates mailbox behavior during concurrent data retrieval by multiple tasks. In this scenario, two tasks are waiting for incoming data transmitted by three separate tasks.
#include <stdio.h> #include "OS_API.h" TIME StartTime; static ERROR SenderTask(PVOID Arg) { HANDLE MailboxHandle; int Message; /* Sleep for specified amount of time */ osSleep(100 * ((TIME) Arg)); /* Open the mailbox */ MailboxHandle = osOpenMailbox("Mbox1"); /* Send messages continuously */ while(MailboxHandle) { /* Send first message after one second */ osSleep(1000); /* Send message */ Message = (int) Arg; osMailboxPost(MailboxHandle, &Message, sizeof(Message)); } /* Return with success */ return ERR_NO_ERROR; } static ERROR ReceiverTask(PVOID Arg) { HANDLE MailboxHandle; BOOL PrevLockState; int Message; /* Open the mailbox */ MailboxHandle = osOpenMailbox("Mbox1"); /* Receive all sent messages */ while(MailboxHandle) { osMailboxPend(MailboxHandle, &Message, sizeof(Message)); /* Enter critical section */ PrevLockState = arLock(); /* Print the message */ printf("%8i: Task%i receives message from task%i\n", (int) (arGetTickCount() - StartTime), (int) Arg, Message); /* Leave critical section */ arRestore(PrevLockState); } /* Return with success */ return ERR_NO_ERROR; } int main(void) { /* Initialization */ arInit(); stInit(); osInit(); /* Startup time */ StartTime = arGetTickCount(); /* Create mailbox */ osCreateMailbox("Mbox1", OS_IPC_PROTECT_MUTEX | OS_IPC_WAIT_IF_EMPTY | OS_IPC_DIRECT_READ_WRITE); /* Create sender tasks */ osCreateTask(SenderTask, (PVOID) 1, 0, 0, FALSE); osCreateTask(SenderTask, (PVOID) 2, 0, 0, FALSE); osCreateTask(SenderTask, (PVOID) 3, 0, 0, FALSE); /* Create receiver tasks */ osCreateTask(ReceiverTask, (PVOID) 4, 0, 0, FALSE); osCreateTask(ReceiverTask, (PVOID) 5, 0, 0, FALSE); /* Start the operating system */ osStart(); /* Deinitialization */ osDeinit(); arDeinit(); return 0; }
When both tasks are waiting for incoming message, the first of waiting tasks will read a message. When it again starts waiting for incoming message, it will be queued, and a second task will read message as first. The result on the console should look as follows:
1100: Task4 receives message from task1
1200: Task5 receives message from task2
1300: Task4 receives message from task3
2100: Task5 receives message from task1
2200: Task4 receives message from task2
2300: Task5 receives message from task3
3100: Task4 receives message from task1
3200: Task5 receives message from task2
3300: Task4 receives message from task3
4100: Task5 receives message from task1
4200: Task4 receives message from task2
4300: Task5 receives message from task3