diff --git a/include/jemalloc/internal/arena_externs.h b/include/jemalloc/internal/arena_externs.h index 9f5c1958..3821233f 100644 --- a/include/jemalloc/internal/arena_externs.h +++ b/include/jemalloc/internal/arena_externs.h @@ -100,7 +100,7 @@ unsigned arena_nthreads_get(arena_t *arena, bool internal); void arena_nthreads_inc(arena_t *arena, bool internal); void arena_nthreads_dec(arena_t *arena, bool internal); arena_t *arena_new(tsdn_t *tsdn, unsigned ind, const arena_config_t *config); -bool arena_init_huge(void); +bool arena_init_huge(arena_t *a0); bool arena_is_huge(unsigned arena_ind); arena_t *arena_choose_huge(tsd_t *tsd); bin_t *arena_bin_choose(tsdn_t *tsdn, arena_t *arena, szind_t binind, diff --git a/include/jemalloc/internal/arena_inlines_b.h b/include/jemalloc/internal/arena_inlines_b.h index 609e73d3..b57dbfdd 100644 --- a/include/jemalloc/internal/arena_inlines_b.h +++ b/include/jemalloc/internal/arena_inlines_b.h @@ -28,14 +28,18 @@ arena_choose_maybe_huge(tsd_t *tsd, arena_t *arena, size_t size) { * 1) is using auto arena selection (i.e. arena == NULL), and 2) the * thread is not assigned to a manual arena. */ - if (unlikely(size >= oversize_threshold)) { - arena_t *tsd_arena = tsd_arena_get(tsd); - if (tsd_arena == NULL || arena_is_auto(tsd_arena)) { - return arena_choose_huge(tsd); - } + arena_t *tsd_arena = tsd_arena_get(tsd); + if (tsd_arena == NULL) { + tsd_arena = arena_choose(tsd, NULL); } - return arena_choose(tsd, NULL); + size_t threshold = atomic_load_zu( + &tsd_arena->pa_shard.pac.oversize_threshold, ATOMIC_RELAXED); + if (unlikely(size >= threshold) && arena_is_auto(tsd_arena)) { + return arena_choose_huge(tsd); + } + + return tsd_arena; } JEMALLOC_ALWAYS_INLINE void diff --git a/src/arena.c b/src/arena.c index 9592ab9d..ab1a9ab8 100644 --- a/src/arena.c +++ b/src/arena.c @@ -1770,7 +1770,7 @@ arena_choose_huge(tsd_t *tsd) { } bool -arena_init_huge(void) { +arena_init_huge(arena_t *a0) { bool huge_enabled; /* The threshold should be large size class. */ @@ -1783,6 +1783,9 @@ arena_init_huge(void) { /* Reserve the index for the huge arena. */ huge_arena_ind = narenas_total_get(); oversize_threshold = opt_oversize_threshold; + /* a0 init happened before malloc_conf_init. */ + atomic_store_zu(&a0->pa_shard.pac.oversize_threshold, + oversize_threshold, ATOMIC_RELAXED); huge_enabled = true; } diff --git a/src/jemalloc.c b/src/jemalloc.c index 37cd159c..8a69d81b 100644 --- a/src/jemalloc.c +++ b/src/jemalloc.c @@ -2090,7 +2090,7 @@ malloc_init_narenas(void) { narenas_auto); } narenas_total_set(narenas_auto); - if (arena_init_huge()) { + if (arena_init_huge(a0)) { narenas_total_inc(); } manual_arena_base = narenas_total_get();