| 555 | } |
| 556 | |
| 557 | static int |
| 558 | find_prev(const struct rte_fbarray *arr, unsigned int start, bool used) |
| 559 | { |
| 560 | const struct used_mask *msk = get_used_mask(arr->data, arr->elt_sz, |
| 561 | arr->len); |
| 562 | unsigned int idx, first, first_mod; |
| 563 | uint64_t ignore_msk; |
| 564 | |
| 565 | /* |
| 566 | * mask only has granularity of MASK_ALIGN, but start may not be aligned |
| 567 | * on that boundary, so construct a special mask to exclude anything we |
| 568 | * don't want to see to avoid confusing clz. |
| 569 | */ |
| 570 | first = MASK_LEN_TO_IDX(start); |
| 571 | first_mod = MASK_LEN_TO_MOD(start); |
| 572 | /* we're going backwards, so mask must start from the top */ |
| 573 | ignore_msk = first_mod == MASK_ALIGN - 1 ? |
| 574 | UINT64_MAX : /* prevent overflow */ |
| 575 | ~(UINT64_MAX << (first_mod + 1)); |
| 576 | |
| 577 | /* go backwards, include zero */ |
| 578 | idx = first; |
| 579 | do { |
| 580 | uint64_t cur = msk->data[idx]; |
| 581 | int found; |
| 582 | |
| 583 | /* if we're looking for free entries, invert mask */ |
| 584 | if (!used) |
| 585 | cur = ~cur; |
| 586 | |
| 587 | /* ignore everything before start on first iteration */ |
| 588 | if (idx == first) |
| 589 | cur &= ignore_msk; |
| 590 | |
| 591 | /* check if we have any entries */ |
| 592 | if (cur == 0) |
| 593 | continue; |
| 594 | |
| 595 | /* |
| 596 | * find last set bit - that will correspond to whatever it is |
| 597 | * that we're looking for. we're counting trailing zeroes, thus |
| 598 | * the value we get is counted from end of mask, so calculate |
| 599 | * position from start of mask. |
| 600 | */ |
| 601 | found = MASK_ALIGN - rte_clz64(cur) - 1; |
| 602 | |
| 603 | return MASK_GET_IDX(idx, found); |
| 604 | } while (idx-- != 0); /* decrement after check to include zero*/ |
| 605 | |
| 606 | /* we didn't find anything */ |
| 607 | rte_errno = used ? ENOENT : ENOSPC; |
| 608 | return -1; |
| 609 | } |
| 610 | |
| 611 | static int |
| 612 | find_rev_contig(const struct rte_fbarray *arr, unsigned int start, bool used) |
no test coverage detected