10#ifndef _RTE_RING_ELEM_PVT_H_
11#define _RTE_RING_ELEM_PVT_H_
14__rte_ring_enqueue_elems_32(
void *ring_table,
const void *obj_table,
15 uint32_t size, uint32_t idx, uint32_t n)
19 uint32_t *ring = (uint32_t *)ring_table;
20 const uint32_t *obj = (
const uint32_t *)obj_table;
22 if (
likely(idx + n <= size)) {
23 for (i = 0; i < (n & ~0x7); i += 8, idx += 8) {
25 ring[idx + 1] = obj[i + 1];
26 ring[idx + 2] = obj[i + 2];
27 ring[idx + 3] = obj[i + 3];
28 ring[idx + 4] = obj[i + 4];
29 ring[idx + 5] = obj[i + 5];
30 ring[idx + 6] = obj[i + 6];
31 ring[idx + 7] = obj[i + 7];
35 ring[idx++] = obj[i++];
37 ring[idx++] = obj[i++];
39 ring[idx++] = obj[i++];
41 ring[idx++] = obj[i++];
43 ring[idx++] = obj[i++];
45 ring[idx++] = obj[i++];
47 ring[idx++] = obj[i++];
50 for (i = 0; idx < size; i++, idx++)
53 for (idx = 0; i < n; i++, idx++)
59__rte_ring_enqueue_elems_64(
void *ring_table,
const void *obj_table,
60 uint32_t size, uint32_t idx, uint32_t n)
64 uint64_t *ring = (uint64_t *)ring_table;
65 const unaligned_uint64_t *obj = (
const unaligned_uint64_t *)obj_table;
67 if (
likely(idx + n <= size)) {
68 for (i = 0; i < (n & ~0x3); i += 4, idx += 4) {
70 ring[idx + 1] = obj[i + 1];
71 ring[idx + 2] = obj[i + 2];
72 ring[idx + 3] = obj[i + 3];
76 ring[idx++] = obj[i++];
78 ring[idx++] = obj[i++];
80 ring[idx++] = obj[i++];
83 for (i = 0; idx < size; i++, idx++)
86 for (idx = 0; i < n; i++, idx++)
92__rte_ring_enqueue_elems_128(
void *ring_table,
const void *obj_table,
93 uint32_t size, uint32_t idx, uint32_t n)
97 rte_int128_t *ring = (rte_int128_t *)ring_table;
98 const rte_int128_t *obj = (
const rte_int128_t *)obj_table;
100 if (
likely(idx + n <= size)) {
101 for (i = 0; i < (n & ~0x1); i += 2, idx += 2)
102 memcpy((
void *)(ring + idx),
103 (
const void *)(obj + i), 32);
106 memcpy((
void *)(ring + idx),
107 (
const void *)(obj + i), 16);
110 for (i = 0; idx < size; i++, idx++)
111 memcpy((
void *)(ring + idx),
112 (
const void *)(obj + i), 16);
114 for (idx = 0; i < n; i++, idx++)
115 memcpy((
void *)(ring + idx),
116 (
const void *)(obj + i), 16);
125__rte_ring_do_enqueue_elems(
void *ring_table,
const void *obj_table,
126 uint32_t size, uint32_t idx, uint32_t esize, uint32_t num)
132 __rte_ring_enqueue_elems_64(ring_table, obj_table, size,
134 else if (esize == 16)
135 __rte_ring_enqueue_elems_128(ring_table, obj_table, size,
138 uint32_t scale, nr_idx, nr_num, nr_size;
141 scale = esize /
sizeof(uint32_t);
142 nr_num = num * scale;
143 nr_idx = idx * scale;
144 nr_size = size * scale;
145 __rte_ring_enqueue_elems_32(ring_table, obj_table, nr_size,
151__rte_ring_enqueue_elems(
struct rte_ring *r, uint32_t prod_head,
152 const void *obj_table, uint32_t esize, uint32_t num)
154 __rte_ring_do_enqueue_elems(&r[1], obj_table, r->
size,
155 prod_head & r->
mask, esize, num);
159__rte_ring_dequeue_elems_32(
void *obj_table,
const void *ring_table,
160 uint32_t size, uint32_t idx, uint32_t n)
163 uint32_t *obj = (uint32_t *)obj_table;
164 const uint32_t *ring = (
const uint32_t *)ring_table;
166 if (
likely(idx + n <= size)) {
167 for (i = 0; i < (n & ~0x7); i += 8, idx += 8) {
169 obj[i + 1] = ring[idx + 1];
170 obj[i + 2] = ring[idx + 2];
171 obj[i + 3] = ring[idx + 3];
172 obj[i + 4] = ring[idx + 4];
173 obj[i + 5] = ring[idx + 5];
174 obj[i + 6] = ring[idx + 6];
175 obj[i + 7] = ring[idx + 7];
179 obj[i++] = ring[idx++];
181 obj[i++] = ring[idx++];
183 obj[i++] = ring[idx++];
185 obj[i++] = ring[idx++];
187 obj[i++] = ring[idx++];
189 obj[i++] = ring[idx++];
191 obj[i++] = ring[idx++];
194 for (i = 0; idx < size; i++, idx++)
197 for (idx = 0; i < n; i++, idx++)
203__rte_ring_dequeue_elems_64(
void *obj_table,
const void *ring_table,
204 uint32_t size, uint32_t idx, uint32_t n)
207 unaligned_uint64_t *obj = (unaligned_uint64_t *)obj_table;
208 const uint64_t *ring = (
const uint64_t *)ring_table;
210 if (
likely(idx + n <= size)) {
211 for (i = 0; i < (n & ~0x3); i += 4, idx += 4) {
213 obj[i + 1] = ring[idx + 1];
214 obj[i + 2] = ring[idx + 2];
215 obj[i + 3] = ring[idx + 3];
219 obj[i++] = ring[idx++];
221 obj[i++] = ring[idx++];
223 obj[i++] = ring[idx++];
226 for (i = 0; idx < size; i++, idx++)
229 for (idx = 0; i < n; i++, idx++)
235__rte_ring_dequeue_elems_128(
void *obj_table,
const void *ring_table,
236 uint32_t size, uint32_t idx, uint32_t n)
239 rte_int128_t *obj = (rte_int128_t *)obj_table;
240 const rte_int128_t *ring = (
const rte_int128_t *)ring_table;
242 if (
likely(idx + n <= size)) {
243 for (i = 0; i < (n & ~0x1); i += 2, idx += 2)
244 memcpy((obj + i), (
const void *)(ring + idx), 32);
247 memcpy((obj + i), (
const void *)(ring + idx), 16);
250 for (i = 0; idx < size; i++, idx++)
251 memcpy((obj + i), (
const void *)(ring + idx), 16);
253 for (idx = 0; i < n; i++, idx++)
254 memcpy((obj + i), (
const void *)(ring + idx), 16);
263__rte_ring_do_dequeue_elems(
void *obj_table,
const void *ring_table,
264 uint32_t size, uint32_t idx, uint32_t esize, uint32_t num)
270 __rte_ring_dequeue_elems_64(obj_table, ring_table, size,
272 else if (esize == 16)
273 __rte_ring_dequeue_elems_128(obj_table, ring_table, size,
276 uint32_t scale, nr_idx, nr_num, nr_size;
279 scale = esize /
sizeof(uint32_t);
280 nr_num = num * scale;
281 nr_idx = idx * scale;
282 nr_size = size * scale;
283 __rte_ring_dequeue_elems_32(obj_table, ring_table, nr_size,
289__rte_ring_dequeue_elems(
struct rte_ring *r, uint32_t cons_head,
290 void *obj_table, uint32_t esize, uint32_t num)
292 __rte_ring_do_dequeue_elems(obj_table, &r[1], r->
size,
293 cons_head & r->
mask, esize, num);
298 uint32_t new_val, uint32_t single)
306 rte_memory_order_relaxed);
313 rte_atomic_store_explicit(&ht->tail, new_val, rte_memory_order_release);
322#ifdef RTE_USE_C11_MEM_MODEL
352__rte_ring_move_prod_head(
struct rte_ring *r,
unsigned int is_sp,
354 uint32_t *old_head, uint32_t *new_head,
355 uint32_t *free_entries)
358 return __rte_ring_headtail_move_head_st(&r->prod, &r->cons, r->
capacity,
359 n, behavior, old_head, new_head, free_entries);
361 return __rte_ring_headtail_move_head_mt(&r->prod, &r->cons, r->
capacity,
362 n, behavior, old_head, new_head, free_entries);
389__rte_ring_move_cons_head(
struct rte_ring *r,
unsigned int is_sc,
391 uint32_t *old_head, uint32_t *new_head,
395 return __rte_ring_headtail_move_head_st(&r->cons, &r->prod, 0,
396 n, behavior, old_head, new_head, entries);
398 return __rte_ring_headtail_move_head_mt(&r->cons, &r->prod, 0,
399 n, behavior, old_head, new_head, entries);
427__rte_ring_do_enqueue_elem(
struct rte_ring *r,
const void *obj_table,
428 unsigned int esize,
unsigned int n,
430 unsigned int *free_space)
432 uint32_t prod_head, prod_next;
433 uint32_t free_entries;
435 n = __rte_ring_move_prod_head(r, is_sp, n, behavior,
436 &prod_head, &prod_next, &free_entries);
440 __rte_ring_enqueue_elems(r, prod_head, obj_table, esize, n);
442 __rte_ring_update_tail(&r->prod, prod_head, prod_next, is_sp);
444 if (free_space != NULL)
445 *free_space = free_entries - n;
474__rte_ring_do_dequeue_elem(
struct rte_ring *r,
void *obj_table,
475 unsigned int esize,
unsigned int n,
477 unsigned int *available)
479 uint32_t cons_head, cons_next;
482 n = __rte_ring_move_cons_head(r, (
int)is_sc, n, behavior,
483 &cons_head, &cons_next, &entries);
487 __rte_ring_dequeue_elems(r, cons_head, obj_table, esize, n);
489 __rte_ring_update_tail(&r->cons, cons_head, cons_next, is_sc);
492 if (available != NULL)
493 *available = entries - n;
#define __rte_always_inline
static __rte_always_inline void rte_wait_until_equal_32(volatile uint32_t *addr, uint32_t expected, rte_memory_order memorder)