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