From c0a667112cf33968b425dfbb50594aba54ea850b Mon Sep 17 00:00:00 2001 From: Jason Evans Date: Tue, 15 Nov 2016 10:31:06 -0800 Subject: [PATCH] Fix arena_reset() crashing bug. This regression was caused by 498856f44a30b31fe713a18eb2fc7c6ecf3a9f63 (Move slabs out of chunks.). --- src/arena.c | 83 +++++++++++++++++++++++++++-------------------------- 1 file changed, 42 insertions(+), 41 deletions(-) diff --git a/src/arena.c b/src/arena.c index ff7b0cd0..ef374d35 100644 --- a/src/arena.c +++ b/src/arena.c @@ -799,6 +799,47 @@ arena_slab_dalloc(tsdn_t *tsdn, arena_t *arena, extent_t *slab) arena_extent_cache_dalloc_locked(tsdn, arena, &extent_hooks, slab); } +static void +arena_bin_slabs_nonfull_insert(arena_bin_t *bin, extent_t *slab) +{ + + assert(extent_slab_data_get(slab)->nfree > 0); + extent_heap_insert(&bin->slabs_nonfull, slab); +} + +static void +arena_bin_slabs_nonfull_remove(arena_bin_t *bin, extent_t *slab) +{ + + extent_heap_remove(&bin->slabs_nonfull, slab); +} + +static extent_t * +arena_bin_slabs_nonfull_tryget(arena_bin_t *bin) +{ + extent_t *slab = extent_heap_remove_first(&bin->slabs_nonfull); + if (slab == NULL) + return (NULL); + if (config_stats) + bin->stats.reslabs++; + return (slab); +} + +static void +arena_bin_slabs_full_insert(arena_bin_t *bin, extent_t *slab) +{ + + assert(extent_slab_data_get(slab)->nfree == 0); + extent_ring_insert(&bin->slabs_full, slab); +} + +static void +arena_bin_slabs_full_remove(extent_t *slab) +{ + + extent_ring_remove(slab); +} + void arena_reset(tsd_t *tsd, arena_t *arena) { @@ -863,6 +904,7 @@ arena_reset(tsd_t *tsd, arena_t *arena) for (slab = qr_next(&bin->slabs_full, qr_link); slab != &bin->slabs_full; slab = qr_next(&bin->slabs_full, qr_link)) { + arena_bin_slabs_full_remove(slab); malloc_mutex_unlock(tsd_tsdn(tsd), &bin->lock); arena_slab_dalloc(tsd_tsdn(tsd), arena, slab); malloc_mutex_lock(tsd_tsdn(tsd), &bin->lock); @@ -880,47 +922,6 @@ arena_reset(tsd_t *tsd, arena_t *arena) malloc_mutex_unlock(tsd_tsdn(tsd), &arena->lock); } -static void -arena_bin_slabs_nonfull_insert(arena_bin_t *bin, extent_t *slab) -{ - - assert(extent_slab_data_get(slab)->nfree > 0); - extent_heap_insert(&bin->slabs_nonfull, slab); -} - -static void -arena_bin_slabs_nonfull_remove(arena_bin_t *bin, extent_t *slab) -{ - - extent_heap_remove(&bin->slabs_nonfull, slab); -} - -static extent_t * -arena_bin_slabs_nonfull_tryget(arena_bin_t *bin) -{ - extent_t *slab = extent_heap_remove_first(&bin->slabs_nonfull); - if (slab == NULL) - return (NULL); - if (config_stats) - bin->stats.reslabs++; - return (slab); -} - -static void -arena_bin_slabs_full_insert(arena_bin_t *bin, extent_t *slab) -{ - - assert(extent_slab_data_get(slab)->nfree == 0); - extent_ring_insert(&bin->slabs_full, slab); -} - -static void -arena_bin_slabs_full_remove(extent_t *slab) -{ - - extent_ring_remove(slab); -} - static extent_t * arena_slab_alloc_hard(tsdn_t *tsdn, arena_t *arena, extent_hooks_t **r_extent_hooks, const arena_bin_info_t *bin_info)