aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQi Wang <interwq@gwu.edu>2017-05-27 15:35:36 -0700
committerQi Wang <interwq@gmail.com>2017-05-29 11:54:00 -0700
commitd5ef5ae9344d72f39569a05e7c9349dded497e41 (patch)
tree9b4986ee43a09a85c0842dfaccd3371b876aa31a
parent49505e558baade576bab40cbd3b9fdaa61ba77d2 (diff)
downloadplatform_external_jemalloc_new-d5ef5ae9344d72f39569a05e7c9349dded497e41.tar.gz
platform_external_jemalloc_new-d5ef5ae9344d72f39569a05e7c9349dded497e41.tar.bz2
platform_external_jemalloc_new-d5ef5ae9344d72f39569a05e7c9349dded497e41.zip
Add opt.stats_print_opts.
The value is passed to atexit(3)-triggered malloc_stats_print() calls.
-rw-r--r--doc/jemalloc.xml.in23
-rw-r--r--include/jemalloc/internal/stats.h21
-rw-r--r--src/ctl.c3
-rw-r--r--src/jemalloc.c31
-rw-r--r--src/stats.c61
5 files changed, 94 insertions, 45 deletions
diff --git a/doc/jemalloc.xml.in b/doc/jemalloc.xml.in
index a45b3587..c2c0e925 100644
--- a/doc/jemalloc.xml.in
+++ b/doc/jemalloc.xml.in
@@ -410,6 +410,8 @@ for (i = 0; i < nbins; i++) {
/* Do something with bin_size... */
}]]></programlisting></para>
+ <varlistentry id="malloc_stats_print_opts">
+ </varlistentry>
<para>The <function>malloc_stats_print()</function> function writes
summary statistics via the <parameter>write_cb</parameter> callback
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>
function is called at program exit via an
<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
has the potential to cause deadlock for a multi-threaded process that
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>
</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">
<term>
<mallctl>opt.junk</mallctl>
diff --git a/include/jemalloc/internal/stats.h b/include/jemalloc/internal/stats.h
index 47ca4f9e..1198779a 100644
--- a/include/jemalloc/internal/stats.h
+++ b/include/jemalloc/internal/stats.h
@@ -7,8 +7,27 @@
#include "jemalloc/internal/size_classes.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 char opt_stats_print_opts[stats_print_tot_num_options+1];
/* Implements je_malloc_stats_print. */
void stats_print(void (*write_cb)(void *, const char *), void *cbopaque,
diff --git a/src/ctl.c b/src/ctl.c
index 28f49398..d10c39bb 100644
--- a/src/ctl.c
+++ b/src/ctl.c
@@ -85,6 +85,7 @@ CTL_PROTO(opt_background_thread)
CTL_PROTO(opt_dirty_decay_ms)
CTL_PROTO(opt_muzzy_decay_ms)
CTL_PROTO(opt_stats_print)
+CTL_PROTO(opt_stats_print_opts)
CTL_PROTO(opt_junk)
CTL_PROTO(opt_zero)
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("muzzy_decay_ms"), CTL(opt_muzzy_decay_ms)},
{NAME("stats_print"), CTL(opt_stats_print)},
+ {NAME("stats_print_opts"), CTL(opt_stats_print_opts)},
{NAME("junk"), CTL(opt_junk)},
{NAME("zero"), CTL(opt_zero)},
{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_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_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_zero, opt_zero, bool)
CTL_RO_NL_CGEN(config_utrace, opt_utrace, opt_utrace, bool)
diff --git a/src/jemalloc.c b/src/jemalloc.c
index dd8365f9..5e3072b5 100644
--- a/src/jemalloc.c
+++ b/src/jemalloc.c
@@ -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);
}
+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
malloc_conf_next(char const **opts_p, char const **k_p, size_t *klen_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) :
SSIZE_MAX);
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 (CONF_MATCH("junk")) {
if (CONF_MATCH_VALUE("true")) {
diff --git a/src/stats.c b/src/stats.c
index 48d3f59b..61550d83 100644
--- a/src/stats.c
+++ b/src/stats.c
@@ -46,7 +46,8 @@ const char *arena_mutex_names[mutex_prof_num_arena_mutexes] = {
/******************************************************************************/
/* 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_final, ",")
OPT_WRITE_BOOL(prof_leak, ",")
- /*
- * stats_print is always emitted, so as long as stats_print comes last
- * it's safe to unconditionally omit the comma here (rather than having
- * to conditionally omit it elsewhere depending on configuration).
- */
- OPT_WRITE_BOOL(stats_print, "")
+ OPT_WRITE_BOOL(stats_print, ",")
+ if (json || opt_stats_print) {
+ /*
+ * stats_print_opts is always emitted for JSON, so as long as it
+ * comes last it's safe to unconditionally omit the comma here
+ * (rather than having to conditionally omit it elsewhere
+ * depending on configuration).
+ */
+ OPT_WRITE_CHAR_P(stats_print_opts, "")
+ }
if (json) {
malloc_cprintf(write_cb, cbopaque,
"\t\t},\n");
@@ -1228,14 +1233,9 @@ stats_print(void (*write_cb)(void *, const char *), void *cbopaque,
int err;
uint64_t epoch;
size_t u64sz;
- bool json = false;
- bool general = true;
- bool merged = config_stats;
- bool destroyed = config_stats;
- bool unmerged = config_stats;
- bool bins = true;
- bool large = true;
- bool mutex = true;
+#define OPTION(o, v, d, s) bool v = d;
+ STATS_PRINT_OPTIONS
+#undef OPTION
/*
* 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) {
- unsigned i;
-
- for (i = 0; opts[i] != '\0'; i++) {
+ for (unsigned i = 0; opts[i] != '\0'; i++) {
switch (opts[i]) {
- case 'J':
- json = true;
- break;
- 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;
+#define OPTION(o, v, d, s) case o: v = s; break;
+ STATS_PRINT_OPTIONS
+#undef OPTION
default:;
}
}