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