From ace679ce7435e990df6b789fde4cefeb0e6b992b Mon Sep 17 00:00:00 2001 From: Jason Evans Date: Fri, 27 Jan 2017 15:03:11 -0800 Subject: [PATCH] Synchronize extent_grow_next accesses. This should have been part of 411697adcda2fd75e135cdcdafb95f2bd295dc7f (Use exponential series to size extents.), which introduced extent_grow_next. --- src/extent.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/extent.c b/src/extent.c index 0dbde72a..e2af2b50 100644 --- a/src/extent.c +++ b/src/extent.c @@ -710,7 +710,7 @@ extent_grow_retained(tsdn_t *tsdn, arena_t *arena, * extent creation as a side effect. */ size = usize + pad; - alloc_size = pind2sz(arena->extent_grow_next); + alloc_size = pind2sz(atomic_read_u(&arena->extent_grow_next)); alloc_size_min = size + PAGE_CEILING(alignment) - PAGE; /* Beware size_t wrap-around. */ if (alloc_size_min < usize) { @@ -809,8 +809,20 @@ extent_grow_retained(tsdn_t *tsdn, arena_t *arena, if (*zero && !extent_zeroed_get(extent)) { memset(extent_addr_get(extent), 0, extent_usize_get(extent)); } - if (arena->extent_grow_next + 1 < NPSIZES) { - arena->extent_grow_next++; + /* + * Increment extent_grow_next, but take care to do so atomically and + * bail out if the increment would exceed the legal range. + */ + while (true) { + pszind_t egn = atomic_read_u(&arena->extent_grow_next); + + if (egn + 1 == NPSIZES) { + break; + } + assert(egn + 1 < NPSIZES); + if (!atomic_cas_u(&arena->extent_grow_next, egn, egn + 1)) { + break; + } } return extent; }