Propagate tsdn to default extent 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 13:37:22 -07:00
parent 02a475d89a
commit cc289f40b6

View File

@ -560,11 +560,24 @@ extent_alloc_cache(tsdn_t *tsdn, arena_t *arena,
return (extent); return (extent);
} }
static void *
extent_alloc_default_impl(tsdn_t *tsdn, arena_t *arena, void *new_addr,
size_t size, size_t alignment, bool *zero, bool *commit)
{
void *ret;
ret = extent_alloc_core(tsdn, arena, new_addr, size, alignment, zero,
commit, arena->dss_prec);
if (ret == NULL)
return (NULL);
return (ret);
}
static void * static void *
extent_alloc_default(extent_hooks_t *extent_hooks, void *new_addr, size_t size, extent_alloc_default(extent_hooks_t *extent_hooks, void *new_addr, size_t size,
size_t alignment, bool *zero, bool *commit, unsigned arena_ind) size_t alignment, bool *zero, bool *commit, unsigned arena_ind)
{ {
void *ret;
tsdn_t *tsdn; tsdn_t *tsdn;
arena_t *arena; arena_t *arena;
@ -577,12 +590,9 @@ extent_alloc_default(extent_hooks_t *extent_hooks, void *new_addr, size_t size,
* already. * already.
*/ */
assert(arena != NULL); assert(arena != NULL);
ret = extent_alloc_core(tsdn, arena, new_addr, size, alignment, zero,
commit, arena->dss_prec);
if (ret == NULL)
return (NULL);
return (ret); return (extent_alloc_default_impl(tsdn, arena, new_addr, size,
alignment, zero, commit));
} }
static extent_t * static extent_t *
@ -619,8 +629,14 @@ extent_alloc_wrapper_hard(tsdn_t *tsdn, arena_t *arena,
extent = extent_alloc(tsdn, arena); extent = extent_alloc(tsdn, arena);
if (extent == NULL) if (extent == NULL)
return (NULL); return (NULL);
if (*r_extent_hooks == &extent_hooks_default) {
/* Call directly to propagate tsdn. */
addr = extent_alloc_default_impl(tsdn, arena, new_addr, size,
alignment, zero, commit);
} else {
addr = (*r_extent_hooks)->alloc(*r_extent_hooks, new_addr, size, addr = (*r_extent_hooks)->alloc(*r_extent_hooks, new_addr, size,
alignment, zero, commit, arena->ind); alignment, zero, commit, arena->ind);
}
if (addr == NULL) { if (addr == NULL) {
extent_dalloc(tsdn, arena, extent); extent_dalloc(tsdn, arena, extent);
return (NULL); return (NULL);
@ -769,22 +785,34 @@ extent_dalloc_cache(tsdn_t *tsdn, arena_t *arena,
extent); extent);
} }
static bool
extent_dalloc_default_impl(tsdn_t *tsdn, void *addr, size_t size)
{
if (!have_dss || !extent_in_dss(tsdn, addr))
return (extent_dalloc_mmap(addr, size));
return (true);
}
static bool static bool
extent_dalloc_default(extent_hooks_t *extent_hooks, void *addr, size_t size, extent_dalloc_default(extent_hooks_t *extent_hooks, void *addr, size_t size,
bool committed, unsigned arena_ind) bool committed, unsigned arena_ind)
{ {
tsdn_t *tsdn;
assert(extent_hooks == &extent_hooks_default); assert(extent_hooks == &extent_hooks_default);
if (!have_dss || !extent_in_dss(tsdn_fetch(), addr)) tsdn = tsdn_fetch();
return (extent_dalloc_mmap(addr, size));
return (true); return (extent_dalloc_default_impl(tsdn, addr, size));
} }
void void
extent_dalloc_wrapper(tsdn_t *tsdn, arena_t *arena, extent_dalloc_wrapper(tsdn_t *tsdn, arena_t *arena,
extent_hooks_t **r_extent_hooks, extent_t *extent) extent_hooks_t **r_extent_hooks, extent_t *extent)
{ {
bool err;
assert(extent_base_get(extent) != NULL); assert(extent_base_get(extent) != NULL);
assert(extent_size_get(extent) != 0); assert(extent_size_get(extent) != 0);
@ -797,9 +825,17 @@ extent_dalloc_wrapper(tsdn_t *tsdn, arena_t *arena,
* allocating threads, and reregister if deallocation fails. * allocating threads, and reregister if deallocation fails.
*/ */
extent_deregister(tsdn, extent); extent_deregister(tsdn, extent);
if (!(*r_extent_hooks)->dalloc(*r_extent_hooks, extent_base_get(extent), if (*r_extent_hooks == &extent_hooks_default) {
extent_size_get(extent), extent_committed_get(extent), /* Call directly to propagate tsdn. */
arena->ind)) { err = extent_dalloc_default_impl(tsdn, extent_base_get(extent),
extent_size_get(extent));
} else {
err = (*r_extent_hooks)->dalloc(*r_extent_hooks,
extent_base_get(extent), extent_size_get(extent),
extent_committed_get(extent), arena->ind);
}
if (!err) {
extent_dalloc(tsdn, arena, extent); extent_dalloc(tsdn, arena, extent);
return; return;
} }
@ -977,35 +1013,52 @@ label_error_a:
} }
static bool static bool
extent_merge_default(extent_hooks_t *extent_hooks, void *addr_a, size_t size_a, extent_merge_default_impl(tsdn_t *tsdn, void *addr_a, void *addr_b)
void *addr_b, size_t size_b, bool committed, unsigned arena_ind)
{ {
assert(extent_hooks == &extent_hooks_default);
if (!maps_coalesce) if (!maps_coalesce)
return (true); return (true);
if (have_dss) { if (have_dss && extent_in_dss(tsdn, addr_a) != extent_in_dss(tsdn,
tsdn_t *tsdn = tsdn_fetch(); addr_b))
if (extent_in_dss(tsdn, addr_a) != extent_in_dss(tsdn, addr_b))
return (true); return (true);
}
return (false); return (false);
} }
static bool
extent_merge_default(extent_hooks_t *extent_hooks, void *addr_a, size_t size_a,
void *addr_b, size_t size_b, bool committed, unsigned arena_ind)
{
tsdn_t *tsdn;
assert(extent_hooks == &extent_hooks_default);
tsdn = tsdn_fetch();
return (extent_merge_default_impl(tsdn, addr_a, addr_b));
}
bool bool
extent_merge_wrapper(tsdn_t *tsdn, arena_t *arena, extent_merge_wrapper(tsdn_t *tsdn, arena_t *arena,
extent_hooks_t **r_extent_hooks, extent_t *a, extent_t *b) extent_hooks_t **r_extent_hooks, extent_t *a, extent_t *b)
{ {
bool err;
rtree_ctx_t rtree_ctx_fallback; rtree_ctx_t rtree_ctx_fallback;
rtree_ctx_t *rtree_ctx = tsdn_rtree_ctx(tsdn, &rtree_ctx_fallback); rtree_ctx_t *rtree_ctx = tsdn_rtree_ctx(tsdn, &rtree_ctx_fallback);
rtree_elm_t *a_elm_a, *a_elm_b, *b_elm_a, *b_elm_b; rtree_elm_t *a_elm_a, *a_elm_b, *b_elm_a, *b_elm_b;
extent_hooks_assure_initialized(arena, r_extent_hooks); extent_hooks_assure_initialized(arena, r_extent_hooks);
if ((*r_extent_hooks)->merge(*r_extent_hooks, extent_base_get(a), if (*r_extent_hooks == &extent_hooks_default) {
extent_size_get(a), extent_base_get(b), extent_size_get(b), /* Call directly to propagate tsdn. */
extent_committed_get(a), arena->ind)) err = extent_merge_default_impl(tsdn, extent_base_get(a),
extent_base_get(b));
} else {
err = (*r_extent_hooks)->merge(*r_extent_hooks,
extent_base_get(a), extent_size_get(a), extent_base_get(b),
extent_size_get(b), extent_committed_get(a), arena->ind);
}
if (err)
return (true); return (true);
/* /*