Propagate tsdn to default chunk hooks.

This avoids bootstrapping issues for configurations that require
allocation during tsd initialization.

This resolves #390.
This commit is contained in:
Jason Evans 2016-06-07 14:00:58 -07:00
parent f70a254d44
commit 09d7bdb314

View File

@ -421,15 +421,11 @@ chunk_arena_get(tsdn_t *tsdn, unsigned arena_ind)
} }
static void * static void *
chunk_alloc_default(void *new_addr, size_t size, size_t alignment, bool *zero, chunk_alloc_default_impl(tsdn_t *tsdn, arena_t *arena, void *new_addr,
bool *commit, unsigned arena_ind) size_t size, size_t alignment, bool *zero, bool *commit)
{ {
void *ret; void *ret;
tsdn_t *tsdn;
arena_t *arena;
tsdn = tsdn_fetch();
arena = chunk_arena_get(tsdn, arena_ind);
ret = chunk_alloc_core(tsdn, arena, new_addr, size, alignment, zero, ret = chunk_alloc_core(tsdn, arena, new_addr, size, alignment, zero,
commit, arena->dss_prec); commit, arena->dss_prec);
if (ret == NULL) if (ret == NULL)
@ -440,6 +436,20 @@ chunk_alloc_default(void *new_addr, size_t size, size_t alignment, bool *zero,
return (ret); return (ret);
} }
static void *
chunk_alloc_default(void *new_addr, size_t size, size_t alignment, bool *zero,
bool *commit, unsigned arena_ind)
{
tsdn_t *tsdn;
arena_t *arena;
tsdn = tsdn_fetch();
arena = chunk_arena_get(tsdn, arena_ind);
return (chunk_alloc_default_impl(tsdn, arena, new_addr, size, alignment,
zero, commit));
}
static void * static void *
chunk_alloc_retained(tsdn_t *tsdn, arena_t *arena, chunk_hooks_t *chunk_hooks, chunk_alloc_retained(tsdn_t *tsdn, arena_t *arena, chunk_hooks_t *chunk_hooks,
void *new_addr, size_t size, size_t alignment, bool *zero, bool *commit) void *new_addr, size_t size, size_t alignment, bool *zero, bool *commit)
@ -472,8 +482,15 @@ chunk_alloc_wrapper(tsdn_t *tsdn, arena_t *arena, chunk_hooks_t *chunk_hooks,
ret = chunk_alloc_retained(tsdn, arena, chunk_hooks, new_addr, size, ret = chunk_alloc_retained(tsdn, arena, chunk_hooks, new_addr, size,
alignment, zero, commit); alignment, zero, commit);
if (ret == NULL) { if (ret == NULL) {
ret = chunk_hooks->alloc(new_addr, size, alignment, zero, if (chunk_hooks->alloc == chunk_alloc_default) {
commit, arena->ind); /* Call directly to propagate tsdn. */
ret = chunk_alloc_default_impl(tsdn, arena, new_addr,
size, alignment, zero, commit);
} else {
ret = chunk_hooks->alloc(new_addr, size, alignment,
zero, commit, arena->ind);
}
if (ret == NULL) if (ret == NULL)
return (NULL); return (NULL);
} }
@ -590,20 +607,31 @@ chunk_dalloc_cache(tsdn_t *tsdn, arena_t *arena, chunk_hooks_t *chunk_hooks,
arena_maybe_purge(tsdn, arena); arena_maybe_purge(tsdn, arena);
} }
static bool
chunk_dalloc_default_impl(tsdn_t *tsdn, void *chunk, size_t size)
{
if (!have_dss || !chunk_in_dss(tsdn, chunk))
return (chunk_dalloc_mmap(chunk, size));
return (true);
}
static bool static bool
chunk_dalloc_default(void *chunk, size_t size, bool committed, chunk_dalloc_default(void *chunk, size_t size, bool committed,
unsigned arena_ind) unsigned arena_ind)
{ {
tsdn_t *tsdn;
if (!have_dss || !chunk_in_dss(tsdn_fetch(), chunk)) tsdn = tsdn_fetch();
return (chunk_dalloc_mmap(chunk, size));
return (true); return (chunk_dalloc_default_impl(tsdn, chunk, size));
} }
void void
chunk_dalloc_wrapper(tsdn_t *tsdn, arena_t *arena, chunk_hooks_t *chunk_hooks, chunk_dalloc_wrapper(tsdn_t *tsdn, arena_t *arena, chunk_hooks_t *chunk_hooks,
void *chunk, size_t size, bool zeroed, bool committed) void *chunk, size_t size, bool zeroed, bool committed)
{ {
bool err;
assert(chunk != NULL); assert(chunk != NULL);
assert(CHUNK_ADDR2BASE(chunk) == chunk); assert(CHUNK_ADDR2BASE(chunk) == chunk);
@ -612,7 +640,13 @@ chunk_dalloc_wrapper(tsdn_t *tsdn, arena_t *arena, chunk_hooks_t *chunk_hooks,
chunk_hooks_assure_initialized(tsdn, arena, chunk_hooks); chunk_hooks_assure_initialized(tsdn, arena, chunk_hooks);
/* Try to deallocate. */ /* Try to deallocate. */
if (!chunk_hooks->dalloc(chunk, size, committed, arena->ind)) if (chunk_hooks->dalloc == chunk_dalloc_default) {
/* Call directly to propagate tsdn. */
err = chunk_dalloc_default_impl(tsdn, chunk, size);
} else
err = chunk_hooks->dalloc(chunk, size, committed, arena->ind);
if (!err)
return; return;
/* Try to decommit; purge if that fails. */ /* Try to decommit; purge if that fails. */
if (committed) { if (committed) {
@ -681,26 +715,34 @@ chunk_split_default(void *chunk, size_t size, size_t size_a, size_t size_b,
} }
static bool static bool
chunk_merge_default(void *chunk_a, size_t size_a, void *chunk_b, size_t size_b, chunk_merge_default_impl(tsdn_t *tsdn, void *chunk_a, void *chunk_b)
bool committed, unsigned arena_ind)
{ {
if (!maps_coalesce) if (!maps_coalesce)
return (true); return (true);
if (have_dss) { if (have_dss && chunk_in_dss(tsdn, chunk_a) != chunk_in_dss(tsdn,
tsdn_t *tsdn = tsdn_fetch(); chunk_b))
if (chunk_in_dss(tsdn, chunk_a) != chunk_in_dss(tsdn, chunk_b)) return (true);
return (true);
}
return (false); return (false);
} }
static bool
chunk_merge_default(void *chunk_a, size_t size_a, void *chunk_b, size_t size_b,
bool committed, unsigned arena_ind)
{
tsdn_t *tsdn;
tsdn = tsdn_fetch();
return (chunk_merge_default_impl(tsdn, chunk_a, chunk_b));
}
static rtree_node_elm_t * static rtree_node_elm_t *
chunks_rtree_node_alloc(size_t nelms) chunks_rtree_node_alloc(size_t nelms)
{ {
return ((rtree_node_elm_t *)base_alloc(tsdn_fetch(), nelms * return ((rtree_node_elm_t *)base_alloc(TSDN_NULL, nelms *
sizeof(rtree_node_elm_t))); sizeof(rtree_node_elm_t)));
} }