Home | History | Annotate | Download | only in thread
      1 /*
      2  * mbox.c
      3  *
      4  * Simple thread mailbox interface
      5  */
      6 
      7 #include "thread.h"
      8 #include "mbox.h"
      9 #include <errno.h>
     10 
     11 void mbox_init(struct mailbox *mbox, size_t size)
     12 {
     13     if (!!mbox) {
     14 	sem_init(&mbox->prod_sem, size); /* All slots empty */
     15 	sem_init(&mbox->cons_sem, 0);    /* No slots full */
     16 	sem_init(&mbox->head_sem, 1);    /* Head mutex */
     17 	sem_init(&mbox->tail_sem, 1);    /* Tail mutex */
     18 
     19 	mbox->wrap = &mbox->data[size];
     20 	mbox->head = &mbox->data[0];
     21 	mbox->tail = &mbox->data[0];
     22     }
     23 };
     24 
     25 int mbox_post(struct mailbox *mbox, void *msg, mstime_t timeout)
     26 {
     27     if (!mbox_is_valid(mbox))
     28 	return ENOMEM;
     29     if (sem_down(&mbox->prod_sem, timeout) == (mstime_t)-1)
     30 	return ENOMEM;
     31     sem_down(&mbox->head_sem, 0);
     32 
     33     *mbox->head = msg;
     34     mbox->head++;
     35     if (mbox->head == mbox->wrap)
     36 	mbox->head = &mbox->data[0];
     37 
     38     sem_up(&mbox->head_sem);
     39     sem_up(&mbox->cons_sem);
     40     return 0;
     41 }
     42 
     43 mstime_t mbox_fetch(struct mailbox *mbox, void **msg, mstime_t timeout)
     44 {
     45     mstime_t t;
     46 
     47     if (!mbox)
     48 	return -1;
     49     t = sem_down(&mbox->cons_sem, timeout);
     50     if (t == (mstime_t)-1)
     51 	return -1;
     52     t += sem_down(&mbox->tail_sem, 0);
     53 
     54     if (msg)
     55 	*msg = *mbox->tail;
     56     mbox->tail++;
     57     if (mbox->tail == mbox->wrap)
     58 	mbox->tail = &mbox->data[0];
     59 
     60     sem_up(&mbox->tail_sem);
     61     sem_up(&mbox->prod_sem);
     62     return t;
     63 }
     64