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 [email protected]
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 * - E_RTE_SECONDARY - function was called from a secondary process instance
100 * - EINVAL - esize is not a multiple of 4 or count provided is not a
101 * power of 2.
102 * - ENOSPC - the maximum number of memzones has already been allocated
103 * - EEXIST - a memzone with the same name already exists
104 * - ENOMEM - no appropriate memory area found in which to create memzone
105 */
106 struct rte_ring *rte_ring_create_elem(const char *name, unsigned int esize,
107 unsigned int count, int socket_id, unsigned int flags);
108
109 /**
110 * Enqueue several objects on the ring (multi-producers safe).
111 *
112 * This function uses a "compare and set" instruction to move the
113 * producer index atomically.
114 *
115 * @param r
116 * A pointer to the ring structure.
117 * @param obj_table
118 * A pointer to a table of objects.
119 * @param esize
120 * The size of ring element, in bytes. It must be a multiple of 4.
121 * This must be the same value used while creating the ring. Otherwise
122 * the results are undefined.
123 * @param n
124 * The number of objects to add in the ring from the obj_table.
125 * @param free_space
126 * if non-NULL, returns the amount of space in the ring after the
127 * enqueue operation has finished.
128 * @return
129 * The number of objects enqueued, either 0 or n
130 */
131 static __rte_always_inline unsigned int
rte_ring_mp_enqueue_bulk_elem(struct rte_ring * r,const void * obj_table,unsigned int esize,unsigned int n,unsigned int * free_space)132 rte_ring_mp_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table,
133 unsigned int esize, unsigned int n, unsigned int *free_space)
134 {
135 return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
136 RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_MT, free_space);
137 }
138
139 /**
140 * Enqueue several objects on a ring
141 *
142 * @warning This API is NOT multi-producers safe
143 *
144 * @param r
145 * A pointer to the ring structure.
146 * @param obj_table
147 * A pointer to a table of objects.
148 * @param esize
149 * The size of ring element, in bytes. It must be a multiple of 4.
150 * This must be the same value used while creating the ring. Otherwise
151 * the results are undefined.
152 * @param n
153 * The number of objects to add in the ring from the obj_table.
154 * @param free_space
155 * if non-NULL, returns the amount of space in the ring after the
156 * enqueue operation has finished.
157 * @return
158 * The number of objects enqueued, either 0 or n
159 */
160 static __rte_always_inline unsigned int
rte_ring_sp_enqueue_bulk_elem(struct rte_ring * r,const void * obj_table,unsigned int esize,unsigned int n,unsigned int * free_space)161 rte_ring_sp_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table,
162 unsigned int esize, unsigned int n, unsigned int *free_space)
163 {
164 return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
165 RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_ST, free_space);
166 }
167
168 #include <rte_ring_hts.h>
169 #include <rte_ring_rts.h>
170
171 /**
172 * Enqueue several objects on a ring.
173 *
174 * This function calls the multi-producer or the single-producer
175 * version depending on the default behavior that was specified at
176 * ring creation time (see flags).
177 *
178 * @param r
179 * A pointer to the ring structure.
180 * @param obj_table
181 * A pointer to a table of objects.
182 * @param esize
183 * The size of ring element, in bytes. It must be a multiple of 4.
184 * This must be the same value used while creating the ring. Otherwise
185 * the results are undefined.
186 * @param n
187 * The number of objects to add in the ring from the obj_table.
188 * @param free_space
189 * if non-NULL, returns the amount of space in the ring after the
190 * enqueue operation has finished.
191 * @return
192 * The number of objects enqueued, either 0 or n
193 */
194 static __rte_always_inline unsigned int
rte_ring_enqueue_bulk_elem(struct rte_ring * r,const void * obj_table,unsigned int esize,unsigned int n,unsigned int * free_space)195 rte_ring_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table,
196 unsigned int esize, unsigned int n, unsigned int *free_space)
197 {
198 switch (r->prod.sync_type) {
199 case RTE_RING_SYNC_MT:
200 return rte_ring_mp_enqueue_bulk_elem(r, obj_table, esize, n,
201 free_space);
202 case RTE_RING_SYNC_ST:
203 return rte_ring_sp_enqueue_bulk_elem(r, obj_table, esize, n,
204 free_space);
205 case RTE_RING_SYNC_MT_RTS:
206 return rte_ring_mp_rts_enqueue_bulk_elem(r, obj_table, esize, n,
207 free_space);
208 case RTE_RING_SYNC_MT_HTS:
209 return rte_ring_mp_hts_enqueue_bulk_elem(r, obj_table, esize, n,
210 free_space);
211 }
212
213 /* valid ring should never reach this point */
214 RTE_ASSERT(0);
215 if (free_space != NULL)
216 *free_space = 0;
217 return 0;
218 }
219
220 /**
221 * Enqueue one object on a ring (multi-producers safe).
222 *
223 * This function uses a "compare and set" instruction to move the
224 * producer index atomically.
225 *
226 * @param r
227 * A pointer to the ring structure.
228 * @param obj
229 * A pointer to the object to be added.
230 * @param esize
231 * The size of ring element, in bytes. It must be a multiple of 4.
232 * This must be the same value used while creating the ring. Otherwise
233 * the results are undefined.
234 * @return
235 * - 0: Success; objects enqueued.
236 * - -ENOBUFS: Not enough room in the ring to enqueue; no object is enqueued.
237 */
238 static __rte_always_inline int
rte_ring_mp_enqueue_elem(struct rte_ring * r,void * obj,unsigned int esize)239 rte_ring_mp_enqueue_elem(struct rte_ring *r, void *obj, unsigned int esize)
240 {
241 return rte_ring_mp_enqueue_bulk_elem(r, obj, esize, 1, NULL) ? 0 :
242 -ENOBUFS;
243 }
244
245 /**
246 * Enqueue one object on a ring
247 *
248 * @warning This API is NOT multi-producers safe
249 *
250 * @param r
251 * A pointer to the ring structure.
252 * @param obj
253 * A pointer to the object to be added.
254 * @param esize
255 * The size of ring element, in bytes. It must be a multiple of 4.
256 * This must be the same value used while creating the ring. Otherwise
257 * the results are undefined.
258 * @return
259 * - 0: Success; objects enqueued.
260 * - -ENOBUFS: Not enough room in the ring to enqueue; no object is enqueued.
261 */
262 static __rte_always_inline int
rte_ring_sp_enqueue_elem(struct rte_ring * r,void * obj,unsigned int esize)263 rte_ring_sp_enqueue_elem(struct rte_ring *r, void *obj, unsigned int esize)
264 {
265 return rte_ring_sp_enqueue_bulk_elem(r, obj, esize, 1, NULL) ? 0 :
266 -ENOBUFS;
267 }
268
269 /**
270 * Enqueue one object on a ring.
271 *
272 * This function calls the multi-producer or the single-producer
273 * version, depending on the default behaviour that was specified at
274 * ring creation time (see flags).
275 *
276 * @param r
277 * A pointer to the ring structure.
278 * @param obj
279 * A pointer to the object to be added.
280 * @param esize
281 * The size of ring element, in bytes. It must be a multiple of 4.
282 * This must be the same value used while creating the ring. Otherwise
283 * the results are undefined.
284 * @return
285 * - 0: Success; objects enqueued.
286 * - -ENOBUFS: Not enough room in the ring to enqueue; no object is enqueued.
287 */
288 static __rte_always_inline int
rte_ring_enqueue_elem(struct rte_ring * r,void * obj,unsigned int esize)289 rte_ring_enqueue_elem(struct rte_ring *r, void *obj, unsigned int esize)
290 {
291 return rte_ring_enqueue_bulk_elem(r, obj, esize, 1, NULL) ? 0 :
292 -ENOBUFS;
293 }
294
295 /**
296 * Dequeue several objects from a ring (multi-consumers safe).
297 *
298 * This function uses a "compare and set" instruction to move the
299 * consumer index atomically.
300 *
301 * @param r
302 * A pointer to the ring structure.
303 * @param obj_table
304 * A pointer to a table of objects that will be filled.
305 * @param esize
306 * The size of ring element, in bytes. It must be a multiple of 4.
307 * This must be the same value used while creating the ring. Otherwise
308 * the results are undefined.
309 * @param n
310 * The number of objects to dequeue from the ring to the obj_table.
311 * @param available
312 * If non-NULL, returns the number of remaining ring entries after the
313 * dequeue has finished.
314 * @return
315 * The number of objects dequeued, either 0 or n
316 */
317 static __rte_always_inline unsigned int
rte_ring_mc_dequeue_bulk_elem(struct rte_ring * r,void * obj_table,unsigned int esize,unsigned int n,unsigned int * available)318 rte_ring_mc_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
319 unsigned int esize, unsigned int n, unsigned int *available)
320 {
321 return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
322 RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_MT, available);
323 }
324
325 /**
326 * Dequeue several objects from a ring (NOT multi-consumers safe).
327 *
328 * @param r
329 * A pointer to the ring structure.
330 * @param obj_table
331 * A pointer to a table of objects that will be filled.
332 * @param esize
333 * The size of ring element, in bytes. It must be a multiple of 4.
334 * This must be the same value used while creating the ring. Otherwise
335 * the results are undefined.
336 * @param n
337 * The number of objects to dequeue from the ring to the obj_table,
338 * must be strictly positive.
339 * @param available
340 * If non-NULL, returns the number of remaining ring entries after the
341 * dequeue has finished.
342 * @return
343 * The number of objects dequeued, either 0 or n
344 */
345 static __rte_always_inline unsigned int
rte_ring_sc_dequeue_bulk_elem(struct rte_ring * r,void * obj_table,unsigned int esize,unsigned int n,unsigned int * available)346 rte_ring_sc_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
347 unsigned int esize, unsigned int n, unsigned int *available)
348 {
349 return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
350 RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_ST, available);
351 }
352
353 /**
354 * Dequeue several objects from a ring.
355 *
356 * This function calls the multi-consumers or the single-consumer
357 * version, depending on the default behaviour that was specified at
358 * ring creation time (see flags).
359 *
360 * @param r
361 * A pointer to the ring structure.
362 * @param obj_table
363 * A pointer to a table of objects that will be filled.
364 * @param esize
365 * The size of ring element, in bytes. It must be a multiple of 4.
366 * This must be the same value used while creating the ring. Otherwise
367 * the results are undefined.
368 * @param n
369 * The number of objects to dequeue from the ring to the obj_table.
370 * @param available
371 * If non-NULL, returns the number of remaining ring entries after the
372 * dequeue has finished.
373 * @return
374 * The number of objects dequeued, either 0 or n
375 */
376 static __rte_always_inline unsigned int
rte_ring_dequeue_bulk_elem(struct rte_ring * r,void * obj_table,unsigned int esize,unsigned int n,unsigned int * available)377 rte_ring_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
378 unsigned int esize, unsigned int n, unsigned int *available)
379 {
380 switch (r->cons.sync_type) {
381 case RTE_RING_SYNC_MT:
382 return rte_ring_mc_dequeue_bulk_elem(r, obj_table, esize, n,
383 available);
384 case RTE_RING_SYNC_ST:
385 return rte_ring_sc_dequeue_bulk_elem(r, obj_table, esize, n,
386 available);
387 case RTE_RING_SYNC_MT_RTS:
388 return rte_ring_mc_rts_dequeue_bulk_elem(r, obj_table, esize,
389 n, available);
390 case RTE_RING_SYNC_MT_HTS:
391 return rte_ring_mc_hts_dequeue_bulk_elem(r, obj_table, esize,
392 n, available);
393 }
394
395 /* valid ring should never reach this point */
396 RTE_ASSERT(0);
397 if (available != NULL)
398 *available = 0;
399 return 0;
400 }
401
402 /**
403 * Dequeue one object from a ring (multi-consumers safe).
404 *
405 * This function uses a "compare and set" instruction to move the
406 * consumer index atomically.
407 *
408 * @param r
409 * A pointer to the ring structure.
410 * @param obj_p
411 * A pointer to the object that will be filled.
412 * @param esize
413 * The size of ring element, in bytes. It must be a multiple of 4.
414 * This must be the same value used while creating the ring. Otherwise
415 * the results are undefined.
416 * @return
417 * - 0: Success; objects dequeued.
418 * - -ENOENT: Not enough entries in the ring to dequeue; no object is
419 * dequeued.
420 */
421 static __rte_always_inline int
rte_ring_mc_dequeue_elem(struct rte_ring * r,void * obj_p,unsigned int esize)422 rte_ring_mc_dequeue_elem(struct rte_ring *r, void *obj_p,
423 unsigned int esize)
424 {
425 return rte_ring_mc_dequeue_bulk_elem(r, obj_p, esize, 1, NULL) ? 0 :
426 -ENOENT;
427 }
428
429 /**
430 * Dequeue one object from a ring (NOT multi-consumers safe).
431 *
432 * @param r
433 * A pointer to the ring structure.
434 * @param obj_p
435 * A pointer to the object that will be filled.
436 * @param esize
437 * The size of ring element, in bytes. It must be a multiple of 4.
438 * This must be the same value used while creating the ring. Otherwise
439 * the results are undefined.
440 * @return
441 * - 0: Success; objects dequeued.
442 * - -ENOENT: Not enough entries in the ring to dequeue, no object is
443 * dequeued.
444 */
445 static __rte_always_inline int
rte_ring_sc_dequeue_elem(struct rte_ring * r,void * obj_p,unsigned int esize)446 rte_ring_sc_dequeue_elem(struct rte_ring *r, void *obj_p,
447 unsigned int esize)
448 {
449 return rte_ring_sc_dequeue_bulk_elem(r, obj_p, esize, 1, NULL) ? 0 :
450 -ENOENT;
451 }
452
453 /**
454 * Dequeue one object from a ring.
455 *
456 * This function calls the multi-consumers or the single-consumer
457 * version depending on the default behaviour that was specified at
458 * ring creation time (see flags).
459 *
460 * @param r
461 * A pointer to the ring structure.
462 * @param obj_p
463 * A pointer to the object that will be filled.
464 * @param esize
465 * The size of ring element, in bytes. It must be a multiple of 4.
466 * This must be the same value used while creating the ring. Otherwise
467 * the results are undefined.
468 * @return
469 * - 0: Success, objects dequeued.
470 * - -ENOENT: Not enough entries in the ring to dequeue, no object is
471 * dequeued.
472 */
473 static __rte_always_inline int
rte_ring_dequeue_elem(struct rte_ring * r,void * obj_p,unsigned int esize)474 rte_ring_dequeue_elem(struct rte_ring *r, void *obj_p, unsigned int esize)
475 {
476 return rte_ring_dequeue_bulk_elem(r, obj_p, esize, 1, NULL) ? 0 :
477 -ENOENT;
478 }
479
480 /**
481 * Enqueue several objects on the ring (multi-producers safe).
482 *
483 * This function uses a "compare and set" instruction to move the
484 * producer index atomically.
485 *
486 * @param r
487 * A pointer to the ring structure.
488 * @param obj_table
489 * A pointer to a table of objects.
490 * @param esize
491 * The size of ring element, in bytes. It must be a multiple of 4.
492 * This must be the same value used while creating the ring. Otherwise
493 * the results are undefined.
494 * @param n
495 * The number of objects to add in the ring from the obj_table.
496 * @param free_space
497 * if non-NULL, returns the amount of space in the ring after the
498 * enqueue operation has finished.
499 * @return
500 * - n: Actual number of objects enqueued.
501 */
502 static __rte_always_inline unsigned int
rte_ring_mp_enqueue_burst_elem(struct rte_ring * r,const void * obj_table,unsigned int esize,unsigned int n,unsigned int * free_space)503 rte_ring_mp_enqueue_burst_elem(struct rte_ring *r, const void *obj_table,
504 unsigned int esize, unsigned int n, unsigned int *free_space)
505 {
506 return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
507 RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_MT, free_space);
508 }
509
510 /**
511 * Enqueue several objects on a ring
512 *
513 * @warning This API is NOT multi-producers safe
514 *
515 * @param r
516 * A pointer to the ring structure.
517 * @param obj_table
518 * A pointer to a table of objects.
519 * @param esize
520 * The size of ring element, in bytes. It must be a multiple of 4.
521 * This must be the same value used while creating the ring. Otherwise
522 * the results are undefined.
523 * @param n
524 * The number of objects to add in the ring from the obj_table.
525 * @param free_space
526 * if non-NULL, returns the amount of space in the ring after the
527 * enqueue operation has finished.
528 * @return
529 * - n: Actual number of objects enqueued.
530 */
531 static __rte_always_inline unsigned int
rte_ring_sp_enqueue_burst_elem(struct rte_ring * r,const void * obj_table,unsigned int esize,unsigned int n,unsigned int * free_space)532 rte_ring_sp_enqueue_burst_elem(struct rte_ring *r, const void *obj_table,
533 unsigned int esize, unsigned int n, unsigned int *free_space)
534 {
535 return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
536 RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_ST, free_space);
537 }
538
539 /**
540 * Enqueue several objects on a ring.
541 *
542 * This function calls the multi-producer or the single-producer
543 * version depending on the default behavior that was specified at
544 * ring creation time (see flags).
545 *
546 * @param r
547 * A pointer to the ring structure.
548 * @param obj_table
549 * A pointer to a table of objects.
550 * @param esize
551 * The size of ring element, in bytes. It must be a multiple of 4.
552 * This must be the same value used while creating the ring. Otherwise
553 * the results are undefined.
554 * @param n
555 * The number of objects to add in the ring from the obj_table.
556 * @param free_space
557 * if non-NULL, returns the amount of space in the ring after the
558 * enqueue operation has finished.
559 * @return
560 * - n: Actual number of objects enqueued.
561 */
562 static __rte_always_inline unsigned int
rte_ring_enqueue_burst_elem(struct rte_ring * r,const void * obj_table,unsigned int esize,unsigned int n,unsigned int * free_space)563 rte_ring_enqueue_burst_elem(struct rte_ring *r, const void *obj_table,
564 unsigned int esize, unsigned int n, unsigned int *free_space)
565 {
566 switch (r->prod.sync_type) {
567 case RTE_RING_SYNC_MT:
568 return rte_ring_mp_enqueue_burst_elem(r, obj_table, esize, n,
569 free_space);
570 case RTE_RING_SYNC_ST:
571 return rte_ring_sp_enqueue_burst_elem(r, obj_table, esize, n,
572 free_space);
573 case RTE_RING_SYNC_MT_RTS:
574 return rte_ring_mp_rts_enqueue_burst_elem(r, obj_table, esize,
575 n, free_space);
576 case RTE_RING_SYNC_MT_HTS:
577 return rte_ring_mp_hts_enqueue_burst_elem(r, obj_table, esize,
578 n, free_space);
579 }
580
581 /* valid ring should never reach this point */
582 RTE_ASSERT(0);
583 if (free_space != NULL)
584 *free_space = 0;
585 return 0;
586 }
587
588 /**
589 * Dequeue several objects from a ring (multi-consumers safe). When the request
590 * objects are more than the available objects, only dequeue the actual number
591 * of objects
592 *
593 * This function uses a "compare and set" instruction to move the
594 * consumer index atomically.
595 *
596 * @param r
597 * A pointer to the ring structure.
598 * @param obj_table
599 * A pointer to a table of objects that will be filled.
600 * @param esize
601 * The size of ring element, in bytes. It must be a multiple of 4.
602 * This must be the same value used while creating the ring. Otherwise
603 * the results are undefined.
604 * @param n
605 * The number of objects to dequeue from the ring to the obj_table.
606 * @param available
607 * If non-NULL, returns the number of remaining ring entries after the
608 * dequeue has finished.
609 * @return
610 * - n: Actual number of objects dequeued, 0 if ring is empty
611 */
612 static __rte_always_inline unsigned int
rte_ring_mc_dequeue_burst_elem(struct rte_ring * r,void * obj_table,unsigned int esize,unsigned int n,unsigned int * available)613 rte_ring_mc_dequeue_burst_elem(struct rte_ring *r, void *obj_table,
614 unsigned int esize, unsigned int n, unsigned int *available)
615 {
616 return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
617 RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_MT, available);
618 }
619
620 /**
621 * Dequeue several objects from a ring (NOT multi-consumers safe).When the
622 * request objects are more than the available objects, only dequeue the
623 * actual number of objects
624 *
625 * @param r
626 * A pointer to the ring structure.
627 * @param obj_table
628 * A pointer to a table of objects that will be filled.
629 * @param esize
630 * The size of ring element, in bytes. It must be a multiple of 4.
631 * This must be the same value used while creating the ring. Otherwise
632 * the results are undefined.
633 * @param n
634 * The number of objects to dequeue from the ring to the obj_table.
635 * @param available
636 * If non-NULL, returns the number of remaining ring entries after the
637 * dequeue has finished.
638 * @return
639 * - n: Actual number of objects dequeued, 0 if ring is empty
640 */
641 static __rte_always_inline unsigned int
rte_ring_sc_dequeue_burst_elem(struct rte_ring * r,void * obj_table,unsigned int esize,unsigned int n,unsigned int * available)642 rte_ring_sc_dequeue_burst_elem(struct rte_ring *r, void *obj_table,
643 unsigned int esize, unsigned int n, unsigned int *available)
644 {
645 return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
646 RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_ST, available);
647 }
648
649 /**
650 * Dequeue multiple objects from a ring up to a maximum number.
651 *
652 * This function calls the multi-consumers or the single-consumer
653 * version, depending on the default behaviour that was specified at
654 * ring creation time (see flags).
655 *
656 * @param r
657 * A pointer to the ring structure.
658 * @param obj_table
659 * A pointer to a table of objects that will be filled.
660 * @param esize
661 * The size of ring element, in bytes. It must be a multiple of 4.
662 * This must be the same value used while creating the ring. Otherwise
663 * the results are undefined.
664 * @param n
665 * The number of objects to dequeue from the ring to the obj_table.
666 * @param available
667 * If non-NULL, returns the number of remaining ring entries after the
668 * dequeue has finished.
669 * @return
670 * - Number of objects dequeued
671 */
672 static __rte_always_inline unsigned int
rte_ring_dequeue_burst_elem(struct rte_ring * r,void * obj_table,unsigned int esize,unsigned int n,unsigned int * available)673 rte_ring_dequeue_burst_elem(struct rte_ring *r, void *obj_table,
674 unsigned int esize, unsigned int n, unsigned int *available)
675 {
676 switch (r->cons.sync_type) {
677 case RTE_RING_SYNC_MT:
678 return rte_ring_mc_dequeue_burst_elem(r, obj_table, esize, n,
679 available);
680 case RTE_RING_SYNC_ST:
681 return rte_ring_sc_dequeue_burst_elem(r, obj_table, esize, n,
682 available);
683 case RTE_RING_SYNC_MT_RTS:
684 return rte_ring_mc_rts_dequeue_burst_elem(r, obj_table, esize,
685 n, available);
686 case RTE_RING_SYNC_MT_HTS:
687 return rte_ring_mc_hts_dequeue_burst_elem(r, obj_table, esize,
688 n, available);
689 }
690
691 /* valid ring should never reach this point */
692 RTE_ASSERT(0);
693 if (available != NULL)
694 *available = 0;
695 return 0;
696 }
697
698 #include <rte_ring_peek.h>
699 #include <rte_ring_peek_zc.h>
700
701 #include <rte_ring.h>
702
703 #ifdef __cplusplus
704 }
705 #endif
706
707 #endif /* _RTE_RING_ELEM_H_ */
708