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

Function mi_segment_check_free

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

Possibly free pages and check if free space is available

Source from the content-addressed store, hash-verified

1277
1278// Possibly free pages and check if free space is available
1279static bool mi_segment_check_free(mi_segment_t* segment, size_t slices_needed, size_t block_size, mi_segments_tld_t* tld)
1280{
1281 mi_assert_internal(block_size < MI_HUGE_BLOCK_SIZE);
1282 mi_assert_internal(mi_segment_is_abandoned(segment));
1283 bool has_page = false;
1284
1285 // for all slices
1286 const mi_slice_t* end;
1287 mi_slice_t* slice = mi_slices_start_iterate(segment, &end);
1288 while (slice < end) {
1289 mi_assert_internal(slice->slice_count > 0);
1290 mi_assert_internal(slice->slice_offset == 0);
1291 if (mi_slice_is_used(slice)) { // used page
1292 // ensure used count is up to date and collect potential concurrent frees
1293 mi_page_t* const page = mi_slice_to_page(slice);
1294 _mi_page_free_collect(page, false);
1295 if (mi_page_all_free(page)) {
1296 // if this page is all free now, free it without adding to any queues (yet)
1297 mi_assert_internal(page->next == NULL && page->prev==NULL);
1298 _mi_stat_decrease(&tld->stats->pages_abandoned, 1);
1299 segment->abandoned--;
1300 slice = mi_segment_page_clear(page, tld); // re-assign slice due to coalesce!
1301 mi_assert_internal(!mi_slice_is_used(slice));
1302 if (slice->slice_count >= slices_needed) {
1303 has_page = true;
1304 }
1305 }
1306 else {
1307 if (page->xblock_size == block_size && mi_page_has_any_available(page)) {
1308 // a page has available free blocks of the right size
1309 has_page = true;
1310 }
1311 }
1312 }
1313 else {
1314 // empty span
1315 if (slice->slice_count >= slices_needed) {
1316 has_page = true;
1317 }
1318 }
1319 slice = slice + slice->slice_count;
1320 }
1321 return has_page;
1322}
1323
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.

Callers 2

mi_segment_try_reclaimFunction · 0.85
_mi_abandoned_collectFunction · 0.85

Calls 9

mi_segment_is_abandonedFunction · 0.85
mi_slices_start_iterateFunction · 0.85
mi_slice_is_usedFunction · 0.85
mi_slice_to_pageFunction · 0.85
_mi_page_free_collectFunction · 0.85
mi_page_all_freeFunction · 0.85
_mi_stat_decreaseFunction · 0.85
mi_segment_page_clearFunction · 0.85

Tested by

no test coverage detected