Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : *
3 : : * Copyright (c) 2019 Arm Limited
4 : : * Copyright (c) 2010-2017 Intel Corporation
5 : : * Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org
6 : : * All rights reserved.
7 : : * Derived from FreeBSD's bufring.h
8 : : * Used as BSD-3 Licensed with permission from Kip Macy.
9 : : */
10 : :
11 : : #ifndef _RTE_RING_ELEM_H_
12 : : #define _RTE_RING_ELEM_H_
13 : :
14 : : /**
15 : : * @file
16 : : * RTE Ring with user defined element size
17 : : */
18 : :
19 : : #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 : 1108 : 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 : 1108 : 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 : 1108 : 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 : 1108 : 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 : 3324 : 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 [ - + + - : 286289 : 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 [ # # # # ]: 0 : if (free_space != NULL)
211 : 0 : *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 [ # # # # ]: 0 : 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 [ + + ]: 1055 : 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 : 1104 : 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 : 1104 : 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 : 1104 : 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 : 1104 : 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 : 3312 : rte_ring_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
373 : : unsigned int esize, unsigned int n, unsigned int *available)
374 : : {
375 [ + + - - : 347090 : 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 [ # # # # ]: 0 : if (available != NULL)
393 : 0 : *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 [ # # # # ]: 0 : 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 [ # # ]: 0 : 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 : 1108 : 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 : 1108 : 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 : 1108 : 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 : 1108 : 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 : 3324 : 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 [ - + - - : 3508338 : 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 [ # # # # ]: 0 : if (free_space != NULL)
579 : 0 : *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 : 1104 : 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 : 1104 : 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 : 1104 : 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 : 1104 : 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 : 3312 : rte_ring_dequeue_burst_elem(struct rte_ring *r, void *obj_table,
669 : : unsigned int esize, unsigned int n, unsigned int *available)
670 : : {
671 [ - + - - : 20311531 : 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 [ # # # # ]: 0 : if (available != NULL)
689 : 0 : *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_ */
|