| 631 | } |
| 632 | |
| 633 | static struct rt_page *__pages_alloc( |
| 634 | pgls_agr_t agr_pgls[], rt_uint32_t size_bits, int affid, |
| 635 | void (*page_remove)(rt_page_t *page_head, struct rt_page *p, |
| 636 | rt_uint32_t size_bits), |
| 637 | void (*page_insert)(rt_page_t *page_head, struct rt_page *p, |
| 638 | rt_uint32_t size_bits), |
| 639 | void (*page_alloc)(rt_page_t page)) |
| 640 | { |
| 641 | rt_page_t *pgls_head = _get_pgls_head(agr_pgls, affid, size_bits); |
| 642 | rt_page_t p = *pgls_head; |
| 643 | |
| 644 | if (p) |
| 645 | { |
| 646 | page_remove(pgls_head, p, size_bits); |
| 647 | } |
| 648 | else |
| 649 | { |
| 650 | rt_uint32_t level; |
| 651 | rt_page_t head; |
| 652 | |
| 653 | /* fallback for allocation */ |
| 654 | for (level = size_bits + 1; level < RT_PAGE_MAX_ORDER; level++) |
| 655 | { |
| 656 | pgls_head = _get_pgls_head(agr_pgls, affid, level); |
| 657 | p = *pgls_head; |
| 658 | if (p) |
| 659 | { |
| 660 | break; |
| 661 | } |
| 662 | } |
| 663 | if (level == RT_PAGE_MAX_ORDER) |
| 664 | { |
| 665 | return 0; |
| 666 | } |
| 667 | |
| 668 | page_remove(pgls_head, p, level); |
| 669 | |
| 670 | /* pick the page satisfied the affinity tag */ |
| 671 | head = p; |
| 672 | p = head + (affid - (affid & AFFID_BITS_MASK(level))); |
| 673 | page_alloc(p); |
| 674 | |
| 675 | /* release the pages caller don't need */ |
| 676 | while (level > size_bits) |
| 677 | { |
| 678 | long lower_bits = level - 1; |
| 679 | rt_page_t middle = _buddy_get(head, lower_bits); |
| 680 | if (p >= middle) |
| 681 | { |
| 682 | page_insert( |
| 683 | _get_pgls_head_by_page(agr_pgls, head, lower_bits), |
| 684 | head, lower_bits); |
| 685 | head = middle; |
| 686 | } |
| 687 | else |
| 688 | { |
| 689 | page_insert( |
| 690 | _get_pgls_head_by_page(agr_pgls, middle, lower_bits), |
no test coverage detected