doc: add Meson coding style to contributors guide
[dpdk.git] / lib / librte_ring / rte_ring_peek.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright (c) 2010-2020 Intel Corporation
4  * Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org
5  * All rights reserved.
6  * Derived from FreeBSD's bufring.h
7  * Used as BSD-3 Licensed with permission from Kip Macy.
8  */
9
10 #ifndef _RTE_RING_PEEK_H_
11 #define _RTE_RING_PEEK_H_
12
13 /**
14  * @file
15  * @b EXPERIMENTAL: this API may change without prior notice
16  * It is not recommended to include this file directly.
17  * Please include <rte_ring_elem.h> instead.
18  *
19  * Ring Peek API
20  * Introduction of rte_ring with serialized producer/consumer (HTS sync mode)
21  * makes possible to split public enqueue/dequeue API into two phases:
22  * - enqueue/dequeue start
23  * - enqueue/dequeue finish
24  * That allows user to inspect objects in the ring without removing them
25  * from it (aka MT safe peek).
26  * Note that right now this new API is available only for two sync modes:
27  * 1) Single Producer/Single Consumer (RTE_RING_SYNC_ST)
28  * 2) Serialized Producer/Serialized Consumer (RTE_RING_SYNC_MT_HTS).
29  * It is a user responsibility to create/init ring with appropriate sync
30  * modes selected.
31  * As an example:
32  * // read 1 elem from the ring:
33  * n = rte_ring_dequeue_bulk_start(ring, &obj, 1, NULL);
34  * if (n != 0) {
35  *    //examine object
36  *    if (object_examine(obj) == KEEP)
37  *       //decided to keep it in the ring.
38  *       rte_ring_dequeue_finish(ring, 0);
39  *    else
40  *       //decided to remove it from the ring.
41  *       rte_ring_dequeue_finish(ring, n);
42  * }
43  * Note that between _start_ and _finish_ none other thread can proceed
44  * with enqueue(/dequeue) operation till _finish_ completes.
45  */
46
47 #ifdef __cplusplus
48 extern "C" {
49 #endif
50
51 #include <rte_ring_peek_elem_pvt.h>
52
53 /**
54  * Start to enqueue several objects on the ring.
55  * Note that no actual objects are put in the queue by this function,
56  * it just reserves for user such ability.
57  * User has to call appropriate enqueue_elem_finish() to copy objects into the
58  * queue and complete given enqueue operation.
59  *
60  * @param r
61  *   A pointer to the ring structure.
62  * @param n
63  *   The number of objects to add in the ring from the obj_table.
64  * @param free_space
65  *   if non-NULL, returns the amount of space in the ring after the
66  *   enqueue operation has finished.
67  * @return
68  *   The number of objects that can be enqueued, either 0 or n
69  */
70 __rte_experimental
71 static __rte_always_inline unsigned int
72 rte_ring_enqueue_bulk_elem_start(struct rte_ring *r, unsigned int n,
73                 unsigned int *free_space)
74 {
75         return __rte_ring_do_enqueue_start(r, n, RTE_RING_QUEUE_FIXED,
76                         free_space);
77 }
78
79 /**
80  * Start to enqueue several objects on the ring.
81  * Note that no actual objects are put in the queue by this function,
82  * it just reserves for user such ability.
83  * User has to call appropriate enqueue_finish() to copy objects into the
84  * queue and complete given enqueue operation.
85  *
86  * @param r
87  *   A pointer to the ring structure.
88  * @param n
89  *   The number of objects to add in the ring from the obj_table.
90  * @param free_space
91  *   if non-NULL, returns the amount of space in the ring after the
92  *   enqueue operation has finished.
93  * @return
94  *   The number of objects that can be enqueued, either 0 or n
95  */
96 __rte_experimental
97 static __rte_always_inline unsigned int
98 rte_ring_enqueue_bulk_start(struct rte_ring *r, unsigned int n,
99                 unsigned int *free_space)
100 {
101         return rte_ring_enqueue_bulk_elem_start(r, n, free_space);
102 }
103
104 /**
105  * Start to enqueue several objects on the ring.
106  * Note that no actual objects are put in the queue by this function,
107  * it just reserves for user such ability.
108  * User has to call appropriate enqueue_elem_finish() to copy objects into the
109  * queue and complete given enqueue operation.
110  *
111  * @param r
112  *   A pointer to the ring structure.
113  * @param n
114  *   The number of objects to add in the ring from the obj_table.
115  * @param free_space
116  *   if non-NULL, returns the amount of space in the ring after the
117  *   enqueue operation has finished.
118  * @return
119  *   Actual number of objects that can be enqueued.
120  */
121 __rte_experimental
122 static __rte_always_inline unsigned int
123 rte_ring_enqueue_burst_elem_start(struct rte_ring *r, unsigned int n,
124                 unsigned int *free_space)
125 {
126         return __rte_ring_do_enqueue_start(r, n, RTE_RING_QUEUE_VARIABLE,
127                         free_space);
128 }
129
130 /**
131  * Start to enqueue several objects on the ring.
132  * Note that no actual objects are put in the queue by this function,
133  * it just reserves for user such ability.
134  * User has to call appropriate enqueue_finish() to copy objects into the
135  * queue and complete given enqueue operation.
136  *
137  * @param r
138  *   A pointer to the ring structure.
139  * @param n
140  *   The number of objects to add in the ring from the obj_table.
141  * @param free_space
142  *   if non-NULL, returns the amount of space in the ring after the
143  *   enqueue operation has finished.
144  * @return
145  *   Actual number of objects that can be enqueued.
146  */
147 __rte_experimental
148 static __rte_always_inline unsigned int
149 rte_ring_enqueue_burst_start(struct rte_ring *r, unsigned int n,
150                 unsigned int *free_space)
151 {
152         return rte_ring_enqueue_burst_elem_start(r, n, free_space);
153 }
154
155 /**
156  * Complete to enqueue several objects on the ring.
157  * Note that number of objects to enqueue should not exceed previous
158  * enqueue_start return value.
159  *
160  * @param r
161  *   A pointer to the ring structure.
162  * @param obj_table
163  *   A pointer to a table of objects.
164  * @param esize
165  *   The size of ring element, in bytes. It must be a multiple of 4.
166  *   This must be the same value used while creating the ring. Otherwise
167  *   the results are undefined.
168  * @param n
169  *   The number of objects to add to the ring from the obj_table.
170  */
171 __rte_experimental
172 static __rte_always_inline void
173 rte_ring_enqueue_elem_finish(struct rte_ring *r, const void *obj_table,
174                 unsigned int esize, unsigned int n)
175 {
176         uint32_t tail;
177
178         switch (r->prod.sync_type) {
179         case RTE_RING_SYNC_ST:
180                 n = __rte_ring_st_get_tail(&r->prod, &tail, n);
181                 if (n != 0)
182                         __rte_ring_enqueue_elems(r, tail, obj_table, esize, n);
183                 __rte_ring_st_set_head_tail(&r->prod, tail, n, 1);
184                 break;
185         case RTE_RING_SYNC_MT_HTS:
186                 n = __rte_ring_hts_get_tail(&r->hts_prod, &tail, n);
187                 if (n != 0)
188                         __rte_ring_enqueue_elems(r, tail, obj_table, esize, n);
189                 __rte_ring_hts_set_head_tail(&r->hts_prod, tail, n, 1);
190                 break;
191         case RTE_RING_SYNC_MT:
192         case RTE_RING_SYNC_MT_RTS:
193         default:
194                 /* unsupported mode, shouldn't be here */
195                 RTE_ASSERT(0);
196         }
197 }
198
199 /**
200  * Complete to enqueue several objects on the ring.
201  * Note that number of objects to enqueue should not exceed previous
202  * enqueue_start return value.
203  *
204  * @param r
205  *   A pointer to the ring structure.
206  * @param obj_table
207  *   A pointer to a table of objects.
208  * @param n
209  *   The number of objects to add to the ring from the obj_table.
210  */
211 __rte_experimental
212 static __rte_always_inline void
213 rte_ring_enqueue_finish(struct rte_ring *r, void * const *obj_table,
214                 unsigned int n)
215 {
216         rte_ring_enqueue_elem_finish(r, obj_table, sizeof(uintptr_t), n);
217 }
218
219 /**
220  * Start to dequeue several objects from the ring.
221  * Note that user has to call appropriate dequeue_finish()
222  * to complete given dequeue operation and actually remove objects the ring.
223  *
224  * @param r
225  *   A pointer to the ring structure.
226  * @param obj_table
227  *   A pointer to a table of objects that will be filled.
228  * @param esize
229  *   The size of ring element, in bytes. It must be a multiple of 4.
230  *   This must be the same value used while creating the ring. Otherwise
231  *   the results are undefined.
232  * @param n
233  *   The number of objects to dequeue from the ring to the obj_table.
234  * @param available
235  *   If non-NULL, returns the number of remaining ring entries after the
236  *   dequeue has finished.
237  * @return
238  *   The number of objects dequeued, either 0 or n.
239  */
240 __rte_experimental
241 static __rte_always_inline unsigned int
242 rte_ring_dequeue_bulk_elem_start(struct rte_ring *r, void *obj_table,
243                 unsigned int esize, unsigned int n, unsigned int *available)
244 {
245         return __rte_ring_do_dequeue_start(r, obj_table, esize, n,
246                         RTE_RING_QUEUE_FIXED, available);
247 }
248
249 /**
250  * Start to dequeue several objects from the ring.
251  * Note that user has to call appropriate dequeue_finish()
252  * to complete given dequeue operation and actually remove objects the ring.
253  *
254  * @param r
255  *   A pointer to the ring structure.
256  * @param obj_table
257  *   A pointer to a table of void * pointers (objects) that will be filled.
258  * @param n
259  *   The number of objects to dequeue from the ring to the obj_table.
260  * @param available
261  *   If non-NULL, returns the number of remaining ring entries after the
262  *   dequeue has finished.
263  * @return
264  *   Actual number of objects dequeued.
265  */
266 __rte_experimental
267 static __rte_always_inline unsigned int
268 rte_ring_dequeue_bulk_start(struct rte_ring *r, void **obj_table,
269                 unsigned int n, unsigned int *available)
270 {
271         return rte_ring_dequeue_bulk_elem_start(r, obj_table, sizeof(uintptr_t),
272                 n, available);
273 }
274
275 /**
276  * Start to dequeue several objects from the ring.
277  * Note that user has to call appropriate dequeue_finish()
278  * to complete given dequeue operation and actually remove objects the ring.
279  *
280  * @param r
281  *   A pointer to the ring structure.
282  * @param obj_table
283  *   A pointer to a table of objects that will be filled.
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  * @param n
289  *   The number of objects to dequeue from the ring to the obj_table.
290  * @param available
291  *   If non-NULL, returns the number of remaining ring entries after the
292  *   dequeue has finished.
293  * @return
294  *   The actual number of objects dequeued.
295  */
296 __rte_experimental
297 static __rte_always_inline unsigned int
298 rte_ring_dequeue_burst_elem_start(struct rte_ring *r, void *obj_table,
299                 unsigned int esize, unsigned int n, unsigned int *available)
300 {
301         return __rte_ring_do_dequeue_start(r, obj_table, esize, n,
302                         RTE_RING_QUEUE_VARIABLE, available);
303 }
304
305 /**
306  * Start to dequeue several objects from the ring.
307  * Note that user has to call appropriate dequeue_finish()
308  * to complete given dequeue operation and actually remove objects the ring.
309  *
310  * @param r
311  *   A pointer to the ring structure.
312  * @param obj_table
313  *   A pointer to a table of void * pointers (objects) that will be filled.
314  * @param n
315  *   The number of objects to dequeue from the ring to the obj_table.
316  * @param available
317  *   If non-NULL, returns the number of remaining ring entries after the
318  *   dequeue has finished.
319  * @return
320  *   The actual number of objects dequeued.
321  */
322 __rte_experimental
323 static __rte_always_inline unsigned int
324 rte_ring_dequeue_burst_start(struct rte_ring *r, void **obj_table,
325                 unsigned int n, unsigned int *available)
326 {
327         return rte_ring_dequeue_burst_elem_start(r, obj_table,
328                 sizeof(uintptr_t), n, available);
329 }
330
331 /**
332  * Complete to dequeue several objects from the ring.
333  * Note that number of objects to dequeue should not exceed previous
334  * dequeue_start return value.
335  *
336  * @param r
337  *   A pointer to the ring structure.
338  * @param n
339  *   The number of objects to remove from the ring.
340  */
341 __rte_experimental
342 static __rte_always_inline void
343 rte_ring_dequeue_elem_finish(struct rte_ring *r, unsigned int n)
344 {
345         uint32_t tail;
346
347         switch (r->cons.sync_type) {
348         case RTE_RING_SYNC_ST:
349                 n = __rte_ring_st_get_tail(&r->cons, &tail, n);
350                 __rte_ring_st_set_head_tail(&r->cons, tail, n, 0);
351                 break;
352         case RTE_RING_SYNC_MT_HTS:
353                 n = __rte_ring_hts_get_tail(&r->hts_cons, &tail, n);
354                 __rte_ring_hts_set_head_tail(&r->hts_cons, tail, n, 0);
355                 break;
356         case RTE_RING_SYNC_MT:
357         case RTE_RING_SYNC_MT_RTS:
358         default:
359                 /* unsupported mode, shouldn't be here */
360                 RTE_ASSERT(0);
361         }
362 }
363
364 /**
365  * Complete to dequeue several objects from the ring.
366  * Note that number of objects to dequeue should not exceed previous
367  * dequeue_start return value.
368  *
369  * @param r
370  *   A pointer to the ring structure.
371  * @param n
372  *   The number of objects to remove from the ring.
373  */
374 __rte_experimental
375 static __rte_always_inline void
376 rte_ring_dequeue_finish(struct rte_ring *r, unsigned int n)
377 {
378         rte_ring_dequeue_elem_finish(r, n);
379 }
380
381 #ifdef __cplusplus
382 }
383 #endif
384
385 #endif /* _RTE_RING_PEEK_H_ */