1 /* SPDX-License-Identifier: BSD-3-Clause
3 * Copyright (c) 2010-2020 Intel Corporation
4 * Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org
6 * Derived from FreeBSD's bufring.h
7 * Used as BSD-3 Licensed with permission from Kip Macy.
10 #ifndef _RTE_RING_PEEK_H_
11 #define _RTE_RING_PEEK_H_
15 * It is not recommended to include this file directly.
16 * Please include <rte_ring_elem.h> instead.
19 * Introduction of rte_ring with serialized producer/consumer (HTS sync mode)
20 * makes possible to split public enqueue/dequeue API into two phases:
21 * - enqueue/dequeue start
22 * - enqueue/dequeue finish
23 * That allows user to inspect objects in the ring without removing them
24 * from it (aka MT safe peek).
25 * Note that right now this new API is available only for two sync modes:
26 * 1) Single Producer/Single Consumer (RTE_RING_SYNC_ST)
27 * 2) Serialized Producer/Serialized Consumer (RTE_RING_SYNC_MT_HTS).
28 * It is a user responsibility to create/init ring with appropriate sync
31 * // read 1 elem from the ring:
32 * n = rte_ring_dequeue_bulk_start(ring, &obj, 1, NULL);
35 * if (object_examine(obj) == KEEP)
36 * //decided to keep it in the ring.
37 * rte_ring_dequeue_finish(ring, 0);
39 * //decided to remove it from the ring.
40 * rte_ring_dequeue_finish(ring, n);
42 * Note that between _start_ and _finish_ none other thread can proceed
43 * with enqueue(/dequeue) operation till _finish_ completes.
50 #include <rte_ring_peek_elem_pvt.h>
53 * Start to enqueue several objects on the ring.
54 * Note that no actual objects are put in the queue by this function,
55 * it just reserves for user such ability.
56 * User has to call appropriate enqueue_elem_finish() to copy objects into the
57 * queue and complete given enqueue operation.
60 * A pointer to the ring structure.
62 * The number of objects to add in the ring from the obj_table.
64 * if non-NULL, returns the amount of space in the ring after the
65 * enqueue operation has finished.
67 * The number of objects that can be enqueued, either 0 or n
69 static __rte_always_inline unsigned int
70 rte_ring_enqueue_bulk_elem_start(struct rte_ring *r, unsigned int n,
71 unsigned int *free_space)
73 return __rte_ring_do_enqueue_start(r, n, RTE_RING_QUEUE_FIXED,
78 * Start to enqueue several objects on the ring.
79 * Note that no actual objects are put in the queue by this function,
80 * it just reserves for user such ability.
81 * User has to call appropriate enqueue_finish() to copy objects into the
82 * queue and complete given enqueue operation.
85 * A pointer to the ring structure.
87 * The number of objects to add in the ring from the obj_table.
89 * if non-NULL, returns the amount of space in the ring after the
90 * enqueue operation has finished.
92 * The number of objects that can be enqueued, either 0 or n
94 static __rte_always_inline unsigned int
95 rte_ring_enqueue_bulk_start(struct rte_ring *r, unsigned int n,
96 unsigned int *free_space)
98 return rte_ring_enqueue_bulk_elem_start(r, n, free_space);
102 * Start to enqueue several objects on the ring.
103 * Note that no actual objects are put in the queue by this function,
104 * it just reserves for user such ability.
105 * User has to call appropriate enqueue_elem_finish() to copy objects into the
106 * queue and complete given enqueue operation.
109 * A pointer to the ring structure.
111 * The number of objects to add in the ring from the obj_table.
113 * if non-NULL, returns the amount of space in the ring after the
114 * enqueue operation has finished.
116 * Actual number of objects that can be enqueued.
118 static __rte_always_inline unsigned int
119 rte_ring_enqueue_burst_elem_start(struct rte_ring *r, unsigned int n,
120 unsigned int *free_space)
122 return __rte_ring_do_enqueue_start(r, n, RTE_RING_QUEUE_VARIABLE,
127 * Start to enqueue several objects on the ring.
128 * Note that no actual objects are put in the queue by this function,
129 * it just reserves for user such ability.
130 * User has to call appropriate enqueue_finish() to copy objects into the
131 * queue and complete given enqueue operation.
134 * A pointer to the ring structure.
136 * The number of objects to add in the ring from the obj_table.
138 * if non-NULL, returns the amount of space in the ring after the
139 * enqueue operation has finished.
141 * Actual number of objects that can be enqueued.
143 static __rte_always_inline unsigned int
144 rte_ring_enqueue_burst_start(struct rte_ring *r, unsigned int n,
145 unsigned int *free_space)
147 return rte_ring_enqueue_burst_elem_start(r, n, free_space);
151 * Complete to enqueue several objects on the ring.
152 * Note that number of objects to enqueue should not exceed previous
153 * enqueue_start return value.
156 * A pointer to the ring structure.
158 * A pointer to a table of objects.
160 * The size of ring element, in bytes. It must be a multiple of 4.
161 * This must be the same value used while creating the ring. Otherwise
162 * the results are undefined.
164 * The number of objects to add to the ring from the obj_table.
166 static __rte_always_inline void
167 rte_ring_enqueue_elem_finish(struct rte_ring *r, const void *obj_table,
168 unsigned int esize, unsigned int n)
172 switch (r->prod.sync_type) {
173 case RTE_RING_SYNC_ST:
174 n = __rte_ring_st_get_tail(&r->prod, &tail, n);
176 __rte_ring_enqueue_elems(r, tail, obj_table, esize, n);
177 __rte_ring_st_set_head_tail(&r->prod, tail, n, 1);
179 case RTE_RING_SYNC_MT_HTS:
180 n = __rte_ring_hts_get_tail(&r->hts_prod, &tail, n);
182 __rte_ring_enqueue_elems(r, tail, obj_table, esize, n);
183 __rte_ring_hts_set_head_tail(&r->hts_prod, tail, n, 1);
185 case RTE_RING_SYNC_MT:
186 case RTE_RING_SYNC_MT_RTS:
188 /* unsupported mode, shouldn't be here */
194 * Complete to enqueue several objects on the ring.
195 * Note that number of objects to enqueue should not exceed previous
196 * enqueue_start return value.
199 * A pointer to the ring structure.
201 * A pointer to a table of objects.
203 * The number of objects to add to the ring from the obj_table.
205 static __rte_always_inline void
206 rte_ring_enqueue_finish(struct rte_ring *r, void * const *obj_table,
209 rte_ring_enqueue_elem_finish(r, obj_table, sizeof(uintptr_t), n);
213 * Start to dequeue several objects from the ring.
214 * Note that user has to call appropriate dequeue_finish()
215 * to complete given dequeue operation and actually remove objects the ring.
218 * A pointer to the ring structure.
220 * A pointer to a table of objects that will be filled.
222 * The size of ring element, in bytes. It must be a multiple of 4.
223 * This must be the same value used while creating the ring. Otherwise
224 * the results are undefined.
226 * The number of objects to dequeue from the ring to the obj_table.
228 * If non-NULL, returns the number of remaining ring entries after the
229 * dequeue has finished.
231 * The number of objects dequeued, either 0 or n.
233 static __rte_always_inline unsigned int
234 rte_ring_dequeue_bulk_elem_start(struct rte_ring *r, void *obj_table,
235 unsigned int esize, unsigned int n, unsigned int *available)
237 return __rte_ring_do_dequeue_start(r, obj_table, esize, n,
238 RTE_RING_QUEUE_FIXED, available);
242 * Start to dequeue several objects from the ring.
243 * Note that user has to call appropriate dequeue_finish()
244 * to complete given dequeue operation and actually remove objects the ring.
247 * A pointer to the ring structure.
249 * A pointer to a table of void * pointers (objects) that will be filled.
251 * The number of objects to dequeue from the ring to the obj_table.
253 * If non-NULL, returns the number of remaining ring entries after the
254 * dequeue has finished.
256 * Actual number of objects dequeued.
258 static __rte_always_inline unsigned int
259 rte_ring_dequeue_bulk_start(struct rte_ring *r, void **obj_table,
260 unsigned int n, unsigned int *available)
262 return rte_ring_dequeue_bulk_elem_start(r, obj_table, sizeof(uintptr_t),
267 * Start to dequeue several objects from the ring.
268 * Note that user has to call appropriate dequeue_finish()
269 * to complete given dequeue operation and actually remove objects the ring.
272 * A pointer to the ring structure.
274 * A pointer to a table of objects that will be filled.
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.
280 * The number of objects to dequeue from the ring to the obj_table.
282 * If non-NULL, returns the number of remaining ring entries after the
283 * dequeue has finished.
285 * The actual number of objects dequeued.
287 static __rte_always_inline unsigned int
288 rte_ring_dequeue_burst_elem_start(struct rte_ring *r, void *obj_table,
289 unsigned int esize, unsigned int n, unsigned int *available)
291 return __rte_ring_do_dequeue_start(r, obj_table, esize, n,
292 RTE_RING_QUEUE_VARIABLE, available);
296 * Start to dequeue several objects from the ring.
297 * Note that user has to call appropriate dequeue_finish()
298 * to complete given dequeue operation and actually remove objects the ring.
301 * A pointer to the ring structure.
303 * A pointer to a table of void * pointers (objects) that will be filled.
305 * The number of objects to dequeue from the ring to the obj_table.
307 * If non-NULL, returns the number of remaining ring entries after the
308 * dequeue has finished.
310 * The actual number of objects dequeued.
312 static __rte_always_inline unsigned int
313 rte_ring_dequeue_burst_start(struct rte_ring *r, void **obj_table,
314 unsigned int n, unsigned int *available)
316 return rte_ring_dequeue_burst_elem_start(r, obj_table,
317 sizeof(uintptr_t), n, available);
321 * Complete to dequeue several objects from the ring.
322 * Note that number of objects to dequeue should not exceed previous
323 * dequeue_start return value.
326 * A pointer to the ring structure.
328 * The number of objects to remove from the ring.
330 static __rte_always_inline void
331 rte_ring_dequeue_elem_finish(struct rte_ring *r, unsigned int n)
335 switch (r->cons.sync_type) {
336 case RTE_RING_SYNC_ST:
337 n = __rte_ring_st_get_tail(&r->cons, &tail, n);
338 __rte_ring_st_set_head_tail(&r->cons, tail, n, 0);
340 case RTE_RING_SYNC_MT_HTS:
341 n = __rte_ring_hts_get_tail(&r->hts_cons, &tail, n);
342 __rte_ring_hts_set_head_tail(&r->hts_cons, tail, n, 0);
344 case RTE_RING_SYNC_MT:
345 case RTE_RING_SYNC_MT_RTS:
347 /* unsupported mode, shouldn't be here */
353 * Complete to dequeue several objects from the ring.
354 * Note that number of objects to dequeue should not exceed previous
355 * dequeue_start return value.
358 * A pointer to the ring structure.
360 * The number of objects to remove from the ring.
362 static __rte_always_inline void
363 rte_ring_dequeue_finish(struct rte_ring *r, unsigned int n)
365 rte_ring_dequeue_elem_finish(r, n);
372 #endif /* _RTE_RING_PEEK_H_ */