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