@@ -120,11 +120,7 @@ static void mi_arena_segment_os_mark_abandoned(mi_segment_t* segment) {
120120 mi_assert (segment -> memid .memkind != MI_MEM_ARENA );
121121 // not in an arena; we use a list of abandoned segments
122122 mi_subproc_t * const subproc = segment -> subproc ;
123- if (!mi_lock_acquire (& subproc -> abandoned_os_lock )) {
124- _mi_error_message (EFAULT , "internal error: failed to acquire the abandoned (os) segment lock to mark abandonment" );
125- // we can continue but cannot visit/reclaim such blocks..
126- }
127- else {
123+ mi_lock (& subproc -> abandoned_os_lock ) {
128124 // push on the tail of the list (important for the visitor)
129125 mi_segment_t * prev = subproc -> abandoned_os_list_tail ;
130126 mi_assert_internal (prev == NULL || prev -> abandoned_os_next == NULL );
@@ -138,7 +134,6 @@ static void mi_arena_segment_os_mark_abandoned(mi_segment_t* segment) {
138134 mi_atomic_increment_relaxed (& subproc -> abandoned_os_list_count );
139135 mi_atomic_increment_relaxed (& subproc -> abandoned_count );
140136 // and release the lock
141- mi_lock_release (& subproc -> abandoned_os_lock );
142137 }
143138 return ;
144139}
@@ -251,7 +246,7 @@ static mi_segment_t* mi_arena_segment_clear_abandoned_next_field(mi_arena_field_
251246 if mi_unlikely (field != 0 ) { // skip zero fields quickly
252247 // we only take the arena lock if there are actually abandoned segments present
253248 if (!has_lock && mi_option_is_enabled (mi_option_visit_abandoned )) {
254- has_lock = (previous -> visit_all ? mi_lock_acquire (& arena -> abandoned_visit_lock ) : mi_lock_try_acquire (& arena -> abandoned_visit_lock ));
249+ has_lock = (previous -> visit_all ? ( mi_lock_acquire (& arena -> abandoned_visit_lock ),true ) : mi_lock_try_acquire (& arena -> abandoned_visit_lock ));
255250 if (!has_lock ) {
256251 if (previous -> visit_all ) {
257252 _mi_error_message (EFAULT , "internal error: failed to visit all abandoned segments due to failure to acquire the visitor lock" );
@@ -289,8 +284,8 @@ static mi_segment_t* mi_arena_segment_clear_abandoned_next_list(mi_arena_field_c
289284 // we only allow one thread per sub-process to do to visit guarded by the `abandoned_os_visit_lock`.
290285 // The lock is released when the cursor is released.
291286 if (!previous -> hold_visit_lock ) {
292- previous -> hold_visit_lock = (previous -> visit_all ? mi_lock_acquire (& previous -> subproc -> abandoned_os_visit_lock )
293- : mi_lock_try_acquire (& previous -> subproc -> abandoned_os_visit_lock ));
287+ previous -> hold_visit_lock = (previous -> visit_all ? ( mi_lock_acquire (& previous -> subproc -> abandoned_os_visit_lock ),true )
288+ : mi_lock_try_acquire (& previous -> subproc -> abandoned_os_visit_lock ));
294289 if (!previous -> hold_visit_lock ) {
295290 if (previous -> visit_all ) {
296291 _mi_error_message (EFAULT , "internal error: failed to visit all abandoned segments due to failure to acquire the OS visitor lock" );
@@ -301,21 +296,15 @@ static mi_segment_t* mi_arena_segment_clear_abandoned_next_list(mi_arena_field_c
301296 // One list entry at a time
302297 while (previous -> os_list_count > 0 ) {
303298 previous -> os_list_count -- ;
304- const bool has_lock = mi_lock_acquire (& previous -> subproc -> abandoned_os_lock ); // this could contend with concurrent OS block abandonment and reclaim from `free`
305- if (has_lock ) {
306- mi_segment_t * segment = previous -> subproc -> abandoned_os_list ;
307- // pop from head of the list, a subsequent mark will push at the end (and thus we iterate through os_list_count entries)
308- if (segment == NULL || mi_arena_segment_os_clear_abandoned (segment , false /* we already have the lock */ )) {
309- mi_lock_release (& previous -> subproc -> abandoned_os_lock );
310- return segment ;
311- }
312- // already abandoned, try again
299+ mi_lock_acquire (& previous -> subproc -> abandoned_os_lock ); // this could contend with concurrent OS block abandonment and reclaim from `free`
300+ mi_segment_t * segment = previous -> subproc -> abandoned_os_list ;
301+ // pop from head of the list, a subsequent mark will push at the end (and thus we iterate through os_list_count entries)
302+ if (segment == NULL || mi_arena_segment_os_clear_abandoned (segment , false /* we already have the lock */ )) {
313303 mi_lock_release (& previous -> subproc -> abandoned_os_lock );
304+ return segment ;
314305 }
315- else {
316- _mi_error_message (EFAULT , "failed to acquire abandoned OS list lock during abandoned block visit\n" );
317- return NULL ;
318- }
306+ // already abandoned, try again
307+ mi_lock_release (& previous -> subproc -> abandoned_os_lock );
319308 }
320309 // done
321310 mi_assert_internal (previous -> os_list_count == 0 );
0 commit comments