Add arena-level name.

An arena-level name can help identify manual arenas.
This commit is contained in:
Guangli Dai
2022-09-01 16:42:56 -07:00
committed by Qi Wang
parent a0734fd6ee
commit ba19d2cb78
8 changed files with 146 additions and 9 deletions

View File

@@ -1547,6 +1547,22 @@ arena_dss_prec_set(arena_t *arena, dss_prec_t dss_prec) {
return false;
}
void
arena_name_get(arena_t *arena, char *name) {
char *end = (char *)memchr((void *)arena->name, '\0', ARENA_NAME_LEN);
assert(end != NULL);
size_t len = (uintptr_t)end - (uintptr_t)arena->name + 1;
assert(len > 0 && len <= ARENA_NAME_LEN);
strncpy(name, arena->name, len);
}
void
arena_name_set(arena_t *arena, const char *name) {
strncpy(arena->name, name, ARENA_NAME_LEN);
arena->name[ARENA_NAME_LEN - 1] = '\0';
}
ssize_t
arena_dirty_decay_ms_default_get(void) {
return atomic_load_zd(&dirty_decay_ms_default, ATOMIC_RELAXED);
@@ -1670,6 +1686,11 @@ arena_new(tsdn_t *tsdn, unsigned ind, const arena_config_t *config) {
arena_set(ind, arena);
arena->ind = ind;
/* Init the name. */
malloc_snprintf(arena->name, sizeof(arena->name), "%s_%u",
arena_is_auto(arena) ? "auto" : "manual", arena->ind);
arena->name[ARENA_NAME_LEN - 1] = '\0';
nstime_init_update(&arena->create_time);
/*

View File

@@ -170,6 +170,7 @@ CTL_PROTO(arena_i_dirty_decay_ms)
CTL_PROTO(arena_i_muzzy_decay_ms)
CTL_PROTO(arena_i_extent_hooks)
CTL_PROTO(arena_i_retain_grow_limit)
CTL_PROTO(arena_i_name)
INDEX_PROTO(arena_i)
CTL_PROTO(arenas_bin_i_size)
CTL_PROTO(arenas_bin_i_nregs)
@@ -504,11 +505,12 @@ static const ctl_named_node_t arena_i_node[] = {
* Undocumented for now, since we anticipate an arena API in flux after
* we cut the last 5-series release.
*/
{NAME("oversize_threshold"), CTL(arena_i_oversize_threshold)},
{NAME("dirty_decay_ms"), CTL(arena_i_dirty_decay_ms)},
{NAME("muzzy_decay_ms"), CTL(arena_i_muzzy_decay_ms)},
{NAME("extent_hooks"), CTL(arena_i_extent_hooks)},
{NAME("retain_grow_limit"), CTL(arena_i_retain_grow_limit)}
{NAME("oversize_threshold"), CTL(arena_i_oversize_threshold)},
{NAME("dirty_decay_ms"), CTL(arena_i_dirty_decay_ms)},
{NAME("muzzy_decay_ms"), CTL(arena_i_muzzy_decay_ms)},
{NAME("extent_hooks"), CTL(arena_i_extent_hooks)},
{NAME("retain_grow_limit"), CTL(arena_i_retain_grow_limit)},
{NAME("name"), CTL(arena_i_name)}
};
static const ctl_named_node_t super_arena_i_node[] = {
{NAME(""), CHILD(named, arena_i)}
@@ -2983,6 +2985,61 @@ label_return:
return ret;
}
/*
* When writing, newp should point to a char array storing the name to be set.
* A name longer than ARENA_NAME_LEN will be arbitrarily cut. When reading,
* oldp should point to a char array whose length is no shorter than
* ARENA_NAME_LEN or the length of the name when it was set.
*/
static int
arena_i_name_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
int ret;
unsigned arena_ind;
char *name;
malloc_mutex_lock(tsd_tsdn(tsd), &ctl_mtx);
MIB_UNSIGNED(arena_ind, 1);
if (arena_ind == MALLCTL_ARENAS_ALL || arena_ind >=
ctl_arenas->narenas) {
ret = EINVAL;
goto label_return;
}
arena_t *arena = arena_get(tsd_tsdn(tsd), arena_ind, false);
if (arena == NULL) {
ret = EFAULT;
goto label_return;
}
if (oldp != NULL && oldlenp != NULL) {
/*
* Read the arena name. When reading, the input oldp should
* point to an array with a length no shorter than
* ARENA_NAME_LEN or the length when it was set.
*/
if (*oldlenp != sizeof(char *)) {
ret = EINVAL;
goto label_return;
}
name = *(char **)oldp;
arena_name_get(arena, name);
}
if (newp != NULL) {
/* Write the arena name. */
WRITE(name, char *);
if (name == NULL) {
ret = EINVAL;
goto label_return;
}
arena_name_set(arena, name);
}
ret = 0;
label_return:
malloc_mutex_unlock(tsd_tsdn(tsd), &ctl_mtx);
return ret;
}
static const ctl_named_node_t *
arena_i_index(tsdn_t *tsdn, const size_t *mib, size_t miblen,
size_t i) {

View File

@@ -42,15 +42,18 @@ const char *arena_mutex_names[mutex_prof_num_arena_mutexes] = {
assert(miblen_new == miblen + 1); \
} while (0)
#define CTL_M2_GET(n, i, v, t) do { \
#define CTL_MIB_GET(n, i, v, t, ind) do { \
size_t mib[CTL_MAX_DEPTH]; \
size_t miblen = sizeof(mib) / sizeof(size_t); \
size_t sz = sizeof(t); \
xmallctlnametomib(n, mib, &miblen); \
mib[2] = (i); \
mib[(ind)] = (i); \
xmallctlbymib(mib, miblen, (void *)v, &sz, NULL, 0); \
} while (0)
#define CTL_M1_GET(n, i, v, t) CTL_MIB_GET(n, i, v, t, 1)
#define CTL_M2_GET(n, i, v, t) CTL_MIB_GET(n, i, v, t, 2)
/******************************************************************************/
/* Data. */
@@ -1042,6 +1045,8 @@ JEMALLOC_COLD
static void
stats_arena_print(emitter_t *emitter, unsigned i, bool bins, bool large,
bool mutex, bool extents, bool hpa) {
char name[ARENA_NAME_LEN];
char *namep = name;
unsigned nthreads;
const char *dss;
ssize_t dirty_decay_ms, muzzy_decay_ms;
@@ -1059,6 +1064,10 @@ stats_arena_print(emitter_t *emitter, unsigned i, bool bins, bool large,
uint64_t uptime;
CTL_GET("arenas.page", &page, size_t);
if (i != MALLCTL_ARENAS_ALL && i != MALLCTL_ARENAS_DESTROYED) {
CTL_M1_GET("arena.0.name", i, (void *)&namep, const char *);
emitter_kv(emitter, "name", "name", emitter_type_string, &namep);
}
CTL_M2_GET("stats.arenas.0.nthreads", i, &nthreads, unsigned);
emitter_kv(emitter, "nthreads", "assigned threads",