Retire a page with no more used blocks Important to not retire too quickly though as new allocations might coming. Note: called from `mi_free` and benchmarks often trigger this due to freeing everything and then allocating again so careful when changing this.
| 426 | // trigger this due to freeing everything and then |
| 427 | // allocating again so careful when changing this. |
| 428 | void _mi_page_retire(mi_page_t* page) mi_attr_noexcept { |
| 429 | mi_assert_internal(page != NULL); |
| 430 | mi_assert_expensive(_mi_page_is_valid(page)); |
| 431 | mi_assert_internal(mi_page_all_free(page)); |
| 432 | |
| 433 | mi_page_set_has_aligned(page, false); |
| 434 | |
| 435 | // don't retire too often.. |
| 436 | // (or we end up retiring and re-allocating most of the time) |
| 437 | // NOTE: refine this more: we should not retire if this |
| 438 | // is the only page left with free blocks. It is not clear |
| 439 | // how to check this efficiently though... |
| 440 | // for now, we don't retire if it is the only page left of this size class. |
| 441 | mi_page_queue_t* pq = mi_page_queue_of(page); |
| 442 | if mi_likely(page->xblock_size <= MI_MAX_RETIRE_SIZE && !mi_page_queue_is_special(pq)) { // not too large && not full or huge queue? |
| 443 | if (pq->last==page && pq->first==page) { // the only page in the queue? |
| 444 | mi_stat_counter_increase(_mi_stats_main.page_no_retire,1); |
| 445 | page->retire_expire = 1 + (page->xblock_size <= MI_SMALL_OBJ_SIZE_MAX ? MI_RETIRE_CYCLES : MI_RETIRE_CYCLES/4); |
| 446 | mi_heap_t* heap = mi_page_heap(page); |
| 447 | mi_assert_internal(pq >= heap->pages); |
| 448 | const size_t index = pq - heap->pages; |
| 449 | mi_assert_internal(index < MI_BIN_FULL && index < MI_BIN_HUGE); |
| 450 | if (index < heap->page_retired_min) heap->page_retired_min = index; |
| 451 | if (index > heap->page_retired_max) heap->page_retired_max = index; |
| 452 | mi_assert_internal(mi_page_all_free(page)); |
| 453 | return; // dont't free after all |
| 454 | } |
| 455 | } |
| 456 | _mi_page_free(page, pq, false); |
| 457 | } |
| 458 | |
| 459 | // free retired pages: we don't need to look at the entire queues |
| 460 | // since we only retire pages that are at the head position in a queue. |
no test coverage detected