mirror of
https://github.com/jemalloc/jemalloc.git
synced 2026-07-24 13:53:11 +00:00
Refactor arena ctl helpers
This commit is contained in:
141
src/ctl.c
141
src/ctl.c
@@ -981,8 +981,41 @@ ctl_accum_atomic_zu(atomic_zu_t *dst, atomic_zu_t *src) {
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Historical compatibility for treating arena.<narenas> as the merged
|
||||||
|
* all-arenas entry. New code should use MALLCTL_ARENAS_ALL.
|
||||||
|
*
|
||||||
|
* `narenas` must be a snapshot of ctl_arenas->narenas taken while holding
|
||||||
|
* ctl_mtx; see ctl_narenas_get.
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
ctl_arena_ind_is_deprecated_all(size_t i, unsigned narenas) {
|
||||||
|
return i == narenas;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* `narenas` must be a snapshot of ctl_arenas->narenas taken while holding
|
||||||
|
* ctl_mtx; see ctl_narenas_get.
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
ctl_arena_ind_is_all(size_t i, unsigned narenas) {
|
||||||
|
return i == MALLCTL_ARENAS_ALL
|
||||||
|
|| ctl_arena_ind_is_deprecated_all(i, narenas);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ctl_arenas->narenas may grow concurrently (arena creation in
|
||||||
|
* ctl_arena_init); all reads must happen while ctl_mtx is held. This
|
||||||
|
* helper centralizes that requirement.
|
||||||
|
*/
|
||||||
static unsigned
|
static unsigned
|
||||||
arenas_i2a_impl(size_t i, bool compat, bool validate) {
|
ctl_narenas_get(tsdn_t *tsdn) {
|
||||||
|
malloc_mutex_assert_owner(tsdn, &ctl_mtx);
|
||||||
|
return ctl_arenas->narenas;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned
|
||||||
|
arenas_i2a_impl(size_t i, unsigned narenas, bool compat, bool validate) {
|
||||||
unsigned a;
|
unsigned a;
|
||||||
|
|
||||||
switch (i) {
|
switch (i) {
|
||||||
@@ -993,7 +1026,7 @@ arenas_i2a_impl(size_t i, bool compat, bool validate) {
|
|||||||
a = 1;
|
a = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (compat && i == ctl_arenas->narenas) {
|
if (compat && ctl_arena_ind_is_deprecated_all(i, narenas)) {
|
||||||
/*
|
/*
|
||||||
* Provide deprecated backward compatibility for
|
* Provide deprecated backward compatibility for
|
||||||
* accessing the merged stats at index narenas rather
|
* accessing the merged stats at index narenas rather
|
||||||
@@ -1001,7 +1034,7 @@ arenas_i2a_impl(size_t i, bool compat, bool validate) {
|
|||||||
* removal in 6.0.0.
|
* removal in 6.0.0.
|
||||||
*/
|
*/
|
||||||
a = 0;
|
a = 0;
|
||||||
} else if (validate && i >= ctl_arenas->narenas) {
|
} else if (validate && i >= narenas) {
|
||||||
a = UINT_MAX;
|
a = UINT_MAX;
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
@@ -1009,8 +1042,7 @@ arenas_i2a_impl(size_t i, bool compat, bool validate) {
|
|||||||
* more than one past the range of indices that have
|
* more than one past the range of indices that have
|
||||||
* initialized ctl data.
|
* initialized ctl data.
|
||||||
*/
|
*/
|
||||||
assert(i < ctl_arenas->narenas
|
assert(i < narenas || (!validate && i == narenas));
|
||||||
|| (!validate && i == ctl_arenas->narenas));
|
|
||||||
a = (unsigned)i + 2;
|
a = (unsigned)i + 2;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -1020,8 +1052,8 @@ arenas_i2a_impl(size_t i, bool compat, bool validate) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static unsigned
|
static unsigned
|
||||||
arenas_i2a(size_t i) {
|
arenas_i2a(size_t i, unsigned narenas) {
|
||||||
return arenas_i2a_impl(i, true, false);
|
return arenas_i2a_impl(i, narenas, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ctl_arena_t *
|
static ctl_arena_t *
|
||||||
@@ -1029,8 +1061,9 @@ arenas_i_impl(tsd_t *tsd, size_t i, bool compat, bool init) {
|
|||||||
ctl_arena_t *ret;
|
ctl_arena_t *ret;
|
||||||
|
|
||||||
assert(!compat || !init);
|
assert(!compat || !init);
|
||||||
|
unsigned narenas = ctl_narenas_get(tsd_tsdn(tsd));
|
||||||
|
|
||||||
ret = ctl_arenas->arenas[arenas_i2a_impl(i, compat, false)];
|
ret = ctl_arenas->arenas[arenas_i2a_impl(i, narenas, compat, false)];
|
||||||
if (init && ret == NULL) {
|
if (init && ret == NULL) {
|
||||||
if (config_stats) {
|
if (config_stats) {
|
||||||
struct container_s {
|
struct container_s {
|
||||||
@@ -1053,10 +1086,12 @@ arenas_i_impl(tsd_t *tsd, size_t i, bool compat, bool init) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ret->arena_ind = (unsigned)i;
|
ret->arena_ind = (unsigned)i;
|
||||||
ctl_arenas->arenas[arenas_i2a_impl(i, compat, false)] = ret;
|
ctl_arenas->arenas[arenas_i2a_impl(i, narenas, compat, false)]
|
||||||
|
= ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(ret == NULL || arenas_i2a(ret->arena_ind) == arenas_i2a(i));
|
assert(ret == NULL ||
|
||||||
|
arenas_i2a(ret->arena_ind, narenas) == arenas_i2a(i, narenas));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1309,6 +1344,8 @@ ctl_arena_init(tsd_t *tsd, const arena_config_t *config) {
|
|||||||
unsigned arena_ind;
|
unsigned arena_ind;
|
||||||
ctl_arena_t *ctl_arena;
|
ctl_arena_t *ctl_arena;
|
||||||
|
|
||||||
|
malloc_mutex_assert_owner(tsd_tsdn(tsd), &ctl_mtx);
|
||||||
|
|
||||||
if ((ctl_arena = ql_last(&ctl_arenas->destroyed, destroyed_link))
|
if ((ctl_arena = ql_last(&ctl_arenas->destroyed, destroyed_link))
|
||||||
!= NULL) {
|
!= NULL) {
|
||||||
ql_remove(&ctl_arenas->destroyed, ctl_arena, destroyed_link);
|
ql_remove(&ctl_arenas->destroyed, ctl_arena, destroyed_link);
|
||||||
@@ -2696,46 +2733,29 @@ label_return:
|
|||||||
static void
|
static void
|
||||||
arena_i_decay(tsdn_t *tsdn, unsigned arena_ind, bool all) {
|
arena_i_decay(tsdn_t *tsdn, unsigned arena_ind, bool all) {
|
||||||
malloc_mutex_lock(tsdn, &ctl_mtx);
|
malloc_mutex_lock(tsdn, &ctl_mtx);
|
||||||
{
|
unsigned narenas = ctl_narenas_get(tsdn);
|
||||||
unsigned narenas = ctl_arenas->narenas;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Access via index narenas is deprecated, and scheduled for
|
* Access via index narenas is deprecated, and scheduled for
|
||||||
* removal in 6.0.0.
|
* removal in 6.0.0.
|
||||||
*/
|
*/
|
||||||
if (arena_ind == MALLCTL_ARENAS_ALL || arena_ind == narenas) {
|
bool decay_all = ctl_arena_ind_is_all(arena_ind, narenas);
|
||||||
unsigned i;
|
unsigned count = decay_all ? narenas : 1;
|
||||||
VARIABLE_ARRAY_UNSAFE(arena_t *, tarenas, narenas);
|
VARIABLE_ARRAY_UNSAFE(arena_t *, tarenas, count);
|
||||||
|
|
||||||
for (i = 0; i < narenas; i++) {
|
if (decay_all) {
|
||||||
tarenas[i] = arena_get(tsdn, i, false);
|
for (unsigned i = 0; i < narenas; i++) {
|
||||||
}
|
tarenas[i] = arena_get(tsdn, i, false);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
assert(arena_ind < narenas);
|
||||||
|
tarenas[0] = arena_get(tsdn, arena_ind, false);
|
||||||
|
}
|
||||||
|
malloc_mutex_unlock(tsdn, &ctl_mtx);
|
||||||
|
|
||||||
/*
|
for (unsigned i = 0; i < count; i++) {
|
||||||
* No further need to hold ctl_mtx, since narenas and
|
if (tarenas[i] != NULL) {
|
||||||
* tarenas contain everything needed below.
|
arena_decay(tsdn, tarenas[i], false, all);
|
||||||
*/
|
|
||||||
malloc_mutex_unlock(tsdn, &ctl_mtx);
|
|
||||||
|
|
||||||
for (i = 0; i < narenas; i++) {
|
|
||||||
if (tarenas[i] != NULL) {
|
|
||||||
arena_decay(
|
|
||||||
tsdn, tarenas[i], false, all);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
arena_t *tarena;
|
|
||||||
|
|
||||||
assert(arena_ind < narenas);
|
|
||||||
|
|
||||||
tarena = arena_get(tsdn, arena_ind, false);
|
|
||||||
|
|
||||||
/* No further need to hold ctl_mtx. */
|
|
||||||
malloc_mutex_unlock(tsdn, &ctl_mtx);
|
|
||||||
|
|
||||||
if (tarena != NULL) {
|
|
||||||
arena_decay(tsdn, tarena, false, all);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2920,8 +2940,8 @@ arena_i_dss_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
|
|||||||
* 6.0.0.
|
* 6.0.0.
|
||||||
*/
|
*/
|
||||||
dss_prec_t dss_prec_old;
|
dss_prec_t dss_prec_old;
|
||||||
if (arena_ind == MALLCTL_ARENAS_ALL
|
unsigned narenas = ctl_narenas_get(tsd_tsdn(tsd));
|
||||||
|| arena_ind == ctl_arenas->narenas) {
|
if (ctl_arena_ind_is_all(arena_ind, narenas)) {
|
||||||
if (dss_prec != dss_prec_limit
|
if (dss_prec != dss_prec_limit
|
||||||
&& extent_dss_prec_set(dss_prec)) {
|
&& extent_dss_prec_set(dss_prec)) {
|
||||||
ret = EFAULT;
|
ret = EFAULT;
|
||||||
@@ -2996,7 +3016,7 @@ arena_i_decay_ms_ctl_impl(tsd_t *tsd, const size_t *mib, size_t miblen,
|
|||||||
extent_state_t state = dirty ? extent_state_dirty : extent_state_muzzy;
|
extent_state_t state = dirty ? extent_state_dirty : extent_state_muzzy;
|
||||||
|
|
||||||
if (oldp != NULL && oldlenp != NULL) {
|
if (oldp != NULL && oldlenp != NULL) {
|
||||||
size_t oldval = arena_decay_ms_get(arena, state);
|
ssize_t oldval = arena_decay_ms_get(arena, state);
|
||||||
READ(oldval, ssize_t);
|
READ(oldval, ssize_t);
|
||||||
}
|
}
|
||||||
if (newp != NULL) {
|
if (newp != NULL) {
|
||||||
@@ -3141,8 +3161,9 @@ arena_i_name_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
|
|||||||
|
|
||||||
malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
|
malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
|
||||||
MIB_UNSIGNED(arena_ind, 1);
|
MIB_UNSIGNED(arena_ind, 1);
|
||||||
if (arena_ind == MALLCTL_ARENAS_ALL
|
unsigned narenas = ctl_narenas_get(tsd_tsdn(tsd));
|
||||||
|| arena_ind >= ctl_arenas->narenas) {
|
if (ctl_arena_ind_is_all(arena_ind, narenas)
|
||||||
|
|| arena_ind > narenas) {
|
||||||
ret = EINVAL;
|
ret = EINVAL;
|
||||||
goto label_return;
|
goto label_return;
|
||||||
}
|
}
|
||||||
@@ -3191,7 +3212,7 @@ arena_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) {
|
|||||||
case MALLCTL_ARENAS_DESTROYED:
|
case MALLCTL_ARENAS_DESTROYED:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (i > ctl_arenas->narenas) {
|
if (i > ctl_narenas_get(tsdn)) {
|
||||||
ret = NULL;
|
ret = NULL;
|
||||||
goto label_return;
|
goto label_return;
|
||||||
}
|
}
|
||||||
@@ -3214,7 +3235,7 @@ arenas_narenas_ctl(tsd_t *tsd, const size_t *mib, size_t miblen, void *oldp,
|
|||||||
|
|
||||||
malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
|
malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
|
||||||
READONLY();
|
READONLY();
|
||||||
narenas = ctl_arenas->narenas;
|
narenas = ctl_narenas_get(tsd_tsdn(tsd));
|
||||||
READ(narenas, unsigned);
|
READ(narenas, unsigned);
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
@@ -3229,8 +3250,8 @@ arenas_decay_ms_ctl_impl(tsd_t *tsd, const size_t *mib, size_t miblen,
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (oldp != NULL && oldlenp != NULL) {
|
if (oldp != NULL && oldlenp != NULL) {
|
||||||
size_t oldval = (dirty ? arena_dirty_decay_ms_default_get()
|
ssize_t oldval = (dirty ? arena_dirty_decay_ms_default_get()
|
||||||
: arena_muzzy_decay_ms_default_get());
|
: arena_muzzy_decay_ms_default_get());
|
||||||
READ(oldval, ssize_t);
|
READ(oldval, ssize_t);
|
||||||
}
|
}
|
||||||
if (newp != NULL) {
|
if (newp != NULL) {
|
||||||
@@ -4254,8 +4275,8 @@ stats_arenas_i_hpa_shard_alloc_j_index(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
ctl_arenas_i_verify(size_t i) {
|
ctl_arenas_i_verify(size_t i, unsigned narenas) {
|
||||||
size_t a = arenas_i2a_impl(i, true, true);
|
size_t a = arenas_i2a_impl(i, narenas, true, true);
|
||||||
if (a == UINT_MAX || !ctl_arenas->arenas[a]->initialized) {
|
if (a == UINT_MAX || !ctl_arenas->arenas[a]->initialized) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -4268,7 +4289,7 @@ stats_arenas_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen, size_t i) {
|
|||||||
const ctl_named_node_t *ret;
|
const ctl_named_node_t *ret;
|
||||||
|
|
||||||
malloc_mutex_lock(tsdn, &ctl_mtx);
|
malloc_mutex_lock(tsdn, &ctl_mtx);
|
||||||
if (ctl_arenas_i_verify(i)) {
|
if (ctl_arenas_i_verify(i, ctl_narenas_get(tsdn))) {
|
||||||
ret = NULL;
|
ret = NULL;
|
||||||
goto label_return;
|
goto label_return;
|
||||||
}
|
}
|
||||||
@@ -4507,7 +4528,7 @@ experimental_arenas_i_index(
|
|||||||
const ctl_named_node_t *ret;
|
const ctl_named_node_t *ret;
|
||||||
|
|
||||||
malloc_mutex_lock(tsdn, &ctl_mtx);
|
malloc_mutex_lock(tsdn, &ctl_mtx);
|
||||||
if (ctl_arenas_i_verify(i)) {
|
if (ctl_arenas_i_verify(i, ctl_narenas_get(tsdn))) {
|
||||||
ret = NULL;
|
ret = NULL;
|
||||||
goto label_return;
|
goto label_return;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user