| 659 | } |
| 660 | |
| 661 | static int |
| 662 | alloc_unr_specificl(struct unrhdr *uh, u_int item, void **p1, void **p2) |
| 663 | { |
| 664 | struct unr *up, *upn; |
| 665 | struct unrb *ub; |
| 666 | u_int i, last, tl; |
| 667 | |
| 668 | mtx_assert(uh->mtx, MA_OWNED); |
| 669 | |
| 670 | if (item < uh->low + uh->first || item > uh->high) |
| 671 | return (-1); |
| 672 | |
| 673 | up = TAILQ_FIRST(&uh->head); |
| 674 | /* Ideal split. */ |
| 675 | if (up == NULL && item - uh->low == uh->first) { |
| 676 | uh->first++; |
| 677 | uh->last--; |
| 678 | uh->busy++; |
| 679 | check_unrhdr(uh, __LINE__); |
| 680 | return (item); |
| 681 | } |
| 682 | |
| 683 | i = item - uh->low - uh->first; |
| 684 | |
| 685 | if (up == NULL) { |
| 686 | up = new_unr(uh, p1, p2); |
| 687 | up->ptr = NULL; |
| 688 | up->len = i; |
| 689 | TAILQ_INSERT_TAIL(&uh->head, up, list); |
| 690 | up = new_unr(uh, p1, p2); |
| 691 | up->ptr = uh; |
| 692 | up->len = 1; |
| 693 | TAILQ_INSERT_TAIL(&uh->head, up, list); |
| 694 | uh->last = uh->high - uh->low - i; |
| 695 | uh->busy++; |
| 696 | check_unrhdr(uh, __LINE__); |
| 697 | return (item); |
| 698 | } else { |
| 699 | /* Find the item which contains the unit we want to allocate. */ |
| 700 | TAILQ_FOREACH(up, &uh->head, list) { |
| 701 | if (up->len > i) |
| 702 | break; |
| 703 | i -= up->len; |
| 704 | } |
| 705 | } |
| 706 | |
| 707 | if (up == NULL) { |
| 708 | if (i > 0) { |
| 709 | up = new_unr(uh, p1, p2); |
| 710 | up->ptr = NULL; |
| 711 | up->len = i; |
| 712 | TAILQ_INSERT_TAIL(&uh->head, up, list); |
| 713 | } |
| 714 | up = new_unr(uh, p1, p2); |
| 715 | up->ptr = uh; |
| 716 | up->len = 1; |
| 717 | TAILQ_INSERT_TAIL(&uh->head, up, list); |
| 718 | goto done; |
no test coverage detected