Skip to content
This repository was archived by the owner on May 20, 2025. It is now read-only.

Commit ada086b

Browse files
committed
mimalloc: consider heap tag when checking available abandoned pages
The logic in mi_segment_check_free didn't match the logic in mi_segment_reclaim/right_page_reclaimed, which led to a segment being reclaimed that did not have available pages for the appropriate heap. This triggered an assertion error in mi_segment_page_alloc_in. Bug was probably introduced in 45e0ec5 Fixes #68
1 parent 70cc038 commit ada086b

1 file changed

Lines changed: 3 additions & 3 deletions

File tree

Objects/mimalloc/segment.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,7 +1041,7 @@ void _mi_segment_page_abandon(mi_page_t* page, mi_segments_tld_t* tld) {
10411041
----------------------------------------------------------- */
10421042

10431043
// Possibly clear pages and check if free space is available
1044-
static bool mi_segment_check_free(mi_segment_t* segment, size_t block_size, bool* all_pages_free)
1044+
static bool mi_segment_check_free(mi_segment_t* segment, size_t block_size, int tag, bool* all_pages_free)
10451045
{
10461046
mi_assert_internal(block_size < MI_HUGE_BLOCK_SIZE);
10471047
bool has_page = false;
@@ -1059,7 +1059,7 @@ static bool mi_segment_check_free(mi_segment_t* segment, size_t block_size, bool
10591059
pages_used_empty++;
10601060
has_page = true;
10611061
}
1062-
else if (page->xblock_size == block_size && mi_page_has_any_available(page)) {
1062+
else if (page->xblock_size == block_size && mi_page_has_any_available(page) && page->tag == tag) {
10631063
// a page has available free blocks of the right size
10641064
has_page = true;
10651065
}
@@ -1170,7 +1170,7 @@ static mi_segment_t* mi_segment_try_reclaim(mi_heap_t* heap, size_t block_size,
11701170
while ((max_tries-- > 0) && ((segment = mi_abandoned_pop()) != NULL)) {
11711171
segment->abandoned_visits++;
11721172
bool all_pages_free;
1173-
bool has_page = mi_segment_check_free(segment,block_size,&all_pages_free); // try to free up pages (due to concurrent frees)
1173+
bool has_page = mi_segment_check_free(segment,block_size,heap->tag,&all_pages_free); // try to free up pages (due to concurrent frees)
11741174
if (all_pages_free) {
11751175
// free the segment (by forced reclaim) to make it available to other threads.
11761176
// note1: we prefer to free a segment as that might lead to reclaiming another

0 commit comments

Comments
 (0)