summaryrefslogtreecommitdiffstats
path: root/src/arena.c
diff options
context:
space:
mode:
authorJason Evans <jasone@canonware.com>2016-09-22 18:57:28 (GMT)
committerJason Evans <jasone@canonware.com>2016-09-22 18:57:28 (GMT)
commitf6d01ff4b7322eeed56c61a11e3e3397765d3f22 (patch)
treeff2b4a49b6d8e92c7e19ea9dfca84110ae77cdb2 /src/arena.c
parentbc49157d21e6ec14a41c7b852370d2e6d9509da2 (diff)
downloadjemalloc-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.c29
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))