diff options
author | H. Peter Anvin <hpa@zytor.com> | 2009-09-09 12:25:04 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2009-09-09 12:25:04 -0700 |
commit | fb1da6f2505664e3c5284f33f395755922ff5983 (patch) | |
tree | 5c3ba64d633979e2ba1606df7637348ac93ee515 | |
parent | c1e82440fc7306010ea86e77ba2425935dc90b37 (diff) | |
download | syslinux-fb1da6f2505664e3c5284f33f395755922ff5983.tar.gz |
core: add simple mailbox library
A very simple mailbox library, designed for lwIP porting.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r-- | core/include/mbox.h | 24 | ||||
-rw-r--r-- | core/thread/mbox.c | 64 |
2 files changed, 88 insertions, 0 deletions
diff --git a/core/include/mbox.h b/core/include/mbox.h new file mode 100644 index 00000000..ac139ff5 --- /dev/null +++ b/core/include/mbox.h @@ -0,0 +1,24 @@ +/* + * mbox.h + * + * Simple thread mailbox interface + */ + +#ifndef _MBOX_H +#define _MBOX_H + +#include "thread.h" + +struct mailbox { + struct semaphore prod_sem; /* Producer semaphore (empty slots) */ + struct semaphore cons_sem; /* Consumer semaphore (data slots) */ + struct semaphore head_sem; /* Head pointer semaphore */ + struct semaphore tail_sem; /* Tail pointer semaphore */ + void **wrap; /* Where pointers wrap */ + void **head; /* Head pointer */ + void **tail; /* Tail pointer */ + + void *data[]; /* Data array */ +}; + +#endif /* _MBOX_H */ diff --git a/core/thread/mbox.c b/core/thread/mbox.c new file mode 100644 index 00000000..107b51bf --- /dev/null +++ b/core/thread/mbox.c @@ -0,0 +1,64 @@ +/* + * mbox.c + * + * Simple thread mailbox interface + */ + +#include "thread.h" +#include "mbox.h" +#include <errno.h> + +void mbox_init(struct mailbox *mbox, size_t size) +{ + 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]; +}; + +static void mbox_post_common(struct mailbox *mbox, void *msg) +{ + 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); +} + +void mbox_post(struct mailbox *mbox, void *msg) +{ + sem_down(&mbox->prod_sem, 0); + mbox_post_common(mbox, msg); +} + +int mbox_trypost(struct mailbox *mbox, void *msg) +{ + if (sem_down(&mbox->prod_sem, -1) == (jiffies_t)-1) + return ENOMEM; + mbox_post_common(mbox, msg); + return 0; +} + +jiffies_t mbox_fetch(struct mailbox *mbox, void **msg, jiffies_t timeout) +{ + if (sem_down(&mbox->cons_sem, timeout) == (jiffies_t)-1) + return -1; + 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); +} |