diff --git a/include/jemalloc/internal/base.h b/include/jemalloc/internal/base.h index 67e19409..9b2c9fb1 100644 --- a/include/jemalloc/internal/base.h +++ b/include/jemalloc/internal/base.h @@ -47,9 +47,9 @@ struct base_s { ehooks_t ehooks; /* - * Use user hooks for metadata when true. + * User-configurable extent hook functions for metadata allocations. */ - bool metadata_use_hooks; + ehooks_t ehooks_base; /* Protects base_alloc() and base_stats_get() operations. */ malloc_mutex_t mtx; @@ -95,6 +95,7 @@ base_t *base_new(tsdn_t *tsdn, unsigned ind, const extent_hooks_t *extent_hooks, bool metadata_use_hooks); void base_delete(tsdn_t *tsdn, base_t *base); ehooks_t *base_ehooks_get(base_t *base); +ehooks_t *base_ehooks_get_for_metadata(base_t *base); extent_hooks_t *base_extent_hooks_set(base_t *base, extent_hooks_t *extent_hooks); void *base_alloc(tsdn_t *tsdn, base_t *base, size_t size, size_t alignment); diff --git a/src/base.c b/src/base.c index 38f6fa4b..7f4d6756 100644 --- a/src/base.c +++ b/src/base.c @@ -295,12 +295,6 @@ base_block_alloc(tsdn_t *tsdn, base_t *base, ehooks_t *ehooks, unsigned ind, return block; } -static ehooks_t * -base_ehooks_get_for_metadata(base_t *base) { - return base->metadata_use_hooks ? &base->ehooks : - (ehooks_t *)&ehooks_default_extent_hooks; -} - /* * Allocate an extent that is at least as large as specified size, with * specified alignment. @@ -375,6 +369,9 @@ base_new(tsdn_t *tsdn, unsigned ind, const extent_hooks_t *extent_hooks, base_t *base = (base_t *)base_extent_bump_alloc_helper(&block->edata, &gap_size, base_size, base_alignment); ehooks_init(&base->ehooks, (extent_hooks_t *)extent_hooks, ind); + ehooks_init(&base->ehooks_base, metadata_use_hooks ? + (extent_hooks_t *)extent_hooks : + (extent_hooks_t *)&ehooks_default_extent_hooks, ind); if (malloc_mutex_init(&base->mtx, "base", WITNESS_RANK_BASE, malloc_mutex_rank_exclusive)) { base_unmap(tsdn, &fake_ehooks, ind, block, block->size); @@ -384,7 +381,6 @@ base_new(tsdn_t *tsdn, unsigned ind, const extent_hooks_t *extent_hooks, base->extent_sn_next = extent_sn_next; base->blocks = block; base->auto_thp_switched = false; - base->metadata_use_hooks = metadata_use_hooks; for (szind_t i = 0; i < SC_NSIZES; i++) { edata_heap_new(&base->avail[i]); } @@ -422,6 +418,11 @@ base_ehooks_get(base_t *base) { return &base->ehooks; } +ehooks_t * +base_ehooks_get_for_metadata(base_t *base) { + return &base->ehooks_base; +} + extent_hooks_t * base_extent_hooks_set(base_t *base, extent_hooks_t *extent_hooks) { extent_hooks_t *old_extent_hooks = diff --git a/test/unit/base.c b/test/unit/base.c index 07a43df7..15e04a8c 100644 --- a/test/unit/base.c +++ b/test/unit/base.c @@ -227,10 +227,39 @@ TEST_BEGIN(test_base_hooks_not_null) { } TEST_END +TEST_BEGIN(test_base_ehooks_get_for_metadata_default_hook) { + extent_hooks_prep(); + memcpy(&hooks, &hooks_not_null, sizeof(extent_hooks_t)); + base_t *base; + tsdn_t *tsdn = tsd_tsdn(tsd_fetch()); + base = base_new(tsdn, 0, &hooks, /* metadata_use_hooks */ false); + ehooks_t *ehooks = base_ehooks_get_for_metadata(base); + expect_true(ehooks_are_default(ehooks), + "Expected default extent hook functions pointer"); + base_delete(tsdn, base); +} +TEST_END + + +TEST_BEGIN(test_base_ehooks_get_for_metadata_custom_hook) { + extent_hooks_prep(); + memcpy(&hooks, &hooks_not_null, sizeof(extent_hooks_t)); + base_t *base; + tsdn_t *tsdn = tsd_tsdn(tsd_fetch()); + base = base_new(tsdn, 0, &hooks, /* metadata_use_hooks */ true); + ehooks_t *ehooks = base_ehooks_get_for_metadata(base); + expect_ptr_eq(&hooks, ehooks_get_extent_hooks_ptr(ehooks), + "Expected user-specified extend hook functions pointer"); + base_delete(tsdn, base); +} +TEST_END + int main(void) { return test( test_base_hooks_default, test_base_hooks_null, - test_base_hooks_not_null); + test_base_hooks_not_null, + test_base_ehooks_get_for_metadata_default_hook, + test_base_ehooks_get_for_metadata_custom_hook); }