mirror of
https://github.com/microsoft/mimalloc.git
synced 2025-01-14 16:47:59 +08:00
fix leak in abandoned block visiting
This commit is contained in:
parent
f7fe5bf20e
commit
635d626c82
@ -946,7 +946,9 @@ static bool mi_arena_visit_abandoned_blocks(mi_subproc_t* subproc, int heap_tag,
|
||||
_mi_arena_field_cursor_init(NULL, subproc, ¤t);
|
||||
mi_segment_t* segment;
|
||||
while ((segment = _mi_arena_segment_clear_abandoned_next(¤t, true /* visit all */)) != NULL) {
|
||||
if (!_mi_segment_visit_blocks(segment, heap_tag, visit_blocks, visitor, arg)) return false;
|
||||
bool ok = _mi_segment_visit_blocks(segment, heap_tag, visit_blocks, visitor, arg);
|
||||
_mi_arena_segment_mark_abandoned(segment);
|
||||
if (!ok) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -39,6 +39,10 @@ static int ITER = 50; // N full iterations destructing and re-creating a
|
||||
|
||||
#define STRESS // undefine for leak test
|
||||
|
||||
#ifndef NDEBUG
|
||||
#define HEAP_WALK // walk the heap objects?
|
||||
#endif
|
||||
|
||||
static bool allow_large_objects = true; // allow very large objects? (set to `true` if SCALE>100)
|
||||
static size_t use_one_size = 0; // use single object size of `N * sizeof(uintptr_t)`?
|
||||
|
||||
@ -129,7 +133,7 @@ static void free_items(void* p) {
|
||||
custom_free(p);
|
||||
}
|
||||
|
||||
/*
|
||||
#ifdef HEAP_WALK
|
||||
static bool visit_blocks(const mi_heap_t* heap, const mi_heap_area_t* area, void* block, size_t block_size, void* arg) {
|
||||
(void)(heap); (void)(area);
|
||||
size_t* total = (size_t*)arg;
|
||||
@ -138,7 +142,7 @@ static bool visit_blocks(const mi_heap_t* heap, const mi_heap_area_t* area, void
|
||||
}
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
|
||||
static void stress(intptr_t tid) {
|
||||
//bench_start_thread();
|
||||
@ -183,9 +187,12 @@ static void stress(intptr_t tid) {
|
||||
data[data_idx] = q;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HEAP_WALK
|
||||
// walk the heap
|
||||
// size_t total = 0;
|
||||
// mi_heap_visit_blocks(mi_heap_get_default(), true, visit_blocks, &total);
|
||||
size_t total = 0;
|
||||
mi_heap_visit_blocks(mi_heap_get_default(), true, visit_blocks, &total);
|
||||
#endif
|
||||
|
||||
// free everything that is left
|
||||
for (size_t i = 0; i < retain_top; i++) {
|
||||
@ -205,6 +212,10 @@ static void test_stress(void) {
|
||||
uintptr_t r = rand();
|
||||
for (int n = 0; n < ITER; n++) {
|
||||
run_os_threads(THREADS, &stress);
|
||||
#ifdef HEAP_WALK
|
||||
size_t total = 0;
|
||||
mi_abandoned_visit_blocks(mi_subproc_main(), -1, true, visit_blocks, &total);
|
||||
#endif
|
||||
for (int i = 0; i < TRANSFERS; i++) {
|
||||
if (chance(50, &r) || n + 1 == ITER) { // free all on last run, otherwise free half of the transfers
|
||||
void* p = atomic_exchange_ptr(&transfer[i], NULL);
|
||||
|
Loading…
x
Reference in New Issue
Block a user