64 lines
1.3 KiB
C
64 lines
1.3 KiB
C
/*
|
|
* mbox.c
|
|
*
|
|
* Simple thread mailbox interface
|
|
*/
|
|
|
|
#include "thread.h"
|
|
#include "mbox.h"
|
|
#include <errno.h>
|
|
|
|
void mbox_init(struct mailbox *mbox, size_t size)
|
|
{
|
|
if (!!mbox) {
|
|
sem_init(&mbox->prod_sem, size); /* All slots empty */
|
|
sem_init(&mbox->cons_sem, 0); /* No slots full */
|
|
sem_init(&mbox->head_sem, 1); /* Head mutex */
|
|
sem_init(&mbox->tail_sem, 1); /* Tail mutex */
|
|
|
|
mbox->wrap = &mbox->data[size];
|
|
mbox->head = &mbox->data[0];
|
|
mbox->tail = &mbox->data[0];
|
|
}
|
|
};
|
|
|
|
int mbox_post(struct mailbox *mbox, void *msg, mstime_t timeout)
|
|
{
|
|
if (!mbox_is_valid(mbox))
|
|
return ENOMEM;
|
|
if (sem_down(&mbox->prod_sem, timeout) == (mstime_t)-1)
|
|
return ENOMEM;
|
|
sem_down(&mbox->head_sem, 0);
|
|
|
|
*mbox->head = msg;
|
|
mbox->head++;
|
|
if (mbox->head == mbox->wrap)
|
|
mbox->head = &mbox->data[0];
|
|
|
|
sem_up(&mbox->head_sem);
|
|
sem_up(&mbox->cons_sem);
|
|
return 0;
|
|
}
|
|
|
|
mstime_t mbox_fetch(struct mailbox *mbox, void **msg, mstime_t timeout)
|
|
{
|
|
mstime_t t;
|
|
|
|
if (!mbox)
|
|
return -1;
|
|
t = sem_down(&mbox->cons_sem, timeout);
|
|
if (t == (mstime_t)-1)
|
|
return -1;
|
|
t += sem_down(&mbox->tail_sem, 0);
|
|
|
|
if (msg)
|
|
*msg = *mbox->tail;
|
|
mbox->tail++;
|
|
if (mbox->tail == mbox->wrap)
|
|
mbox->tail = &mbox->data[0];
|
|
|
|
sem_up(&mbox->tail_sem);
|
|
sem_up(&mbox->prod_sem);
|
|
return t;
|
|
}
|