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

Function mi_segment_reclaim

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

Reclaim an abandoned segment; returns NULL if the segment was freed set `right_page_reclaimed` to `true` if it reclaimed a page of the right `block_size` that was not full.

Source from the content-addressed store, hash-verified

1324// Reclaim an abandoned segment; returns NULL if the segment was freed
1325// set `right_page_reclaimed` to `true` if it reclaimed a page of the right `block_size` that was not full.
1326static mi_segment_t* mi_segment_reclaim(mi_segment_t* segment, mi_heap_t* heap, size_t requested_block_size, bool* right_page_reclaimed, mi_segments_tld_t* tld) {
1327 mi_assert_internal(mi_atomic_load_ptr_relaxed(mi_segment_t, &segment->abandoned_next) == NULL);
1328 mi_assert_expensive(mi_segment_is_valid(segment, tld));
1329 if (right_page_reclaimed != NULL) { *right_page_reclaimed = false; }
1330
1331 segment->thread_id = _mi_thread_id();
1332 segment->abandoned_visits = 0;
1333 mi_segments_track_size((long)mi_segment_size(segment), tld);
1334 mi_assert_internal(segment->next == NULL);
1335 _mi_stat_decrease(&tld->stats->segments_abandoned, 1);
1336
1337 // for all slices
1338 const mi_slice_t* end;
1339 mi_slice_t* slice = mi_slices_start_iterate(segment, &end);
1340 while (slice < end) {
1341 mi_assert_internal(slice->slice_count > 0);
1342 mi_assert_internal(slice->slice_offset == 0);
1343 if (mi_slice_is_used(slice)) {
1344 // in use: reclaim the page in our heap
1345 mi_page_t* page = mi_slice_to_page(slice);
1346 mi_assert_internal(!page->is_reset);
1347 mi_assert_internal(page->is_committed);
1348 mi_assert_internal(mi_page_thread_free_flag(page)==MI_NEVER_DELAYED_FREE);
1349 mi_assert_internal(mi_page_heap(page) == NULL);
1350 mi_assert_internal(page->next == NULL && page->prev==NULL);
1351 _mi_stat_decrease(&tld->stats->pages_abandoned, 1);
1352 segment->abandoned--;
1353 // set the heap again and allow delayed free again
1354 mi_page_set_heap(page, heap);
1355 _mi_page_use_delayed_free(page, MI_USE_DELAYED_FREE, true); // override never (after heap is set)
1356 _mi_page_free_collect(page, false); // ensure used count is up to date
1357 if (mi_page_all_free(page)) {
1358 // if everything free by now, free the page
1359 slice = mi_segment_page_clear(page, tld); // set slice again due to coalesceing
1360 }
1361 else {
1362 // otherwise reclaim it into the heap
1363 _mi_page_reclaim(heap, page);
1364 if (requested_block_size == page->xblock_size && mi_page_has_any_available(page)) {
1365 if (right_page_reclaimed != NULL) { *right_page_reclaimed = true; }
1366 }
1367 }
1368 }
1369 else {
1370 // the span is free, add it to our page queues
1371 slice = mi_segment_span_free_coalesce(slice, tld); // set slice again due to coalesceing
1372 }
1373 mi_assert_internal(slice->slice_count>0 && slice->slice_offset==0);
1374 slice = slice + slice->slice_count;
1375 }
1376
1377 mi_assert(segment->abandoned == 0);
1378 if (segment->used == 0) { // due to page_clear
1379 mi_assert_internal(right_page_reclaimed == NULL || !(*right_page_reclaimed));
1380 mi_segment_free(segment, false, tld);
1381 return NULL;
1382 }
1383 else {

Callers 3

mi_segment_try_reclaimFunction · 0.85
_mi_abandoned_collectFunction · 0.85

Calls 15

mi_segment_is_validFunction · 0.85
_mi_thread_idFunction · 0.85
mi_segments_track_sizeFunction · 0.85
mi_segment_sizeFunction · 0.85
_mi_stat_decreaseFunction · 0.85
mi_slices_start_iterateFunction · 0.85
mi_slice_is_usedFunction · 0.85
mi_slice_to_pageFunction · 0.85
mi_page_thread_free_flagFunction · 0.85
mi_page_heapFunction · 0.85
mi_page_set_heapFunction · 0.85

Tested by

no test coverage detected