11 #ifndef _RTE_RING_ELEM_H_
12 #define _RTE_RING_ELEM_H_
26 #include <sys/queue.h>
29 #include <rte_config.h>
110 unsigned int count,
int socket_id,
unsigned int flags);
113 __rte_ring_enqueue_elems_32(
struct rte_ring *r,
const uint32_t
size,
114 uint32_t idx,
const void *obj_table, uint32_t n)
117 uint32_t *ring = (uint32_t *)&r[1];
118 const uint32_t *obj = (
const uint32_t *)obj_table;
119 if (
likely(idx + n < size)) {
120 for (i = 0; i < (n & ~0x7); i += 8, idx += 8) {
122 ring[idx + 1] = obj[i + 1];
123 ring[idx + 2] = obj[i + 2];
124 ring[idx + 3] = obj[i + 3];
125 ring[idx + 4] = obj[i + 4];
126 ring[idx + 5] = obj[i + 5];
127 ring[idx + 6] = obj[i + 6];
128 ring[idx + 7] = obj[i + 7];
132 ring[idx++] = obj[i++];
134 ring[idx++] = obj[i++];
136 ring[idx++] = obj[i++];
138 ring[idx++] = obj[i++];
140 ring[idx++] = obj[i++];
142 ring[idx++] = obj[i++];
144 ring[idx++] = obj[i++];
147 for (i = 0; idx <
size; i++, idx++)
150 for (idx = 0; i < n; i++, idx++)
156 __rte_ring_enqueue_elems_64(
struct rte_ring *r, uint32_t prod_head,
157 const void *obj_table, uint32_t n)
160 const uint32_t size = r->
size;
161 uint32_t idx = prod_head & r->
mask;
162 uint64_t *ring = (uint64_t *)&r[1];
163 const uint64_t *obj = (
const uint64_t *)obj_table;
164 if (
likely(idx + n < size)) {
165 for (i = 0; i < (n & ~0x3); i += 4, idx += 4) {
167 ring[idx + 1] = obj[i + 1];
168 ring[idx + 2] = obj[i + 2];
169 ring[idx + 3] = obj[i + 3];
173 ring[idx++] = obj[i++];
175 ring[idx++] = obj[i++];
177 ring[idx++] = obj[i++];
180 for (i = 0; idx <
size; i++, idx++)
183 for (idx = 0; i < n; i++, idx++)
189 __rte_ring_enqueue_elems_128(
struct rte_ring *r, uint32_t prod_head,
190 const void *obj_table, uint32_t n)
193 const uint32_t size = r->
size;
194 uint32_t idx = prod_head & r->
mask;
195 rte_int128_t *ring = (rte_int128_t *)&r[1];
196 const rte_int128_t *obj = (
const rte_int128_t *)obj_table;
197 if (
likely(idx + n < size)) {
198 for (i = 0; i < (n & ~0x1); i += 2, idx += 2)
199 memcpy((
void *)(ring + idx),
200 (
const void *)(obj + i), 32);
203 memcpy((
void *)(ring + idx),
204 (
const void *)(obj + i), 16);
207 for (i = 0; idx <
size; i++, idx++)
208 memcpy((
void *)(ring + idx),
209 (
const void *)(obj + i), 16);
211 for (idx = 0; i < n; i++, idx++)
212 memcpy((
void *)(ring + idx),
213 (
const void *)(obj + i), 16);
222 __rte_ring_enqueue_elems(
struct rte_ring *r, uint32_t prod_head,
223 const void *obj_table, uint32_t esize, uint32_t num)
229 __rte_ring_enqueue_elems_64(r, prod_head, obj_table, num);
230 else if (esize == 16)
231 __rte_ring_enqueue_elems_128(r, prod_head, obj_table, num);
233 uint32_t idx, scale, nr_idx, nr_num, nr_size;
236 scale = esize /
sizeof(uint32_t);
237 nr_num = num * scale;
238 idx = prod_head & r->
mask;
239 nr_idx = idx * scale;
240 nr_size = r->
size * scale;
241 __rte_ring_enqueue_elems_32(r, nr_size, nr_idx,
247 __rte_ring_dequeue_elems_32(
struct rte_ring *r,
const uint32_t size,
248 uint32_t idx,
void *obj_table, uint32_t n)
251 uint32_t *ring = (uint32_t *)&r[1];
252 uint32_t *obj = (uint32_t *)obj_table;
253 if (
likely(idx + n < size)) {
254 for (i = 0; i < (n & ~0x7); i += 8, idx += 8) {
256 obj[i + 1] = ring[idx + 1];
257 obj[i + 2] = ring[idx + 2];
258 obj[i + 3] = ring[idx + 3];
259 obj[i + 4] = ring[idx + 4];
260 obj[i + 5] = ring[idx + 5];
261 obj[i + 6] = ring[idx + 6];
262 obj[i + 7] = ring[idx + 7];
266 obj[i++] = ring[idx++];
268 obj[i++] = ring[idx++];
270 obj[i++] = ring[idx++];
272 obj[i++] = ring[idx++];
274 obj[i++] = ring[idx++];
276 obj[i++] = ring[idx++];
278 obj[i++] = ring[idx++];
281 for (i = 0; idx <
size; i++, idx++)
284 for (idx = 0; i < n; i++, idx++)
290 __rte_ring_dequeue_elems_64(
struct rte_ring *r, uint32_t prod_head,
291 void *obj_table, uint32_t n)
294 const uint32_t size = r->
size;
295 uint32_t idx = prod_head & r->
mask;
296 uint64_t *ring = (uint64_t *)&r[1];
297 uint64_t *obj = (uint64_t *)obj_table;
298 if (
likely(idx + n < size)) {
299 for (i = 0; i < (n & ~0x3); i += 4, idx += 4) {
301 obj[i + 1] = ring[idx + 1];
302 obj[i + 2] = ring[idx + 2];
303 obj[i + 3] = ring[idx + 3];
307 obj[i++] = ring[idx++];
309 obj[i++] = ring[idx++];
311 obj[i++] = ring[idx++];
314 for (i = 0; idx <
size; i++, idx++)
317 for (idx = 0; i < n; i++, idx++)
323 __rte_ring_dequeue_elems_128(
struct rte_ring *r, uint32_t prod_head,
324 void *obj_table, uint32_t n)
327 const uint32_t size = r->
size;
328 uint32_t idx = prod_head & r->
mask;
329 rte_int128_t *ring = (rte_int128_t *)&r[1];
330 rte_int128_t *obj = (rte_int128_t *)obj_table;
331 if (
likely(idx + n < size)) {
332 for (i = 0; i < (n & ~0x1); i += 2, idx += 2)
333 memcpy((
void *)(obj + i), (
void *)(ring + idx), 32);
336 memcpy((
void *)(obj + i), (
void *)(ring + idx), 16);
339 for (i = 0; idx <
size; i++, idx++)
340 memcpy((
void *)(obj + i), (
void *)(ring + idx), 16);
342 for (idx = 0; i < n; i++, idx++)
343 memcpy((
void *)(obj + i), (
void *)(ring + idx), 16);
352 __rte_ring_dequeue_elems(
struct rte_ring *r, uint32_t cons_head,
353 void *obj_table, uint32_t esize, uint32_t num)
359 __rte_ring_dequeue_elems_64(r, cons_head, obj_table, num);
360 else if (esize == 16)
361 __rte_ring_dequeue_elems_128(r, cons_head, obj_table, num);
363 uint32_t idx, scale, nr_idx, nr_num, nr_size;
366 scale = esize /
sizeof(uint32_t);
367 nr_num = num * scale;
368 idx = cons_head & r->
mask;
369 nr_idx = idx * scale;
370 nr_size = r->
size * scale;
371 __rte_ring_dequeue_elems_32(r, nr_size, nr_idx,
385 #ifdef RTE_USE_C11_MEM_MODEL
386 #include "rte_ring_c11_mem.h"
388 #include "rte_ring_generic.h"
416 __rte_ring_do_enqueue_elem(
struct rte_ring *r,
const void *obj_table,
417 unsigned int esize,
unsigned int n,
418 enum rte_ring_queue_behavior behavior,
unsigned int is_sp,
419 unsigned int *free_space)
421 uint32_t prod_head, prod_next;
422 uint32_t free_entries;
424 n = __rte_ring_move_prod_head(r, is_sp, n, behavior,
425 &prod_head, &prod_next, &free_entries);
429 __rte_ring_enqueue_elems(r, prod_head, obj_table, esize, n);
431 update_tail(&r->prod, prod_head, prod_next, is_sp, 1);
433 if (free_space != NULL)
434 *free_space = free_entries - n;
463 __rte_ring_do_dequeue_elem(
struct rte_ring *r,
void *obj_table,
464 unsigned int esize,
unsigned int n,
465 enum rte_ring_queue_behavior behavior,
unsigned int is_sc,
466 unsigned int *available)
468 uint32_t cons_head, cons_next;
471 n = __rte_ring_move_cons_head(r, (
int)is_sc, n, behavior,
472 &cons_head, &cons_next, &entries);
476 __rte_ring_dequeue_elems(r, cons_head, obj_table, esize, n);
478 update_tail(&r->cons, cons_head, cons_next, is_sc, 0);
481 if (available != NULL)
482 *available = entries - n;
510 unsigned int esize,
unsigned int n,
unsigned int *free_space)
512 return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
513 RTE_RING_QUEUE_FIXED, __IS_MP, free_space);
539 unsigned int esize,
unsigned int n,
unsigned int *free_space)
541 return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
542 RTE_RING_QUEUE_FIXED, __IS_SP, free_space);
570 unsigned int esize,
unsigned int n,
unsigned int *free_space)
572 return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
573 RTE_RING_QUEUE_FIXED, r->prod.single, free_space);
675 unsigned int esize,
unsigned int n,
unsigned int *available)
677 return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
678 RTE_RING_QUEUE_FIXED, __IS_MC, available);
703 unsigned int esize,
unsigned int n,
unsigned int *available)
705 return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
706 RTE_RING_QUEUE_FIXED, __IS_SC, available);
734 unsigned int esize,
unsigned int n,
unsigned int *available)
736 return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
737 RTE_RING_QUEUE_FIXED, r->cons.single, available);
842 unsigned int esize,
unsigned int n,
unsigned int *free_space)
844 return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
845 RTE_RING_QUEUE_VARIABLE, __IS_MP, free_space);
871 unsigned int esize,
unsigned int n,
unsigned int *free_space)
873 return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
874 RTE_RING_QUEUE_VARIABLE, __IS_SP, free_space);
902 unsigned int esize,
unsigned int n,
unsigned int *free_space)
904 return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
905 RTE_RING_QUEUE_VARIABLE, r->prod.single, free_space);
934 unsigned int esize,
unsigned int n,
unsigned int *available)
936 return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
937 RTE_RING_QUEUE_VARIABLE, __IS_MC, available);
963 unsigned int esize,
unsigned int n,
unsigned int *available)
965 return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
966 RTE_RING_QUEUE_VARIABLE, __IS_SC, available);
994 unsigned int esize,
unsigned int n,
unsigned int *available)
996 return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
997 RTE_RING_QUEUE_VARIABLE,
998 r->cons.single, available);
static __rte_always_inline int rte_ring_sp_enqueue_elem(struct rte_ring *r, void *obj, unsigned int esize)
static __rte_always_inline int rte_ring_sc_dequeue_elem(struct rte_ring *r, void *obj_p, unsigned int esize)
#define __rte_always_inline
static __rte_always_inline int rte_ring_enqueue_elem(struct rte_ring *r, void *obj, unsigned int esize)
static __rte_always_inline unsigned rte_ring_mc_dequeue_burst_elem(struct rte_ring *r, void *obj_table, unsigned int esize, unsigned int n, unsigned int *available)
static __rte_always_inline unsigned int rte_ring_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table, unsigned int esize, unsigned int n, unsigned int *free_space)
static __rte_always_inline unsigned rte_ring_enqueue_burst_elem(struct rte_ring *r, const void *obj_table, unsigned int esize, unsigned int n, unsigned int *free_space)
static __rte_always_inline unsigned int rte_ring_mp_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table, unsigned int esize, unsigned int n, unsigned int *free_space)
static __rte_always_inline unsigned int rte_ring_mc_dequeue_bulk_elem(struct rte_ring *r, void *obj_table, unsigned int esize, unsigned int n, unsigned int *available)
static __rte_always_inline unsigned rte_ring_sc_dequeue_burst_elem(struct rte_ring *r, void *obj_table, unsigned int esize, unsigned int n, unsigned int *available)
__rte_experimental struct rte_ring * rte_ring_create_elem(const char *name, unsigned int esize, unsigned int count, int socket_id, unsigned int flags)
static __rte_always_inline int rte_ring_mc_dequeue_elem(struct rte_ring *r, void *obj_p, unsigned int esize)
__rte_experimental ssize_t rte_ring_get_memsize_elem(unsigned int esize, unsigned int count)
static __rte_always_inline unsigned rte_ring_mp_enqueue_burst_elem(struct rte_ring *r, const void *obj_table, unsigned int esize, unsigned int n, unsigned int *free_space)
static __rte_always_inline unsigned int rte_ring_sc_dequeue_bulk_elem(struct rte_ring *r, void *obj_table, unsigned int esize, unsigned int n, unsigned int *available)
static __rte_always_inline unsigned int rte_ring_dequeue_bulk_elem(struct rte_ring *r, void *obj_table, unsigned int esize, unsigned int n, unsigned int *available)
static __rte_always_inline int rte_ring_dequeue_elem(struct rte_ring *r, void *obj_p, unsigned int esize)
static __rte_always_inline unsigned int rte_ring_sp_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table, unsigned int esize, unsigned int n, unsigned int *free_space)
static __rte_always_inline int rte_ring_mp_enqueue_elem(struct rte_ring *r, void *obj, unsigned int esize)
static __rte_always_inline unsigned int rte_ring_dequeue_burst_elem(struct rte_ring *r, void *obj_table, unsigned int esize, unsigned int n, unsigned int *available)
static __rte_always_inline unsigned rte_ring_sp_enqueue_burst_elem(struct rte_ring *r, const void *obj_table, unsigned int esize, unsigned int n, unsigned int *free_space)