Synchronize arena->decay with arena->decay.mtx.
This removes the last use of arena->lock.
This commit is contained in:
parent
d433471f58
commit
f8fee6908d
@ -81,7 +81,7 @@ arena_decay_ticks(tsdn_t *tsdn, arena_t *arena, unsigned nticks) {
|
|||||||
|
|
||||||
JEMALLOC_ALWAYS_INLINE void
|
JEMALLOC_ALWAYS_INLINE void
|
||||||
arena_decay_tick(tsdn_t *tsdn, arena_t *arena) {
|
arena_decay_tick(tsdn_t *tsdn, arena_t *arena) {
|
||||||
malloc_mutex_assert_not_owner(tsdn, &arena->lock);
|
malloc_mutex_assert_not_owner(tsdn, &arena->decay.mtx);
|
||||||
|
|
||||||
arena_decay_ticks(tsdn, arena, 1);
|
arena_decay_ticks(tsdn, arena, 1);
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,8 @@ struct arena_bin_info_s {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct arena_decay_s {
|
struct arena_decay_s {
|
||||||
|
/* Synchronizes all fields. */
|
||||||
|
malloc_mutex_t mtx;
|
||||||
/*
|
/*
|
||||||
* Approximate time in seconds from the creation of a set of unused
|
* Approximate time in seconds from the creation of a set of unused
|
||||||
* dirty pages until an equivalent set of unused dirty pages is purged
|
* dirty pages until an equivalent set of unused dirty pages is purged
|
||||||
@ -121,12 +123,6 @@ struct arena_s {
|
|||||||
*/
|
*/
|
||||||
unsigned nthreads[2];
|
unsigned nthreads[2];
|
||||||
|
|
||||||
/*
|
|
||||||
* Synchronizes various arena operations, as indicated in field-specific
|
|
||||||
* comments.
|
|
||||||
*/
|
|
||||||
malloc_mutex_t lock;
|
|
||||||
|
|
||||||
/* Synchronization: internal. */
|
/* Synchronization: internal. */
|
||||||
arena_stats_t stats;
|
arena_stats_t stats;
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ typedef int witness_comp_t (const witness_t *, void *, const witness_t *,
|
|||||||
*/
|
*/
|
||||||
#define WITNESS_RANK_CORE 9U
|
#define WITNESS_RANK_CORE 9U
|
||||||
|
|
||||||
#define WITNESS_RANK_ARENA 9U
|
#define WITNESS_RANK_DECAY 9U
|
||||||
#define WITNESS_RANK_TCACHE_QL 10U
|
#define WITNESS_RANK_TCACHE_QL 10U
|
||||||
#define WITNESS_RANK_EXTENTS 11U
|
#define WITNESS_RANK_EXTENTS 11U
|
||||||
#define WITNESS_RANK_EXTENT_FREELIST 12U
|
#define WITNESS_RANK_EXTENT_FREELIST 12U
|
||||||
|
56
src/arena.c
56
src/arena.c
@ -144,13 +144,11 @@ arena_stats_large_nrequests_add(tsdn_t *tsdn, arena_stats_t *arena_stats,
|
|||||||
void
|
void
|
||||||
arena_basic_stats_merge(tsdn_t *tsdn, arena_t *arena, unsigned *nthreads,
|
arena_basic_stats_merge(tsdn_t *tsdn, arena_t *arena, unsigned *nthreads,
|
||||||
const char **dss, ssize_t *decay_time, size_t *nactive, size_t *ndirty) {
|
const char **dss, ssize_t *decay_time, size_t *nactive, size_t *ndirty) {
|
||||||
malloc_mutex_lock(tsdn, &arena->lock);
|
|
||||||
*nthreads += arena_nthreads_get(arena, false);
|
*nthreads += arena_nthreads_get(arena, false);
|
||||||
*dss = dss_prec_names[arena_dss_prec_get(arena)];
|
*dss = dss_prec_names[arena_dss_prec_get(arena)];
|
||||||
*decay_time = arena->decay.time;
|
*decay_time = arena_decay_time_get(tsdn, arena);
|
||||||
*nactive += atomic_read_zu(&arena->nactive);
|
*nactive += atomic_read_zu(&arena->nactive);
|
||||||
*ndirty += extents_npages_get(&arena->extents_cached);
|
*ndirty += extents_npages_get(&arena->extents_cached);
|
||||||
malloc_mutex_unlock(tsdn, &arena->lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -607,7 +605,7 @@ arena_decay_epoch_advance(tsdn_t *tsdn, arena_t *arena, const nstime_t *time) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
arena_decay_init(arena_t *arena, ssize_t decay_time) {
|
arena_decay_reinit(arena_t *arena, ssize_t decay_time) {
|
||||||
arena->decay.time = decay_time;
|
arena->decay.time = decay_time;
|
||||||
if (decay_time > 0) {
|
if (decay_time > 0) {
|
||||||
nstime_init2(&arena->decay.interval, decay_time, 0);
|
nstime_init2(&arena->decay.interval, decay_time, 0);
|
||||||
@ -622,6 +620,15 @@ arena_decay_init(arena_t *arena, ssize_t decay_time) {
|
|||||||
memset(arena->decay.backlog, 0, SMOOTHSTEP_NSTEPS * sizeof(size_t));
|
memset(arena->decay.backlog, 0, SMOOTHSTEP_NSTEPS * sizeof(size_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
arena_decay_init(arena_t *arena, ssize_t decay_time) {
|
||||||
|
if (malloc_mutex_init(&arena->decay.mtx, "decay", WITNESS_RANK_DECAY)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
arena_decay_reinit(arena, decay_time);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
arena_decay_time_valid(ssize_t decay_time) {
|
arena_decay_time_valid(ssize_t decay_time) {
|
||||||
if (decay_time < -1) {
|
if (decay_time < -1) {
|
||||||
@ -637,9 +644,9 @@ ssize_t
|
|||||||
arena_decay_time_get(tsdn_t *tsdn, arena_t *arena) {
|
arena_decay_time_get(tsdn_t *tsdn, arena_t *arena) {
|
||||||
ssize_t decay_time;
|
ssize_t decay_time;
|
||||||
|
|
||||||
malloc_mutex_lock(tsdn, &arena->lock);
|
malloc_mutex_lock(tsdn, &arena->decay.mtx);
|
||||||
decay_time = arena->decay.time;
|
decay_time = arena->decay.time;
|
||||||
malloc_mutex_unlock(tsdn, &arena->lock);
|
malloc_mutex_unlock(tsdn, &arena->decay.mtx);
|
||||||
|
|
||||||
return decay_time;
|
return decay_time;
|
||||||
}
|
}
|
||||||
@ -650,7 +657,7 @@ arena_decay_time_set(tsdn_t *tsdn, arena_t *arena, ssize_t decay_time) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
malloc_mutex_lock(tsdn, &arena->lock);
|
malloc_mutex_lock(tsdn, &arena->decay.mtx);
|
||||||
/*
|
/*
|
||||||
* Restart decay backlog from scratch, which may cause many dirty pages
|
* Restart decay backlog from scratch, which may cause many dirty pages
|
||||||
* to be immediately purged. It would conceptually be possible to map
|
* to be immediately purged. It would conceptually be possible to map
|
||||||
@ -659,16 +666,16 @@ arena_decay_time_set(tsdn_t *tsdn, arena_t *arena, ssize_t decay_time) {
|
|||||||
* infrequent, either between the {-1, 0, >0} states, or a one-time
|
* infrequent, either between the {-1, 0, >0} states, or a one-time
|
||||||
* arbitrary change during initial arena configuration.
|
* arbitrary change during initial arena configuration.
|
||||||
*/
|
*/
|
||||||
arena_decay_init(arena, decay_time);
|
arena_decay_reinit(arena, decay_time);
|
||||||
arena_maybe_purge(tsdn, arena);
|
arena_maybe_purge(tsdn, arena);
|
||||||
malloc_mutex_unlock(tsdn, &arena->lock);
|
malloc_mutex_unlock(tsdn, &arena->decay.mtx);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
arena_maybe_purge(tsdn_t *tsdn, arena_t *arena) {
|
arena_maybe_purge(tsdn_t *tsdn, arena_t *arena) {
|
||||||
malloc_mutex_assert_owner(tsdn, &arena->lock);
|
malloc_mutex_assert_owner(tsdn, &arena->decay.mtx);
|
||||||
|
|
||||||
/* Purge all or nothing if the option is disabled. */
|
/* Purge all or nothing if the option is disabled. */
|
||||||
if (arena->decay.time <= 0) {
|
if (arena->decay.time <= 0) {
|
||||||
@ -766,7 +773,7 @@ arena_purge_stashed(tsdn_t *tsdn, arena_t *arena,
|
|||||||
static void
|
static void
|
||||||
arena_purge_to_limit(tsdn_t *tsdn, arena_t *arena, size_t ndirty_limit) {
|
arena_purge_to_limit(tsdn_t *tsdn, arena_t *arena, size_t ndirty_limit) {
|
||||||
witness_assert_depth_to_rank(tsdn, WITNESS_RANK_CORE, 1);
|
witness_assert_depth_to_rank(tsdn, WITNESS_RANK_CORE, 1);
|
||||||
malloc_mutex_assert_owner(tsdn, &arena->lock);
|
malloc_mutex_assert_owner(tsdn, &arena->decay.mtx);
|
||||||
|
|
||||||
if (atomic_cas_u(&arena->purging, 0, 1)) {
|
if (atomic_cas_u(&arena->purging, 0, 1)) {
|
||||||
return;
|
return;
|
||||||
@ -778,19 +785,19 @@ arena_purge_to_limit(tsdn_t *tsdn, arena_t *arena, size_t ndirty_limit) {
|
|||||||
|
|
||||||
extent_list_init(&purge_extents);
|
extent_list_init(&purge_extents);
|
||||||
|
|
||||||
malloc_mutex_unlock(tsdn, &arena->lock);
|
malloc_mutex_unlock(tsdn, &arena->decay.mtx);
|
||||||
|
|
||||||
npurge = arena_stash_dirty(tsdn, arena, &extent_hooks, ndirty_limit,
|
npurge = arena_stash_dirty(tsdn, arena, &extent_hooks, ndirty_limit,
|
||||||
&purge_extents);
|
&purge_extents);
|
||||||
if (npurge == 0) {
|
if (npurge == 0) {
|
||||||
malloc_mutex_lock(tsdn, &arena->lock);
|
malloc_mutex_lock(tsdn, &arena->decay.mtx);
|
||||||
goto label_return;
|
goto label_return;
|
||||||
}
|
}
|
||||||
npurged = arena_purge_stashed(tsdn, arena, &extent_hooks,
|
npurged = arena_purge_stashed(tsdn, arena, &extent_hooks,
|
||||||
&purge_extents);
|
&purge_extents);
|
||||||
assert(npurged == npurge);
|
assert(npurged == npurge);
|
||||||
|
|
||||||
malloc_mutex_lock(tsdn, &arena->lock);
|
malloc_mutex_lock(tsdn, &arena->decay.mtx);
|
||||||
|
|
||||||
if (config_stats) {
|
if (config_stats) {
|
||||||
arena_stats_lock(tsdn, &arena->stats);
|
arena_stats_lock(tsdn, &arena->stats);
|
||||||
@ -805,13 +812,13 @@ label_return:
|
|||||||
|
|
||||||
void
|
void
|
||||||
arena_purge(tsdn_t *tsdn, arena_t *arena, bool all) {
|
arena_purge(tsdn_t *tsdn, arena_t *arena, bool all) {
|
||||||
malloc_mutex_lock(tsdn, &arena->lock);
|
malloc_mutex_lock(tsdn, &arena->decay.mtx);
|
||||||
if (all) {
|
if (all) {
|
||||||
arena_purge_to_limit(tsdn, arena, 0);
|
arena_purge_to_limit(tsdn, arena, 0);
|
||||||
} else {
|
} else {
|
||||||
arena_maybe_purge(tsdn, arena);
|
arena_maybe_purge(tsdn, arena);
|
||||||
}
|
}
|
||||||
malloc_mutex_unlock(tsdn, &arena->lock);
|
malloc_mutex_unlock(tsdn, &arena->decay.mtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -822,9 +829,9 @@ arena_slab_dalloc(tsdn_t *tsdn, arena_t *arena, extent_t *slab) {
|
|||||||
extent_dalloc_cache(tsdn, arena, &extent_hooks, slab);
|
extent_dalloc_cache(tsdn, arena, &extent_hooks, slab);
|
||||||
|
|
||||||
arena_nactive_sub(arena, npages);
|
arena_nactive_sub(arena, npages);
|
||||||
malloc_mutex_lock(tsdn, &arena->lock);
|
malloc_mutex_lock(tsdn, &arena->decay.mtx);
|
||||||
arena_maybe_purge(tsdn, arena);
|
arena_maybe_purge(tsdn, arena);
|
||||||
malloc_mutex_unlock(tsdn, &arena->lock);
|
malloc_mutex_unlock(tsdn, &arena->decay.mtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1641,9 +1648,6 @@ arena_new(tsdn_t *tsdn, unsigned ind, extent_hooks_t *extent_hooks) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
arena->nthreads[0] = arena->nthreads[1] = 0;
|
arena->nthreads[0] = arena->nthreads[1] = 0;
|
||||||
if (malloc_mutex_init(&arena->lock, "arena", WITNESS_RANK_ARENA)) {
|
|
||||||
goto label_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config_stats) {
|
if (config_stats) {
|
||||||
if (arena_stats_init(tsdn, &arena->stats)) {
|
if (arena_stats_init(tsdn, &arena->stats)) {
|
||||||
@ -1684,7 +1688,9 @@ arena_new(tsdn_t *tsdn, unsigned ind, extent_hooks_t *extent_hooks) {
|
|||||||
atomic_write_u(&arena->purging, 0);
|
atomic_write_u(&arena->purging, 0);
|
||||||
atomic_write_zu(&arena->nactive, 0);
|
atomic_write_zu(&arena->nactive, 0);
|
||||||
|
|
||||||
arena_decay_init(arena, arena_decay_time_default_get());
|
if (arena_decay_init(arena, arena_decay_time_default_get())) {
|
||||||
|
goto label_error;
|
||||||
|
}
|
||||||
|
|
||||||
extent_list_init(&arena->large);
|
extent_list_init(&arena->large);
|
||||||
if (malloc_mutex_init(&arena->large_mtx, "arena_large",
|
if (malloc_mutex_init(&arena->large_mtx, "arena_large",
|
||||||
@ -1742,7 +1748,7 @@ arena_boot(void) {
|
|||||||
|
|
||||||
void
|
void
|
||||||
arena_prefork0(tsdn_t *tsdn, arena_t *arena) {
|
arena_prefork0(tsdn_t *tsdn, arena_t *arena) {
|
||||||
malloc_mutex_prefork(tsdn, &arena->lock);
|
malloc_mutex_prefork(tsdn, &arena->decay.mtx);
|
||||||
if (config_stats && config_tcache) {
|
if (config_stats && config_tcache) {
|
||||||
malloc_mutex_prefork(tsdn, &arena->tcache_ql_mtx);
|
malloc_mutex_prefork(tsdn, &arena->tcache_ql_mtx);
|
||||||
}
|
}
|
||||||
@ -1782,7 +1788,7 @@ arena_postfork_parent(tsdn_t *tsdn, arena_t *arena) {
|
|||||||
malloc_mutex_postfork_parent(tsdn, &arena->extent_freelist_mtx);
|
malloc_mutex_postfork_parent(tsdn, &arena->extent_freelist_mtx);
|
||||||
extents_postfork_parent(tsdn, &arena->extents_cached);
|
extents_postfork_parent(tsdn, &arena->extents_cached);
|
||||||
extents_postfork_parent(tsdn, &arena->extents_retained);
|
extents_postfork_parent(tsdn, &arena->extents_retained);
|
||||||
malloc_mutex_postfork_parent(tsdn, &arena->lock);
|
malloc_mutex_postfork_parent(tsdn, &arena->decay.mtx);
|
||||||
if (config_stats && config_tcache) {
|
if (config_stats && config_tcache) {
|
||||||
malloc_mutex_postfork_parent(tsdn, &arena->tcache_ql_mtx);
|
malloc_mutex_postfork_parent(tsdn, &arena->tcache_ql_mtx);
|
||||||
}
|
}
|
||||||
@ -1800,7 +1806,7 @@ arena_postfork_child(tsdn_t *tsdn, arena_t *arena) {
|
|||||||
malloc_mutex_postfork_child(tsdn, &arena->extent_freelist_mtx);
|
malloc_mutex_postfork_child(tsdn, &arena->extent_freelist_mtx);
|
||||||
extents_postfork_child(tsdn, &arena->extents_cached);
|
extents_postfork_child(tsdn, &arena->extents_cached);
|
||||||
extents_postfork_child(tsdn, &arena->extents_retained);
|
extents_postfork_child(tsdn, &arena->extents_retained);
|
||||||
malloc_mutex_postfork_child(tsdn, &arena->lock);
|
malloc_mutex_postfork_child(tsdn, &arena->decay.mtx);
|
||||||
if (config_stats && config_tcache) {
|
if (config_stats && config_tcache) {
|
||||||
malloc_mutex_postfork_child(tsdn, &arena->tcache_ql_mtx);
|
malloc_mutex_postfork_child(tsdn, &arena->tcache_ql_mtx);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user