diff options
author | Jason Evans <jasone@canonware.com> | 2016-09-22 18:57:28 (GMT) |
---|---|---|
committer | Jason Evans <jasone@canonware.com> | 2016-09-22 18:57:28 (GMT) |
commit | f6d01ff4b7322eeed56c61a11e3e3397765d3f22 (patch) | |
tree | ff2b4a49b6d8e92c7e19ea9dfca84110ae77cdb2 /src/arena.c | |
parent | bc49157d21e6ec14a41c7b852370d2e6d9509da2 (diff) | |
download | jemalloc-f6d01ff4b7322eeed56c61a11e3e3397765d3f22.zip jemalloc-f6d01ff4b7322eeed56c61a11e3e3397765d3f22.tar.gz jemalloc-f6d01ff4b7322eeed56c61a11e3e3397765d3f22.tar.bz2 |
Protect extents_dirty access with extents_mtx.
This fixes race conditions during purging.
Diffstat (limited to 'src/arena.c')
-rw-r--r-- | src/arena.c | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/src/arena.c b/src/arena.c index 7dcf12d..da9e985 100644 --- a/src/arena.c +++ b/src/arena.c @@ -101,9 +101,12 @@ arena_extent_cache_dalloc(tsdn_t *tsdn, arena_t *arena, } void -arena_extent_cache_maybe_insert(arena_t *arena, extent_t *extent, bool cache) +arena_extent_cache_maybe_insert(tsdn_t *tsdn, arena_t *arena, extent_t *extent, + bool cache) { + malloc_mutex_assert_owner(tsdn, &arena->extents_mtx); + if (cache) { extent_ring_insert(&arena->extents_dirty, extent); arena->ndirty += arena_extent_dirty_npages(extent); @@ -111,9 +114,12 @@ arena_extent_cache_maybe_insert(arena_t *arena, extent_t *extent, bool cache) } void -arena_extent_cache_maybe_remove(arena_t *arena, extent_t *extent, bool dirty) +arena_extent_cache_maybe_remove(tsdn_t *tsdn, arena_t *arena, extent_t *extent, + bool dirty) { + malloc_mutex_assert_owner(tsdn, &arena->extents_mtx); + if (dirty) { extent_ring_remove(extent); assert(arena->ndirty >= arena_extent_dirty_npages(extent)); @@ -727,6 +733,8 @@ arena_dirty_count(tsdn_t *tsdn, arena_t *arena) extent_t *extent; size_t ndirty = 0; + malloc_mutex_assert_owner(tsdn, &arena->extents_mtx); + for (extent = qr_next(&arena->extents_dirty, qr_link); extent != &arena->extents_dirty; extent = qr_next(extent, qr_link)) ndirty += extent_size_get(extent) >> LG_PAGE; @@ -741,6 +749,8 @@ arena_stash_dirty(tsdn_t *tsdn, arena_t *arena, extent_hooks_t **r_extent_hooks, extent_t *extent, *next; size_t nstashed = 0; + malloc_mutex_lock(tsdn, &arena->extents_mtx); + /* Stash extents according to ndirty_limit. */ for (extent = qr_next(&arena->extents_dirty, qr_link); extent != &arena->extents_dirty; extent = next) { @@ -756,9 +766,9 @@ arena_stash_dirty(tsdn_t *tsdn, arena_t *arena, extent_hooks_t **r_extent_hooks, next = qr_next(extent, qr_link); /* Allocate. */ zero = false; - textent = arena_extent_cache_alloc_locked(tsdn, arena, - r_extent_hooks, extent_base_get(extent), - extent_size_get(extent), 0, CACHELINE, &zero, false); + textent = extent_alloc_cache_locked(tsdn, arena, r_extent_hooks, + extent_base_get(extent), extent_size_get(extent), 0, + CACHELINE, &zero, false); assert(textent == extent); assert(zero == extent_zeroed_get(extent)); extent_ring_remove(extent); @@ -770,6 +780,7 @@ arena_stash_dirty(tsdn_t *tsdn, arena_t *arena, extent_hooks_t **r_extent_hooks, break; } + malloc_mutex_unlock(tsdn, &arena->extents_mtx); return (nstashed); } @@ -1788,9 +1799,6 @@ arena_new(tsdn_t *tsdn, unsigned ind) arena->nactive = 0; arena->ndirty = 0; - extent_init(&arena->extents_dirty, arena, NULL, 0, 0, false, false, - false, false); - if (opt_purge == purge_mode_decay) arena_decay_init(arena, arena_decay_time_default_get()); @@ -1804,12 +1812,15 @@ arena_new(tsdn_t *tsdn, unsigned ind) extent_heap_new(&arena->extents_retained[i]); } - arena->extent_hooks = (extent_hooks_t *)&extent_hooks_default; + extent_init(&arena->extents_dirty, arena, NULL, 0, 0, false, false, + false, false); if (malloc_mutex_init(&arena->extents_mtx, "arena_extents", WITNESS_RANK_ARENA_EXTENTS)) return (NULL); + arena->extent_hooks = (extent_hooks_t *)&extent_hooks_default; + ql_new(&arena->extent_cache); if (malloc_mutex_init(&arena->extent_cache_mtx, "arena_extent_cache", WITNESS_RANK_ARENA_EXTENT_CACHE)) |