MCPcopy Create free account
hub / github.com/CppCXY/EmmyLuaCodeStyle / mi_segment_try_reclaim

Function mi_segment_try_reclaim

3rd/mimalloc-2.0.9/src/segment.c:1396–1432  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1394}
1395
1396static mi_segment_t* mi_segment_try_reclaim(mi_heap_t* heap, size_t needed_slices, size_t block_size, bool* reclaimed, mi_segments_tld_t* tld)
1397{
1398 *reclaimed = false;
1399 mi_segment_t* segment;
1400 long max_tries = mi_option_get_clamp(mi_option_max_segment_reclaim, 8, 1024); // limit the work to bound allocation times
1401 while ((max_tries-- > 0) && ((segment = mi_abandoned_pop()) != NULL)) {
1402 segment->abandoned_visits++;
1403 // todo: an arena exclusive heap will potentially visit many abandoned unsuitable segments
1404 // and push them into the visited list and use many tries. Perhaps we can skip non-suitable ones in a better way?
1405 bool is_suitable = _mi_heap_memid_is_suitable(heap, segment->memid);
1406 bool has_page = mi_segment_check_free(segment,needed_slices,block_size,tld); // try to free up pages (due to concurrent frees)
1407 if (segment->used == 0) {
1408 // free the segment (by forced reclaim) to make it available to other threads.
1409 // note1: we prefer to free a segment as that might lead to reclaiming another
1410 // segment that is still partially used.
1411 // note2: we could in principle optimize this by skipping reclaim and directly
1412 // freeing but that would violate some invariants temporarily)
1413 mi_segment_reclaim(segment, heap, 0, NULL, tld);
1414 }
1415 else if (has_page && is_suitable) {
1416 // found a large enough free span, or a page of the right block_size with free space
1417 // we return the result of reclaim (which is usually `segment`) as it might free
1418 // the segment due to concurrent frees (in which case `NULL` is returned).
1419 return mi_segment_reclaim(segment, heap, block_size, reclaimed, tld);
1420 }
1421 else if (segment->abandoned_visits > 3 && is_suitable) {
1422 // always reclaim on 3rd visit to limit the abandoned queue length.
1423 mi_segment_reclaim(segment, heap, 0, NULL, tld);
1424 }
1425 else {
1426 // otherwise, push on the visited list so it gets not looked at too quickly again
1427 mi_segment_delayed_decommit(segment, true /* force? */, tld->stats); // forced decommit if needed as we may not visit soon again
1428 mi_abandoned_visited_push(segment);
1429 }
1430 }
1431 return NULL;
1432}
1433
1434
1435void _mi_abandoned_collect(mi_heap_t* heap, bool force, mi_segments_tld_t* tld)

Callers 1

Calls 7

mi_option_get_clampFunction · 0.85
mi_abandoned_popFunction · 0.85
mi_segment_check_freeFunction · 0.85
mi_segment_reclaimFunction · 0.85

Tested by

no test coverage detected