mirror of
https://github.com/microsoft/mimalloc.git
synced 2024-12-28 22:05:40 +08:00
refactor delayed_free code
This commit is contained in:
parent
5ad2effb39
commit
49ceb4d018
@ -90,7 +90,7 @@ void* _mi_page_malloc(mi_heap_t* heap, mi_page_t* page, size_t size) mi_at
|
|||||||
void* _mi_heap_malloc_zero(mi_heap_t* heap, size_t size, bool zero);
|
void* _mi_heap_malloc_zero(mi_heap_t* heap, size_t size, bool zero);
|
||||||
void* _mi_heap_realloc_zero(mi_heap_t* heap, void* p, size_t newsize, bool zero);
|
void* _mi_heap_realloc_zero(mi_heap_t* heap, void* p, size_t newsize, bool zero);
|
||||||
mi_block_t* _mi_page_ptr_unalign(const mi_segment_t* segment, const mi_page_t* page, const void* p);
|
mi_block_t* _mi_page_ptr_unalign(const mi_segment_t* segment, const mi_page_t* page, const void* p);
|
||||||
void _mi_free_delayed_block(mi_page_t* page, mi_block_t* block);
|
bool _mi_free_delayed_block(mi_block_t* block);
|
||||||
|
|
||||||
#if MI_DEBUG>1
|
#if MI_DEBUG>1
|
||||||
bool _mi_page_is_valid(mi_page_t* page);
|
bool _mi_page_is_valid(mi_page_t* page);
|
||||||
|
14
src/alloc.c
14
src/alloc.c
@ -249,8 +249,20 @@ void mi_free(void* p) mi_attr_noexcept
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _mi_free_delayed_block(mi_page_t* page, mi_block_t* block) {
|
bool _mi_free_delayed_block(mi_block_t* block) {
|
||||||
|
// get segment and page
|
||||||
|
const mi_segment_t* segment = _mi_ptr_segment(block);
|
||||||
|
mi_assert_internal(_mi_ptr_cookie(segment) == segment->cookie);
|
||||||
|
mi_assert_internal(_mi_thread_id() == segment->thread_id);
|
||||||
|
mi_page_t* page = _mi_segment_page_of(segment, block);
|
||||||
|
if (mi_tf_delayed(page->thread_free) == MI_DELAYED_FREEING) {
|
||||||
|
// we might already start delayed freeing while another thread has not yet
|
||||||
|
// reset the delayed_freeing flag; in that case don't free it quite yet if
|
||||||
|
// this is the last block remaining.
|
||||||
|
if (page->used - page->thread_freed == 1) return false;
|
||||||
|
}
|
||||||
_mi_free_block(page,true,block);
|
_mi_free_block(page,true,block);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bytes available in a block
|
// Bytes available in a block
|
||||||
|
18
src/page.c
18
src/page.c
@ -139,8 +139,8 @@ void _mi_page_use_delayed_free(mi_page_t* page, mi_delayed_t delay ) {
|
|||||||
static void mi_page_thread_free_collect(mi_page_t* page)
|
static void mi_page_thread_free_collect(mi_page_t* page)
|
||||||
{
|
{
|
||||||
mi_block_t* head;
|
mi_block_t* head;
|
||||||
mi_thread_free_t tfree = 0;
|
mi_thread_free_t tfree;
|
||||||
mi_thread_free_t tfreex = 0;
|
mi_thread_free_t tfreex;
|
||||||
do {
|
do {
|
||||||
tfreex = tfree = page->thread_free;
|
tfreex = tfree = page->thread_free;
|
||||||
head = mi_tf_block(tfree);
|
head = mi_tf_block(tfree);
|
||||||
@ -258,18 +258,10 @@ void _mi_heap_delayed_free(mi_heap_t* heap) {
|
|||||||
// and free them all
|
// and free them all
|
||||||
while(block != NULL) {
|
while(block != NULL) {
|
||||||
mi_block_t* next = mi_block_nextx(heap->cookie,block);
|
mi_block_t* next = mi_block_nextx(heap->cookie,block);
|
||||||
// get segment and page
|
// use internal free instead of regular one to keep stats etc correct
|
||||||
const mi_segment_t* segment = _mi_ptr_segment(block);
|
if (!_mi_free_delayed_block(block)) {
|
||||||
mi_assert_internal(_mi_ptr_cookie(segment) == segment->cookie);
|
|
||||||
mi_assert_internal(_mi_thread_id() == segment->thread_id);
|
|
||||||
mi_page_t* page = _mi_segment_page_of(segment, block);
|
|
||||||
if (mi_tf_delayed(page->thread_free) != MI_DELAYED_FREEING) {
|
|
||||||
// use internal free instead of regular one to keep stats etc correct
|
|
||||||
_mi_free_delayed_block(page,block);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// we might already start delayed freeing while another thread has not yet
|
// we might already start delayed freeing while another thread has not yet
|
||||||
// reset the flag; in that case delay it further :-(
|
// reset the delayed_freeing flag; in that case delay it further by reinserting.
|
||||||
mi_block_t* dfree;
|
mi_block_t* dfree;
|
||||||
do {
|
do {
|
||||||
dfree = (mi_block_t*)heap->thread_delayed_free;
|
dfree = (mi_block_t*)heap->thread_delayed_free;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user