[syslinux:lwip] core: add simple mailbox library
syslinux-bot for H. Peter Anvin
hpa at zytor.com
Fri Apr 22 20:05:05 PDT 2011
Commit-ID: f7de2806b8fe4acbcec64a3084bfecf002d72a5c
Gitweb: http://syslinux.zytor.com/commit/f7de2806b8fe4acbcec64a3084bfecf002d72a5c
Author: H. Peter Anvin <hpa at zytor.com>
AuthorDate: Wed, 9 Sep 2009 12:25:04 -0700
Committer: Eric W. Biederman <ebiederm at xmission.com>
CommitDate: Fri, 8 Apr 2011 14:45:13 -0700
core: add simple mailbox library
A very simple mailbox library, designed for lwIP porting.
Signed-off-by: H. Peter Anvin <hpa at zytor.com>
---
core/include/mbox.h | 24 ++++++++++++++++++
core/thread/mbox.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 92 insertions(+), 0 deletions(-)
diff --git a/core/include/mbox.h b/core/include/mbox.h
new file mode 100644
index 0000000..ac139ff
--- /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 0000000..bc0b010
--- /dev/null
+++ b/core/thread/mbox.c
@@ -0,0 +1,68 @@
+/*
+ * 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) == (mstime_t)-1)
+ return ENOMEM;
+ mbox_post_common(mbox, msg);
+ return 0;
+}
+
+mstime_t mbox_fetch(struct mailbox *mbox, void **msg, mstime_t timeout)
+{
+ mstime_t t;
+
+ 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;
+}
More information about the Syslinux-commits
mailing list