mirror of
https://github.com/microsoft/mimalloc.git
synced 2024-12-28 22:05:40 +08:00
fix thread-id reset on page abandonment
This commit is contained in:
parent
ff88361329
commit
12257e5bc1
@ -323,7 +323,13 @@ static inline uintptr_t mi_page_thread_id(const mi_page_t* page) {
|
||||
}
|
||||
|
||||
static inline void mi_page_init_flags(mi_page_t* page, uintptr_t thread_id) {
|
||||
page->flags = thread_id;
|
||||
mi_assert_internal((thread_id & MI_PAGE_FLAGS_MASK) == 0);
|
||||
page->flags = thread_id;
|
||||
}
|
||||
|
||||
static inline void mi_page_set_thread_id(mi_page_t* page, uintptr_t thread_id) {
|
||||
mi_assert_internal((thread_id & MI_PAGE_FLAGS_MASK) == 0);
|
||||
page->flags = thread_id | (page->flags & MI_PAGE_FLAGS_MASK);
|
||||
}
|
||||
|
||||
static inline bool mi_page_is_in_full(const mi_page_t* page) {
|
||||
|
@ -231,6 +231,8 @@ static bool _mi_heap_done(void) {
|
||||
mi_heap_t* heap = _mi_heap_default;
|
||||
if (!mi_heap_is_initialized(heap)) return true;
|
||||
|
||||
void* p = mi_malloc(16);
|
||||
|
||||
// reset default heap
|
||||
_mi_heap_default = (_mi_is_main_thread() ? &_mi_heap_main : (mi_heap_t*)&_mi_heap_empty);
|
||||
|
||||
@ -239,7 +241,7 @@ static bool _mi_heap_done(void) {
|
||||
// switch to backing heap and free it
|
||||
heap = heap->tld->heap_backing;
|
||||
if (!mi_heap_is_initialized(heap)) return false;
|
||||
|
||||
|
||||
// collect if not the main thread
|
||||
if (heap != &_mi_heap_main) {
|
||||
_mi_heap_collect_abandon(heap);
|
||||
@ -258,6 +260,7 @@ static bool _mi_heap_done(void) {
|
||||
mi_assert_internal(heap->tld->heap_backing == &_mi_heap_main);
|
||||
}
|
||||
#endif
|
||||
mi_free(p);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -549,6 +549,11 @@ static void mi_segment_abandon(mi_segment_t* segment, mi_segments_tld_t* tld) {
|
||||
mi_assert_internal(segment->used > 0);
|
||||
mi_assert_internal(segment->abandoned_next == NULL);
|
||||
mi_assert_expensive(mi_segment_is_valid(segment));
|
||||
#if MI_DEBUG>1
|
||||
for (size_t i = 0; i < segment->capacity; i++) {
|
||||
mi_assert_internal(!segment->pages[i].segment_in_use || mi_page_thread_id(&segment->pages[i]) == 0);
|
||||
}
|
||||
#endif
|
||||
// remove the segment from the free page queue if needed
|
||||
mi_segment_remove_from_free_queue(segment,tld);
|
||||
mi_assert_internal(segment->next == NULL && segment->prev == NULL);
|
||||
@ -563,10 +568,11 @@ static void mi_segment_abandon(mi_segment_t* segment, mi_segments_tld_t* tld) {
|
||||
}
|
||||
|
||||
void _mi_segment_page_abandon(mi_page_t* page, mi_segments_tld_t* tld) {
|
||||
mi_assert(page != NULL);
|
||||
mi_assert(page != NULL && mi_page_thread_id(page) != 0);
|
||||
mi_segment_t* segment = _mi_page_segment(page);
|
||||
mi_assert_expensive(mi_segment_is_valid(segment));
|
||||
segment->abandoned++;
|
||||
mi_page_set_thread_id(page, 0);
|
||||
_mi_stat_increase(&tld->stats->pages_abandoned, 1);
|
||||
mi_assert_internal(segment->abandoned <= segment->used);
|
||||
if (segment->used == segment->abandoned) {
|
||||
@ -618,7 +624,7 @@ bool _mi_segment_try_reclaim_abandoned( mi_heap_t* heap, bool try_all, mi_segmen
|
||||
}
|
||||
else {
|
||||
// otherwise reclaim it
|
||||
mi_page_init_flags(page,segment->thread_id);
|
||||
mi_page_set_thread_id(page,segment->thread_id);
|
||||
_mi_page_reclaim(heap,page);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user