Skip to content

Commit 96b69d7

Browse files
committed
fix leak where OS abandoned blocks were not always reclaimed
1 parent 00dacba commit 96b69d7

File tree

5 files changed

+361
-291
lines changed

5 files changed

+361
-291
lines changed

include/mimalloc/internal.h

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -131,13 +131,17 @@ void* _mi_arena_meta_zalloc(size_t size, mi_memid_t* memid);
131131
void _mi_arena_meta_free(void* p, mi_memid_t memid, size_t size);
132132

133133
typedef struct mi_arena_field_cursor_s { // abstract struct
134-
size_t start;
135-
size_t end;
136-
size_t bitmap_idx;
137-
mi_subproc_t* subproc;
134+
size_t os_list_count; // max entries to visit in the OS abandoned list
135+
size_t start; // start arena idx (may need to be wrapped)
136+
size_t end; // end arena idx (exclusive, may need to be wrapped)
137+
size_t bitmap_idx; // current bit idx for an arena
138+
mi_subproc_t* subproc; // only visit blocks in this sub-process
139+
bool visit_all; // ensure all abandoned blocks are seen (blocking)
140+
bool hold_visit_lock; // if the subproc->abandoned_os_visit_lock is held
138141
} mi_arena_field_cursor_t;
139-
void _mi_arena_field_cursor_init(mi_heap_t* heap, mi_subproc_t* subproc, mi_arena_field_cursor_t* current);
140-
mi_segment_t* _mi_arena_segment_clear_abandoned_next(mi_arena_field_cursor_t* previous, bool visit_all);
142+
void _mi_arena_field_cursor_init(mi_heap_t* heap, mi_subproc_t* subproc, bool visit_all, mi_arena_field_cursor_t* current);
143+
mi_segment_t* _mi_arena_segment_clear_abandoned_next(mi_arena_field_cursor_t* previous);
144+
void _mi_arena_field_cursor_done(mi_arena_field_cursor_t* current);
141145

142146
// "segment-map.c"
143147
void _mi_segment_map_allocated_at(const mi_segment_t* segment);

include/mimalloc/types.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -613,7 +613,8 @@ void _mi_stat_counter_increase(mi_stat_counter_t* stat, size_t amount);
613613
struct mi_subproc_s {
614614
_Atomic(size_t) abandoned_count; // count of abandoned segments for this sub-process
615615
_Atomic(size_t) abandoned_os_list_count; // count of abandoned segments in the os-list
616-
mi_lock_t abandoned_os_lock; // lock for the abandoned segments outside of arena's
616+
mi_lock_t abandoned_os_lock; // lock for the abandoned os segment list (outside of arena's) (this lock protect list operations)
617+
mi_lock_t abandoned_os_visit_lock; // ensure only one thread per subproc visits the abandoned os list
617618
mi_segment_t* abandoned_os_list; // doubly-linked list of abandoned segments outside of arena's (in OS allocated memory)
618619
mi_segment_t* abandoned_os_list_tail; // the tail-end of the list
619620
mi_memid_t memid; // provenance of this memory block

0 commit comments

Comments
 (0)