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