xref: /dpdk/lib/eal/include/rte_fbarray.h (revision 719834a6849e1daf4a70ff7742bbcc3ae7e25607)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2017-2018 Intel Corporation
3  */
4 
5 #ifndef RTE_FBARRAY_H
6 #define RTE_FBARRAY_H
7 
8 /**
9  * @file
10  *
11  * File-backed shared indexed array for DPDK.
12  *
13  * Basic workflow is expected to be the following:
14  *  1) Allocate array either using ``rte_fbarray_init()`` or
15  *     ``rte_fbarray_attach()`` (depending on whether it's shared between
16  *     multiple DPDK processes)
17  *  2) find free spots using ``rte_fbarray_find_next_free()``
18  *  3) get pointer to data in the free spot using ``rte_fbarray_get()``, and
19  *     copy data into the pointer (element size is fixed)
20  *  4) mark entry as used using ``rte_fbarray_set_used()``
21  *
22  * Calls to ``rte_fbarray_init()`` and ``rte_fbarray_destroy()`` will have
23  * consequences for all processes, while calls to ``rte_fbarray_attach()`` and
24  * ``rte_fbarray_detach()`` will only have consequences within a single process.
25  * Therefore, it is safe to call ``rte_fbarray_attach()`` or
26  * ``rte_fbarray_detach()`` while another process is using ``rte_fbarray``,
27  * provided no other thread within the same process will try to use
28  * ``rte_fbarray`` before attaching or after detaching. It is not safe to call
29  * ``rte_fbarray_init()`` or ``rte_fbarray_destroy()`` while another thread or
30  * another process is using ``rte_fbarray``.
31  */
32 
33 #include <stdio.h>
34 
35 #include <rte_rwlock.h>
36 
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
40 
41 #define RTE_FBARRAY_NAME_LEN 64
42 
43 struct rte_fbarray {
44 	char name[RTE_FBARRAY_NAME_LEN]; /**< name associated with an array */
45 	unsigned int count;              /**< number of entries stored */
46 	unsigned int len;                /**< current length of the array */
47 	unsigned int elt_sz;             /**< size of each element */
48 	void *data;                      /**< data pointer */
49 	rte_rwlock_t rwlock;             /**< multiprocess lock */
50 };
51 
52 /**
53  * Set up ``rte_fbarray`` structure and allocate underlying resources.
54  *
55  * Call this function to correctly set up ``rte_fbarray`` and allocate
56  * underlying files that will be backing the data in the current process. Note
57  * that in order to use and share ``rte_fbarray`` between multiple processes,
58  * data pointed to by ``arr`` pointer must itself be allocated in shared memory.
59  *
60  * @param arr
61  *   Valid pointer to allocated ``rte_fbarray`` structure.
62  *
63  * @param name
64  *   Unique name to be assigned to this array.
65  *
66  * @param len
67  *   Number of elements initially available in the array.
68  *
69  * @param elt_sz
70  *   Size of each element.
71  *
72  * @return
73  *  - 0 on success.
74  *  - -1 on failure, with ``rte_errno`` indicating reason for failure.
75  */
76 int
77 rte_fbarray_init(struct rte_fbarray *arr, const char *name, unsigned int len,
78 		unsigned int elt_sz);
79 
80 
81 /**
82  * Attach to a file backing an already allocated and correctly set up
83  * ``rte_fbarray`` structure.
84  *
85  * Call this function to attach to file that will be backing the data in the
86  * current process. The structure must have been previously correctly set up
87  * with a call to ``rte_fbarray_init()``. Calls to ``rte_fbarray_attach()`` are
88  * usually meant to be performed in a multiprocessing scenario, with data
89  * pointed to by ``arr`` pointer allocated in shared memory.
90  *
91  * @param arr
92  *   Valid pointer to allocated and correctly set up rte_fbarray structure.
93  *
94  * @return
95  *  - 0 on success.
96  *  - -1 on failure, with ``rte_errno`` indicating reason for failure.
97  */
98 int
99 rte_fbarray_attach(struct rte_fbarray *arr);
100 
101 
102 /**
103  * Deallocate resources for an already allocated and correctly set up
104  * ``rte_fbarray`` structure, and remove the underlying file.
105  *
106  * Call this function to deallocate all resources associated with an
107  * ``rte_fbarray`` structure within the current process. This will also
108  * zero-fill data pointed to by ``arr`` pointer and remove the underlying file
109  * backing the data, so it is expected that by the time this function is called,
110  * all other processes have detached from this ``rte_fbarray``.
111  *
112  * @param arr
113  *   Valid pointer to allocated and correctly set up ``rte_fbarray`` structure.
114  *
115  * @return
116  *  - 0 on success.
117  *  - -1 on failure, with ``rte_errno`` indicating reason for failure.
118  */
119 int
120 rte_fbarray_destroy(struct rte_fbarray *arr);
121 
122 
123 /**
124  * Deallocate resources for an already allocated and correctly set up
125  * ``rte_fbarray`` structure.
126  *
127  * Call this function to deallocate all resources associated with an
128  * ``rte_fbarray`` structure within current process.
129  *
130  * @param arr
131  *   Valid pointer to allocated and correctly set up ``rte_fbarray`` structure.
132  *
133  * @return
134  *  - 0 on success.
135  *  - -1 on failure, with ``rte_errno`` indicating reason for failure.
136  */
137 int
138 rte_fbarray_detach(struct rte_fbarray *arr);
139 
140 
141 /**
142  * Get pointer to element residing at specified index.
143  *
144  * @param arr
145  *   Valid pointer to allocated and correctly set up ``rte_fbarray`` structure.
146  *
147  * @param idx
148  *   Index of an element to get a pointer to.
149  *
150  * @return
151  *  - non-NULL pointer on success.
152  *  - NULL on failure, with ``rte_errno`` indicating reason for failure.
153  */
154 void *
155 rte_fbarray_get(const struct rte_fbarray *arr, unsigned int idx);
156 
157 
158 /**
159  * Find index of a specified element within the array.
160  *
161  * @param arr
162  *   Valid pointer to allocated and correctly set up ``rte_fbarray`` structure.
163  *
164  * @param elt
165  *   Pointer to element to find index to.
166  *
167  * @return
168  *  - non-negative integer on success.
169  *  - -1 on failure, with ``rte_errno`` indicating reason for failure.
170  */
171 int
172 rte_fbarray_find_idx(const struct rte_fbarray *arr, const void *elt);
173 
174 
175 /**
176  * Mark specified element as used.
177  *
178  * @param arr
179  *   Valid pointer to allocated and correctly set up ``rte_fbarray`` structure.
180  *
181  * @param idx
182  *   Element index to mark as used.
183  *
184  * @return
185  *  - 0 on success.
186  *  - -1 on failure, with ``rte_errno`` indicating reason for failure.
187  */
188 int
189 rte_fbarray_set_used(struct rte_fbarray *arr, unsigned int idx);
190 
191 
192 /**
193  * Mark specified element as free.
194  *
195  * @param arr
196  *   Valid pointer to allocated and correctly set up ``rte_fbarray`` structure.
197  *
198  * @param idx
199  *   Element index to mark as free.
200  *
201  * @return
202  *  - 0 on success.
203  *  - -1 on failure, with ``rte_errno`` indicating reason for failure.
204  */
205 int
206 rte_fbarray_set_free(struct rte_fbarray *arr, unsigned int idx);
207 
208 
209 /**
210  * Check whether element at specified index is marked as used.
211  *
212  * @param arr
213  *   Valid pointer to allocated and correctly set up ``rte_fbarray`` structure.
214  *
215  * @param idx
216  *   Element index to check as used.
217  *
218  * @return
219  *  - 1 if element is used.
220  *  - 0 if element is unused.
221  *  - -1 on failure, with ``rte_errno`` indicating reason for failure.
222  */
223 int
224 rte_fbarray_is_used(struct rte_fbarray *arr, unsigned int idx);
225 
226 
227 /**
228  * Find index of next free element, starting at specified index.
229  *
230  * @param arr
231  *   Valid pointer to allocated and correctly set up ``rte_fbarray`` structure.
232  *
233  * @param start
234  *   Element index to start search from.
235  *
236  * @return
237  *  - non-negative integer on success.
238  *  - -1 on failure, with ``rte_errno`` indicating reason for failure.
239  */
240 int
241 rte_fbarray_find_next_free(struct rte_fbarray *arr, unsigned int start);
242 
243 
244 /**
245  * Find index of next used element, starting at specified index.
246  *
247  * @param arr
248  *   Valid pointer to allocated and correctly set up ``rte_fbarray`` structure.
249  *
250  * @param start
251  *   Element index to start search from.
252  *
253  * @return
254  *  - non-negative integer on success.
255  *  - -1 on failure, with ``rte_errno`` indicating reason for failure.
256  */
257 int
258 rte_fbarray_find_next_used(struct rte_fbarray *arr, unsigned int start);
259 
260 
261 /**
262  * Find index of next chunk of ``n`` free elements, starting at specified index.
263  *
264  * @param arr
265  *   Valid pointer to allocated and correctly set up ``rte_fbarray`` structure.
266  *
267  * @param start
268  *   Element index to start search from.
269  *
270  * @param n
271  *   Number of free elements to look for.
272  *
273  * @return
274  *  - non-negative integer on success.
275  *  - -1 on failure, with ``rte_errno`` indicating reason for failure.
276  */
277 int
278 rte_fbarray_find_next_n_free(struct rte_fbarray *arr, unsigned int start,
279 		unsigned int n);
280 
281 
282 /**
283  * Find index of next chunk of ``n`` used elements, starting at specified index.
284  *
285  * @param arr
286  *   Valid pointer to allocated and correctly set up ``rte_fbarray`` structure.
287  *
288  * @param start
289  *   Element index to start search from.
290  *
291  * @param n
292  *   Number of used elements to look for.
293  *
294  * @return
295  *  - non-negative integer on success.
296  *  - -1 on failure, with ``rte_errno`` indicating reason for failure.
297  */
298 int
299 rte_fbarray_find_next_n_used(struct rte_fbarray *arr, unsigned int start,
300 		unsigned int n);
301 
302 
303 /**
304  * Find how many more free entries there are, starting at specified index.
305  *
306  * @param arr
307  *   Valid pointer to allocated and correctly set up ``rte_fbarray`` structure.
308  *
309  * @param start
310  *   Element index to start search from.
311  *
312  * @return
313  *  - non-negative integer on success.
314  *  - -1 on failure, with ``rte_errno`` indicating reason for failure.
315  */
316 int
317 rte_fbarray_find_contig_free(struct rte_fbarray *arr,
318 		unsigned int start);
319 
320 
321 /**
322  * Find how many more used entries there are, starting at specified index.
323  *
324  * @param arr
325  *   Valid pointer to allocated and correctly set up ``rte_fbarray`` structure.
326  *
327  * @param start
328  *   Element index to start search from.
329  *
330  * @return
331  *  - non-negative integer on success.
332  *  - -1 on failure, with ``rte_errno`` indicating reason for failure.
333  */
334 int
335 rte_fbarray_find_contig_used(struct rte_fbarray *arr, unsigned int start);
336 
337 /**
338  * Find index of previous free element, starting at specified index.
339  *
340  * @param arr
341  *   Valid pointer to allocated and correctly set up ``rte_fbarray`` structure.
342  *
343  * @param start
344  *   Element index to start search from.
345  *
346  * @return
347  *  - non-negative integer on success.
348  *  - -1 on failure, with ``rte_errno`` indicating reason for failure.
349  */
350 int
351 rte_fbarray_find_prev_free(struct rte_fbarray *arr, unsigned int start);
352 
353 
354 /**
355  * Find index of previous used element, starting at specified index.
356  *
357  * @param arr
358  *   Valid pointer to allocated and correctly set up ``rte_fbarray`` structure.
359  *
360  * @param start
361  *   Element index to start search from.
362  *
363  * @return
364  *  - non-negative integer on success.
365  *  - -1 on failure, with ``rte_errno`` indicating reason for failure.
366  */
367 int
368 rte_fbarray_find_prev_used(struct rte_fbarray *arr, unsigned int start);
369 
370 
371 /**
372  * Find lowest start index of chunk of ``n`` free elements, down from specified
373  * index.
374  *
375  * @param arr
376  *   Valid pointer to allocated and correctly set up ``rte_fbarray`` structure.
377  *
378  * @param start
379  *   Element index to start search from.
380  *
381  * @param n
382  *   Number of free elements to look for.
383  *
384  * @return
385  *  - non-negative integer on success.
386  *  - -1 on failure, with ``rte_errno`` indicating reason for failure.
387  */
388 int
389 rte_fbarray_find_prev_n_free(struct rte_fbarray *arr, unsigned int start,
390 		unsigned int n);
391 
392 
393 /**
394  * Find lowest start index of chunk of ``n`` used elements, down from specified
395  * index.
396  *
397  * @param arr
398  *   Valid pointer to allocated and correctly set up ``rte_fbarray`` structure.
399  *
400  * @param start
401  *   Element index to start search from.
402  *
403  * @param n
404  *   Number of used elements to look for.
405  *
406  * @return
407  *  - non-negative integer on success.
408  *  - -1 on failure, with ``rte_errno`` indicating reason for failure.
409  */
410 int
411 rte_fbarray_find_prev_n_used(struct rte_fbarray *arr, unsigned int start,
412 		unsigned int n);
413 
414 
415 /**
416  * Find how many more free entries there are before specified index (like
417  * ``rte_fbarray_find_contig_free`` but going in reverse).
418  *
419  * @param arr
420  *   Valid pointer to allocated and correctly set up ``rte_fbarray`` structure.
421  *
422  * @param start
423  *   Element index to start search from.
424  *
425  * @return
426  *  - non-negative integer on success.
427  *  - -1 on failure, with ``rte_errno`` indicating reason for failure.
428  */
429 int
430 rte_fbarray_find_rev_contig_free(struct rte_fbarray *arr,
431 		unsigned int start);
432 
433 
434 /**
435  * Find how many more used entries there are before specified index (like
436  * ``rte_fbarray_find_contig_used`` but going in reverse).
437  *
438  * @param arr
439  *   Valid pointer to allocated and correctly set up ``rte_fbarray`` structure.
440  *
441  * @param start
442  *   Element index to start search from.
443  *
444  * @return
445  *  - non-negative integer on success.
446  *  - -1 on failure, with ``rte_errno`` indicating reason for failure.
447  */
448 int
449 rte_fbarray_find_rev_contig_used(struct rte_fbarray *arr, unsigned int start);
450 
451 
452 /**
453  * Find index of biggest chunk of free elements, starting at specified index.
454  *
455  * @param arr
456  *   Valid pointer to allocated and correctly set up ``rte_fbarray`` structure.
457  *
458  * @param start
459  *   Element index to start search from.
460  *
461  * @return
462  *  - non-negative integer on success.
463  *  - -1 on failure, with ``rte_errno`` indicating reason for failure.
464  */
465 int
466 rte_fbarray_find_biggest_free(struct rte_fbarray *arr, unsigned int start);
467 
468 
469 /**
470  * Find index of biggest chunk of used elements, starting at specified index.
471  *
472  * @param arr
473  *   Valid pointer to allocated and correctly set up ``rte_fbarray`` structure.
474  *
475  * @param start
476  *   Element index to start search from.
477  *
478  * @return
479  *  - non-negative integer on success.
480  *  - -1 on failure, with ``rte_errno`` indicating reason for failure.
481  */
482 int
483 rte_fbarray_find_biggest_used(struct rte_fbarray *arr, unsigned int start);
484 
485 
486 /**
487  * Find index of biggest chunk of free elements before a specified index (like
488  * ``rte_fbarray_find_biggest_free``, but going in reverse).
489  *
490  * @param arr
491  *   Valid pointer to allocated and correctly set up ``rte_fbarray`` structure.
492  *
493  * @param start
494  *   Element index to start search from.
495  *
496  * @return
497  *  - non-negative integer on success.
498  *  - -1 on failure, with ``rte_errno`` indicating reason for failure.
499  */
500 int
501 rte_fbarray_find_rev_biggest_free(struct rte_fbarray *arr, unsigned int start);
502 
503 
504 /**
505  * Find index of biggest chunk of used elements before a specified index (like
506  * ``rte_fbarray_find_biggest_used``, but going in reverse).
507  *
508  * @param arr
509  *   Valid pointer to allocated and correctly set up ``rte_fbarray`` structure.
510  *
511  * @param start
512  *   Element index to start search from.
513  *
514  * @return
515  *  - non-negative integer on success.
516  *  - -1 on failure, with ``rte_errno`` indicating reason for failure.
517  */
518 int
519 rte_fbarray_find_rev_biggest_used(struct rte_fbarray *arr, unsigned int start);
520 
521 
522 /**
523  * Dump ``rte_fbarray`` metadata.
524  *
525  * @param arr
526  *   Valid pointer to allocated and correctly set up ``rte_fbarray`` structure.
527  *
528  * @param f
529  *   File object to dump information into.
530  */
531 void
532 rte_fbarray_dump_metadata(struct rte_fbarray *arr, FILE *f);
533 
534 #ifdef __cplusplus
535 }
536 #endif
537 
538 #endif /* RTE_FBARRAY_H */
539