aboutsummaryrefslogtreecommitdiff
path: root/platform/linux-generic/include/odp_ring_st_internal.h
diff options
context:
space:
mode:
Diffstat (limited to 'platform/linux-generic/include/odp_ring_st_internal.h')
-rw-r--r--platform/linux-generic/include/odp_ring_st_internal.h109
1 files changed, 109 insertions, 0 deletions
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..543ca9cb2
--- /dev/null
+++ b/platform/linux-generic/include/odp_ring_st_internal.h
@@ -0,0 +1,109 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2018 Linaro Limited
+ */
+
+#ifndef ODP_RING_ST_INTERNAL_H_
+#define ODP_RING_ST_INTERNAL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <odp/api/align.h>
+#include <odp/api/hints.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;
+} ring_st_t;
+
+/* Initialize ring. Ring size must be a power of two. */
+static inline void ring_st_init(ring_st_t *ring)
+{
+ ring->head = 0;
+ ring->tail = 0;
+}
+
+/* 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 *ring_data,
+ uint32_t ring_mask, uint32_t data[],
+ uint32_t max_num)
+{
+ uint32_t head, tail, idx;
+ uint32_t num, i;
+
+ head = ring->head;
+ tail = ring->tail;
+ num = tail - head;
+
+ /* Empty */
+ if (num == 0)
+ return 0;
+
+ if (num > max_num)
+ num = max_num;
+
+ idx = head & ring_mask;
+
+ for (i = 0; i < num; i++) {
+ data[i] = ring_data[idx];
+ idx = (idx + 1) & ring_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, uint32_t *ring_data,
+ uint32_t ring_mask,
+ const uint32_t data[],
+ uint32_t num_data)
+{
+ uint32_t head, tail, size, idx;
+ uint32_t num, i;
+
+ head = ring->head;
+ tail = ring->tail;
+ size = ring_mask + 1;
+ num = size - (tail - head);
+
+ /* Full */
+ if (num == 0)
+ return 0;
+
+ if (num > num_data)
+ num = num_data;
+
+ idx = tail & ring_mask;
+
+ for (i = 0; i < num; i++) {
+ ring_data[idx] = data[i];
+ idx = (idx + 1) & ring_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;
+}
+
+/* Return current ring length */
+static inline uint32_t ring_st_length(ring_st_t *ring)
+{
+ return ring->tail - ring->head;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif