From 698bb2cae70dbe096d6ece60670ac5e3897f5da2 Mon Sep 17 00:00:00 2001 From: daan Date: Mon, 31 Oct 2022 11:01:01 -0700 Subject: [PATCH] split out _mi_page_try_use_delayed_free for contention reduction (issue #630) --- include/mimalloc-internal.h | 3 ++- src/alloc.c | 2 +- src/page.c | 8 +++++++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/include/mimalloc-internal.h b/include/mimalloc-internal.h index eecfea0d..23981240 100644 --- a/include/mimalloc-internal.h +++ b/include/mimalloc-internal.h @@ -117,7 +117,8 @@ void _mi_heap_delayed_free_all(mi_heap_t* heap); bool _mi_heap_delayed_free_partial(mi_heap_t* heap); void _mi_heap_collect_retired(mi_heap_t* heap, bool force); -bool _mi_page_use_delayed_free(mi_page_t* page, mi_delayed_t delay, bool override_never); +void _mi_page_use_delayed_free(mi_page_t* page, mi_delayed_t delay, bool override_never); +bool _mi_page_try_use_delayed_free(mi_page_t* page, mi_delayed_t delay, bool override_never); size_t _mi_page_queue_append(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_queue_t* append); void _mi_deferred_free(mi_heap_t* heap, bool force); diff --git a/src/alloc.c b/src/alloc.c index 44c0bf8b..10945702 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -531,7 +531,7 @@ bool _mi_free_delayed_block(mi_block_t* block) { // some blocks may end up in the page `thread_free` list with no blocks in the // heap `thread_delayed_free` list which may cause the page to be never freed! // (it would only be freed if we happen to scan it in `mi_page_queue_find_free_ex`) - if (!_mi_page_use_delayed_free(page, MI_USE_DELAYED_FREE, false /* dont overwrite never delayed */)) { + if (!_mi_page_try_use_delayed_free(page, MI_USE_DELAYED_FREE, false /* dont overwrite never delayed */)) { return false; } diff --git a/src/page.c b/src/page.c index f09753d6..26b9c9f1 100644 --- a/src/page.c +++ b/src/page.c @@ -122,7 +122,13 @@ bool _mi_page_is_valid(mi_page_t* page) { } #endif -bool _mi_page_use_delayed_free(mi_page_t* page, mi_delayed_t delay, bool override_never) { +void _mi_page_use_delayed_free(mi_page_t* page, mi_delayed_t delay, bool override_never) { + while (!_mi_page_try_use_delayed_free(page, delay, override_never)) { + mi_atomic_yield(); + } +} + +bool _mi_page_try_use_delayed_free(mi_page_t* page, mi_delayed_t delay, bool override_never) { mi_thread_free_t tfreex; mi_delayed_t old_delay; mi_thread_free_t tfree;