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

Function _mi_mem_free

3rd/mimalloc-2.0.9/src/region.c:393–447  ·  view source on GitHub ↗

Free previously allocated memory with a given id.

Source from the content-addressed store, hash-verified

391
392// Free previously allocated memory with a given id.
393void _mi_mem_free(void* p, size_t size, size_t alignment, size_t align_offset, size_t id, bool full_commit, bool any_reset, mi_os_tld_t* tld) {
394 mi_assert_internal(size > 0 && tld != NULL);
395 if (p==NULL) return;
396 if (size==0) return;
397 size = _mi_align_up(size, _mi_os_page_size());
398
399 size_t arena_memid = 0;
400 mi_bitmap_index_t bit_idx;
401 mem_region_t* region;
402 if (mi_memid_is_arena(id,&region,&bit_idx,&arena_memid)) {
403 // was a direct arena allocation, pass through
404 _mi_arena_free(p, size, alignment, align_offset, arena_memid, full_commit, tld->stats);
405 }
406 else {
407 // allocated in a region
408 mi_assert_internal(align_offset == 0);
409 mi_assert_internal(size <= MI_REGION_MAX_OBJ_SIZE); if (size > MI_REGION_MAX_OBJ_SIZE) return;
410 const size_t blocks = mi_region_block_count(size);
411 mi_assert_internal(blocks + bit_idx <= MI_BITMAP_FIELD_BITS);
412 mi_region_info_t info;
413 info.value = mi_atomic_load_acquire(&region->info);
414 mi_assert_internal(info.value != 0);
415 void* blocks_start = mi_region_blocks_start(region, bit_idx);
416 mi_assert_internal(blocks_start == p); // not a pointer in our area?
417 mi_assert_internal(bit_idx + blocks <= MI_BITMAP_FIELD_BITS);
418 if (blocks_start != p || bit_idx + blocks > MI_BITMAP_FIELD_BITS) return; // or `abort`?
419
420 // committed?
421 if (full_commit && (size % MI_SEGMENT_SIZE) == 0) {
422 _mi_bitmap_claim(&region->commit, 1, blocks, bit_idx, NULL);
423 }
424
425 if (any_reset) {
426 // set the is_reset bits if any pages were reset
427 _mi_bitmap_claim(&region->reset, 1, blocks, bit_idx, NULL);
428 }
429
430 // reset the blocks to reduce the working set.
431 if (!info.x.is_large && !info.x.is_pinned && mi_option_is_enabled(mi_option_segment_reset)
432 && (mi_option_is_enabled(mi_option_eager_commit) ||
433 mi_option_is_enabled(mi_option_reset_decommits))) // cannot reset halfway committed segments, use only `option_page_reset` instead
434 {
435 bool any_unreset;
436 _mi_bitmap_claim(&region->reset, 1, blocks, bit_idx, &any_unreset);
437 if (any_unreset) {
438 _mi_abandoned_await_readers(); // ensure no more pending write (in case reset = decommit)
439 _mi_mem_reset(p, blocks * MI_SEGMENT_SIZE, tld);
440 }
441 }
442
443 // and unclaim
444 bool all_unclaimed = mi_bitmap_unclaim(&region->in_use, 1, blocks, bit_idx);
445 mi_assert_internal(all_unclaimed); MI_UNUSED(all_unclaimed);
446 }
447}
448
449
450/* ----------------------------------------------------------------------------

Callers

nothing calls this directly

Calls 10

_mi_align_upFunction · 0.85
_mi_os_page_sizeFunction · 0.85
mi_memid_is_arenaFunction · 0.85
_mi_arena_freeFunction · 0.85
mi_region_block_countFunction · 0.85
mi_region_blocks_startFunction · 0.85
_mi_bitmap_claimFunction · 0.85
mi_option_is_enabledFunction · 0.85
_mi_mem_resetFunction · 0.85

Tested by

no test coverage detected