Skip to content

Commit

Permalink
print out all malloc_conf settings in stats
Browse files Browse the repository at this point in the history
  • Loading branch information
Shirui Cheng committed Feb 2, 2024
1 parent f96010b commit 2fe16a3
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 2 deletions.
3 changes: 3 additions & 0 deletions include/jemalloc/internal/jemalloc_internal_externs.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ extern atomic_zu_t zero_realloc_count;
extern bool opt_cache_oblivious;
extern unsigned opt_debug_double_free_max_scan;

extern char malloc_conf_file[PATH_MAX + 1];
extern char malloc_conf_env_var[PATH_MAX + 1];

/* Escape free-fastpath when ptr & mask == 0 (for sanitization purpose). */
extern uintptr_t san_cache_bin_nonfast_mask;

Expand Down
26 changes: 25 additions & 1 deletion src/ctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ CTL_PROTO(thread_allocatedp)
CTL_PROTO(thread_deallocated)
CTL_PROTO(thread_deallocatedp)
CTL_PROTO(thread_idle)
CTL_PROTO(malloc_conf_global_var_malloc_conf)
CTL_PROTO(malloc_conf_file)
CTL_PROTO(malloc_conf_env_var)
CTL_PROTO(malloc_conf_global_var_malloc_conf_2_conf_harder)
CTL_PROTO(config_cache_oblivious)
CTL_PROTO(config_debug)
CTL_PROTO(config_fill)
Expand Down Expand Up @@ -920,6 +924,15 @@ static const ctl_named_node_t experimental_node[] = {
{NAME("thread"), CHILD(named, experimental_thread)}
};

static const ctl_named_node_t malloc_conf_node[] = {
{NAME("global_var_malloc_conf"),
CTL(malloc_conf_global_var_malloc_conf)},
{NAME("file"), CTL(malloc_conf_file)},
{NAME("env_var"), CTL(malloc_conf_env_var)},
{NAME("global_var_malloc_conf_2_conf_harder"),
CTL(malloc_conf_global_var_malloc_conf_2_conf_harder)}
};

