Find a page with free blocks of `page->block_size`.
| 701 | |
| 702 | // Find a page with free blocks of `page->block_size`. |
| 703 | static mi_page_t* mi_page_queue_find_free_ex(mi_heap_t* heap, mi_page_queue_t* pq, bool first_try) |
| 704 | { |
| 705 | // search through the pages in "next fit" order |
| 706 | size_t count = 0; |
| 707 | mi_page_t* page = pq->first; |
| 708 | while (page != NULL) |
| 709 | { |
| 710 | mi_page_t* next = page->next; // remember next |
| 711 | count++; |
| 712 | |
| 713 | // 0. collect freed blocks by us and other threads |
| 714 | _mi_page_free_collect(page, false); |
| 715 | |
| 716 | // 1. if the page contains free blocks, we are done |
| 717 | if (mi_page_immediate_available(page)) { |
| 718 | break; // pick this one |
| 719 | } |
| 720 | |
| 721 | // 2. Try to extend |
| 722 | if (page->capacity < page->reserved) { |
| 723 | mi_page_extend_free(heap, page, heap->tld); |
| 724 | mi_assert_internal(mi_page_immediate_available(page)); |
| 725 | break; |
| 726 | } |
| 727 | |
| 728 | // 3. If the page is completely full, move it to the `mi_pages_full` |
| 729 | // queue so we don't visit long-lived pages too often. |
| 730 | mi_assert_internal(!mi_page_is_in_full(page) && !mi_page_immediate_available(page)); |
| 731 | mi_page_to_full(page, pq); |
| 732 | |
| 733 | page = next; |
| 734 | } // for each page |
| 735 | |
| 736 | mi_heap_stat_counter_increase(heap, searches, count); |
| 737 | |
| 738 | if (page == NULL) { |
| 739 | _mi_heap_collect_retired(heap, false); // perhaps make a page available? |
| 740 | page = mi_page_fresh(heap, pq); |
| 741 | if (page == NULL && first_try) { |
| 742 | // out-of-memory _or_ an abandoned page with free blocks was reclaimed, try once again |
| 743 | page = mi_page_queue_find_free_ex(heap, pq, false); |
| 744 | } |
| 745 | } |
| 746 | else { |
| 747 | mi_assert(pq->first == page); |
| 748 | page->retire_expire = 0; |
| 749 | } |
| 750 | mi_assert_internal(page == NULL || mi_page_immediate_available(page)); |
| 751 | return page; |
| 752 | } |
| 753 | |
| 754 | |
| 755 |
no test coverage detected