Abandon a page with used blocks at the end of a thread. Note: only call if it is ensured that no references exist from the `page->heap->thread_delayed_free` into this page. Currently only called through `mi_heap_collect_ex` which ensures this.
| 364 | // the `page->heap->thread_delayed_free` into this page. |
| 365 | // Currently only called through `mi_heap_collect_ex` which ensures this. |
| 366 | void _mi_page_abandon(mi_page_t* page, mi_page_queue_t* pq) { |
| 367 | mi_assert_internal(page != NULL); |
| 368 | mi_assert_expensive(_mi_page_is_valid(page)); |
| 369 | mi_assert_internal(pq == mi_page_queue_of(page)); |
| 370 | mi_assert_internal(mi_page_heap(page) != NULL); |
| 371 | |
| 372 | mi_heap_t* pheap = mi_page_heap(page); |
| 373 | |
| 374 | // remove from our page list |
| 375 | mi_segments_tld_t* segments_tld = &pheap->tld->segments; |
| 376 | mi_page_queue_remove(pq, page); |
| 377 | |
| 378 | // page is no longer associated with our heap |
| 379 | mi_assert_internal(mi_page_thread_free_flag(page)==MI_NEVER_DELAYED_FREE); |
| 380 | mi_page_set_heap(page, NULL); |
| 381 | |
| 382 | #if MI_DEBUG>1 |
| 383 | // check there are no references left.. |
| 384 | for (mi_block_t* block = (mi_block_t*)pheap->thread_delayed_free; block != NULL; block = mi_block_nextx(pheap, block, pheap->keys)) { |
| 385 | mi_assert_internal(_mi_ptr_page(block) != page); |
| 386 | } |
| 387 | #endif |
| 388 | |
| 389 | // and abandon it |
| 390 | mi_assert_internal(mi_page_heap(page) == NULL); |
| 391 | _mi_segment_page_abandon(page,segments_tld); |
| 392 | } |
| 393 | |
| 394 | |
| 395 | // Free a page with no more free blocks |
no test coverage detected