Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : *
3 : : * Copyright (c) 2019 Arm Limited
4 : : * Copyright (c) 2010-2017 Intel Corporation
5 : : * Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org
6 : : * All rights reserved.
7 : : * Derived from FreeBSD's bufring.h
8 : : * Used as BSD-3 Licensed with permission from Kip Macy.
9 : : */
10 : :
11 : : #ifndef _RTE_RING_ELEM_H_
12 : : #define _RTE_RING_ELEM_H_
13 : :
14 : : /**
15 : : * @file
16 : : * RTE Ring with user defined element size
17 : : */
18 : :
19 : : #ifdef __cplusplus
20 : : extern "C" {
21 : : #endif
22 : :
23 : : #include <rte_ring_core.h>
24 : : #include <rte_ring_elem_pvt.h>
25 : :
26 : : /**
27 : : * Calculate the memory size needed for a ring with given element size
28 : : *
29 : : * This function returns the number of bytes needed for a ring, given
30 : : * the number of elements in it and the size of the element. This value
31 : : * is the sum of the size of the structure rte_ring and the size of the
32 : : * memory needed for storing the elements. The value is aligned to a cache
33 : : * line size.
34 : : *
35 : : * @param esize
36 : : * The size of ring element, in bytes. It must be a multiple of 4.
37 : : * @param count
38 : : * The number of elements in the ring (must be a power of 2).
39 : : * @return
40 : : * - The memory size needed for the ring on success.
41 : : * - -EINVAL - esize is not a multiple of 4 or count provided is not a
42 : : * power of 2.
43 : : */
44 : : ssize_t rte_ring_get_memsize_elem(unsigned int esize, unsigned int count);
45 : :
46 : : /**
47 : : * Create a new ring named *name* that stores elements with given size.
48 : : *
49 : : * This function uses ``memzone_reserve()`` to allocate memory. Then it
50 : : * calls rte_ring_init() to initialize an empty ring.
51 : : *
52 : : * The new ring size is set to *count*, which must be a power of
53 : : * two. Water marking is disabled by default. The real usable ring size
54 : : * is *count-1* instead of *count* to differentiate a full ring from an
55 : : * empty ring.
56 : : *
57 : : * The ring is added in RTE_TAILQ_RING list.
58 : : *
59 : : * @param name
60 : : * The name of the ring.
61 : : * @param esize
62 : : * The size of ring element, in bytes. It must be a multiple of 4.
63 : : * @param count
64 : : * The number of elements in the ring (must be a power of 2).
65 : : * @param socket_id
66 : : * The *socket_id* argument is the socket identifier in case of
67 : : * NUMA. The value can be *SOCKET_ID_ANY* if there is no NUMA
68 : : * constraint for the reserved zone.
69 : : * @param flags
70 : : * An OR of the following:
71 : : * - One of mutually exclusive flags that define producer behavior:
72 : : * - RING_F_SP_ENQ: If this flag is set, the default behavior when
73 : : * using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``
74 : : * is "single-producer".
75 : : * - RING_F_MP_RTS_ENQ: If this flag is set, the default behavior when
76 : : * using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``
77 : : * is "multi-producer RTS mode".
78 : : * - RING_F_MP_HTS_ENQ: If this flag is set, the default behavior when
79 : : * using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``
80 : : * is "multi-producer HTS mode".
81 : : * If none of these flags is set, then default "multi-producer"
82 : : * behavior is selected.
83 : : * - One of mutually exclusive flags that define consumer behavior:
84 : : * - RING_F_SC_DEQ: If this flag is set, the default behavior when
85 : : * using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``
86 : : * is "single-consumer". Otherwise, it is "multi-consumers".
87 : : * - RING_F_MC_RTS_DEQ: If this flag is set, the default behavior when
88 : : * using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``
89 : : * is "multi-consumer RTS mode".
90 : : * - RING_F_MC_HTS_DEQ: If this flag is set, the default behavior when
91 : : * using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``
92 : : * is "multi-consumer HTS mode".
93 : : * If none of these flags is set, then default "multi-consumer"
94 : : * behavior is selected.
95 : : * @return
96 : : * On success, the pointer to the new allocated ring. NULL on error with
97 : : * rte_errno set appropriately. Possible errno values include:
98 : : * - E_RTE_NO_CONFIG - function could not get pointer to rte_config structure
99 : : * - EINVAL - esize is not a multiple of 4 or count provided is not a
100 : : * power of 2.
101 : : * - ENOSPC - the maximum number of memzones has already been allocated
102 : : * - EEXIST - a memzone with the same name already exists
103 : : * - ENOMEM - no appropriate memory area found in which to create memzone
104 : : */
105 : : struct rte_ring *rte_ring_create_elem(const char *name, unsigned int esize,
106 : : unsigned int count, int socket_id, unsigned int flags);
107 : :
108 : : /**
109 : : * Enqueue several objects on the ring (multi-producers safe).
110 : : *
111 : : * This function uses a "compare and set" instruction to move the
112 : : * producer index atomically.
113 : : *
114 : : * @param r
115 : : * A pointer to the ring structure.
116 : : * @param obj_table
117 : : * A pointer to a table of objects.
118 : : * @param esize
119 : : * The size of ring element, in bytes. It must be a multiple of 4.
120 : : * This must be the same value used while creating the ring. Otherwise
121 : : * the results are undefined.
122 : : * @param n
123 : : * The number of objects to add in the ring from the obj_table.
124 : : * @param free_space
125 : : * if non-NULL, returns the amount of space in the ring after the
126 : : * enqueue operation has finished.
127 : : * @return
128 : : * The number of objects enqueued, either 0 or n
129 : : */
130 : : static __rte_always_inline unsigned int
131 : 1108 : rte_ring_mp_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table,
132 : : unsigned int esize, unsigned int n, unsigned int *free_space)
133 : : {
134 : 1108 : return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
135 : : RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_MT, free_space);
136 : : }
137 : :
138 : : /**
139 : : * Enqueue several objects on a ring
140 : : *
141 : : * @warning This API is NOT multi-producers safe
142 : : *
143 : : * @param r
144 : : * A pointer to the ring structure.
145 : : * @param obj_table
146 : : * A pointer to a table of objects.
147 : : * @param esize
148 : : * The size of ring element, in bytes. It must be a multiple of 4.
149 : : * This must be the same value used while creating the ring. Otherwise
150 : : * the results are undefined.
151 : : * @param n
152 : : * The number of objects to add in the ring from the obj_table.
153 : : * @param free_space
154 : : * if non-NULL, returns the amount of space in the ring after the
155 : : * enqueue operation has finished.
156 : : * @return
157 : : * The number of objects enqueued, either 0 or n
158 : : */
159 : : static __rte_always_inline unsigned int
160 : 1108 : rte_ring_sp_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table,
161 : : unsigned int esize, unsigned int n, unsigned int *free_space)
162 : : {
163 : 1108 : return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
164 : : RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_ST, free_space);
165 : : }
166 : :
167 : : #include <rte_ring_hts.h>
168 : : #include <rte_ring_rts.h>
169 : :
170 : : /**
171 : : * Enqueue several objects on a ring.
172 : : *
173 : : * This function calls the multi-producer or the single-producer
174 : : * version depending on the default behavior that was specified at
175 : : * ring creation time (see flags).
176 : : *
177 : : * @param r
178 : : * A pointer to the ring structure.
179 : : * @param obj_table
180 : : * A pointer to a table of objects.
181 : : * @param esize
182 : : * The size of ring element, in bytes. It must be a multiple of 4.
183 : : * This must be the same value used while creating the ring. Otherwise
184 : : * the results are undefined.
185 : : * @param n
186 : : * The number of objects to add in the ring from the obj_table.
187 : : * @param free_space
188 : : * if non-NULL, returns the amount of space in the ring after the
189 : : * enqueue operation has finished.
190 : : * @return
191 : : * The number of objects enqueued, either 0 or n
192 : : */
193 : : static __rte_always_inline unsigned int
194 : 3324 : rte_ring_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table,
195 : : unsigned int esize, unsigned int n, unsigned int *free_space)
196 : : {
197 [ - + + - : 287072 : switch (r->prod.sync_type) {
- - + - -
- - + - -
- - + - -
- + + + +
- + + + +
- - + - -
- # # # #
# # # # #
# # # # #
# # # # #
# ]
198 : : case RTE_RING_SYNC_MT:
199 : : return rte_ring_mp_enqueue_bulk_elem(r, obj_table, esize, n,
200 : : free_space);
201 : : case RTE_RING_SYNC_ST:
202 : : return rte_ring_sp_enqueue_bulk_elem(r, obj_table, esize, n,
203 : : free_space);
204 : : case RTE_RING_SYNC_MT_RTS:
205 : : return rte_ring_mp_rts_enqueue_bulk_elem(r, obj_table, esize, n,
206 : : free_space);
207 : : case RTE_RING_SYNC_MT_HTS:
208 : : return rte_ring_mp_hts_enqueue_bulk_elem(r, obj_table, esize, n,
209 : : free_space);
210 : : }
211 : :
212 : : /* valid ring should never reach this point */
213 : : RTE_ASSERT(0);
214 [ # # # # ]: 0 : if (free_space != NULL)
215 : 0 : *free_space = 0;
216 : : return 0;
217 : : }
218 : :
219 : : /**
220 : : * Enqueue one object on a ring (multi-producers safe).
221 : : *
222 : : * This function uses a "compare and set" instruction to move the
223 : : * producer index atomically.
224 : : *
225 : : * @param r
226 : : * A pointer to the ring structure.
227 : : * @param obj
228 : : * A pointer to the object to be added.
229 : : * @param esize
230 : : * The size of ring element, in bytes. It must be a multiple of 4.
231 : : * This must be the same value used while creating the ring. Otherwise
232 : : * the results are undefined.
233 : : * @return
234 : : * - 0: Success; objects enqueued.
235 : : * - -ENOBUFS: Not enough room in the ring to enqueue; no object is enqueued.
236 : : */
237 : : static __rte_always_inline int
238 : : rte_ring_mp_enqueue_elem(struct rte_ring *r, void *obj, unsigned int esize)
239 : : {
240 [ # # # # ]: 0 : return rte_ring_mp_enqueue_bulk_elem(r, obj, esize, 1, NULL) ? 0 :
241 : : -ENOBUFS;
242 : : }
243 : :
244 : : /**
245 : : * Enqueue one object on a ring
246 : : *
247 : : * @warning This API is NOT multi-producers safe
248 : : *
249 : : * @param r
250 : : * A pointer to the ring structure.
251 : : * @param obj
252 : : * A pointer to the object to be added.
253 : : * @param esize
254 : : * The size of ring element, in bytes. It must be a multiple of 4.
255 : : * This must be the same value used while creating the ring. Otherwise
256 : : * the results are undefined.
257 : : * @return
258 : : * - 0: Success; objects enqueued.
259 : : * - -ENOBUFS: Not enough room in the ring to enqueue; no object is enqueued.
260 : : */
261 : : static __rte_always_inline int
262 : : rte_ring_sp_enqueue_elem(struct rte_ring *r, void *obj, unsigned int esize)
263 : : {
264 : : return rte_ring_sp_enqueue_bulk_elem(r, obj, esize, 1, NULL) ? 0 :
265 : : -ENOBUFS;
266 : : }
267 : :
268 : : /**
269 : : * Enqueue one object on a ring.
270 : : *
271 : : * This function calls the multi-producer or the single-producer
272 : : * version, depending on the default behaviour that was specified at
273 : : * ring creation time (see flags).
274 : : *
275 : : * @param r
276 : : * A pointer to the ring structure.
277 : : * @param obj
278 : : * A pointer to the object to be added.
279 : : * @param esize
280 : : * The size of ring element, in bytes. It must be a multiple of 4.
281 : : * This must be the same value used while creating the ring. Otherwise
282 : : * the results are undefined.
283 : : * @return
284 : : * - 0: Success; objects enqueued.
285 : : * - -ENOBUFS: Not enough room in the ring to enqueue; no object is enqueued.
286 : : */
287 : : static __rte_always_inline int
288 : : rte_ring_enqueue_elem(struct rte_ring *r, void *obj, unsigned int esize)
289 : : {
290 [ + + ]: 1051 : return rte_ring_enqueue_bulk_elem(r, obj, esize, 1, NULL) ? 0 :
291 : : -ENOBUFS;
292 : : }
293 : :
294 : : /**
295 : : * Dequeue several objects from a ring (multi-consumers safe).
296 : : *
297 : : * This function uses a "compare and set" instruction to move the
298 : : * consumer index atomically.
299 : : *
300 : : * @param r
301 : : * A pointer to the ring structure.
302 : : * @param obj_table
303 : : * A pointer to a table of objects that will be filled.
304 : : * @param esize
305 : : * The size of ring element, in bytes. It must be a multiple of 4.
306 : : * This must be the same value used while creating the ring. Otherwise
307 : : * the results are undefined.
308 : : * @param n
309 : : * The number of objects to dequeue from the ring to the obj_table.
310 : : * @param available
311 : : * If non-NULL, returns the number of remaining ring entries after the
312 : : * dequeue has finished.
313 : : * @return
314 : : * The number of objects dequeued, either 0 or n
315 : : */
316 : : static __rte_always_inline unsigned int
317 : 1104 : rte_ring_mc_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
318 : : unsigned int esize, unsigned int n, unsigned int *available)
319 : : {
320 : 1104 : return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
321 : : RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_MT, available);
322 : : }
323 : :
324 : : /**
325 : : * Dequeue several objects from a ring (NOT multi-consumers safe).
326 : : *
327 : : * @param r
328 : : * A pointer to the ring structure.
329 : : * @param obj_table
330 : : * A pointer to a table of objects that will be filled.
331 : : * @param esize
332 : : * The size of ring element, in bytes. It must be a multiple of 4.
333 : : * This must be the same value used while creating the ring. Otherwise
334 : : * the results are undefined.
335 : : * @param n
336 : : * The number of objects to dequeue from the ring to the obj_table,
337 : : * must be strictly positive.
338 : : * @param available
339 : : * If non-NULL, returns the number of remaining ring entries after the
340 : : * dequeue has finished.
341 : : * @return
342 : : * The number of objects dequeued, either 0 or n
343 : : */
344 : : static __rte_always_inline unsigned int
345 : 1104 : rte_ring_sc_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
346 : : unsigned int esize, unsigned int n, unsigned int *available)
347 : : {
348 : 1104 : return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
349 : : RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_ST, available);
350 : : }
351 : :
352 : : /**
353 : : * Dequeue several objects from a ring.
354 : : *
355 : : * This function calls the multi-consumers or the single-consumer
356 : : * version, depending on the default behaviour that was specified at
357 : : * ring creation time (see flags).
358 : : *
359 : : * @param r
360 : : * A pointer to the ring structure.
361 : : * @param obj_table
362 : : * A pointer to a table of objects that will be filled.
363 : : * @param esize
364 : : * The size of ring element, in bytes. It must be a multiple of 4.
365 : : * This must be the same value used while creating the ring. Otherwise
366 : : * the results are undefined.
367 : : * @param n
368 : : * The number of objects to dequeue from the ring to the obj_table.
369 : : * @param available
370 : : * If non-NULL, returns the number of remaining ring entries after the
371 : : * dequeue has finished.
372 : : * @return
373 : : * The number of objects dequeued, either 0 or n
374 : : */
375 : : static __rte_always_inline unsigned int
376 : 3312 : rte_ring_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
377 : : unsigned int esize, unsigned int n, unsigned int *available)
378 : : {
379 [ + + - - : 397595 : switch (r->cons.sync_type) {
- - + - -
- - + - -
- - + - -
- + + + +
- + + + +
- - + - -
- # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# ]
380 : : case RTE_RING_SYNC_MT:
381 : : return rte_ring_mc_dequeue_bulk_elem(r, obj_table, esize, n,
382 : : available);
383 : : case RTE_RING_SYNC_ST:
384 : : return rte_ring_sc_dequeue_bulk_elem(r, obj_table, esize, n,
385 : : available);
386 : : case RTE_RING_SYNC_MT_RTS:
387 : : return rte_ring_mc_rts_dequeue_bulk_elem(r, obj_table, esize,
388 : : n, available);
389 : : case RTE_RING_SYNC_MT_HTS:
390 : : return rte_ring_mc_hts_dequeue_bulk_elem(r, obj_table, esize,
391 : : n, available);
392 : : }
393 : :
394 : : /* valid ring should never reach this point */
395 : : RTE_ASSERT(0);
396 [ # # # # ]: 0 : if (available != NULL)
397 : 0 : *available = 0;
398 : : return 0;
399 : : }
400 : :
401 : : /**
402 : : * Dequeue one object from a ring (multi-consumers safe).
403 : : *
404 : : * This function uses a "compare and set" instruction to move the
405 : : * consumer index atomically.
406 : : *
407 : : * @param r
408 : : * A pointer to the ring structure.
409 : : * @param obj_p
410 : : * A pointer to the object that will be filled.
411 : : * @param esize
412 : : * The size of ring element, in bytes. It must be a multiple of 4.
413 : : * This must be the same value used while creating the ring. Otherwise
414 : : * the results are undefined.
415 : : * @return
416 : : * - 0: Success; objects dequeued.
417 : : * - -ENOENT: Not enough entries in the ring to dequeue; no object is
418 : : * dequeued.
419 : : */
420 : : static __rte_always_inline int
421 : : rte_ring_mc_dequeue_elem(struct rte_ring *r, void *obj_p,
422 : : unsigned int esize)
423 : : {
424 [ # # # # ]: 0 : return rte_ring_mc_dequeue_bulk_elem(r, obj_p, esize, 1, NULL) ? 0 :
425 : : -ENOENT;
426 : : }
427 : :
428 : : /**
429 : : * Dequeue one object from a ring (NOT multi-consumers safe).
430 : : *
431 : : * @param r
432 : : * A pointer to the ring structure.
433 : : * @param obj_p
434 : : * A pointer to the object that will be filled.
435 : : * @param esize
436 : : * The size of ring element, in bytes. It must be a multiple of 4.
437 : : * This must be the same value used while creating the ring. Otherwise
438 : : * the results are undefined.
439 : : * @return
440 : : * - 0: Success; objects dequeued.
441 : : * - -ENOENT: Not enough entries in the ring to dequeue, no object is
442 : : * dequeued.
443 : : */
444 : : static __rte_always_inline int
445 : : rte_ring_sc_dequeue_elem(struct rte_ring *r, void *obj_p,
446 : : unsigned int esize)
447 : : {
448 : : return rte_ring_sc_dequeue_bulk_elem(r, obj_p, esize, 1, NULL) ? 0 :
449 : : -ENOENT;
450 : : }
451 : :
452 : : /**
453 : : * Dequeue one object from a ring.
454 : : *
455 : : * This function calls the multi-consumers or the single-consumer
456 : : * version depending on the default behaviour that was specified at
457 : : * ring creation time (see flags).
458 : : *
459 : : * @param r
460 : : * A pointer to the ring structure.
461 : : * @param obj_p
462 : : * A pointer to the object that will be filled.
463 : : * @param esize
464 : : * The size of ring element, in bytes. It must be a multiple of 4.
465 : : * This must be the same value used while creating the ring. Otherwise
466 : : * the results are undefined.
467 : : * @return
468 : : * - 0: Success, objects dequeued.
469 : : * - -ENOENT: Not enough entries in the ring to dequeue, no object is
470 : : * dequeued.
471 : : */
472 : : static __rte_always_inline int
473 : : rte_ring_dequeue_elem(struct rte_ring *r, void *obj_p, unsigned int esize)
474 : : {
475 [ # # ]: 0 : return rte_ring_dequeue_bulk_elem(r, obj_p, esize, 1, NULL) ? 0 :
476 : : -ENOENT;
477 : : }
478 : :
479 : : /**
480 : : * Enqueue several objects on the ring (multi-producers safe).
481 : : *
482 : : * This function uses a "compare and set" instruction to move the
483 : : * producer index atomically.
484 : : *
485 : : * @param r
486 : : * A pointer to the ring structure.
487 : : * @param obj_table
488 : : * A pointer to a table of objects.
489 : : * @param esize
490 : : * The size of ring element, in bytes. It must be a multiple of 4.
491 : : * This must be the same value used while creating the ring. Otherwise
492 : : * the results are undefined.
493 : : * @param n
494 : : * The number of objects to add in the ring from the obj_table.
495 : : * @param free_space
496 : : * if non-NULL, returns the amount of space in the ring after the
497 : : * enqueue operation has finished.
498 : : * @return
499 : : * - n: Actual number of objects enqueued.
500 : : */
501 : : static __rte_always_inline unsigned int
502 : 1108 : rte_ring_mp_enqueue_burst_elem(struct rte_ring *r, const void *obj_table,
503 : : unsigned int esize, unsigned int n, unsigned int *free_space)
504 : : {
505 : 1108 : return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
506 : : RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_MT, free_space);
507 : : }
508 : :
509 : : /**
510 : : * Enqueue several objects on a ring
511 : : *
512 : : * @warning This API is NOT multi-producers safe
513 : : *
514 : : * @param r
515 : : * A pointer to the ring structure.
516 : : * @param obj_table
517 : : * A pointer to a table of objects.
518 : : * @param esize
519 : : * The size of ring element, in bytes. It must be a multiple of 4.
520 : : * This must be the same value used while creating the ring. Otherwise
521 : : * the results are undefined.
522 : : * @param n
523 : : * The number of objects to add in the ring from the obj_table.
524 : : * @param free_space
525 : : * if non-NULL, returns the amount of space in the ring after the
526 : : * enqueue operation has finished.
527 : : * @return
528 : : * - n: Actual number of objects enqueued.
529 : : */
530 : : static __rte_always_inline unsigned int
531 : 1108 : rte_ring_sp_enqueue_burst_elem(struct rte_ring *r, const void *obj_table,
532 : : unsigned int esize, unsigned int n, unsigned int *free_space)
533 : : {
534 : 1108 : return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
535 : : RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_ST, free_space);
536 : : }
537 : :
538 : : /**
539 : : * Enqueue several objects on a ring.
540 : : *
541 : : * This function calls the multi-producer or the single-producer
542 : : * version depending on the default behavior that was specified at
543 : : * ring creation time (see flags).
544 : : *
545 : : * @param r
546 : : * A pointer to the ring structure.
547 : : * @param obj_table
548 : : * A pointer to a table of objects.
549 : : * @param esize
550 : : * The size of ring element, in bytes. It must be a multiple of 4.
551 : : * This must be the same value used while creating the ring. Otherwise
552 : : * the results are undefined.
553 : : * @param n
554 : : * The number of objects to add in the ring from the obj_table.
555 : : * @param free_space
556 : : * if non-NULL, returns the amount of space in the ring after the
557 : : * enqueue operation has finished.
558 : : * @return
559 : : * - n: Actual number of objects enqueued.
560 : : */
561 : : static __rte_always_inline unsigned int
562 : 3324 : rte_ring_enqueue_burst_elem(struct rte_ring *r, const void *obj_table,
563 : : unsigned int esize, unsigned int n, unsigned int *free_space)
564 : : {
565 [ - + - - : 4557832 : switch (r->prod.sync_type) {
- - + - -
- + + + +
- + + + +
- - + - -
- - + - -
- ]
566 : : case RTE_RING_SYNC_MT:
567 : : return rte_ring_mp_enqueue_burst_elem(r, obj_table, esize, n,
568 : : free_space);
569 : : case RTE_RING_SYNC_ST:
570 : : return rte_ring_sp_enqueue_burst_elem(r, obj_table, esize, n,
571 : : free_space);
572 : : case RTE_RING_SYNC_MT_RTS:
573 : : return rte_ring_mp_rts_enqueue_burst_elem(r, obj_table, esize,
574 : : n, free_space);
575 : : case RTE_RING_SYNC_MT_HTS:
576 : : return rte_ring_mp_hts_enqueue_burst_elem(r, obj_table, esize,
577 : : n, free_space);
578 : : }
579 : :
580 : : /* valid ring should never reach this point */
581 : : RTE_ASSERT(0);
582 [ # # # # ]: 0 : if (free_space != NULL)
583 : 0 : *free_space = 0;
584 : : return 0;
585 : : }
586 : :
587 : : /**
588 : : * Dequeue several objects from a ring (multi-consumers safe). When the request
589 : : * objects are more than the available objects, only dequeue the actual number
590 : : * of objects
591 : : *
592 : : * This function uses a "compare and set" instruction to move the
593 : : * consumer index atomically.
594 : : *
595 : : * @param r
596 : : * A pointer to the ring structure.
597 : : * @param obj_table
598 : : * A pointer to a table of objects that will be filled.
599 : : * @param esize
600 : : * The size of ring element, in bytes. It must be a multiple of 4.
601 : : * This must be the same value used while creating the ring. Otherwise
602 : : * the results are undefined.
603 : : * @param n
604 : : * The number of objects to dequeue from the ring to the obj_table.
605 : : * @param available
606 : : * If non-NULL, returns the number of remaining ring entries after the
607 : : * dequeue has finished.
608 : : * @return
609 : : * - n: Actual number of objects dequeued, 0 if ring is empty
610 : : */
611 : : static __rte_always_inline unsigned int
612 : 1104 : rte_ring_mc_dequeue_burst_elem(struct rte_ring *r, void *obj_table,
613 : : unsigned int esize, unsigned int n, unsigned int *available)
614 : : {
615 : 1104 : return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
616 : : RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_MT, available);
617 : : }
618 : :
619 : : /**
620 : : * Dequeue several objects from a ring (NOT multi-consumers safe).When the
621 : : * request objects are more than the available objects, only dequeue the
622 : : * actual number of objects
623 : : *
624 : : * @param r
625 : : * A pointer to the ring structure.
626 : : * @param obj_table
627 : : * A pointer to a table of objects that will be filled.
628 : : * @param esize
629 : : * The size of ring element, in bytes. It must be a multiple of 4.
630 : : * This must be the same value used while creating the ring. Otherwise
631 : : * the results are undefined.
632 : : * @param n
633 : : * The number of objects to dequeue from the ring to the obj_table.
634 : : * @param available
635 : : * If non-NULL, returns the number of remaining ring entries after the
636 : : * dequeue has finished.
637 : : * @return
638 : : * - n: Actual number of objects dequeued, 0 if ring is empty
639 : : */
640 : : static __rte_always_inline unsigned int
641 : 1104 : rte_ring_sc_dequeue_burst_elem(struct rte_ring *r, void *obj_table,
642 : : unsigned int esize, unsigned int n, unsigned int *available)
643 : : {
644 : 1104 : return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
645 : : RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_ST, available);
646 : : }
647 : :
648 : : /**
649 : : * Dequeue multiple objects from a ring up to a maximum number.
650 : : *
651 : : * This function calls the multi-consumers or the single-consumer
652 : : * version, depending on the default behaviour that was specified at
653 : : * ring creation time (see flags).
654 : : *
655 : : * @param r
656 : : * A pointer to the ring structure.
657 : : * @param obj_table
658 : : * A pointer to a table of objects that will be filled.
659 : : * @param esize
660 : : * The size of ring element, in bytes. It must be a multiple of 4.
661 : : * This must be the same value used while creating the ring. Otherwise
662 : : * the results are undefined.
663 : : * @param n
664 : : * The number of objects to dequeue from the ring to the obj_table.
665 : : * @param available
666 : : * If non-NULL, returns the number of remaining ring entries after the
667 : : * dequeue has finished.
668 : : * @return
669 : : * - Number of objects dequeued
670 : : */
671 : : static __rte_always_inline unsigned int
672 : 3312 : rte_ring_dequeue_burst_elem(struct rte_ring *r, void *obj_table,
673 : : unsigned int esize, unsigned int n, unsigned int *available)
674 : : {
675 [ - + - - : 21360731 : switch (r->cons.sync_type) {
- - + - -
- + + + +
- + + + +
- ]
676 : : case RTE_RING_SYNC_MT:
677 : : return rte_ring_mc_dequeue_burst_elem(r, obj_table, esize, n,
678 : : available);
679 : : case RTE_RING_SYNC_ST:
680 : : return rte_ring_sc_dequeue_burst_elem(r, obj_table, esize, n,
681 : : available);
682 : : case RTE_RING_SYNC_MT_RTS:
683 : : return rte_ring_mc_rts_dequeue_burst_elem(r, obj_table, esize,
684 : : n, available);
685 : : case RTE_RING_SYNC_MT_HTS:
686 : : return rte_ring_mc_hts_dequeue_burst_elem(r, obj_table, esize,
687 : : n, available);
688 : : }
689 : :
690 : : /* valid ring should never reach this point */
691 : : RTE_ASSERT(0);
692 [ # # # # ]: 0 : if (available != NULL)
693 : 0 : *available = 0;
694 : : return 0;
695 : : }
696 : :
697 : : #include <rte_ring_peek.h>
698 : : #include <rte_ring_peek_zc.h>
699 : :
700 : : #include <rte_ring.h>
701 : :
702 : : #ifdef __cplusplus
703 : : }
704 : : #endif
705 : :
706 : : #endif /* _RTE_RING_ELEM_H_ */
|