[API-NEXT,PATCHv3,03/13] linux-gen: drv: adding barrier

Message ID 1471679163-17240-4-git-send-email-christophe.milard@linaro.org
State New
Headers show

Commit Message

Christophe Milard Aug. 20, 2016, 7:45 a.m.
Based on API interface files.

Signed-off-by: Christophe Milard <christophe.milard@linaro.org>

---
 include/odp_drv.h                                  |  1 +
 platform/linux-generic/Makefile.am                 |  3 ++
 platform/linux-generic/drv_barrier.c               | 50 ++++++++++++++++++++++
 platform/linux-generic/include/odp/drv/barrier.h   | 30 +++++++++++++
 .../include/odp/drv/plat/barrier_types.h           | 38 ++++++++++++++++
 5 files changed, 122 insertions(+)
 create mode 100644 platform/linux-generic/drv_barrier.c
 create mode 100644 platform/linux-generic/include/odp/drv/barrier.h
 create mode 100644 platform/linux-generic/include/odp/drv/plat/barrier_types.h

-- 
2.7.4

Patch

diff --git a/include/odp_drv.h b/include/odp_drv.h
index 776cf12..31c620e 100644
--- a/include/odp_drv.h
+++ b/include/odp_drv.h
@@ -20,6 +20,7 @@  extern C {
 
 #include <odp/drv/align.h>
 #include <odp/drv/atomic.h>
+#include <odp/drv/barrier.h>
 #include <odp/drv/byteorder.h>
 #include <odp/drv/compiler.h>
 #include <odp/drv/spinlock.h>
diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am
index 747e96f..42e9996 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -96,6 +96,7 @@  odpdrvincludedir = $(includedir)/odp/drv
 odpdrvinclude_HEADERS = \
 		  $(srcdir)/include/odp/drv/align.h \
 		  $(srcdir)/include/odp/drv/atomic.h \
+		  $(srcdir)/include/odp/drv/barrier.h \
 		  $(srcdir)/include/odp/drv/byteorder.h \
 		  $(srcdir)/include/odp/drv/compiler.h \
 		  $(srcdir)/include/odp/drv/spinlock.h \
@@ -105,6 +106,7 @@  odpdrvinclude_HEADERS = \
 odpdrvplatincludedir = $(includedir)/odp/drv/plat
 odpdrvplatinclude_HEADERS = \
 		  $(srcdir)/include/odp/drv/plat/atomic_types.h \
+		  $(srcdir)/include/odp/drv/plat/barrier_types.h \
 		  $(srcdir)/include/odp/drv/plat/byteorder_types.h \
 		  $(srcdir)/include/odp/drv/plat/spinlock_types.h
 
@@ -204,6 +206,7 @@  __LIB__libodp_linux_la_SOURCES = \
 			   odp_version.c \
 			   odp_weak.c \
 			   drv_atomic.c \
+			   drv_barrier.c \
 			   drv_spinlock.c \
 			   arch/@ARCH_DIR@/odp_cpu_arch.c \
 			   arch/@ARCH_DIR@/odp_sysinfo_parse.c
diff --git a/platform/linux-generic/drv_barrier.c b/platform/linux-generic/drv_barrier.c
new file mode 100644
index 0000000..7a83981
--- /dev/null
+++ b/platform/linux-generic/drv_barrier.c
@@ -0,0 +1,50 @@ 
+/* Copyright (c) 2016, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+#include <odp/drv/barrier.h>
+#include <odp/drv/sync.h>
+#include <odp/api/cpu.h>
+#include <odp/drv/atomic.h>
+
+void odpdrv_barrier_init(odpdrv_barrier_t *barrier, int count)
+{
+	barrier->count = (uint32_t)count;
+	odpdrv_atomic_init_u32(&barrier->bar, 0);
+}
+
+/*
+ * Efficient barrier_sync -
+ *
+ *   Barriers are initialized with a count of the number of callers
+ *   that must sync on the barrier before any may proceed.
+ *
+ *   To avoid race conditions and to permit the barrier to be fully
+ *   reusable, the barrier value cycles between 0..2*count-1. When
+ *   synchronizing the wasless variable simply tracks which half of
+ *   the cycle the barrier was in upon entry.  Exit is when the
+ *   barrier crosses to the other half of the cycle.
+ */
+void odpdrv_barrier_wait(odpdrv_barrier_t *barrier)
+{
+	uint32_t count;
+	int wasless;
+
+	odpdrv_mb_full();
+
+	count   = odpdrv_atomic_fetch_inc_u32(&barrier->bar);
+	wasless = count < barrier->count;
+
+	if (count == 2 * barrier->count - 1) {
+		/* Wrap around *atomically* */
+		odpdrv_atomic_sub_u32(&barrier->bar, 2 * barrier->count);
+	} else {
+		while ((odpdrv_atomic_load_u32(&barrier->bar) < barrier->count)
+				== wasless)
+			odp_cpu_pause();
+	}
+
+	odpdrv_mb_full();
+}
diff --git a/platform/linux-generic/include/odp/drv/barrier.h b/platform/linux-generic/include/odp/drv/barrier.h
new file mode 100644
index 0000000..877cacf
--- /dev/null
+++ b/platform/linux-generic/include/odp/drv/barrier.h
@@ -0,0 +1,30 @@ 
+/* Copyright (c) 2016, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODPDRV execution barriers
+ */
+
+#ifndef ODPDRV_PLAT_BARRIER_H_
+#define ODPDRV_PLAT_BARRIER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <odp/drv/std_types.h>
+#include <odp/drv/atomic.h>
+#include <odp/drv/plat/barrier_types.h>
+
+#include <odp/drv/spec/barrier.h>
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/platform/linux-generic/include/odp/drv/plat/barrier_types.h b/platform/linux-generic/include/odp/drv/plat/barrier_types.h
new file mode 100644
index 0000000..32264a1
--- /dev/null
+++ b/platform/linux-generic/include/odp/drv/plat/barrier_types.h
@@ -0,0 +1,38 @@ 
+/* Copyright (c) 2016, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * ODPDRV barrier
+ */
+
+#ifndef ODPDRV_BARRIER_TYPES_H_
+#define ODPDRV_BARRIER_TYPES_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <odp/drv/std_types.h>
+#include <odp/drv/atomic.h>
+
+/**
+ * @internal
+ * ODPDRV thread synchronization barrier
+ */
+struct odpdrv_barrier_s {
+	uint32_t		count;  /**< Thread count */
+	odpdrv_atomic_u32_t	bar;    /**< Barrier counter */
+};
+
+typedef struct odpdrv_barrier_s odpdrv_barrier_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif