diff options
| author | Qi Wang <interwq@gwu.edu> | 2017-05-27 15:35:36 -0700 |
|---|---|---|
| committer | Qi Wang <interwq@gmail.com> | 2017-05-29 11:54:00 -0700 |
| commit | d5ef5ae9344d72f39569a05e7c9349dded497e41 (patch) | |
| tree | 9b4986ee43a09a85c0842dfaccd3371b876aa31a | |
| parent | 49505e558baade576bab40cbd3b9fdaa61ba77d2 (diff) | |
| download | platform_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.in | 23 | ||||
| -rw-r--r-- | include/jemalloc/internal/stats.h | 21 | ||||
| -rw-r--r-- | src/ctl.c | 3 | ||||
| -rw-r--r-- | src/jemalloc.c | 31 | ||||
| -rw-r--r-- | src/stats.c | 61 |
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, @@ -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:; } } |
