40 #include <sys/queue.h>
43 #include <rte_config.h>
51 #define RTE_TAILQ_RING_NAME "RTE_RING"
53 enum rte_ring_queue_behavior {
54 RTE_RING_QUEUE_FIXED = 0,
55 RTE_RING_QUEUE_VARIABLE
58 #define RTE_RING_MZ_PREFIX "RG_"
60 #define RTE_RING_NAMESIZE (RTE_MEMZONE_NAMESIZE - \
61 sizeof(RTE_RING_MZ_PREFIX) + 1)
66 struct rte_ring_headtail {
67 volatile uint32_t head;
68 volatile uint32_t tail;
107 #define RING_F_SP_ENQ 0x0001
108 #define RING_F_SC_DEQ 0x0002
117 #define RING_F_EXACT_SZ 0x0004
118 #define RTE_RING_SZ_MASK (0x7fffffffU)
219 int socket_id,
unsigned flags);
241 #define ENQUEUE_PTRS(r, ring_start, prod_head, obj_table, n, obj_type) do { \
243 const uint32_t size = (r)->size; \
244 uint32_t idx = prod_head & (r)->mask; \
245 obj_type *ring = (obj_type *)ring_start; \
246 if (likely(idx + n < size)) { \
247 for (i = 0; i < (n & ((~(unsigned)0x3))); i+=4, idx+=4) { \
248 ring[idx] = obj_table[i]; \
249 ring[idx+1] = obj_table[i+1]; \
250 ring[idx+2] = obj_table[i+2]; \
251 ring[idx+3] = obj_table[i+3]; \
255 ring[idx++] = obj_table[i++]; \
257 ring[idx++] = obj_table[i++]; \
259 ring[idx++] = obj_table[i++]; \
262 for (i = 0; idx < size; i++, idx++)\
263 ring[idx] = obj_table[i]; \
264 for (idx = 0; i < n; i++, idx++) \
265 ring[idx] = obj_table[i]; \
272 #define DEQUEUE_PTRS(r, ring_start, cons_head, obj_table, n, obj_type) do { \
274 uint32_t idx = cons_head & (r)->mask; \
275 const uint32_t size = (r)->size; \
276 obj_type *ring = (obj_type *)ring_start; \
277 if (likely(idx + n < size)) { \
278 for (i = 0; i < (n & (~(unsigned)0x3)); i+=4, idx+=4) {\
279 obj_table[i] = ring[idx]; \
280 obj_table[i+1] = ring[idx+1]; \
281 obj_table[i+2] = ring[idx+2]; \
282 obj_table[i+3] = ring[idx+3]; \
286 obj_table[i++] = ring[idx++]; \
288 obj_table[i++] = ring[idx++]; \
290 obj_table[i++] = ring[idx++]; \
293 for (i = 0; idx < size; i++, idx++) \
294 obj_table[i] = ring[idx]; \
295 for (idx = 0; i < n; i++, idx++) \
296 obj_table[i] = ring[idx]; \
309 #ifdef RTE_RING_USE_C11_MEM_MODEL
310 #include "rte_ring_c11_mem.h"
312 #include "rte_ring_generic.h"
336 __rte_ring_do_enqueue(
struct rte_ring *r,
void *
const *obj_table,
337 unsigned int n,
enum rte_ring_queue_behavior behavior,
338 unsigned int is_sp,
unsigned int *free_space)
340 uint32_t prod_head, prod_next;
341 uint32_t free_entries;
343 n = __rte_ring_move_prod_head(r, is_sp, n, behavior,
344 &prod_head, &prod_next, &free_entries);
348 ENQUEUE_PTRS(r, &r[1], prod_head, obj_table, n,
void *);
350 update_tail(&r->prod, prod_head, prod_next, is_sp, 1);
352 if (free_space != NULL)
353 *free_space = free_entries - n;
378 __rte_ring_do_dequeue(
struct rte_ring *r,
void **obj_table,
379 unsigned int n,
enum rte_ring_queue_behavior behavior,
380 unsigned int is_sc,
unsigned int *available)
382 uint32_t cons_head, cons_next;
385 n = __rte_ring_move_cons_head(r, (
int)is_sc, n, behavior,
386 &cons_head, &cons_next, &entries);
390 DEQUEUE_PTRS(r, &r[1], cons_head, obj_table, n,
void *);
392 update_tail(&r->cons, cons_head, cons_next, is_sc, 0);
395 if (available != NULL)
396 *available = entries - n;
420 unsigned int n,
unsigned int *free_space)
422 return __rte_ring_do_enqueue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
423 __IS_MP, free_space);
443 unsigned int n,
unsigned int *free_space)
445 return __rte_ring_do_enqueue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
446 __IS_SP, free_space);
470 unsigned int n,
unsigned int *free_space)
472 return __rte_ring_do_enqueue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
473 r->prod.single, free_space);
554 unsigned int n,
unsigned int *available)
556 return __rte_ring_do_dequeue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
578 unsigned int n,
unsigned int *available)
580 return __rte_ring_do_dequeue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
605 unsigned int *available)
607 return __rte_ring_do_dequeue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
608 r->cons.single, available);
680 static inline unsigned
683 uint32_t prod_tail = r->prod.tail;
684 uint32_t cons_tail = r->cons.tail;
685 uint32_t count = (prod_tail - cons_tail) & r->
mask;
697 static inline unsigned
743 static inline unsigned int
757 static inline unsigned int
803 unsigned int n,
unsigned int *free_space)
805 return __rte_ring_do_enqueue(r, obj_table, n,
806 RTE_RING_QUEUE_VARIABLE, __IS_MP, free_space);
826 unsigned int n,
unsigned int *free_space)
828 return __rte_ring_do_enqueue(r, obj_table, n,
829 RTE_RING_QUEUE_VARIABLE, __IS_SP, free_space);
853 unsigned int n,
unsigned int *free_space)
855 return __rte_ring_do_enqueue(r, obj_table, n, RTE_RING_QUEUE_VARIABLE,
856 r->prod.single, free_space);
881 unsigned int n,
unsigned int *available)
883 return __rte_ring_do_dequeue(r, obj_table, n,
884 RTE_RING_QUEUE_VARIABLE, __IS_MC, available);
906 unsigned int n,
unsigned int *available)
908 return __rte_ring_do_dequeue(r, obj_table, n,
909 RTE_RING_QUEUE_VARIABLE, __IS_SC, available);
933 unsigned int n,
unsigned int *available)
935 return __rte_ring_do_dequeue(r, obj_table, n,
936 RTE_RING_QUEUE_VARIABLE,
937 r->cons.single, available);