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