mirror of
https://github.com/jemalloc/jemalloc.git
synced 2026-05-16 09:56:22 +03:00
HPA: Do deferred operations on background threads.
This commit is contained in:
parent
583284f2d9
commit
1d4a7666d5
12 changed files with 256 additions and 7 deletions
|
|
@ -465,6 +465,7 @@ arena_decay(tsdn_t *tsdn, arena_t *arena, bool is_background_thread, bool all) {
|
|||
void
|
||||
arena_do_deferred_work(tsdn_t *tsdn, arena_t *arena) {
|
||||
arena_decay(tsdn, arena, true, false);
|
||||
pa_shard_do_deferred_work(tsdn, &arena->pa_shard);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -13,6 +13,13 @@ JEMALLOC_DIAGNOSTIC_DISABLE_SPURIOUS
|
|||
/* Read-only after initialization. */
|
||||
bool opt_background_thread = BACKGROUND_THREAD_DEFAULT;
|
||||
size_t opt_max_background_threads = MAX_BACKGROUND_THREAD_LIMIT + 1;
|
||||
/*
|
||||
* This is disabled (and set to -1) if the HPA is. If the HPA is enabled,
|
||||
* malloc_conf initialization sets it to
|
||||
* BACKGROUND_THREAD_HPA_INTERVAL_MAX_DEFAULT_WHEN_ENABLED.
|
||||
*/
|
||||
ssize_t opt_background_thread_hpa_interval_max_ms =
|
||||
BACKGROUND_THREAD_HPA_INTERVAL_MAX_UNINITIALIZED;
|
||||
|
||||
/* Used for thread creation, termination and stats. */
|
||||
malloc_mutex_t background_thread_lock;
|
||||
|
|
@ -209,7 +216,20 @@ arena_decay_compute_purge_interval(tsdn_t *tsdn, arena_t *arena) {
|
|||
i2 = arena_decay_compute_purge_interval_impl(tsdn,
|
||||
&arena->pa_shard.pac.decay_muzzy, &arena->pa_shard.pac.ecache_muzzy);
|
||||
|
||||
return i1 < i2 ? i1 : i2;
|
||||
uint64_t min_so_far = i1 < i2 ? i1 : i2;
|
||||
if (opt_background_thread_hpa_interval_max_ms >= 0) {
|
||||
uint64_t hpa_interval = 1000 * 1000 *
|
||||
(uint64_t)opt_background_thread_hpa_interval_max_ms;
|
||||
if (hpa_interval < min_so_far) {
|
||||
if (hpa_interval < BACKGROUND_THREAD_MIN_INTERVAL_NS) {
|
||||
min_so_far = BACKGROUND_THREAD_MIN_INTERVAL_NS;
|
||||
} else {
|
||||
min_so_far = hpa_interval;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return min_so_far;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -607,16 +627,16 @@ background_threads_enable(tsd_t *tsd) {
|
|||
malloc_mutex_assert_owner(tsd_tsdn(tsd), &background_thread_lock);
|
||||
|
||||
VARIABLE_ARRAY(bool, marked, max_background_threads);
|
||||
unsigned i, nmarked;
|
||||
for (i = 0; i < max_background_threads; i++) {
|
||||
unsigned nmarked;
|
||||
for (unsigned i = 0; i < max_background_threads; i++) {
|
||||
marked[i] = false;
|
||||
}
|
||||
nmarked = 0;
|
||||
/* Thread 0 is required and created at the end. */
|
||||
marked[0] = true;
|
||||
/* Mark the threads we need to create for thread 0. */
|
||||
unsigned n = narenas_total_get();
|
||||
for (i = 1; i < n; i++) {
|
||||
unsigned narenas = narenas_total_get();
|
||||
for (unsigned i = 1; i < narenas; i++) {
|
||||
if (marked[i % max_background_threads] ||
|
||||
arena_get(tsd_tsdn(tsd), i, false) == NULL) {
|
||||
continue;
|
||||
|
|
@ -633,7 +653,18 @@ background_threads_enable(tsd_t *tsd) {
|
|||
}
|
||||
}
|
||||
|
||||
return background_thread_create_locked(tsd, 0);
|
||||
bool err = background_thread_create_locked(tsd, 0);
|
||||
if (err) {
|
||||
return true;
|
||||
}
|
||||
for (unsigned i = 0; i < narenas; i++) {
|
||||
arena_t *arena = arena_get(tsd_tsdn(tsd), i, false);
|
||||
if (arena != NULL) {
|
||||
pa_shard_set_deferral_allowed(tsd_tsdn(tsd),
|
||||
&arena->pa_shard, true);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
@ -647,6 +678,14 @@ background_threads_disable(tsd_t *tsd) {
|
|||
return true;
|
||||
}
|
||||
assert(n_background_threads == 0);
|
||||
unsigned narenas = narenas_total_get();
|
||||
for (unsigned i = 0; i < narenas; i++) {
|
||||
arena_t *arena = arena_get(tsd_tsdn(tsd), i, false);
|
||||
if (arena != NULL) {
|
||||
pa_shard_set_deferral_allowed(tsd_tsdn(tsd),
|
||||
&arena->pa_shard, false);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,6 +111,7 @@ CTL_PROTO(opt_percpu_arena)
|
|||
CTL_PROTO(opt_oversize_threshold)
|
||||
CTL_PROTO(opt_background_thread)
|
||||
CTL_PROTO(opt_max_background_threads)
|
||||
CTL_PROTO(opt_background_thread_hpa_interval_max_ms)
|
||||
CTL_PROTO(opt_dirty_decay_ms)
|
||||
CTL_PROTO(opt_muzzy_decay_ms)
|
||||
CTL_PROTO(opt_stats_print)
|
||||
|
|
@ -423,6 +424,8 @@ static const ctl_named_node_t opt_node[] = {
|
|||
{NAME("oversize_threshold"), CTL(opt_oversize_threshold)},
|
||||
{NAME("background_thread"), CTL(opt_background_thread)},
|
||||
{NAME("max_background_threads"), CTL(opt_max_background_threads)},
|
||||
{NAME("background_thread_hpa_interval_max_ms"),
|
||||
CTL(opt_background_thread_hpa_interval_max_ms)},
|
||||
{NAME("dirty_decay_ms"), CTL(opt_dirty_decay_ms)},
|
||||
{NAME("muzzy_decay_ms"), CTL(opt_muzzy_decay_ms)},
|
||||
{NAME("stats_print"), CTL(opt_stats_print)},
|
||||
|
|
@ -2139,6 +2142,8 @@ CTL_RO_NL_GEN(opt_percpu_arena, percpu_arena_mode_names[opt_percpu_arena],
|
|||
CTL_RO_NL_GEN(opt_oversize_threshold, opt_oversize_threshold, size_t)
|
||||
CTL_RO_NL_GEN(opt_background_thread, opt_background_thread, bool)
|
||||
CTL_RO_NL_GEN(opt_max_background_threads, opt_max_background_threads, size_t)
|
||||
CTL_RO_NL_GEN(opt_background_thread_hpa_interval_max_ms,
|
||||
opt_background_thread_hpa_interval_max_ms, ssize_t)
|
||||
CTL_RO_NL_GEN(opt_dirty_decay_ms, opt_dirty_decay_ms, ssize_t)
|
||||
CTL_RO_NL_GEN(opt_muzzy_decay_ms, opt_muzzy_decay_ms, ssize_t)
|
||||
CTL_RO_NL_GEN(opt_stats_print, opt_stats_print, bool)
|
||||
|
|
|
|||
|
|
@ -1410,6 +1410,10 @@ malloc_conf_init_helper(sc_data_t *sc_data, unsigned bin_shard_sizes[SC_NBINS],
|
|||
CONF_CHECK_MIN, CONF_CHECK_MAX,
|
||||
true);
|
||||
CONF_HANDLE_BOOL(opt_hpa, "hpa")
|
||||
CONF_HANDLE_SSIZE_T(
|
||||
opt_background_thread_hpa_interval_max_ms,
|
||||
"background_thread_hpa_interval_max_ms", -1,
|
||||
SSIZE_MAX)
|
||||
CONF_HANDLE_SIZE_T(opt_hpa_opts.slab_max_alloc,
|
||||
"hpa_slab_max_alloc", PAGE, HUGEPAGE,
|
||||
CONF_CHECK_MIN, CONF_CHECK_MAX, true);
|
||||
|
|
@ -1659,6 +1663,11 @@ malloc_conf_init(sc_data_t *sc_data, unsigned bin_shard_sizes[SC_NBINS]) {
|
|||
malloc_conf_init_helper(NULL, NULL, true, opts_cache, buf);
|
||||
malloc_conf_init_helper(sc_data, bin_shard_sizes, false, opts_cache,
|
||||
NULL);
|
||||
if (opt_hpa && opt_background_thread_hpa_interval_max_ms
|
||||
== BACKGROUND_THREAD_HPA_INTERVAL_MAX_UNINITIALIZED) {
|
||||
opt_background_thread_hpa_interval_max_ms =
|
||||
BACKGROUND_THREAD_HPA_INTERVAL_MAX_DEFAULT_WHEN_ENABLED;
|
||||
}
|
||||
}
|
||||
|
||||
#undef MALLOC_CONF_NSOURCES
|
||||
|
|
|
|||
12
src/pa.c
12
src/pa.c
|
|
@ -208,3 +208,15 @@ ssize_t
|
|||
pa_decay_ms_get(pa_shard_t *shard, extent_state_t state) {
|
||||
return pac_decay_ms_get(&shard->pac, state);
|
||||
}
|
||||
|
||||
void
|
||||
pa_shard_set_deferral_allowed(tsdn_t *tsdn, pa_shard_t *shard,
|
||||
bool deferral_allowed) {
|
||||
hpa_shard_set_deferral_allowed(tsdn, &shard->hpa_shard,
|
||||
deferral_allowed);
|
||||
}
|
||||
|
||||
void
|
||||
pa_shard_do_deferred_work(tsdn_t *tsdn, pa_shard_t *shard) {
|
||||
hpa_shard_do_deferred_work(tsdn, &shard->hpa_shard);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1494,6 +1494,7 @@ stats_general_print(emitter_t *emitter) {
|
|||
OPT_WRITE_SIZE_T("hpa_sec_batch_fill_extra")
|
||||
OPT_WRITE_CHAR_P("metadata_thp")
|
||||
OPT_WRITE_BOOL_MUTABLE("background_thread", "background_thread")
|
||||
OPT_WRITE_SSIZE_T("background_thread_hpa_interval_max_ms")
|
||||
OPT_WRITE_SSIZE_T_MUTABLE("dirty_decay_ms", "arenas.dirty_decay_ms")
|
||||
OPT_WRITE_SSIZE_T_MUTABLE("muzzy_decay_ms", "arenas.muzzy_decay_ms")
|
||||
OPT_WRITE_SIZE_T("lg_extent_max_active_fit")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue