10#ifndef _RTE_RING_ELEM_PVT_H_
11#define _RTE_RING_ELEM_PVT_H_
13#if defined(RTE_TOOLCHAIN_GCC) && (GCC_VERSION >= 120000)
14#pragma GCC diagnostic push
15#pragma GCC diagnostic ignored "-Wstringop-overflow"
16#pragma GCC diagnostic ignored "-Wstringop-overread"
20__rte_ring_enqueue_elems_32(
struct rte_ring *r,
const uint32_t size,
21 uint32_t idx,
const void *obj_table, uint32_t n)
24 uint32_t *ring = (uint32_t *)&r[1];
25 const uint32_t *obj = (
const uint32_t *)obj_table;
26 if (
likely(idx + n <= size)) {
27 for (i = 0; i < (n & ~0x7); i += 8, idx += 8) {
29 ring[idx + 1] = obj[i + 1];
30 ring[idx + 2] = obj[i + 2];
31 ring[idx + 3] = obj[i + 3];
32 ring[idx + 4] = obj[i + 4];
33 ring[idx + 5] = obj[i + 5];
34 ring[idx + 6] = obj[i + 6];
35 ring[idx + 7] = obj[i + 7];
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++];
49 ring[idx++] = obj[i++];
51 ring[idx++] = obj[i++];
54 for (i = 0; idx < size; i++, idx++)
57 for (idx = 0; i < n; i++, idx++)
63__rte_ring_enqueue_elems_64(
struct rte_ring *r, uint32_t prod_head,
64 const void *obj_table, uint32_t n)
67 const uint32_t size = r->
size;
68 uint32_t idx = prod_head & r->
mask;
69 uint64_t *ring = (uint64_t *)&r[1];
70 const unaligned_uint64_t *obj = (
const unaligned_uint64_t *)obj_table;
71 if (
likely(idx + n <= size)) {
72 for (i = 0; i < (n & ~0x3); i += 4, idx += 4) {
74 ring[idx + 1] = obj[i + 1];
75 ring[idx + 2] = obj[i + 2];
76 ring[idx + 3] = obj[i + 3];
80 ring[idx++] = obj[i++];
82 ring[idx++] = obj[i++];
84 ring[idx++] = obj[i++];
87 for (i = 0; idx < size; i++, idx++)
90 for (idx = 0; i < n; i++, idx++)
96__rte_ring_enqueue_elems_128(
struct rte_ring *r, uint32_t prod_head,
97 const void *obj_table, uint32_t n)
100 const uint32_t size = r->
size;
101 uint32_t idx = prod_head & r->
mask;
102 rte_int128_t *ring = (rte_int128_t *)&r[1];
103 const rte_int128_t *obj = (
const rte_int128_t *)obj_table;
104 if (
likely(idx + n <= size)) {
105 for (i = 0; i < (n & ~0x1); i += 2, idx += 2)
106 memcpy((
void *)(ring + idx),
107 (
const void *)(obj + i), 32);
110 memcpy((
void *)(ring + idx),
111 (
const void *)(obj + i), 16);
114 for (i = 0; idx < size; i++, idx++)
115 memcpy((
void *)(ring + idx),
116 (
const void *)(obj + i), 16);
118 for (idx = 0; i < n; i++, idx++)
119 memcpy((
void *)(ring + idx),
120 (
const void *)(obj + i), 16);
129__rte_ring_enqueue_elems(
struct rte_ring *r, uint32_t prod_head,
130 const void *obj_table, uint32_t esize, uint32_t num)
136 __rte_ring_enqueue_elems_64(r, prod_head, obj_table, num);
137 else if (esize == 16)
138 __rte_ring_enqueue_elems_128(r, prod_head, obj_table, num);
140 uint32_t idx, scale, nr_idx, nr_num, nr_size;
143 scale = esize /
sizeof(uint32_t);
144 nr_num = num * scale;
145 idx = prod_head & r->
mask;
146 nr_idx = idx * scale;
147 nr_size = r->
size * scale;
148 __rte_ring_enqueue_elems_32(r, nr_size, nr_idx,
154__rte_ring_dequeue_elems_32(
struct rte_ring *r,
const uint32_t size,
155 uint32_t idx,
void *obj_table, uint32_t n)
158 uint32_t *ring = (uint32_t *)&r[1];
159 uint32_t *obj = (uint32_t *)obj_table;
160 if (
likely(idx + n <= size)) {
161 for (i = 0; i < (n & ~0x7); i += 8, idx += 8) {
163 obj[i + 1] = ring[idx + 1];
164 obj[i + 2] = ring[idx + 2];
165 obj[i + 3] = ring[idx + 3];
166 obj[i + 4] = ring[idx + 4];
167 obj[i + 5] = ring[idx + 5];
168 obj[i + 6] = ring[idx + 6];
169 obj[i + 7] = ring[idx + 7];
173 obj[i++] = ring[idx++];
175 obj[i++] = ring[idx++];
177 obj[i++] = ring[idx++];
179 obj[i++] = ring[idx++];
181 obj[i++] = ring[idx++];
183 obj[i++] = ring[idx++];
185 obj[i++] = ring[idx++];
188 for (i = 0; idx < size; i++, idx++)
191 for (idx = 0; i < n; i++, idx++)
197__rte_ring_dequeue_elems_64(
struct rte_ring *r, uint32_t cons_head,
198 void *obj_table, uint32_t n)
201 const uint32_t size = r->
size;
202 uint32_t idx = cons_head & r->
mask;
203 uint64_t *ring = (uint64_t *)&r[1];
204 unaligned_uint64_t *obj = (unaligned_uint64_t *)obj_table;
205 if (
likely(idx + n <= size)) {
206 for (i = 0; i < (n & ~0x3); i += 4, idx += 4) {
208 obj[i + 1] = ring[idx + 1];
209 obj[i + 2] = ring[idx + 2];
210 obj[i + 3] = ring[idx + 3];
214 obj[i++] = ring[idx++];
216 obj[i++] = ring[idx++];
218 obj[i++] = ring[idx++];
221 for (i = 0; idx < size; i++, idx++)
224 for (idx = 0; i < n; i++, idx++)
230__rte_ring_dequeue_elems_128(
struct rte_ring *r, uint32_t cons_head,
231 void *obj_table, uint32_t n)
234 const uint32_t size = r->
size;
235 uint32_t idx = cons_head & r->
mask;
236 rte_int128_t *ring = (rte_int128_t *)&r[1];
237 rte_int128_t *obj = (rte_int128_t *)obj_table;
238 if (
likely(idx + n <= size)) {
239 for (i = 0; i < (n & ~0x1); i += 2, idx += 2)
240 memcpy((
void *)(obj + i), (
void *)(ring + idx), 32);
243 memcpy((
void *)(obj + i), (
void *)(ring + idx), 16);
246 for (i = 0; idx < size; i++, idx++)
247 memcpy((
void *)(obj + i), (
void *)(ring + idx), 16);
249 for (idx = 0; i < n; i++, idx++)
250 memcpy((
void *)(obj + i), (
void *)(ring + idx), 16);
259__rte_ring_dequeue_elems(
struct rte_ring *r, uint32_t cons_head,
260 void *obj_table, uint32_t esize, uint32_t num)
266 __rte_ring_dequeue_elems_64(r, cons_head, obj_table, num);
267 else if (esize == 16)
268 __rte_ring_dequeue_elems_128(r, cons_head, obj_table, num);
270 uint32_t idx, scale, nr_idx, nr_num, nr_size;
273 scale = esize /
sizeof(uint32_t);
274 nr_num = num * scale;
275 idx = cons_head & r->
mask;
276 nr_idx = idx * scale;
277 nr_size = r->
size * scale;
278 __rte_ring_dequeue_elems_32(r, nr_size, nr_idx,
290#ifdef RTE_USE_C11_MEM_MODEL
291#include "rte_ring_c11_pvt.h"
293#include "rte_ring_generic_pvt.h"
321__rte_ring_do_enqueue_elem(
struct rte_ring *r,
const void *obj_table,
322 unsigned int esize,
unsigned int n,
324 unsigned int *free_space)
326 uint32_t prod_head, prod_next;
327 uint32_t free_entries;
329 n = __rte_ring_move_prod_head(r, is_sp, n, behavior,
330 &prod_head, &prod_next, &free_entries);
334 __rte_ring_enqueue_elems(r, prod_head, obj_table, esize, n);
336 __rte_ring_update_tail(&r->prod, prod_head, prod_next, is_sp, 1);
338 if (free_space != NULL)
339 *free_space = free_entries - n;
368__rte_ring_do_dequeue_elem(
struct rte_ring *r,
void *obj_table,
369 unsigned int esize,
unsigned int n,
371 unsigned int *available)
373 uint32_t cons_head, cons_next;
376 n = __rte_ring_move_cons_head(r, (
int)is_sc, n, behavior,
377 &cons_head, &cons_next, &entries);
381 __rte_ring_dequeue_elems(r, cons_head, obj_table, esize, n);
383 __rte_ring_update_tail(&r->cons, cons_head, cons_next, is_sc, 0);
386 if (available != NULL)
387 *available = entries - n;
391#if defined(RTE_TOOLCHAIN_GCC) && (GCC_VERSION >= 120000)
392#pragma GCC diagnostic pop
#define __rte_always_inline