Add opt.stats_print_opts.
The value is passed to atexit(3)-triggered malloc_stats_print() calls.
This commit is contained in:
parent
49505e558b
commit
d5ef5ae934
@ -410,6 +410,8 @@ for (i = 0; i < nbins; i++) {
|
|||||||
/* Do something with bin_size... */
|
/* Do something with bin_size... */
|
||||||
}]]></programlisting></para>
|
}]]></programlisting></para>
|
||||||
|
|
||||||
|
<varlistentry id="malloc_stats_print_opts">
|
||||||
|
</varlistentry>
|
||||||
<para>The <function>malloc_stats_print()</function> function writes
|
<para>The <function>malloc_stats_print()</function> function writes
|
||||||
summary statistics via the <parameter>write_cb</parameter> callback
|
summary statistics via the <parameter>write_cb</parameter> callback
|
||||||
function pointer and <parameter>cbopaque</parameter> data passed to
|
function pointer and <parameter>cbopaque</parameter> data passed to
|
||||||
@ -1046,7 +1048,9 @@ mallctl("arena." STRINGIFY(MALLCTL_ARENAS_ALL) ".decay",
|
|||||||
enabled, the <function>malloc_stats_print()</function>
|
enabled, the <function>malloc_stats_print()</function>
|
||||||
function is called at program exit via an
|
function is called at program exit via an
|
||||||
<citerefentry><refentrytitle>atexit</refentrytitle>
|
<citerefentry><refentrytitle>atexit</refentrytitle>
|
||||||
<manvolnum>3</manvolnum></citerefentry> function. If
|
<manvolnum>3</manvolnum></citerefentry> function. <link
|
||||||
|
linkend="opt.stats_print_opts"><mallctl>opt.stats_print_opts</mallctl></link>
|
||||||
|
can be combined to specify output options. If
|
||||||
<option>--enable-stats</option> is specified during configuration, this
|
<option>--enable-stats</option> is specified during configuration, this
|
||||||
has the potential to cause deadlock for a multi-threaded process that
|
has the potential to cause deadlock for a multi-threaded process that
|
||||||
exits while one or more threads are executing in the memory allocation
|
exits while one or more threads are executing in the memory allocation
|
||||||
@ -1061,6 +1065,23 @@ mallctl("arena." STRINGIFY(MALLCTL_ARENAS_ALL) ".decay",
|
|||||||
development. This option is disabled by default.</para></listitem>
|
development. This option is disabled by default.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry id="opt.stats_print_opts">
|
||||||
|
<term>
|
||||||
|
<mallctl>opt.stats_print_opts</mallctl>
|
||||||
|
(<type>const char *</type>)
|
||||||
|
<literal>r-</literal>
|
||||||
|
</term>
|
||||||
|
<listitem><para>Options (the <parameter>opts</parameter> string) to pass
|
||||||
|
to the <function>malloc_stats_print()</function> at exit (enabled
|
||||||
|
through <link
|
||||||
|
linkend="opt.stats_print"><mallctl>opt.stats_print</mallctl></link>). See
|
||||||
|
available options in <link
|
||||||
|
linkend="malloc_stats_print_opts"><function>malloc_stats_print()</function></link>.
|
||||||
|
Has no effect unless <link
|
||||||
|
linkend="opt.stats_print"><mallctl>opt.stats_print</mallctl></link> is
|
||||||
|
enabled. The default is <quote></quote>.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry id="opt.junk">
|
<varlistentry id="opt.junk">
|
||||||
<term>
|
<term>
|
||||||
<mallctl>opt.junk</mallctl>
|
<mallctl>opt.junk</mallctl>
|
||||||
|
@ -7,8 +7,27 @@
|
|||||||
#include "jemalloc/internal/size_classes.h"
|
#include "jemalloc/internal/size_classes.h"
|
||||||
#include "jemalloc/internal/stats_tsd.h"
|
#include "jemalloc/internal/stats_tsd.h"
|
||||||
|
|
||||||
/* The opt.stats_print storage. */
|
/* OPTION(opt, var_name, default, set_value_to) */
|
||||||
|
#define STATS_PRINT_OPTIONS \
|
||||||
|
OPTION('J', json, false, true) \
|
||||||
|
OPTION('g', general, true, false) \
|
||||||
|
OPTION('m', merged, config_stats, false) \
|
||||||
|
OPTION('d', destroyed, config_stats, false) \
|
||||||
|
OPTION('a', unmerged, config_stats, false) \
|
||||||
|
OPTION('b', bins, true, false) \
|
||||||
|
OPTION('l', large, true, false) \
|
||||||
|
OPTION('x', mutex, true, false)
|
||||||
|
|
||||||
|
enum {
|
||||||
|
#define OPTION(o, v, d, s) stats_print_option_num_##v,
|
||||||
|
STATS_PRINT_OPTIONS
|
||||||
|
#undef OPTION
|
||||||
|
stats_print_tot_num_options
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Options for stats_print. */
|
||||||
extern bool opt_stats_print;
|
extern bool opt_stats_print;
|
||||||
|
extern char opt_stats_print_opts[stats_print_tot_num_options+1];
|
||||||
|
|
||||||
/* Implements je_malloc_stats_print. */
|
/* Implements je_malloc_stats_print. */
|
||||||
void stats_print(void (*write_cb)(void *, const char *), void *cbopaque,
|
void stats_print(void (*write_cb)(void *, const char *), void *cbopaque,
|
||||||
|
@ -85,6 +85,7 @@ CTL_PROTO(opt_background_thread)
|
|||||||
CTL_PROTO(opt_dirty_decay_ms)
|
CTL_PROTO(opt_dirty_decay_ms)
|
||||||
CTL_PROTO(opt_muzzy_decay_ms)
|
CTL_PROTO(opt_muzzy_decay_ms)
|
||||||
CTL_PROTO(opt_stats_print)
|
CTL_PROTO(opt_stats_print)
|
||||||
|
CTL_PROTO(opt_stats_print_opts)
|
||||||
CTL_PROTO(opt_junk)
|
CTL_PROTO(opt_junk)
|
||||||
CTL_PROTO(opt_zero)
|
CTL_PROTO(opt_zero)
|
||||||
CTL_PROTO(opt_utrace)
|
CTL_PROTO(opt_utrace)
|
||||||
@ -277,6 +278,7 @@ static const ctl_named_node_t opt_node[] = {
|
|||||||
{NAME("dirty_decay_ms"), CTL(opt_dirty_decay_ms)},
|
{NAME("dirty_decay_ms"), CTL(opt_dirty_decay_ms)},
|
||||||
{NAME("muzzy_decay_ms"), CTL(opt_muzzy_decay_ms)},
|
{NAME("muzzy_decay_ms"), CTL(opt_muzzy_decay_ms)},
|
||||||
{NAME("stats_print"), CTL(opt_stats_print)},
|
{NAME("stats_print"), CTL(opt_stats_print)},
|
||||||
|
{NAME("stats_print_opts"), CTL(opt_stats_print_opts)},
|
||||||
{NAME("junk"), CTL(opt_junk)},
|
{NAME("junk"), CTL(opt_junk)},
|
||||||
{NAME("zero"), CTL(opt_zero)},
|
{NAME("zero"), CTL(opt_zero)},
|
||||||
{NAME("utrace"), CTL(opt_utrace)},
|
{NAME("utrace"), CTL(opt_utrace)},
|
||||||
@ -1557,6 +1559,7 @@ CTL_RO_NL_GEN(opt_background_thread, opt_background_thread, bool)
|
|||||||
CTL_RO_NL_GEN(opt_dirty_decay_ms, opt_dirty_decay_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_muzzy_decay_ms, opt_muzzy_decay_ms, ssize_t)
|
||||||
CTL_RO_NL_GEN(opt_stats_print, opt_stats_print, bool)
|
CTL_RO_NL_GEN(opt_stats_print, opt_stats_print, bool)
|
||||||
|
CTL_RO_NL_GEN(opt_stats_print_opts, opt_stats_print_opts, const char *)
|
||||||
CTL_RO_NL_CGEN(config_fill, opt_junk, opt_junk, const char *)
|
CTL_RO_NL_CGEN(config_fill, opt_junk, opt_junk, const char *)
|
||||||
CTL_RO_NL_CGEN(config_fill, opt_zero, opt_zero, bool)
|
CTL_RO_NL_CGEN(config_fill, opt_zero, opt_zero, bool)
|
||||||
CTL_RO_NL_CGEN(config_utrace, opt_utrace, opt_utrace, bool)
|
CTL_RO_NL_CGEN(config_utrace, opt_utrace, opt_utrace, bool)
|
||||||
|
@ -724,7 +724,7 @@ stats_print_atexit(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
je_malloc_stats_print(NULL, NULL, NULL);
|
je_malloc_stats_print(NULL, NULL, opt_stats_print_opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -777,6 +777,31 @@ malloc_ncpus(void) {
|
|||||||
return ((result == -1) ? 1 : (unsigned)result);
|
return ((result == -1) ? 1 : (unsigned)result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_opt_stats_print_opts(const char *v, size_t vlen) {
|
||||||
|
size_t opts_len = strlen(opt_stats_print_opts);
|
||||||
|
assert(opts_len <= stats_print_tot_num_options);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < vlen; i++) {
|
||||||
|
switch (v[i]) {
|
||||||
|
#define OPTION(o, v, d, s) case o: break;
|
||||||
|
STATS_PRINT_OPTIONS
|
||||||
|
#undef OPTION
|
||||||
|
default: continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strchr(opt_stats_print_opts, v[i]) != NULL) {
|
||||||
|
/* Ignore repeated. */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
opt_stats_print_opts[opts_len++] = v[i];
|
||||||
|
opt_stats_print_opts[opts_len] = '\0';
|
||||||
|
assert(opts_len <= stats_print_tot_num_options);
|
||||||
|
}
|
||||||
|
assert(opts_len == strlen(opt_stats_print_opts));
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
malloc_conf_next(char const **opts_p, char const **k_p, size_t *klen_p,
|
malloc_conf_next(char const **opts_p, char const **k_p, size_t *klen_p,
|
||||||
char const **v_p, size_t *vlen_p) {
|
char const **v_p, size_t *vlen_p) {
|
||||||
@ -1099,6 +1124,10 @@ malloc_conf_init(void) {
|
|||||||
QU(SSIZE_MAX) ? NSTIME_SEC_MAX * KQU(1000) :
|
QU(SSIZE_MAX) ? NSTIME_SEC_MAX * KQU(1000) :
|
||||||
SSIZE_MAX);
|
SSIZE_MAX);
|
||||||
CONF_HANDLE_BOOL(opt_stats_print, "stats_print")
|
CONF_HANDLE_BOOL(opt_stats_print, "stats_print")
|
||||||
|
if (CONF_MATCH("stats_print_opts")) {
|
||||||
|
init_opt_stats_print_opts(v, vlen);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (config_fill) {
|
if (config_fill) {
|
||||||
if (CONF_MATCH("junk")) {
|
if (CONF_MATCH("junk")) {
|
||||||
if (CONF_MATCH_VALUE("true")) {
|
if (CONF_MATCH_VALUE("true")) {
|
||||||
|
61
src/stats.c
61
src/stats.c
@ -46,7 +46,8 @@ const char *arena_mutex_names[mutex_prof_num_arena_mutexes] = {
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/* Data. */
|
/* Data. */
|
||||||
|
|
||||||
bool opt_stats_print = false;
|
bool opt_stats_print = false;
|
||||||
|
char opt_stats_print_opts[stats_print_tot_num_options+1] = "";
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
@ -838,12 +839,16 @@ stats_general_print(void (*write_cb)(void *, const char *), void *cbopaque,
|
|||||||
OPT_WRITE_BOOL(prof_gdump, ",")
|
OPT_WRITE_BOOL(prof_gdump, ",")
|
||||||
OPT_WRITE_BOOL(prof_final, ",")
|
OPT_WRITE_BOOL(prof_final, ",")
|
||||||
OPT_WRITE_BOOL(prof_leak, ",")
|
OPT_WRITE_BOOL(prof_leak, ",")
|
||||||
/*
|
OPT_WRITE_BOOL(stats_print, ",")
|
||||||
* stats_print is always emitted, so as long as stats_print comes last
|
if (json || opt_stats_print) {
|
||||||
* it's safe to unconditionally omit the comma here (rather than having
|
/*
|
||||||
* to conditionally omit it elsewhere depending on configuration).
|
* stats_print_opts is always emitted for JSON, so as long as it
|
||||||
*/
|
* comes last it's safe to unconditionally omit the comma here
|
||||||
OPT_WRITE_BOOL(stats_print, "")
|
* (rather than having to conditionally omit it elsewhere
|
||||||
|
* depending on configuration).
|
||||||
|
*/
|
||||||
|
OPT_WRITE_CHAR_P(stats_print_opts, "")
|
||||||
|
}
|
||||||
if (json) {
|
if (json) {
|
||||||
malloc_cprintf(write_cb, cbopaque,
|
malloc_cprintf(write_cb, cbopaque,
|
||||||
"\t\t},\n");
|
"\t\t},\n");
|
||||||
@ -1228,14 +1233,9 @@ stats_print(void (*write_cb)(void *, const char *), void *cbopaque,
|
|||||||
int err;
|
int err;
|
||||||
uint64_t epoch;
|
uint64_t epoch;
|
||||||
size_t u64sz;
|
size_t u64sz;
|
||||||
bool json = false;
|
#define OPTION(o, v, d, s) bool v = d;
|
||||||
bool general = true;
|
STATS_PRINT_OPTIONS
|
||||||
bool merged = config_stats;
|
#undef OPTION
|
||||||
bool destroyed = config_stats;
|
|
||||||
bool unmerged = config_stats;
|
|
||||||
bool bins = true;
|
|
||||||
bool large = true;
|
|
||||||
bool mutex = true;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Refresh stats, in case mallctl() was called by the application.
|
* Refresh stats, in case mallctl() was called by the application.
|
||||||
@ -1260,34 +1260,11 @@ stats_print(void (*write_cb)(void *, const char *), void *cbopaque,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (opts != NULL) {
|
if (opts != NULL) {
|
||||||
unsigned i;
|
for (unsigned i = 0; opts[i] != '\0'; i++) {
|
||||||
|
|
||||||
for (i = 0; opts[i] != '\0'; i++) {
|
|
||||||
switch (opts[i]) {
|
switch (opts[i]) {
|
||||||
case 'J':
|
#define OPTION(o, v, d, s) case o: v = s; break;
|
||||||
json = true;
|
STATS_PRINT_OPTIONS
|
||||||
break;
|
#undef OPTION
|
||||||
case 'g':
|
|
||||||
general = false;
|
|
||||||
break;
|
|
||||||
case 'm':
|
|
||||||
merged = false;
|
|
||||||
break;
|
|
||||||
case 'd':
|
|
||||||
destroyed = false;
|
|
||||||
break;
|
|
||||||
case 'a':
|
|
||||||
unmerged = false;
|
|
||||||
break;
|
|
||||||
case 'b':
|
|
||||||
bins = false;
|
|
||||||
break;
|
|
||||||
case 'l':
|
|
||||||
large = false;
|
|
||||||
break;
|
|
||||||
case 'x':
|
|
||||||
mutex = false;
|
|
||||||
break;
|
|
||||||
default:;
|
default:;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user