static const ctl_named_node_t root_node[] = {
{NAME("version"), CTL(version)},
{NAME("epoch"), CTL(epoch)},
Expand All @@ -933,7 +946,8 @@ static const ctl_named_node_t root_node[] = {
{NAME("arenas"), CHILD(named, arenas)},
{NAME("prof"), CHILD(named, prof)},
{NAME("stats"), CHILD(named, stats)},
{NAME("experimental"), CHILD(named, experimental)}
{NAME("experimental"), CHILD(named, experimental)},
{NAME("malloc_conf"), CHILD(named, malloc_conf)}
};
static const ctl_named_node_t super_root_node[] = {
{NAME(""), CHILD(named, root)}
Expand Down Expand Up @@ -1986,6 +2000,16 @@ label_return: \

CTL_RO_NL_GEN(version, JEMALLOC_VERSION, const char *)

CTL_RO_NL_CGEN(je_malloc_conf, malloc_conf_global_var_malloc_conf,
je_malloc_conf, const char *)
CTL_RO_NL_CGEN(malloc_conf_file, malloc_conf_file, malloc_conf_file,
const char *)
CTL_RO_NL_CGEN(malloc_conf_env_var, malloc_conf_env_var,
malloc_conf_env_var, const char *)
CTL_RO_NL_CGEN(je_malloc_conf_2_conf_harder,
malloc_conf_global_var_malloc_conf_2_conf_harder,
je_malloc_conf_2_conf_harder, const char *)

static int
epoch_ctl(tsd_t *tsd, const size_t *mib, size_t miblen,
void *oldp, size_t *oldlenp, void *newp, size_t newlen) {
Expand Down
7 changes: 7 additions & 0 deletions src/jemalloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ const char *je_malloc_conf_2_conf_harder
#endif
;

char malloc_conf_file[PATH_MAX + 1];
char malloc_conf_env_var[PATH_MAX + 1];

bool opt_abort =
#ifdef JEMALLOC_DEBUG
true
Expand Down Expand Up @@ -1009,6 +1012,8 @@ obtain_malloc_conf(unsigned which_source, char buf[PATH_MAX + 1]) {
set_errno(saved_errno);
}
#endif
strncpy(malloc_conf_file, buf, linklen);
malloc_conf_file[linklen] = '\0';
buf[linklen] = '\0';
ret = buf;
break;
Expand All @@ -1026,6 +1031,8 @@ obtain_malloc_conf(unsigned which_source, char buf[PATH_MAX + 1]) {
* Do nothing; opts is already initialized to the value
* of the MALLOC_CONF environment variable.
*/
strncpy(malloc_conf_env_var, ret, PATH_MAX);
malloc_conf_env_var[PATH_MAX] = '\0';
} else {
/* No configuration specified. */
ret = NULL;
Expand Down
37 changes: 37 additions & 0 deletions src/stats.c
Original file line number Diff line number Diff line change
Expand Up @@ -1430,6 +1430,43 @@ stats_general_print(emitter_t *emitter) {
#undef CONFIG_WRITE_BOOL
emitter_dict_end(emitter); /* Close "config" dict. */

/*
* malloc_conf.
*
* Sources are documented in https://jemalloc.net/jemalloc.3.html#tuning
* - (Not Included Here) The string specified via --with-malloc-conf,
* which is already printed out above as config.malloc_conf
* - (Included) The string pointed to by the global variable malloc_conf
* - (Included) The “name” of the file referenced by the symbolic link
* named /etc/malloc.conf
* - (Included) The value of the environment variable MALLOC_CONF
* - (Optional, Internal) The string pointed to by the global variable
* malloc_conf_2_conf_harder, which is hidden from the public.
*
* Note: The outputs are strictly ordered by priorities (low -> high).
*
* */
#define MALLOC_CONF_WRITE(name, message) \
if (je_mallctl("malloc_conf."name, (void *)&cpv, &cpsz, NULL, 0) != \
0) { \
cpv = ""; \
} \
emitter_kv(emitter, name, message, emitter_type_string, &cpv);

emitter_dict_begin(emitter, "malloc_conf", "Tuning settings");
MALLOC_CONF_WRITE("global_var_malloc_conf", "Global variable malloc_conf");
MALLOC_CONF_WRITE("file", "Symbolic link malloc.conf");
MALLOC_CONF_WRITE("env_var", "Environment variable MALLOC_CONF");
/* As this config is internal only, skip the output if it's NULL */
if (je_mallctl("malloc_conf.global_var_malloc_conf_2_conf_harder",
(void *)&cpv, &cpsz, NULL, 0) == 0) {
emitter_kv(emitter, "global_var_malloc_conf_2_conf_harder", "Global "
"variable malloc_conf_2_conf_harder", emitter_type_string, &cpv);
}
emitter_dict_end(emitter); /* Close "malloc_conf" dict. */

#undef MALLOC_CONF_WRITE

/* opt. */
#define OPT_WRITE(name, var, size, emitter_type) \
if (je_mallctl("opt."name, (void *)&var, &size, NULL, 0) == \
Expand Down
25 changes: 24 additions & 1 deletion test/unit/malloc_conf_2.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,31 @@ TEST_BEGIN(test_malloc_conf_2) {
}
TEST_END

TEST_BEGIN(test_mallctl_global_var) {
#ifdef _WIN32
bool windows = true;
#else
bool windows = false;
#endif
/* Windows doesn't support weak symbol linker trickery. */
test_skip_if(windows);

const char *mc;
size_t sz = sizeof(mc);
expect_d_eq(mallctl("malloc_conf.global_var_malloc_conf",
(void *)&mc, &sz, NULL, 0), 0, "Unexpected mallctl() failure");
expect_str_eq(mc, malloc_conf, "Unexpected value for malloc_conf");

expect_d_eq(mallctl("malloc_conf.global_var_malloc_conf_2_conf_harder",
(void *)&mc, &sz, NULL, 0), 0, "Unexpected mallctl() failure");
expect_str_eq(mc, malloc_conf_2_conf_harder, "Unexpected value for "
"malloc_conf_2_conf_harder");
}
TEST_END

int
main(void) {
return test(
test_malloc_conf_2);
test_malloc_conf_2,
test_mallctl_global_var);
}

0 comments on commit 2fe16a3

Please sign in to comment.