Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : *
3 : : * Copyright (c) 2017,2018 HXT-semitech Corporation.
4 : : * Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org
5 : : * All rights reserved.
6 : : * Derived from FreeBSD's bufring.h
7 : : * Used as BSD-3 Licensed with permission from Kip Macy.
8 : : */
9 : :
10 : : #ifndef _RTE_RING_ELEM_PVT_H_
11 : : #define _RTE_RING_ELEM_PVT_H_
12 : :
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"
17 : : #endif
18 : :
19 : : static __rte_always_inline void
20 : : __rte_ring_enqueue_elems_32(void *ring_table, const void *obj_table,
21 : : uint32_t size, uint32_t idx, uint32_t n)
22 : : {
23 : : unsigned int i;
24 : :
25 : : uint32_t *ring = (uint32_t *)ring_table;
26 : : const uint32_t *obj = (const uint32_t *)obj_table;
27 : :
28 : 190874840 : if (likely(idx + n <= size)) {
29 [ + + + + : 229134 : for (i = 0; i < (n & ~0x7); i += 8, idx += 8) {
+ + + + -
- - - - -
+ + - - -
- - - - -
- - - - -
- - - - -
- - + + -
- + + + +
+ + + + +
+ - - + +
+ + + + +
+ ]
30 : 194525 : ring[idx] = obj[i];
31 : 194525 : ring[idx + 1] = obj[i + 1];
32 : 194525 : ring[idx + 2] = obj[i + 2];
33 : 194525 : ring[idx + 3] = obj[i + 3];
34 : 194525 : ring[idx + 4] = obj[i + 4];
35 : 194525 : ring[idx + 5] = obj[i + 5];
36 : 194525 : ring[idx + 6] = obj[i + 6];
37 : 194525 : ring[idx + 7] = obj[i + 7];
38 : : }
39 [ - - + - : 34609 : switch (n & 0x7) {
- - - + -
- + - - +
+ + - + -
- + - - +
- - + - -
- - + - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - + - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
+ + + + -
+ + + - -
- - - - -
- + + + +
+ + + + +
- + + + +
+ + + + +
- - + + +
+ + + + +
+ + + - +
+ + + + +
+ - - - -
- - - - +
+ + + + +
+ + - + +
+ + + + +
- + + + -
+ + + - +
+ + + + +
+ ]
40 : 10 : case 7:
41 : 10 : ring[idx++] = obj[i++]; /* fallthrough */
42 : 1063 : case 6:
43 : 1063 : ring[idx++] = obj[i++]; /* fallthrough */
44 : 5219 : case 5:
45 : 5219 : ring[idx++] = obj[i++]; /* fallthrough */
46 : 5229 : case 4:
47 : 5229 : ring[idx++] = obj[i++]; /* fallthrough */
48 : 5240 : case 3:
49 : 5240 : ring[idx++] = obj[i++]; /* fallthrough */
50 : 5317 : case 2:
51 : 5317 : ring[idx++] = obj[i++]; /* fallthrough */
52 : 9478 : case 1:
53 : 190849471 : ring[idx++] = obj[i++]; /* fallthrough */
54 : : }
55 : : } else {
56 [ - - - - : 1277260 : for (i = 0; idx < size; i++, idx++)
- - - - -
- - - - -
- - - - -
- - - - -
- - + + -
- - - - -
- - + + -
- + + + +
+ + + + +
+ - - + +
+ + + + +
+ ]
57 : 1277022 : ring[idx] = obj[i];
58 : : /* Start at the beginning */
59 [ - - - - : 1309420 : for (idx = 0; i < n; i++, idx++)
- - - - -
- - - - -
- - - - -
- - - - -
- - + + -
- - - - -
- - + + -
- + + + +
+ + + + +
+ - - + +
+ + + + +
+ ]
60 : 1309182 : ring[idx] = obj[i];
61 : : }
62 : : }
63 : :
64 : : static __rte_always_inline void
65 : : __rte_ring_enqueue_elems_64(void *ring_table, const void *obj_table,
66 : : uint32_t size, uint32_t idx, uint32_t n)
67 : : {
68 : : unsigned int i;
69 : :
70 : : uint64_t *ring = (uint64_t *)ring_table;
71 : : const unaligned_uint64_t *obj = (const unaligned_uint64_t *)obj_table;
72 : :
73 [ + - + - : 47953456 : if (likely(idx + n <= size)) {
- - - - -
- - - - -
+ - - - -
- - - - -
- - - + -
- - - - -
- - + + -
- + + + +
+ + + + +
+ - - + +
+ + + + +
+ ]
74 [ + + + + : 52532324 : for (i = 0; i < (n & ~0x3); i += 4, idx += 4) {
- + + + -
- - - - -
- - - - +
+ - - - -
- - - + -
- - - - -
- - - - -
- - - - -
- - - - +
+ - - + +
+ + + + +
+ + + - -
+ + + + +
+ + + + +
- - + + +
+ + + + +
+ + - - +
+ + + + +
+ + ]
75 : 4910666 : ring[idx] = obj[i];
76 : 4910666 : ring[idx + 1] = obj[i + 1];
77 : 4910666 : ring[idx + 2] = obj[i + 2];
78 : 4910666 : ring[idx + 3] = obj[i + 3];
79 : : }
80 [ - - + - : 47621658 : switch (n & 0x3) {
- + + + -
- + - + +
+ + - - -
- - - - -
- - - - -
- - - - -
- - - + +
+ - - - -
- - - - -
- - - - +
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - + + +
+ - - - -
- + + + +
+ + + - +
+ + + + +
+ + + + +
- - - - +
+ + + - +
+ + + + +
+ + + + +
+ + + + -
- - - - +
+ + + + +
+ - + + +
+ + + + +
+ + + - -
- - - + +
+ + + + +
+ + + + +
+ + + ]
81 : 80 : case 3:
82 : 80 : ring[idx++] = obj[i++]; /* fallthrough */
83 : 2155772 : case 2:
84 : 2155772 : ring[idx++] = obj[i++]; /* fallthrough */
85 : 47486148 : case 1:
86 : 47754038 : ring[idx++] = obj[i++];
87 : : }
88 : : } else {
89 [ - - + + : 815632 : for (i = 0; idx < size; i++, idx++)
- - + + -
- - - - -
+ + - - +
+ - - - -
- - + + -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - + +
- - - - -
- - - + +
- - + + +
+ + + + +
+ + - - +
+ + + + +
+ + + + -
- + + + +
+ + + + +
+ - - + +
+ + + + +
+ ]
90 : 744836 : ring[idx] = obj[i];
91 : : /* Start at the beginning */
92 [ - - + + : 869188 : for (idx = 0; i < n; i++, idx++)
- - + + -
- - - - -
+ + - - +
+ - - - -
- - + + -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - + +
- - - - -
- - - + +
- - + + +
+ + + + +
+ + - - +
+ + + + +
+ + + + -
- + + + +
+ + + + +
+ - - + +
+ + + + +
+ ]
93 : 798392 : ring[idx] = obj[i];
94 : : }
95 : : }
96 : :
97 : : static __rte_always_inline void
98 : : __rte_ring_enqueue_elems_128(void *ring_table, const void *obj_table,
99 : : uint32_t size, uint32_t idx, uint32_t n)
100 : : {
101 : : unsigned int i;
102 : :
103 : : rte_int128_t *ring = (rte_int128_t *)ring_table;
104 : : const rte_int128_t *obj = (const rte_int128_t *)obj_table;
105 : :
106 [ - - + - : 29910 : if (likely(idx + n <= size)) {
+ - - - -
- - - - -
+ - - - -
- - - - -
- - - + -
- - - - -
- - + + -
- + + + +
+ + + + +
+ - - + +
+ + + + +
+ ]
107 [ - - + + : 96712 : for (i = 0; i < (n & ~0x1); i += 2, idx += 2)
- - - - -
- + + - -
- - - - -
- - - - -
+ + - + +
+ + + + +
+ + + + -
- + + + +
+ + + + ]
108 : 71073 : memcpy((void *)(ring + idx),
109 : 71073 : (const void *)(obj + i), 32);
110 [ - - + + : 25639 : switch (n & 0x1) {
- - - - -
- + + - -
- - - - -
- - - - -
+ + + - +
+ + + + +
+ + + + -
- + + + +
+ + + + ]
111 : 23030 : case 1:
112 : 27138 : memcpy((void *)(ring + idx),
113 : 23030 : (const void *)(obj + i), 16);
114 : : }
115 : : } else {
116 [ - - - - : 225407 : for (i = 0; idx < size; i++, idx++)
- - - - -
- - - - -
- - - - -
- - - - -
- - + + -
- - - - -
- - + + -
- + + + +
+ + + + +
+ - - + +
+ + + + +
+ ]
117 : 225290 : memcpy((void *)(ring + idx),
118 : 225290 : (const void *)(obj + i), 16);
119 : : /* Start at the beginning */
120 [ - - - - : 209315 : for (idx = 0; i < n; i++, idx++)
- - - - -
- - - - -
- - - - -
- - - - -
- - + + -
- - - - -
- - + + -
- + + + +
+ + + + +
+ - - + +
+ + + + +
+ ]
121 : 209198 : memcpy((void *)(ring + idx),
122 : 209198 : (const void *)(obj + i), 16);
123 : : }
124 : : }
125 : :
126 : : /* the actual enqueue of elements on the ring.
127 : : * Placed here since identical code needed in both
128 : : * single and multi producer enqueue functions.
129 : : */
130 : : static __rte_always_inline void
131 : : __rte_ring_do_enqueue_elems(void *ring_table, const void *obj_table,
132 : : uint32_t size, uint32_t idx, uint32_t esize, uint32_t num)
133 : : {
134 : : /* 8B and 16B copies implemented individually to retain
135 : : * the current performance.
136 : : */
137 [ + + - + : 48657 : if (esize == 8)
- + - + -
- ]
138 : : __rte_ring_enqueue_elems_64(ring_table, obj_table, size,
139 : : idx, num);
140 [ - + + + : 41763 : else if (esize == 16)
+ + - + -
- - - - -
+ + - - -
- - - - -
- - + + -
- - - - -
- - + + -
- + + + +
+ + + + +
+ - - + +
+ + + + +
+ ]
141 : : __rte_ring_enqueue_elems_128(ring_table, obj_table, size,
142 : : idx, num);
143 : : else {
144 : : uint32_t scale, nr_idx, nr_num, nr_size;
145 : :
146 : : /* Normalize to uint32_t */
147 : 34847 : scale = esize / sizeof(uint32_t);
148 : 25530 : nr_num = num * scale;
149 : 34847 : nr_idx = idx * scale;
150 [ + - + - : 34847 : nr_size = size * scale;
+ - + - -
- - - - -
+ - - - -
- - - - -
- - - + -
- - - - -
- - + + -
- + + + +
+ + + + +
+ - - + +
+ + + + +
+ ]
151 : : __rte_ring_enqueue_elems_32(ring_table, obj_table, nr_size,
152 : : nr_idx, nr_num);
153 : : }
154 : : }
155 : :
156 : : static __rte_always_inline void
157 : : __rte_ring_enqueue_elems(struct rte_ring *r, uint32_t prod_head,
158 : : const void *obj_table, uint32_t esize, uint32_t num)
159 : : {
160 : 238845082 : __rte_ring_do_enqueue_elems(&r[1], obj_table, r->size,
161 [ + - + + : 238845082 : prod_head & r->mask, esize, num);
+ + + + +
- + - + -
+ + + - +
+ - - - -
- - + + -
- - - - -
+ - - - +
+ - - + -
- - - - -
- + + - -
- - - - -
- - - + +
- - - - -
- - - + +
- - + + +
+ + + + +
+ + - - +
+ + + + +
+ + + + -
- + + + +
+ + + + +
+ - - + +
+ + + + +
+ ]
162 : : }
163 : :
164 : : static __rte_always_inline void
165 : : __rte_ring_dequeue_elems_32(void *obj_table, const void *ring_table,
166 : : uint32_t size, uint32_t idx, uint32_t n)
167 : : {
168 : : unsigned int i;
169 : : uint32_t *obj = (uint32_t *)obj_table;
170 : : const uint32_t *ring = (const uint32_t *)ring_table;
171 : :
172 : 438181 : if (likely(idx + n <= size)) {
173 [ + + + + : 230105 : for (i = 0; i < (n & ~0x7); i += 8, idx += 8) {
+ + + + -
- + + + +
+ + - - -
- - - - -
- - + + -
- - - - -
- - + + -
- + + + +
+ + + + +
+ - - + +
+ + + + +
+ ]
174 : 194585 : obj[i] = ring[idx];
175 : 194585 : obj[i + 1] = ring[idx + 1];
176 : 194585 : obj[i + 2] = ring[idx + 2];
177 : 194585 : obj[i + 3] = ring[idx + 3];
178 : 194585 : obj[i + 4] = ring[idx + 4];
179 : 194585 : obj[i + 5] = ring[idx + 5];
180 : 194585 : obj[i + 6] = ring[idx + 6];
181 : 194585 : obj[i + 7] = ring[idx + 7];
182 : : }
183 [ - + - - : 35520 : switch (n & 0x7) {
+ + - + -
- + - - +
+ + - - +
- - + - -
- - + - -
+ - - - -
- - - - -
- - - - -
- - - + -
- - - - -
- + - - -
- - + - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - + - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
+ + + + -
+ + + - -
- - - - -
- + + + +
+ + + + +
- + + + +
+ + + + +
- - + + +
+ + + + +
+ + + - +
+ + + + +
+ - - - -
- - - - +
+ + + + +
+ + - + +
+ + + + +
- + + + -
+ + + - +
+ + + + +
+ ]
184 : 10 : case 7:
185 : 10 : obj[i++] = ring[idx++]; /* fallthrough */
186 : 2019 : case 6:
187 : 2019 : obj[i++] = ring[idx++]; /* fallthrough */
188 : 6144 : case 5:
189 : 6144 : obj[i++] = ring[idx++]; /* fallthrough */
190 : 6154 : case 4:
191 : 6154 : obj[i++] = ring[idx++]; /* fallthrough */
192 : 6166 : case 3:
193 : 6166 : obj[i++] = ring[idx++]; /* fallthrough */
194 : 6256 : case 2:
195 : 6256 : obj[i++] = ring[idx++]; /* fallthrough */
196 : 10386 : case 1:
197 : 412809 : obj[i++] = ring[idx++]; /* fallthrough */
198 : : }
199 : : } else {
200 [ - - - - : 1277260 : for (i = 0; idx < size; i++, idx++)
- - - - -
- - - - -
- - - - -
- - - - -
- - + + -
- - - - -
- - + + -
- + + + +
+ + + + +
+ - - + +
+ + + + +
+ # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# ]
201 : 1277022 : obj[i] = ring[idx];
202 : : /* Start at the beginning */
203 [ - - - - : 1309420 : for (idx = 0; i < n; i++, idx++)
- - - - -
- - - - -
- - - - -
- - - - -
- - + + -
- - - - -
- - + + -
- + + + +
+ + + + +
+ - - + +
+ + + + +
+ # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# ]
204 : 1309182 : obj[i] = ring[idx];
205 : : }
206 : : }
207 : :
208 : : static __rte_always_inline void
209 : : __rte_ring_dequeue_elems_64(void *obj_table, const void *ring_table,
210 : : uint32_t size, uint32_t idx, uint32_t n)
211 : : {
212 : : unsigned int i;
213 : : unaligned_uint64_t *obj = (unaligned_uint64_t *)obj_table;
214 : : const uint64_t *ring = (const uint64_t *)ring_table;
215 : :
216 [ + - + - : 47883437 : if (likely(idx + n <= size)) {
- - - - -
- - - - -
+ - - - -
- - - - -
- - + + -
- - - - -
- - + + -
- + + + +
+ + + + +
+ - - + +
+ + + + +
+ ]
217 [ + + + + : 52468079 : for (i = 0; i < (n & ~0x3); i += 4, idx += 4) {
- + + + -
- - - - -
+ + - - -
- - - - -
- - - + -
- - - - -
- - - - +
+ - - - -
- - - - +
+ - - + +
+ + + + +
+ + + - -
+ + + + +
+ + + + +
- - + + +
+ + + + +
+ + - - +
+ + + + +
+ + ]
218 : 4914326 : obj[i] = ring[idx];
219 : 4914326 : obj[i + 1] = ring[idx + 1];
220 : 4914326 : obj[i + 2] = ring[idx + 2];
221 : 4914326 : obj[i + 3] = ring[idx + 3];
222 : : }
223 [ - + + + : 47553753 : switch (n & 0x3) {
- + + + -
- + - + +
+ + - - -
- - - - -
- - - - -
+ - + - -
- - - - -
- - - - -
- - - - -
- - - - +
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
+ - - - -
- - - - -
- - - - -
- - + + +
+ - - - -
- + + + +
+ + + - +
+ + + + +
+ + + + +
- - - - +
+ + + - +
+ + + + +
+ + + + +
+ + + + -
- - - - +
+ + + + +
+ - + + +
+ + + + +
+ + + - -
- - - + +
+ + + + +
+ + + + +
+ + + ]
224 : 23 : case 3:
225 : 23 : obj[i++] = ring[idx++]; /* fallthrough */
226 : 2155677 : case 2:
227 : 2155677 : obj[i++] = ring[idx++]; /* fallthrough */
228 : 47482841 : case 1:
229 : 47749607 : obj[i++] = ring[idx++]; /* fallthrough */
230 : : }
231 : : } else {
232 [ - - + + : 813761 : for (i = 0; idx < size; i++, idx++)
+ + + + -
- - - - -
- - - - -
- - - - -
- - + + -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - + +
- - - - -
- - - + +
- - + + +
+ + + + +
+ + - - +
+ + + + +
+ + + + -
- + + + +
+ + + + +
+ - - + +
+ + + + +
+ ]
233 : 743985 : obj[i] = ring[idx];
234 : : /* Start at the beginning */
235 [ - - + + : 851911 : for (idx = 0; i < n; i++, idx++)
+ + + + -
- - - - -
- - - - -
- - - - -
- - + + -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - + +
- - - - -
- - - + +
- - + + +
+ + + + +
+ + - - +
+ + + + +
+ + + + -
- + + + +
+ + + + +
+ - - + +
+ + + + +
+ ]
236 : 782135 : obj[i] = ring[idx];
237 : : }
238 : : }
239 : :
240 : : static __rte_always_inline void
241 : : __rte_ring_dequeue_elems_128(void *obj_table, const void *ring_table,
242 : : uint32_t size, uint32_t idx, uint32_t n)
243 : : {
244 : : unsigned int i;
245 : : rte_int128_t *obj = (rte_int128_t *)obj_table;
246 : : const rte_int128_t *ring = (const rte_int128_t *)ring_table;
247 : :
248 [ + - + - : 29657 : if (likely(idx + n <= size)) {
- - - - -
- - - - -
+ - - - -
- - - - -
- - + + -
- - - - -
- - + + -
- + + + +
+ + + + +
+ - - + +
+ + + + +
+ ]
249 [ - - + + : 96603 : for (i = 0; i < (n & ~0x1); i += 2, idx += 2)
- - - - -
- + + - -
+ + - - +
+ - - - -
+ + + + +
+ + + + +
+ + + + -
- + + + +
+ + + + ]
250 : 71194 : memcpy((obj + i), (const void *)(ring + idx), 32);
251 [ - - + + : 25409 : switch (n & 0x1) {
- - - - -
- + + - -
- + - - +
+ - - - -
+ + + + +
+ + + + +
+ + + + -
- + + + +
+ + + + ]
252 : 22789 : case 1:
253 : 26920 : memcpy((obj + i), (const void *)(ring + idx), 16);
254 : : }
255 : : } else {
256 [ - - - - : 225407 : for (i = 0; idx < size; i++, idx++)
- - - - -
- - - - -
- - - - -
- - - - -
- - + + -
- - - - -
- - + + -
- + + + +
+ + + + +
+ - - + +
+ + + + +
+ ]
257 : 225290 : memcpy((obj + i), (const void *)(ring + idx), 16);
258 : : /* Start at the beginning */
259 [ - - - - : 209315 : for (idx = 0; i < n; i++, idx++)
- - - - -
- - - - -
- - - - -
- - - - -
- - + + -
- - - - -
- - + + -
- + + + +
+ + + + +
+ - - + +
+ + + + +
+ ]
260 : 209198 : memcpy((obj + i), (const void *)(ring + idx), 16);
261 : : }
262 : : }
263 : :
264 : : /* the actual dequeue of elements from the ring.
265 : : * Placed here since identical code needed in both
266 : : * single and multi producer enqueue functions.
267 : : */
268 : : static __rte_always_inline void
269 : : __rte_ring_do_dequeue_elems(void *obj_table, const void *ring_table,
270 : : uint32_t size, uint32_t idx, uint32_t esize, uint32_t num)
271 : : {
272 : : /* 8B and 16B copies implemented individually to retain
273 : : * the current performance.
274 : : */
275 [ + + - + : 49519 : if (esize == 8)
- + - + -
- - + - +
+ - ]
276 : : __rte_ring_dequeue_elems_64(obj_table, ring_table, size,
277 : : idx, num);
278 [ + + + + : 42651 : else if (esize == 16)
- + - + -
- - + - +
+ + - - -
- - - - -
- - + + -
- - - - -
- - + + -
- + + + +
+ + + + +
+ - - + +
+ + + + +
+ ]
279 : : __rte_ring_dequeue_elems_128(obj_table, ring_table, size,
280 : : idx, num);
281 : : else {
282 : : uint32_t scale, nr_idx, nr_num, nr_size;
283 : :
284 : : /* Normalize to uint32_t */
285 : 35757 : scale = esize / sizeof(uint32_t);
286 : 27567 : nr_num = num * scale;
287 : 35757 : nr_idx = idx * scale;
288 [ + - + - : 35757 : nr_size = size * scale;
+ - + - -
- + - + -
+ - - - -
- - - - -
- - + + -
- - - - -
- - + + -
- + + + +
+ + + + +
+ - - + +
+ + + + +
+ ]
289 : : __rte_ring_dequeue_elems_32(obj_table, ring_table, nr_size,
290 : : nr_idx, nr_num);
291 : : }
292 : : }
293 : :
294 : : static __rte_always_inline void
295 : : __rte_ring_dequeue_elems(struct rte_ring *r, uint32_t cons_head,
296 : : void *obj_table, uint32_t esize, uint32_t num)
297 : : {
298 : 48338113 : __rte_ring_do_dequeue_elems(obj_table, &r[1], r->size,
299 [ + + + + : 48338113 : cons_head & r->mask, esize, num);
+ + + + -
- + - - -
+ - - - +
- - - - -
- - + + -
- - - - -
- - - - +
+ - - - -
- - - - -
- + + - -
- - - - -
- - - + +
- - - - -
- - - + +
- - + + +
+ + + + +
+ + - - +
+ + + + +
+ + + + -
- + + + +
+ + + + +
+ - - + +
+ + + + +
+ # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # #
# ]
300 : : }
301 : :
302 : : static __rte_always_inline void
303 : : __rte_ring_update_tail(struct rte_ring_headtail *ht, uint32_t old_val,
304 : : uint32_t new_val, uint32_t single)
305 : : {
306 : : /*
307 : : * If there are other enqueues/dequeues in progress that preceded us,
308 : : * we need to wait for them to complete
309 : : */
310 [ + - + - ]: 9 : if (!single)
311 : 90619456 : rte_wait_until_equal_32((uint32_t *)(uintptr_t)&ht->tail, old_val,
312 : : rte_memory_order_relaxed);
313 : :
314 : : /*
315 : : * R0: Establishes a synchronizing edge with load-acquire of tail at A1.
316 : : * Ensures that memory effects by this thread on ring elements array
317 : : * is observed by a different thread of the other type.
318 : : */
319 [ - + ]: 196800634 : rte_atomic_store_explicit(&ht->tail, new_val, rte_memory_order_release);
320 : 94872662 : }
321 : :
322 : : /*
323 : : * The function __rte_ring_headtail_move_head_mt,st has two versions
324 : : * based on what is most efficient on a given architecture.
325 : : *
326 : : * The C11 is preferred but on x86 GCC has 10% performance drop.
327 : : */
328 : : #ifdef RTE_USE_C11_MEM_MODEL
329 : : #include "rte_ring_c11_pvt.h"
330 : : #else
331 : : #include "rte_ring_gcc_pvt.h"
332 : : #endif
333 : :
334 : : /**
335 : : * @internal This function updates the producer head for enqueue
336 : : *
337 : : * @param r
338 : : * A pointer to the ring structure
339 : : * @param is_sp
340 : : * Indicates whether multi-producer path is needed or not
341 : : * @param n
342 : : * The number of elements we will want to enqueue, i.e. how far should the
343 : : * head be moved
344 : : * @param behavior
345 : : * RTE_RING_QUEUE_FIXED: Enqueue a fixed number of items from a ring
346 : : * RTE_RING_QUEUE_VARIABLE: Enqueue as many items as possible from ring
347 : : * @param old_head
348 : : * Returns head value as it was before the move, i.e. where enqueue starts
349 : : * @param new_head
350 : : * Returns the current/new head value i.e. where enqueue finishes
351 : : * @param free_entries
352 : : * Returns the amount of free space in the ring BEFORE head was moved
353 : : * @return
354 : : * Actual number of objects enqueued.
355 : : * If behavior == RTE_RING_QUEUE_FIXED, this will be 0 or n only.
356 : : */
357 : : static __rte_always_inline unsigned int
358 : : __rte_ring_move_prod_head(struct rte_ring *r, unsigned int is_sp,
359 : : unsigned int n, enum rte_ring_queue_behavior behavior,
360 : : uint32_t *old_head, uint32_t *new_head,
361 : : uint32_t *free_entries)
362 : : {
363 : : if (is_sp)
364 : 193622829 : return __rte_ring_headtail_move_head_st(&r->prod, &r->cons, r->capacity,
365 : : n, behavior, old_head, new_head, free_entries);
366 : : else
367 : 45218491 : return __rte_ring_headtail_move_head_mt(&r->prod, &r->cons, r->capacity,
368 : : n, behavior, old_head, new_head, free_entries);
369 : : }
370 : :
371 : : /**
372 : : * @internal This function updates the consumer head for dequeue
373 : : *
374 : : * @param r
375 : : * A pointer to the ring structure
376 : : * @param is_sc
377 : : * Indicates whether multi-consumer path is needed or not
378 : : * @param n
379 : : * The number of elements we will want to dequeue, i.e. how far should the
380 : : * head be moved
381 : : * @param behavior
382 : : * RTE_RING_QUEUE_FIXED: Dequeue a fixed number of items from a ring
383 : : * RTE_RING_QUEUE_VARIABLE: Dequeue as many items as possible from ring
384 : : * @param old_head
385 : : * Returns head value as it was before the move, i.e. where dequeue starts
386 : : * @param new_head
387 : : * Returns the current/new head value i.e. where dequeue finishes
388 : : * @param entries
389 : : * Returns the number of entries in the ring BEFORE head was moved
390 : : * @return
391 : : * - Actual number of objects dequeued.
392 : : * If behavior == RTE_RING_QUEUE_FIXED, this will be 0 or n only.
393 : : */
394 : : static __rte_always_inline unsigned int
395 : : __rte_ring_move_cons_head(struct rte_ring *r, unsigned int is_sc,
396 : : unsigned int n, enum rte_ring_queue_behavior behavior,
397 : : uint32_t *old_head, uint32_t *new_head,
398 : : uint32_t *entries)
399 : : {
400 : : if (is_sc)
401 : : return __rte_ring_headtail_move_head_st(&r->cons, &r->prod, 0,
402 : : n, behavior, old_head, new_head, entries);
403 : : else
404 : : return __rte_ring_headtail_move_head_mt(&r->cons, &r->prod, 0,
405 : : n, behavior, old_head, new_head, entries);
406 : : }
407 : :
408 : : /**
409 : : * @internal Enqueue several objects on the ring
410 : : *
411 : : * @param r
412 : : * A pointer to the ring structure.
413 : : * @param obj_table
414 : : * A pointer to a table of objects.
415 : : * @param esize
416 : : * The size of ring element, in bytes. It must be a multiple of 4.
417 : : * This must be the same value used while creating the ring. Otherwise
418 : : * the results are undefined.
419 : : * @param n
420 : : * The number of objects to add in the ring from the obj_table.
421 : : * @param behavior
422 : : * RTE_RING_QUEUE_FIXED: Enqueue a fixed number of items from a ring
423 : : * RTE_RING_QUEUE_VARIABLE: Enqueue as many items as possible from ring
424 : : * @param is_sp
425 : : * Indicates whether to use single producer or multi-producer head update
426 : : * @param free_space
427 : : * returns the amount of space after the enqueue operation has finished
428 : : * @return
429 : : * Actual number of objects enqueued.
430 : : * If behavior == RTE_RING_QUEUE_FIXED, this will be 0 or n only.
431 : : */
432 : : static __rte_always_inline unsigned int
433 : : __rte_ring_do_enqueue_elem(struct rte_ring *r, const void *obj_table,
434 : : unsigned int esize, unsigned int n,
435 : : enum rte_ring_queue_behavior behavior, unsigned int is_sp,
436 : : unsigned int *free_space)
437 : : {
438 : : uint32_t prod_head, prod_next;
439 : : uint32_t free_entries;
440 : :
441 : : n = __rte_ring_move_prod_head(r, is_sp, n, behavior,
442 : : &prod_head, &prod_next, &free_entries);
443 [ - + - - : 45218491 : if (n == 0)
- - - - -
- - - - -
- - - - -
- - - - -
+ + + + +
+ + + + +
+ + + + +
+ ]
444 : 43 : goto end;
445 : :
446 : : __rte_ring_enqueue_elems(r, prod_head, obj_table, esize, n);
447 : :
448 : : __rte_ring_update_tail(&r->prod, prod_head, prod_next, is_sp);
449 [ + - # # : 45235949 : end:
# # # # ]
450 [ - + - - : 8310 : if (free_space != NULL)
- + - + -
+ - - - +
- + - + -
- - + - +
- + - - -
+ - + ]
451 : 9297 : *free_space = free_entries - n;
452 : : return n;
453 : : }
454 : :
455 : : /**
456 : : * @internal Dequeue several objects from the ring
457 : : *
458 : : * @param r
459 : : * A pointer to the ring structure.
460 : : * @param obj_table
461 : : * A pointer to a table of objects.
462 : : * @param esize
463 : : * The size of ring element, in bytes. It must be a multiple of 4.
464 : : * This must be the same value used while creating the ring. Otherwise
465 : : * the results are undefined.
466 : : * @param n
467 : : * The number of objects to pull from the ring.
468 : : * @param behavior
469 : : * RTE_RING_QUEUE_FIXED: Dequeue a fixed number of items from a ring
470 : : * RTE_RING_QUEUE_VARIABLE: Dequeue as many items as possible from ring
471 : : * @param is_sc
472 : : * Indicates whether to use single consumer or multi-consumer head update
473 : : * @param available
474 : : * returns the number of remaining ring entries after the dequeue has finished
475 : : * @return
476 : : * - Actual number of objects dequeued.
477 : : * If behavior == RTE_RING_QUEUE_FIXED, this will be 0 or n only.
478 : : */
479 : : static __rte_always_inline unsigned int
480 : : __rte_ring_do_dequeue_elem(struct rte_ring *r, void *obj_table,
481 : : unsigned int esize, unsigned int n,
482 : : enum rte_ring_queue_behavior behavior, unsigned int is_sc,
483 : : unsigned int *available)
484 : : {
485 : : uint32_t cons_head, cons_next;
486 : : uint32_t entries;
487 : :
488 : : n = __rte_ring_move_cons_head(r, (int)is_sc, n, behavior,
489 : : &cons_head, &cons_next, &entries);
490 [ + + - - : 45432243 : if (n == 0)
- - - - -
- - - - -
- - - - -
- - - - -
- + - + -
+ - + - +
- + - + -
+ # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
491 : 16834483 : goto end;
492 : :
493 : : __rte_ring_dequeue_elems(r, cons_head, obj_table, esize, n);
494 : :
495 : : __rte_ring_update_tail(&r->cons, cons_head, cons_next, is_sc);
496 : :
497 [ + + + - : 49347342 : end:
+ - + - ]
498 [ - + - - : 8280 : if (available != NULL)
- + - + -
+ - - - +
- + - + -
- - + - +
- + - - -
+ - + ]
499 : 2 : *available = entries - n;
500 : : return n;
501 : : }
502 : :
503 : : #if defined(RTE_TOOLCHAIN_GCC) && (GCC_VERSION >= 120000)
504 : : #pragma GCC diagnostic pop
505 : : #endif
506 : :
507 : : #endif /* _RTE_RING_ELEM_PVT_H_ */
|