fix bug where continue would wrongly exit the do-while loop for delayed freeing

This commit is contained in:
daan 2020-01-04 17:32:50 -08:00
parent a2a9230ad6
commit 59fa286294

View file

@ -119,23 +119,22 @@ bool _mi_page_is_valid(mi_page_t* page) {
} }
#endif #endif
void _mi_page_use_delayed_free(mi_page_t* page, mi_delayed_t delay) {
void _mi_page_use_delayed_free(mi_page_t* page, mi_delayed_t delay ) {
mi_thread_free_t tfree; mi_thread_free_t tfree;
mi_thread_free_t tfreex; mi_thread_free_t tfreex;
mi_delayed_t old_delay;
do { do {
tfreex = tfree = page->thread_free; tfree = mi_atomic_read_relaxed(&page->thread_free);
if (mi_unlikely(mi_tf_delayed(tfree) < MI_DELAYED_FREEING)) { tfreex = mi_tf_set_delayed(tfree, delay);
tfreex = mi_tf_set_delayed(tfree,delay); old_delay = mi_tf_delayed(tfree);
} if (mi_unlikely(old_delay == MI_DELAYED_FREEING)) {
else if (mi_unlikely(mi_tf_delayed(tfree) == MI_DELAYED_FREEING)) {
mi_atomic_yield(); // delay until outstanding MI_DELAYED_FREEING are done. mi_atomic_yield(); // delay until outstanding MI_DELAYED_FREEING are done.
continue; // and try again
} }
} else if (delay == old_delay) {
while((mi_tf_delayed(tfreex) != mi_tf_delayed(tfree)) && // avoid atomic operation if already equal break; // avoid atomic operation if already equal
!mi_atomic_cas_weak(mi_atomic_cast(uintptr_t,&page->thread_free), tfreex, tfree)); }
} while ((old_delay == MI_DELAYED_FREEING) ||
!mi_atomic_cas_weak(mi_atomic_cast(uintptr_t, &page->thread_free), tfreex, tfree));
} }