[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Minios-devel] [UNIKRAFT PATCH 5/5] lib/ukmpi: Introduce libukmpi





On 14.06.2018 20:04, Sharan Santhanam wrote:
Initial implementation for inter thread communication using mailbox.

Signed-off-by: Simon Kuenzer <simon.kuenzer@xxxxxxxxx>
Signed-off-by: Sharan Santhanam <sharan.santhanam@xxxxxxxxx>
---
  lib/Config.uk               |   1 +
  lib/Makefile.uk             |   1 +
  lib/ukmpi/Config.uk         |  16 ++++
  lib/ukmpi/Makefile.uk       |   6 ++
  lib/ukmpi/export.syms       |   7 ++
  lib/ukmpi/include/uk/mbox.h |  71 ++++++++++++++++++
  lib/ukmpi/mbox.c            | 178 ++++++++++++++++++++++++++++++++++++++++++++
  7 files changed, 280 insertions(+)
  create mode 100644 lib/ukmpi/Config.uk
  create mode 100644 lib/ukmpi/Makefile.uk
  create mode 100644 lib/ukmpi/export.syms
  create mode 100644 lib/ukmpi/include/uk/mbox.h
  create mode 100644 lib/ukmpi/mbox.c

diff --git a/lib/Config.uk b/lib/Config.uk
index 9e6b269..dafb80d 100644
--- a/lib/Config.uk
+++ b/lib/Config.uk
@@ -33,5 +33,6 @@ source "lib/ukallocbbuddy/Config.uk"
  source "lib/uksched/Config.uk"
  source "lib/ukschedcoop/Config.uk"
  source "lib/fdt/Config.uk"
+source "lib/ukmpi/Config.uk"
  source "lib/uklock/Config.uk"
  source "lib/ukswrand/Config.uk"
diff --git a/lib/Makefile.uk b/lib/Makefile.uk
index a79ad0d..a632336 100644
--- a/lib/Makefile.uk
+++ b/lib/Makefile.uk
@@ -17,3 +17,4 @@ $(eval $(call _import_lib,$(CONFIG_UK_BASE)/lib/ukschedcoop))
  $(eval $(call _import_lib,$(CONFIG_UK_BASE)/lib/fdt))
  $(eval $(call _import_lib,$(CONFIG_UK_BASE)/lib/vfscore))
  $(eval $(call _import_lib,$(CONFIG_UK_BASE)/lib/uklock))
+$(eval $(call _import_lib,$(CONFIG_UK_BASE)/lib/ukmpi))
diff --git a/lib/ukmpi/Config.uk b/lib/ukmpi/Config.uk
new file mode 100644
index 0000000..a59d408
--- /dev/null
+++ b/lib/ukmpi/Config.uk
@@ -0,0 +1,16 @@
+config LIBUKMPI
+       bool "Message Passing interface"
+       default n
+       help
+               Provide inter thread communication.
+
+if LIBUKMPI
+       menu "MPI Options"
+               config LIBUKMBOX
+               bool "MBox: Mailbox Interface"
+               select LIBUKLOCK

Hum, I think we should also select LIBUKSCHED and LIBUKALLOC. Then we can remove the guards from the headers and C files. People may be surprised to have nothing provided by the header because the unselected the scheduler.

