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