aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2009-09-09 12:25:04 -0700
committerH. Peter Anvin <hpa@zytor.com>2009-09-09 12:25:04 -0700
commitfb1da6f2505664e3c5284f33f395755922ff5983 (patch)
tree5c3ba64d633979e2ba1606df7637348ac93ee515
parentc1e82440fc7306010ea86e77ba2425935dc90b37 (diff)
downloadlwip-fb1da6f2505664e3c5284f33f395755922ff5983.tar.gz
lwip-fb1da6f2505664e3c5284f33f395755922ff5983.tar.xz
lwip-fb1da6f2505664e3c5284f33f395755922ff5983.zip
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.h24
-rw-r--r--core/thread/mbox.c64
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);
+}