1 /* SPDX-License-Identifier: BSD-3-Clause
3 * Copyright (c) 2010-2020 Intel Corporation
4 * Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org
6 * Derived from FreeBSD's bufring.h
7 * Used as BSD-3 Licensed with permission from Kip Macy.
10 #ifndef _RTE_RING_HTS_H_
11 #define _RTE_RING_HTS_H_
14 * @file rte_ring_hts.h
15 * @b EXPERIMENTAL: this API may change without prior notice
16 * It is not recommended to include this file directly.
17 * Please include <rte_ring.h> instead.
19 * Contains functions for serialized, aka Head-Tail Sync (HTS) ring mode.
20 * In that mode enqueue/dequeue operation is fully serialized:
21 * at any given moment only one enqueue/dequeue operation can proceed.
22 * This is achieved by allowing a thread to proceed with changing head.value
23 * only when head.value == tail.value.
24 * Both head and tail values are updated atomically (as one 64-bit value).
25 * To achieve that 64-bit CAS is used by head update routine.
32 #include <rte_ring_hts_elem_pvt.h>
35 * Enqueue several objects on the HTS ring (multi-producers safe).
38 * A pointer to the ring structure.
40 * A pointer to a table of objects.
42 * The size of ring element, in bytes. It must be a multiple of 4.
43 * This must be the same value used while creating the ring. Otherwise
44 * the results are undefined.
46 * The number of objects to add in the ring from the obj_table.
48 * if non-NULL, returns the amount of space in the ring after the
49 * enqueue operation has finished.
51 * The number of objects enqueued, either 0 or n
54 static __rte_always_inline unsigned int
55 rte_ring_mp_hts_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table,
56 unsigned int esize, unsigned int n, unsigned int *free_space)
58 return __rte_ring_do_hts_enqueue_elem(r, obj_table, esize, n,
59 RTE_RING_QUEUE_FIXED, free_space);
63 * Dequeue several objects from an HTS ring (multi-consumers safe).
66 * A pointer to the ring structure.
68 * A pointer to a table of objects that will be filled.
70 * The size of ring element, in bytes. It must be a multiple of 4.
71 * This must be the same value used while creating the ring. Otherwise
72 * the results are undefined.
74 * The number of objects to dequeue from the ring to the obj_table.
76 * If non-NULL, returns the number of remaining ring entries after the
77 * dequeue has finished.
79 * The number of objects dequeued, either 0 or n
82 static __rte_always_inline unsigned int
83 rte_ring_mc_hts_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
84 unsigned int esize, unsigned int n, unsigned int *available)
86 return __rte_ring_do_hts_dequeue_elem(r, obj_table, esize, n,
87 RTE_RING_QUEUE_FIXED, available);
91 * Enqueue several objects on the HTS ring (multi-producers safe).
94 * A pointer to the ring structure.
96 * A pointer to a table of objects.
98 * The size of ring element, in bytes. It must be a multiple of 4.
99 * This must be the same value used while creating the ring. Otherwise
100 * the results are undefined.
102 * The number of objects to add in the ring from the obj_table.
104 * if non-NULL, returns the amount of space in the ring after the
105 * enqueue operation has finished.
107 * - n: Actual number of objects enqueued.
110 static __rte_always_inline unsigned int
111 rte_ring_mp_hts_enqueue_burst_elem(struct rte_ring *r, const void *obj_table,
112 unsigned int esize, unsigned int n, unsigned int *free_space)
114 return __rte_ring_do_hts_enqueue_elem(r, obj_table, esize, n,
115 RTE_RING_QUEUE_VARIABLE, free_space);
119 * Dequeue several objects from an HTS ring (multi-consumers safe).
120 * When the requested objects are more than the available objects,
121 * only dequeue the actual number of objects.
124 * A pointer to the ring structure.
126 * A pointer to a table of objects that will be filled.
128 * The size of ring element, in bytes. It must be a multiple of 4.
129 * This must be the same value used while creating the ring. Otherwise
130 * the results are undefined.
132 * The number of objects to dequeue from the ring to the obj_table.
134 * If non-NULL, returns the number of remaining ring entries after the
135 * dequeue has finished.
137 * - n: Actual number of objects dequeued, 0 if ring is empty
140 static __rte_always_inline unsigned int
141 rte_ring_mc_hts_dequeue_burst_elem(struct rte_ring *r, void *obj_table,
142 unsigned int esize, unsigned int n, unsigned int *available)
144 return __rte_ring_do_hts_dequeue_elem(r, obj_table, esize, n,
145 RTE_RING_QUEUE_VARIABLE, available);
149 * Enqueue several objects on the HTS ring (multi-producers safe).
152 * A pointer to the ring structure.
154 * A pointer to a table of void * pointers (objects).
156 * The number of objects to add in the ring from the obj_table.
158 * if non-NULL, returns the amount of space in the ring after the
159 * enqueue operation has finished.
161 * The number of objects enqueued, either 0 or n
164 static __rte_always_inline unsigned int
165 rte_ring_mp_hts_enqueue_bulk(struct rte_ring *r, void * const *obj_table,
166 unsigned int n, unsigned int *free_space)
168 return rte_ring_mp_hts_enqueue_bulk_elem(r, obj_table,
169 sizeof(uintptr_t), n, free_space);
173 * Dequeue several objects from an HTS ring (multi-consumers safe).
176 * A pointer to the ring structure.
178 * A pointer to a table of void * pointers (objects) that will be filled.
180 * The number of objects to dequeue from the ring to the obj_table.
182 * If non-NULL, returns the number of remaining ring entries after the
183 * dequeue has finished.
185 * The number of objects dequeued, either 0 or n
188 static __rte_always_inline unsigned int
189 rte_ring_mc_hts_dequeue_bulk(struct rte_ring *r, void **obj_table,
190 unsigned int n, unsigned int *available)
192 return rte_ring_mc_hts_dequeue_bulk_elem(r, obj_table,
193 sizeof(uintptr_t), n, available);
197 * Enqueue several objects on the HTS ring (multi-producers safe).
200 * A pointer to the ring structure.
202 * A pointer to a table of void * pointers (objects).
204 * The number of objects to add in the ring from the obj_table.
206 * if non-NULL, returns the amount of space in the ring after the
207 * enqueue operation has finished.
209 * - n: Actual number of objects enqueued.
212 static __rte_always_inline unsigned int
213 rte_ring_mp_hts_enqueue_burst(struct rte_ring *r, void * const *obj_table,
214 unsigned int n, unsigned int *free_space)
216 return rte_ring_mp_hts_enqueue_burst_elem(r, obj_table,
217 sizeof(uintptr_t), n, free_space);
221 * Dequeue several objects from an HTS ring (multi-consumers safe).
222 * When the requested objects are more than the available objects,
223 * only dequeue the actual number of objects.
226 * A pointer to the ring structure.
228 * A pointer to a table of void * pointers (objects) that will be filled.
230 * The number of objects to dequeue from the ring to the obj_table.
232 * If non-NULL, returns the number of remaining ring entries after the
233 * dequeue has finished.
235 * - n: Actual number of objects dequeued, 0 if ring is empty
238 static __rte_always_inline unsigned int
239 rte_ring_mc_hts_dequeue_burst(struct rte_ring *r, void **obj_table,
240 unsigned int n, unsigned int *available)
242 return rte_ring_mc_hts_dequeue_burst_elem(r, obj_table,
243 sizeof(uintptr_t), n, available);
250 #endif /* _RTE_RING_HTS_H_ */