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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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