+               default n
+               help
+                       Use mail box as a communication interface.
+       endmenu
+endif
diff --git a/lib/ukmpi/Makefile.uk b/lib/ukmpi/Makefile.uk
new file mode 100644
index 0000000..85aa6b7
--- /dev/null
+++ b/lib/ukmpi/Makefile.uk
@@ -0,0 +1,6 @@
+$(eval $(call addlib_s,libukmpi,$(CONFIG_LIBUKMPI)))
+
+CINCLUDES-$(CONFIG_LIBUKMPI)   += -I$(LIBUKMPI_BASE)/include
+CXXINCLUDES-$(CONFIG_LIBUKMPI) += -I$(LIBUKMPI_BASE)/include
+
+LIBUKMPI_SRCS-$(CONFIG_LIBUKMBOX) += $(LIBUKMPI_BASE)/mbox.c
diff --git a/lib/ukmpi/export.syms b/lib/ukmpi/export.syms
new file mode 100644
index 0000000..4c4c887
--- /dev/null
+++ b/lib/ukmpi/export.syms
@@ -0,0 +1,7 @@
+uk_mbox_create
+uk_mbox_free
+uk_mbox_post
+uk_mbox_post_try
+uk_mbox_post_to
+uk_mbox_recv_try
+uk_mbox_recv_to
diff --git a/lib/ukmpi/include/uk/mbox.h b/lib/ukmpi/include/uk/mbox.h
new file mode 100644
index 0000000..79fb950
--- /dev/null
+++ b/lib/ukmpi/include/uk/mbox.h
@@ -0,0 +1,71 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Authors: Simon Kuenzer <simon.kuenzer@xxxxxxxxx>
+ *
+ * Copyright (c) 2018, NEC Europe Ltd., NEC Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holder nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY.
+ */
+
+
+#ifndef __UK_MBOX_H__
+#define __UK_MBOX_H__
+
+#include <uk/config.h>
+
+#if CONFIG_LIBUKMBOX
+#include <uk/semaphore.h>
+#include <errno.h>
+#if CONFIG_LIBUKSCHED && CONFIG_LIBUKALLOC
+#include <uk/alloc.h>
+#endif /* CONFIG_LIBUKSCHED && CONFIG_LIBUKALLOC */
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#if CONFIG_LIBUKSCHED && CONFIG_LIBUKALLOC
+struct uk_mbox;
+
+struct uk_mbox *uk_mbox_create(struct uk_alloc *a, size_t size);
+void uk_mbox_free(struct uk_alloc *a, struct uk_mbox *m);
+
+void uk_mbox_post(struct uk_mbox *m, void *msg);
+int uk_mbox_post_try(struct uk_mbox *m, void *msg);
+__nsec uk_mbox_post_to(struct uk_mbox *m, void *msg, __nsec timeout);
+
+int uk_mbox_recv_try(struct uk_mbox *m, void **msg);
+__nsec uk_mbox_recv_to(struct uk_mbox *m, void **msg, __nsec timeout);
+#endif /* CONFIG_LIBUKSCHED && CONFIG_LIBUKALLOC */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* CONFIG_LIBUKMBOX */
+#endif /* __UK_MBOX_H__ */
diff --git a/lib/ukmpi/mbox.c b/lib/ukmpi/mbox.c
new file mode 100644
index 0000000..532885b
--- /dev/null
+++ b/lib/ukmpi/mbox.c
@@ -0,0 +1,178 @@
+#include <uk/mbox.h>
+#include <uk/assert.h>
+#include <uk/arch/limits.h>
+
+#if CONFIG_LIBUKSCHED && CONFIG_LIBUKALLOC
+struct uk_mbox {
+       size_t len;
+       struct uk_semaphore readsem;
+       long readpos;
+       struct uk_semaphore writesem;
+       long writepos;
+
+       void *msgs[];
+};
+
+struct uk_mbox *uk_mbox_create(struct uk_alloc *a, size_t size)
+{
+       struct uk_mbox *m;
+
+       UK_ASSERT(size <= __L_MAX);
+
+       m = uk_malloc(a, sizeof(*m) + (sizeof(void*) * (size + 1)));
+       if (!m)
+               return NULL;
+
+       m->len = size + 1;
+
+       uk_semaphore_init(&m->readsem, 0);
+       m->readpos = 0;
+
+       uk_semaphore_init(&m->writesem, (long) size);
+       m->writepos = 0;
+
+       uk_printd(DLVL_INFO, "Created mailbox %p\n", m);
+       return m;
+}
+
+/* Deallocates a mailbox. If there are messages still present in the
+ * mailbox when the mailbox is deallocated, it is an indication of a
+ * programming error in lwIP and the developer should be notified. */
+void uk_mbox_free(struct uk_alloc *a, struct uk_mbox *m)
+{
+       uk_printd(DLVL_INFO, "Release mailbox %p\n", m);
+
+       UK_ASSERT(a);
+       UK_ASSERT(m);
+       UK_ASSERT(m->readpos == m->writepos);
+
+       uk_free(a, m);
+}
+
+/* Posts the "msg" to the mailbox, internal version that actually does the
+ * post. */
+static inline void _do_mbox_post(struct uk_mbox *m, void *msg)
+{
+       /* The caller got a semaphore token, so we are now allowed to increment
+        * writer, but we still need to prevent concurrency between writers
+        * (interrupt handler vs main) */
+       unsigned long irqf;
+
+       UK_ASSERT(m);
+
+       irqf = ukplat_lcpu_save_irqf();
+       m->msgs[m->writepos] = msg;
+       m->writepos = (m->writepos + 1) % m->len;
+       UK_ASSERT(m->readpos != m->writepos);
+       ukplat_lcpu_restore_irqf(irqf);
+       uk_printd(DLVL_INFO, "Posted message %p to mailbox %p\n", msg, m);
+
+       uk_semaphore_up(&m->readsem);
+}
+
+void uk_mbox_post(struct uk_mbox *m, void *msg)
+{
+       /* The caller got a semaphore token, so we are now allowed to increment
+        * writer, but we still need to prevent concurrency between writers
+        * (interrupt handler vs main) */
+       UK_ASSERT(m);
+
+       uk_semaphore_down(&m->writesem);
+       _do_mbox_post(m, msg);
+}
+
+int uk_mbox_post_try(struct uk_mbox *m, void *msg)
+{
+       UK_ASSERT(m);
+
+       if (!uk_semaphore_down_try(&m->writesem))
+               return -ENOBUFS;
+       _do_mbox_post(m, msg);
+       return 0;
+}
+
+__nsec uk_mbox_post_to(struct uk_mbox *m, void *msg, __nsec timeout)
+{
+       __nsec ret;
+
+       UK_ASSERT(m);
+
+       ret = uk_semaphore_down_to(&m->writesem, timeout);
+       if (ret != __NSEC_MAX)
+               _do_mbox_post(m, msg);
+       return ret;
+}
+
+/*
+ * Fetch a message from a mailbox. Internal version that actually does the
+ * fetch.
+ */
+static inline void *_do_mbox_recv(struct uk_mbox *m)
+{
+       unsigned long irqf;
+       void *ret;
+
+       uk_printd(DLVL_INFO, "Receive message from mailbox %p\n", m);
+       irqf = ukplat_lcpu_save_irqf();
+       UK_ASSERT(m->readpos != m->writepos);
+       ret = m->msgs[m->readpos];
+       m->readpos = (m->readpos + 1) % m->len;
+       ukplat_lcpu_restore_irqf(irqf);
+
+       uk_semaphore_up(&m->writesem);
+
+       return ret;
+}
+
+/* This is similar to uk_mbox_fetch, however if a message is not
+ * present in the mailbox, it immediately returns with the code
+ * SYS_MBOX_EMPTY. On success 0 is returned.
+ *
+ * To allow for efficient implementations, this can be defined as a
+ * function-like macro in sys_arch.h instead of a normal function. For
+ * example, a naive implementation could be:
+ *   #define uk_mbox_tryfetch(mbox,msg) \
+ *     uk_mbox_fetch(mbox,msg,1)
+ * although this would introduce unnecessary delays. */
+
+int uk_mbox_recv_try(struct uk_mbox *m, void **msg)
+{
+       void *rmsg;
+       UK_ASSERT(m);
+
+       if (!uk_semaphore_down_try(&m->readsem))
+               return -ENOMSG;
+
+       rmsg =  _do_mbox_recv(m);
+       if (msg)
+               *msg = rmsg;
+       return 0;
+}
+
+
+/* Blocks the thread until a message arrives in the mailbox, but does
+ * not block the thread longer than "timeout" milliseconds (similar to
+ * the sys_arch_sem_wait() function). The "msg" argument is a result
+ * parameter that is set by the function (i.e., by doing "*msg =
+ * ptr"). The "msg" parameter maybe NULL to indicate that the message
+ * should be dropped.
+ *
+ * The return values are the same as for the sys_arch_sem_wait() function:
+ * Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a
+ * timeout. */
+__nsec uk_mbox_recv_to(struct uk_mbox *m, void **msg, __nsec timeout)
+{
+       void *rmsg = NULL;
+       __nsec ret;
+
+       UK_ASSERT(m);
+
+       ret = uk_semaphore_down_to(&m->readsem, timeout);
+       if (ret != __NSEC_MAX)
+               rmsg = _do_mbox_recv(m);
+
+       if (msg)
+               *msg = rmsg;
+       return ret;
+}
+#endif /* CONFIG_LIBUKSCHED && CONFIG_LIBUKALLOC */


_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.