diff mbox series

[v3,2/10] linux-gen: ring_st: ring for single thread usage

Message ID 1519819218-27901-3-git-send-email-odpbot@yandex.ru
State New
Headers show
Series [v3,1/10] linux-gen: queue: inline queue from index conversion | expand

Commit Message

Github ODP bot Feb. 28, 2018, noon UTC
From: Petri Savolainen <petri.savolainen@linaro.org>


This ring can be used as simple FIFO when enqueue / dequeue
operation synchronization is not needed, or synchronization is
provided by an upper layer already.

Signed-off-by: Petri Savolainen <petri.savolainen@linaro.org>

---
/** Email created from pull request 492 (psavol:master-sched-optim)
 ** https://github.com/Linaro/odp/pull/492
 ** Patch: https://github.com/Linaro/odp/pull/492.patch
 ** Base sha: f5e12df388352b27f09787028a0040afb28564f4
 ** Merge commit sha: 56e6340663c8679516a24dc81df13a53488b86b8
 **/
 platform/linux-generic/Makefile.am                 |   3 +-
 .../linux-generic/include/odp_ring_st_internal.h   | 109 +++++++++++++++++++++
 2 files changed, 111 insertions(+), 1 deletion(-)
 create mode 100644 platform/linux-generic/include/odp_ring_st_internal.h
diff mbox series

Patch

diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am
index b6e195555..c35c0bfe3 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -111,9 +111,10 @@  noinst_HEADERS = \
 		  include/odp_posix_extensions.h \
 		  include/odp_queue_internal.h \
 		  include/odp_queue_scalable_internal.h \
-		  include/odp_ring_internal.h \
 		  include/odp_queue_if.h \
 		  include/odp_queue_lf.h \
+		  include/odp_ring_internal.h \
+		  include/odp_ring_st_internal.h \
 		  include/odp_schedule_if.h \
 		  include/odp_schedule_scalable.h \
 		  include/odp_schedule_scalable_config.h \
diff --git a/platform/linux-generic/include/odp_ring_st_internal.h b/platform/linux-generic/include/odp_ring_st_internal.h
new file mode 100644
index 000000000..5fb37d4ef
--- /dev/null
+++ b/platform/linux-generic/include/odp_ring_st_internal.h
@@ -0,0 +1,109 @@ 
+/* Copyright (c) 2018, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier:     BSD-3-Clause
+ */
+
+#ifndef ODP_RING_ST_INTERNAL_H_
+#define ODP_RING_ST_INTERNAL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <odp/api/hints.h>
+#include <odp_align_internal.h>
+
+/* Basic ring for single thread usage. Operations must be synchronized by using
+ * locks (or other means), when multiple threads use the same ring. */
+typedef struct {
+	uint32_t head;
+	uint32_t tail;
+	uint32_t mask;
+	uint32_t *data;
+
+} ring_st_t;
+
+/* Initialize ring. Ring size must be a power of two. */
+static inline void ring_st_init(ring_st_t *ring, uint32_t *data, uint32_t size)
+{
+	ring->head = 0;
+	ring->tail = 0;
+	ring->mask = size - 1;
+	ring->data = data;
+}
+
+/* Dequeue data from the ring head. Max_num is smaller than ring size.*/
+static inline uint32_t ring_st_deq_multi(ring_st_t *ring, uint32_t data[],
+					 uint32_t max_num)
+{
+	uint32_t head, tail, mask, idx;
+	uint32_t num, i;
+
+	head = ring->head;
+	tail = ring->tail;
+	mask = ring->mask;
+	num  = tail - head;
+
+	/* Empty */
+	if (num == 0)
+		return 0;
+
+	if (num > max_num)
+		num = max_num;
+
+	idx = head & mask;
+
+	for (i = 0; i < num; i++) {
+		data[i] = ring->data[idx];
+		idx     = (idx + 1) & mask;
+	}
+
+	ring->head = head + num;
+
+	return num;
+}
+
+/* Enqueue data into the ring tail. Num_data is smaller than ring size. */
+static inline uint32_t ring_st_enq_multi(ring_st_t *ring, const uint32_t data[],
+					 uint32_t num_data)
+{
+	uint32_t head, tail, mask, size, idx;
+	uint32_t num, i;
+
+	head = ring->head;
+	tail = ring->tail;
+	mask = ring->mask;
+	size = mask + 1;
+	num  = size - (tail - head);
+
+	/* Full */
+	if (num == 0)
+		return 0;
+
+	if (num > num_data)
+		num = num_data;
+
+	idx = tail & mask;
+
+	for (i = 0; i < num; i++) {
+		ring->data[idx] = data[i];
+		idx     = (idx + 1) & mask;
+	}
+
+	ring->tail = tail + num;
+
+	return num;
+}
+
+/* Check if ring is empty */
+static inline int ring_st_is_empty(ring_st_t *ring)
+{
+	return ring->head == ring->tail;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif