add recursion guard to deferred callback

This commit is contained in:
daan 2019-09-09 08:02:41 -07:00
parent e227341f5b
commit 23155c5d71
4 changed files with 7 additions and 4 deletions

View file

@ -405,6 +405,7 @@ typedef struct mi_os_tld_s {
// Thread local data // Thread local data
struct mi_tld_s { struct mi_tld_s {
unsigned long long heartbeat; // monotonic heartbeat count unsigned long long heartbeat; // monotonic heartbeat count
bool recurse; // true if deferred was called; used to prevent infinite recursion.
mi_heap_t* heap_backing; // backing heap of this thread (cannot be deleted) mi_heap_t* heap_backing; // backing heap of this thread (cannot be deleted)
mi_segments_tld_t segments; // segment tld mi_segments_tld_t segments; // segment tld
mi_os_tld_t os; // os tld mi_os_tld_t os; // os tld

View file

@ -110,7 +110,7 @@ static void mi_heap_collect_ex(mi_heap_t* heap, mi_collect_t collect)
{ {
if (!mi_heap_is_initialized(heap)) return; if (!mi_heap_is_initialized(heap)) return;
_mi_deferred_free(heap, collect > NORMAL); _mi_deferred_free(heap, collect > NORMAL);
// collect (some) abandoned pages // collect (some) abandoned pages
if (collect >= NORMAL && !heap->no_reclaim) { if (collect >= NORMAL && !heap->no_reclaim) {
if (collect == NORMAL) { if (collect == NORMAL) {

View file

@ -96,7 +96,7 @@ mi_decl_thread mi_heap_t* _mi_heap_default = (mi_heap_t*)&_mi_heap_empty;
#define tld_main_stats ((mi_stats_t*)((uint8_t*)&tld_main + offsetof(mi_tld_t,stats))) #define tld_main_stats ((mi_stats_t*)((uint8_t*)&tld_main + offsetof(mi_tld_t,stats)))
static mi_tld_t tld_main = { static mi_tld_t tld_main = {
0, 0, false,
&_mi_heap_main, &_mi_heap_main,
{ { NULL, NULL }, {NULL ,NULL}, 0, 0, 0, 0, 0, 0, NULL, tld_main_stats }, // segments { { NULL, NULL }, {NULL ,NULL}, 0, 0, 0, 0, 0, 0, NULL, tld_main_stats }, // segments
{ 0, tld_main_stats }, // os { 0, tld_main_stats }, // os

View file

@ -702,12 +702,14 @@ static inline mi_page_t* mi_find_free_page(mi_heap_t* heap, size_t size) {
a certain number of allocations. a certain number of allocations.
----------------------------------------------------------- */ ----------------------------------------------------------- */
static mi_deferred_free_fun* deferred_free = NULL; static volatile mi_deferred_free_fun* deferred_free = NULL;
void _mi_deferred_free(mi_heap_t* heap, bool force) { void _mi_deferred_free(mi_heap_t* heap, bool force) {
heap->tld->heartbeat++; heap->tld->heartbeat++;
if (deferred_free != NULL) { if (deferred_free != NULL && !heap->tld->recurse) {
heap->tld->recurse = true;
deferred_free(force, heap->tld->heartbeat); deferred_free(force, heap->tld->heartbeat);
heap->tld->recurse = false;
} }
} }