Пример #1
0
        // 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.
        private static partial void _mi_page_abandon(mi_page_t *page, mi_page_queue_t *pq)
        {
            mi_assert_internal((MI_DEBUG > 1) && (page != null));
            mi_assert_expensive((MI_DEBUG > 2) && _mi_page_is_valid(page));
            mi_assert_internal((MI_DEBUG > 1) && (pq == mi_page_queue_of(page)));
            mi_assert_internal((MI_DEBUG > 1) && (mi_page_heap(page) != null));

            mi_heap_t *pheap = mi_page_heap(page);

            // remove from our page list
            mi_segments_tld_t *segments_tld = &pheap->tld->segments;

            mi_page_queue_remove(pq, page);

            // page is no longer associated with our heap
            mi_assert_internal((MI_DEBUG > 1) && (mi_page_thread_free_flag(page) == MI_NEVER_DELAYED_FREE));
            mi_page_set_heap(page, null);

            if (MI_DEBUG > 1)
            {
                // check there are no references left..
                for (mi_block_t *block = (mi_block_t *)pheap->thread_delayed_free; block != null; block = mi_block_nextx(pheap, block, &pheap->keys.e0))
                {
                    mi_assert_internal((MI_DEBUG > 1) && (_mi_ptr_page(block) != page));
                }
            }

            // and abandon it
            mi_assert_internal((MI_DEBUG > 1) && (mi_page_heap(page) == null));
            _mi_segment_page_abandon(page, segments_tld);
        }
Пример #2
0
        // Free a page with no more free blocks
        private static partial void _mi_page_free(mi_page_t *page, mi_page_queue_t *pq, bool force)
        {
            mi_assert_internal((MI_DEBUG > 1) && (page != null));
            mi_assert_expensive((MI_DEBUG > 2) && _mi_page_is_valid(page));
            mi_assert_internal((MI_DEBUG > 1) && (pq == mi_page_queue_of(page)));
            mi_assert_internal((MI_DEBUG > 1) && mi_page_all_free(page));
            mi_assert_internal((MI_DEBUG > 1) && (mi_page_thread_free_flag(page) != MI_DELAYED_FREEING));

            // no more aligned blocks in here
            mi_page_set_has_aligned(page, false);

            // remove from the page list
            // (no need to do _mi_heap_delayed_free first as all blocks are already free)
            mi_segments_tld_t *segments_tld = &mi_page_heap(page)->tld->segments;

            mi_page_queue_remove(pq, page);

            // and free it
            mi_page_set_heap(page, null);
            _mi_segment_page_free(page, force, segments_tld);
        }