Fix extent_alloc_dss() regressions.

Page-align the gap, if any, and add/use extent_dalloc_gap(), which
registers the gap extent before deallocation.
This commit is contained in:
Jason Evans 2016-06-05 15:27:20 -07:00
parent c4bb17f891
commit 4e910fc958
4 changed files with 33 additions and 22 deletions

View File

@ -105,6 +105,7 @@ extent_t *extent_alloc_cache(tsdn_t *tsdn, arena_t *arena,
extent_t *extent_alloc_wrapper(tsdn_t *tsdn, arena_t *arena, extent_t *extent_alloc_wrapper(tsdn_t *tsdn, arena_t *arena,
extent_hooks_t **r_extent_hooks, void *new_addr, size_t usize, size_t pad, extent_hooks_t **r_extent_hooks, void *new_addr, size_t usize, size_t pad,
size_t alignment, bool *zero, bool *commit, bool slab); size_t alignment, bool *zero, bool *commit, bool slab);
void extent_dalloc_gap(tsdn_t *tsdn, arena_t *arena, extent_t *extent);
void extent_dalloc_cache(tsdn_t *tsdn, arena_t *arena, void extent_dalloc_cache(tsdn_t *tsdn, arena_t *arena,
extent_hooks_t **r_extent_hooks, extent_t *extent); extent_hooks_t **r_extent_hooks, extent_t *extent);
void extent_dalloc_wrapper(tsdn_t *tsdn, arena_t *arena, void extent_dalloc_wrapper(tsdn_t *tsdn, arena_t *arena,

View File

@ -158,6 +158,7 @@ extent_committed_get
extent_committed_set extent_committed_set
extent_dalloc extent_dalloc
extent_dalloc_cache extent_dalloc_cache
extent_dalloc_gap
extent_dalloc_mmap extent_dalloc_mmap
extent_dalloc_wrapper extent_dalloc_wrapper
extent_decommit_wrapper extent_decommit_wrapper

View File

@ -732,6 +732,18 @@ extent_record(tsdn_t *tsdn, arena_t *arena, extent_hooks_t **r_extent_hooks,
malloc_mutex_unlock(tsdn, &arena->extents_mtx); malloc_mutex_unlock(tsdn, &arena->extents_mtx);
} }
void
extent_dalloc_gap(tsdn_t *tsdn, arena_t *arena, extent_t *extent)
{
extent_hooks_t *extent_hooks = EXTENT_HOOKS_INITIALIZER;
if (extent_register(tsdn, extent)) {
extent_leak(tsdn, arena, &extent_hooks, false, extent);
return;
}
extent_dalloc_wrapper(tsdn, arena, &extent_hooks, extent);
}
void void
extent_dalloc_cache(tsdn_t *tsdn, arena_t *arena, extent_dalloc_cache(tsdn_t *tsdn, arena_t *arena,
extent_hooks_t **r_extent_hooks, extent_t *extent) extent_hooks_t **r_extent_hooks, extent_t *extent)

View File

@ -70,7 +70,7 @@ extent_alloc_dss(tsdn_t *tsdn, arena_t *arena, void *new_addr, size_t size,
size_t alignment, bool *zero, bool *commit) size_t alignment, bool *zero, bool *commit)
{ {
void *ret; void *ret;
extent_t *pad; extent_t *gap;
cassert(have_dss); cassert(have_dss);
assert(size > 0); assert(size > 0);
@ -83,8 +83,8 @@ extent_alloc_dss(tsdn_t *tsdn, arena_t *arena, void *new_addr, size_t size,
if ((intptr_t)size < 0) if ((intptr_t)size < 0)
return (NULL); return (NULL);
pad = extent_alloc(tsdn, arena); gap = extent_alloc(tsdn, arena);
if (pad == NULL) if (gap == NULL)
return (NULL); return (NULL);
malloc_mutex_lock(tsdn, &dss_mtx); malloc_mutex_lock(tsdn, &dss_mtx);
@ -95,8 +95,8 @@ extent_alloc_dss(tsdn_t *tsdn, arena_t *arena, void *new_addr, size_t size,
* malloc. * malloc.
*/ */
while (true) { while (true) {
void *pad_addr, *dss_next; void *gap_addr, *dss_next;
size_t pad_size; size_t gap_size;
intptr_t incr; intptr_t incr;
/* Avoid an unnecessary system call. */ /* Avoid an unnecessary system call. */
@ -111,23 +111,23 @@ extent_alloc_dss(tsdn_t *tsdn, arena_t *arena, void *new_addr, size_t size,
break; break;
/* /*
* Compute how much pad space (if any) is necessary to * Compute how much gap space (if any) is necessary to
* satisfy alignment. This space can be recycled for * satisfy alignment. This space can be recycled for
* later use. * later use.
*/ */
pad_addr = (void *)((uintptr_t)dss_max); gap_addr = (void *)(PAGE_CEILING((uintptr_t)dss_max));
ret = (void *)ALIGNMENT_CEILING((uintptr_t)dss_max, ret = (void *)ALIGNMENT_CEILING((uintptr_t)gap_addr,
alignment); PAGE_CEILING(alignment));
pad_size = (uintptr_t)ret - (uintptr_t)pad_addr; gap_size = (uintptr_t)ret - (uintptr_t)gap_addr;
if (pad_size != 0) { if (gap_size != 0) {
extent_init(pad, arena, pad_addr, pad_size, extent_init(gap, arena, gap_addr, gap_size,
pad_size, false, false, true, false); gap_size, false, false, true, false);
} }
dss_next = (void *)((uintptr_t)ret + size); dss_next = (void *)((uintptr_t)ret + size);
if ((uintptr_t)ret < (uintptr_t)dss_max || if ((uintptr_t)ret < (uintptr_t)dss_max ||
(uintptr_t)dss_next < (uintptr_t)dss_max) (uintptr_t)dss_next < (uintptr_t)dss_max)
break; /* Wrap-around. */ break; /* Wrap-around. */
incr = pad_size + size; incr = gap_size + size;
dss_prev = extent_dss_sbrk(incr); dss_prev = extent_dss_sbrk(incr);
if (dss_prev == (void *)-1) if (dss_prev == (void *)-1)
break; break;
@ -135,13 +135,10 @@ extent_alloc_dss(tsdn_t *tsdn, arena_t *arena, void *new_addr, size_t size,
/* Success. */ /* Success. */
dss_max = dss_next; dss_max = dss_next;
malloc_mutex_unlock(tsdn, &dss_mtx); malloc_mutex_unlock(tsdn, &dss_mtx);
if (pad_size != 0) { if (gap_size != 0)
extent_hooks_t *extent_hooks = extent_dalloc_gap(tsdn, arena, gap);
EXTENT_HOOKS_INITIALIZER; else
extent_dalloc_wrapper(tsdn, arena, extent_dalloc(tsdn, arena, gap);
&extent_hooks, pad);
} else
extent_dalloc(tsdn, arena, pad);
if (*zero) if (*zero)
memset(ret, 0, size); memset(ret, 0, size);
if (!*commit) if (!*commit)
@ -152,7 +149,7 @@ extent_alloc_dss(tsdn_t *tsdn, arena_t *arena, void *new_addr, size_t size,
} }
/* OOM. */ /* OOM. */
malloc_mutex_unlock(tsdn, &dss_mtx); malloc_mutex_unlock(tsdn, &dss_mtx);
extent_dalloc(tsdn, arena, pad); extent_dalloc(tsdn, arena, gap);
return (NULL); return (NULL);
} }