Add the w4opaque argument to numerous functions.

Add the w4opaque argument malloc_message() and malloc_stats_print(), and
propagate the change through all the internal APIs as necessary.
This commit is contained in:
Jason Evans 2010-01-19 12:11:25 -08:00
parent b34e8684ec
commit ed1bf457fb
8 changed files with 157 additions and 120 deletions

View File

@ -65,12 +65,12 @@
@roff_tcache@.Ft void @roff_tcache@.Ft void
@roff_tcache@.Fn @jemalloc_prefix@malloc_tcache_flush "void" @roff_tcache@.Fn @jemalloc_prefix@malloc_tcache_flush "void"
.Ft void .Ft void
.Fn @jemalloc_prefix@malloc_stats_print "void (*write4)(const char *, const char *, const char *, const char *)" "const char *opts" .Fn @jemalloc_prefix@malloc_stats_print "void (*write4)(void *" "const char *" "const char *" "const char *" "const char *)" "const char *opts"
.Ft const char * .Ft const char *
.Va @jemalloc_prefix@malloc_options ; .Va @jemalloc_prefix@malloc_options ;
.Ft void .Ft void
.Fo \*(lp*@jemalloc_prefix@malloc_message\*(rp .Fo \*(lp*@jemalloc_prefix@malloc_message\*(rp
.Fa "const char *p1" "const char *p2" "const char *p3" "const char *p4" .Fa "void *w4opaque" "const char *p1" "const char *p2" "const char *p3" "const char *p4"
.Fc .Fc
.Sh DESCRIPTION .Sh DESCRIPTION
The The
@ -181,8 +181,12 @@ The
.Fn @jemalloc_prefix@malloc_stats_print .Fn @jemalloc_prefix@malloc_stats_print
function writes human-readable summary statistics via the function writes human-readable summary statistics via the
.Fa write4 .Fa write4
callback function, or callback function pointer and
.Fn malloc_message .Fa w4opaque
data passed to
.Fn write4 ,
or
.Fn @jemalloc_prefix@malloc_message
if if
.Fa write4 .Fa write4
is is
@ -531,13 +535,20 @@ option is set, all warnings are treated as errors.
.Pp .Pp
The The
.Va @jemalloc_prefix@malloc_message .Va @jemalloc_prefix@malloc_message
variable allows the programmer to override the function which emits variable allows the programmer to override the function which emits the text
the text strings forming the errors and warnings if for some reason strings forming the errors and warnings if for some reason the
the
.Dv STDERR_FILENO .Dv STDERR_FILENO
file descriptor is not suitable for this. file descriptor is not suitable for this.
Please note that doing anything which tries to allocate memory in .Va @jemalloc_prefix@malloc_message
this function is likely to result in a crash or deadlock. takes the
.Fa w4opaque
pointer argument that is
.Dv NULL
unless overridden by the arguments in a call to
.Fn @jemalloc_prefix@malloc_stats_print ,
followed by four string pointers.
Please note that doing anything which tries to allocate memory in this function
is likely to result in a crash or deadlock.
.Pp .Pp
All messages are prefixed by All messages are prefixed by
.Dq <jemalloc>: . .Dq <jemalloc>: .

View File

@ -411,9 +411,11 @@ void arena_stats_merge(arena_t *arena, size_t *nactive, size_t *ndirty,
void arena_stats_mprint(arena_t *arena, size_t nactive, size_t ndirty, void arena_stats_mprint(arena_t *arena, size_t nactive, size_t ndirty,
const arena_stats_t *astats, const malloc_bin_stats_t *bstats, const arena_stats_t *astats, const malloc_bin_stats_t *bstats,
const malloc_large_stats_t *lstats, bool bins, bool large, const malloc_large_stats_t *lstats, bool bins, bool large,
void (*write4)(const char *, const char *, const char *, const char *)); void (*write4)(void *, const char *, const char *, const char *,
const char *), void *w4opaque);
void arena_stats_print(arena_t *arena, bool bins, bool large, void arena_stats_print(arena_t *arena, bool bins, bool large,
void (*write4)(const char *, const char *, const char *, const char *)); void (*write4)(void *, const char *, const char *, const char *,
const char *), void *w4opaque);
#endif #endif
void *arena_ralloc(void *ptr, size_t size, size_t oldsize); void *arena_ralloc(void *ptr, size_t size, size_t oldsize);
bool arena_new(arena_t *arena, unsigned ind); bool arena_new(arena_t *arena, unsigned ind);

View File

@ -36,8 +36,8 @@
#include "internal/ql.h" #include "internal/ql.h"
#endif #endif
extern void (*JEMALLOC_P(malloc_message))(const char *p1, const char *p2, extern void (*JEMALLOC_P(malloc_message))(void *w4opaque, const char *p1,
const char *p3, const char *p4); const char *p2, const char *p3, const char *p4);
/* /*
* Define a custom assert() in order to reduce the chances of deadlock during * Define a custom assert() in order to reduce the chances of deadlock during
@ -274,7 +274,7 @@ JEMALLOC_INLINE void
malloc_write4(const char *p1, const char *p2, const char *p3, const char *p4) malloc_write4(const char *p1, const char *p2, const char *p3, const char *p4)
{ {
JEMALLOC_P(malloc_message)(p1, p2, p3, p4); JEMALLOC_P(malloc_message)(NULL, p1, p2, p3, p4);
} }
/* /*

View File

@ -129,8 +129,9 @@ extern bool opt_stats_print;
char *umax2s(uintmax_t x, unsigned base, char *s); char *umax2s(uintmax_t x, unsigned base, char *s);
#ifdef JEMALLOC_STATS #ifdef JEMALLOC_STATS
void malloc_cprintf(void (*write4)(const char *, const char *, const char *, void malloc_cprintf(void (*write4)(void *, const char *, const char *,
const char *), const char *format, ...) JEMALLOC_ATTR(format(printf, 2, 3)); const char *, const char *), void *w4opaque, const char *format, ...)
JEMALLOC_ATTR(format(printf, 3, 4));
void malloc_printf(const char *format, ...) void malloc_printf(const char *format, ...)
JEMALLOC_ATTR(format(printf, 1, 2)); JEMALLOC_ATTR(format(printf, 1, 2));
#endif #endif

View File

@ -151,8 +151,8 @@ static int opt_narenas_lshift = 0;
/******************************************************************************/ /******************************************************************************/
/* Function prototypes for non-inline static functions. */ /* Function prototypes for non-inline static functions. */
static void wrtmessage(const char *p1, const char *p2, const char *p3, static void wrtmessage(void *w4opaque, const char *p1, const char *p2,
const char *p4); const char *p3, const char *p4);
static void stats_print_atexit(void); static void stats_print_atexit(void);
static unsigned malloc_ncpus(void); static unsigned malloc_ncpus(void);
static bool malloc_init_hard(void); static bool malloc_init_hard(void);
@ -168,7 +168,8 @@ JEMALLOC_ATTR(visibility("hidden"))
static static
#endif #endif
void void
wrtmessage(const char *p1, const char *p2, const char *p3, const char *p4) wrtmessage(void *w4opaque, const char *p1, const char *p2, const char *p3,
const char *p4)
{ {
if (write(STDERR_FILENO, p1, strlen(p1)) < 0 if (write(STDERR_FILENO, p1, strlen(p1)) < 0
@ -178,7 +179,7 @@ wrtmessage(const char *p1, const char *p2, const char *p3, const char *p4)
return; return;
} }
void (*JEMALLOC_P(malloc_message))(const char *p1, const char *p2, void (*JEMALLOC_P(malloc_message))(void *, const char *p1, const char *p2,
const char *p3, const char *p4) JEMALLOC_ATTR(visibility("default")) = const char *p3, const char *p4) JEMALLOC_ATTR(visibility("default")) =
wrtmessage; wrtmessage;
@ -361,7 +362,7 @@ stats_print_atexit(void)
} }
} }
#endif #endif
JEMALLOC_P(malloc_stats_print)(NULL, NULL); JEMALLOC_P(malloc_stats_print)(NULL, NULL, NULL);
} }
static inline void * static inline void *

View File

@ -10,7 +10,7 @@ extern "C" {
#endif #endif
extern const char *JEMALLOC_P(malloc_options); extern const char *JEMALLOC_P(malloc_options);
extern void (*JEMALLOC_P(malloc_message))(const char *p1, extern void (*JEMALLOC_P(malloc_message))(void *, const char *p1,
const char *p2, const char *p3, const char *p4); const char *p2, const char *p3, const char *p4);
void *JEMALLOC_P(malloc)(size_t size) JEMALLOC_ATTR(malloc); void *JEMALLOC_P(malloc)(size_t size) JEMALLOC_ATTR(malloc);
@ -24,8 +24,9 @@ size_t JEMALLOC_P(malloc_usable_size)(const void *ptr);
#ifdef JEMALLOC_TCACHE #ifdef JEMALLOC_TCACHE
void JEMALLOC_P(malloc_tcache_flush)(void); void JEMALLOC_P(malloc_tcache_flush)(void);
#endif #endif
void JEMALLOC_P(malloc_stats_print)(void (*write4)(const char *, void JEMALLOC_P(malloc_stats_print)(void (*write4)(void *, const char *,
const char *, const char *, const char *), const char *opts); const char *, const char *, const char *), void *w4opaque,
const char *opts);
#ifdef __cplusplus #ifdef __cplusplus
}; };

View File

@ -175,12 +175,15 @@ static void arena_dalloc_bin_run(arena_t *arena, arena_chunk_t *chunk,
#ifdef JEMALLOC_STATS #ifdef JEMALLOC_STATS
static void arena_stats_aprint(size_t nactive, size_t ndirty, static void arena_stats_aprint(size_t nactive, size_t ndirty,
const arena_stats_t *astats, const arena_stats_t *astats,
void (*write4)(const char *, const char *, const char *, const char *)); void (*write4)(void *, const char *, const char *, const char *,
const char *), void *w4opaque);
static void arena_stats_bprint(arena_t *arena, static void arena_stats_bprint(arena_t *arena,
const malloc_bin_stats_t *bstats, const malloc_bin_stats_t *bstats,
void (*write4)(const char *, const char *, const char *, const char *)); void (*write4)(void *, const char *, const char *, const char *,
const char *), void *w4opaque);
static void arena_stats_lprint(const malloc_large_stats_t *lstats, static void arena_stats_lprint(const malloc_large_stats_t *lstats,
void (*write4)(const char *, const char *, const char *, const char *)); void (*write4)(void *, const char *, const char *, const char *,
const char *), void *w4opaque);
#endif #endif
static void arena_ralloc_large_shrink(arena_t *arena, arena_chunk_t *chunk, static void arena_ralloc_large_shrink(arena_t *arena, arena_chunk_t *chunk,
void *ptr, size_t size, size_t oldsize); void *ptr, size_t size, size_t oldsize);
@ -1603,10 +1606,11 @@ arena_stats_merge(arena_t *arena, size_t *nactive, size_t *ndirty,
static void static void
arena_stats_aprint(size_t nactive, size_t ndirty, const arena_stats_t *astats, arena_stats_aprint(size_t nactive, size_t ndirty, const arena_stats_t *astats,
void (*write4)(const char *, const char *, const char *, const char *)) void (*write4)(void *, const char *, const char *, const char *,
const char *), void *w4opaque)
{ {
malloc_cprintf(write4, malloc_cprintf(write4, w4opaque,
"dirty pages: %zu:%zu active:dirty, %llu sweep%s," "dirty pages: %zu:%zu active:dirty, %llu sweep%s,"
" %llu madvise%s, %llu purged\n", " %llu madvise%s, %llu purged\n",
nactive, ndirty, nactive, ndirty,
@ -1614,38 +1618,39 @@ arena_stats_aprint(size_t nactive, size_t ndirty, const arena_stats_t *astats,
astats->nmadvise, astats->nmadvise == 1 ? "" : "s", astats->nmadvise, astats->nmadvise == 1 ? "" : "s",
astats->purged); astats->purged);
malloc_cprintf(write4, malloc_cprintf(write4, w4opaque,
" allocated nmalloc ndalloc\n"); " allocated nmalloc ndalloc\n");
malloc_cprintf(write4, "small: %12zu %12llu %12llu\n", malloc_cprintf(write4, w4opaque, "small: %12zu %12llu %12llu\n",
astats->allocated_small, astats->nmalloc_small, astats->allocated_small, astats->nmalloc_small,
astats->ndalloc_small); astats->ndalloc_small);
malloc_cprintf(write4, "medium: %12zu %12llu %12llu\n", malloc_cprintf(write4, w4opaque, "medium: %12zu %12llu %12llu\n",
astats->allocated_medium, astats->nmalloc_medium, astats->allocated_medium, astats->nmalloc_medium,
astats->ndalloc_medium); astats->ndalloc_medium);
malloc_cprintf(write4, "large: %12zu %12llu %12llu\n", malloc_cprintf(write4, w4opaque, "large: %12zu %12llu %12llu\n",
astats->allocated_large, astats->nmalloc_large, astats->allocated_large, astats->nmalloc_large,
astats->ndalloc_large); astats->ndalloc_large);
malloc_cprintf(write4, "total: %12zu %12llu %12llu\n", malloc_cprintf(write4, w4opaque, "total: %12zu %12llu %12llu\n",
astats->allocated_small + astats->allocated_medium + astats->allocated_small + astats->allocated_medium +
astats->allocated_large, astats->nmalloc_small + astats->allocated_large, astats->nmalloc_small +
astats->nmalloc_medium + astats->nmalloc_large, astats->nmalloc_medium + astats->nmalloc_large,
astats->ndalloc_small + astats->ndalloc_medium + astats->ndalloc_small + astats->ndalloc_medium +
astats->ndalloc_large); astats->ndalloc_large);
malloc_cprintf(write4, "mapped: %12zu\n", astats->mapped); malloc_cprintf(write4, w4opaque, "mapped: %12zu\n", astats->mapped);
} }
static void static void
arena_stats_bprint(arena_t *arena, const malloc_bin_stats_t *bstats, arena_stats_bprint(arena_t *arena, const malloc_bin_stats_t *bstats,
void (*write4)(const char *, const char *, const char *, const char *)) void (*write4)(void *, const char *, const char *, const char *,
const char *), void *w4opaque)
{ {
unsigned i, gap_start; unsigned i, gap_start;
#ifdef JEMALLOC_TCACHE #ifdef JEMALLOC_TCACHE
malloc_cprintf(write4, malloc_cprintf(write4, w4opaque,
"bins: bin size regs pgs requests " "bins: bin size regs pgs requests "
"nfills nflushes newruns reruns maxruns curruns\n"); "nfills nflushes newruns reruns maxruns curruns\n");
#else #else
malloc_cprintf(write4, malloc_cprintf(write4, w4opaque,
"bins: bin size regs pgs requests " "bins: bin size regs pgs requests "
"newruns reruns maxruns curruns\n"); "newruns reruns maxruns curruns\n");
#endif #endif
@ -1657,17 +1662,17 @@ arena_stats_bprint(arena_t *arena, const malloc_bin_stats_t *bstats,
if (gap_start != UINT_MAX) { if (gap_start != UINT_MAX) {
if (i > gap_start + 1) { if (i > gap_start + 1) {
/* Gap of more than one size class. */ /* Gap of more than one size class. */
malloc_cprintf(write4, malloc_cprintf(write4, w4opaque,
"[%u..%u]\n", gap_start, "[%u..%u]\n", gap_start,
i - 1); i - 1);
} else { } else {
/* Gap of one size class. */ /* Gap of one size class. */
malloc_cprintf(write4, "[%u]\n", malloc_cprintf(write4, w4opaque,
gap_start); "[%u]\n", gap_start);
} }
gap_start = UINT_MAX; gap_start = UINT_MAX;
} }
malloc_cprintf(write4, malloc_cprintf(write4, w4opaque,
"%13u %1s %5u %4u %3u %9llu %9llu" "%13u %1s %5u %4u %3u %9llu %9llu"
#ifdef JEMALLOC_TCACHE #ifdef JEMALLOC_TCACHE
" %9llu %9llu" " %9llu %9llu"
@ -1695,24 +1700,25 @@ arena_stats_bprint(arena_t *arena, const malloc_bin_stats_t *bstats,
if (gap_start != UINT_MAX) { if (gap_start != UINT_MAX) {
if (i > gap_start + 1) { if (i > gap_start + 1) {
/* Gap of more than one size class. */ /* Gap of more than one size class. */
malloc_cprintf(write4, "[%u..%u]\n", gap_start, malloc_cprintf(write4, w4opaque, "[%u..%u]\n",
i - 1); gap_start, i - 1);
} else { } else {
/* Gap of one size class. */ /* Gap of one size class. */
malloc_cprintf(write4, "[%u]\n", gap_start); malloc_cprintf(write4, w4opaque, "[%u]\n", gap_start);
} }
} }
} }
static void static void
arena_stats_lprint(const malloc_large_stats_t *lstats, arena_stats_lprint(const malloc_large_stats_t *lstats,
void (*write4)(const char *, const char *, const char *, const char *)) void (*write4)(void *, const char *, const char *, const char *,
const char *), void *w4opaque)
{ {
size_t i; size_t i;
ssize_t gap_start; ssize_t gap_start;
size_t nlclasses = (chunksize - PAGE_SIZE) >> PAGE_SHIFT; size_t nlclasses = (chunksize - PAGE_SIZE) >> PAGE_SHIFT;
malloc_cprintf(write4, malloc_cprintf(write4, w4opaque,
"large: size pages nrequests maxruns curruns\n"); "large: size pages nrequests maxruns curruns\n");
for (i = 0, gap_start = -1; i < nlclasses; i++) { for (i = 0, gap_start = -1; i < nlclasses; i++) {
@ -1721,11 +1727,11 @@ arena_stats_lprint(const malloc_large_stats_t *lstats,
gap_start = i; gap_start = i;
} else { } else {
if (gap_start != -1) { if (gap_start != -1) {
malloc_cprintf(write4, "[%zu]\n", malloc_cprintf(write4, w4opaque, "[%zu]\n",
i - gap_start); i - gap_start);
gap_start = -1; gap_start = -1;
} }
malloc_cprintf(write4, malloc_cprintf(write4, w4opaque,
"%13zu %5zu %9llu %9zu %9zu\n", "%13zu %5zu %9llu %9zu %9zu\n",
(i+1) << PAGE_SHIFT, i+1, (i+1) << PAGE_SHIFT, i+1,
lstats[i].nrequests, lstats[i].nrequests,
@ -1734,26 +1740,28 @@ arena_stats_lprint(const malloc_large_stats_t *lstats,
} }
} }
if (gap_start != -1) if (gap_start != -1)
malloc_cprintf(write4, "[%zu]\n", i - gap_start); malloc_cprintf(write4, w4opaque, "[%zu]\n", i - gap_start);
} }
void void
arena_stats_mprint(arena_t *arena, size_t nactive, size_t ndirty, arena_stats_mprint(arena_t *arena, size_t nactive, size_t ndirty,
const arena_stats_t *astats, const malloc_bin_stats_t *bstats, const arena_stats_t *astats, const malloc_bin_stats_t *bstats,
const malloc_large_stats_t *lstats, bool bins, bool large, const malloc_large_stats_t *lstats, bool bins, bool large,
void (*write4)(const char *, const char *, const char *, const char *)) void (*write4)(void *, const char *, const char *, const char *,
const char *), void *w4opaque)
{ {
arena_stats_aprint(nactive, ndirty, astats, write4); arena_stats_aprint(nactive, ndirty, astats, write4, w4opaque);
if (bins && astats->nmalloc_small + astats->nmalloc_medium > 0) if (bins && astats->nmalloc_small + astats->nmalloc_medium > 0)
arena_stats_bprint(arena, bstats, write4); arena_stats_bprint(arena, bstats, write4, w4opaque);
if (large && astats->nmalloc_large > 0) if (large && astats->nmalloc_large > 0)
arena_stats_lprint(lstats, write4); arena_stats_lprint(lstats, write4, w4opaque);
} }
void void
arena_stats_print(arena_t *arena, bool bins, bool large, arena_stats_print(arena_t *arena, bool bins, bool large,
void (*write4)(const char *, const char *, const char *, const char *)) void (*write4)(void *, const char *, const char *, const char *,
const char *), void *w4opaque)
{ {
size_t nactive, ndirty; size_t nactive, ndirty;
arena_stats_t astats; arena_stats_t astats;
@ -1768,7 +1776,7 @@ arena_stats_print(arena_t *arena, bool bins, bool large,
arena_stats_merge(arena, &nactive, &ndirty, &astats, bstats, lstats); arena_stats_merge(arena, &nactive, &ndirty, &astats, bstats, lstats);
arena_stats_mprint(arena, nactive, ndirty, &astats, bstats, lstats, arena_stats_mprint(arena, nactive, ndirty, &astats, bstats, lstats,
bins, large, write4); bins, large, write4, w4opaque);
} }
#endif #endif

View File

@ -10,8 +10,8 @@ bool opt_stats_print = false;
/* Function prototypes for non-inline static functions. */ /* Function prototypes for non-inline static functions. */
static void static void
malloc_vcprintf(void (*write4)(const char *, const char *, const char *, malloc_vcprintf(void (*write4)(void *, const char *, const char *, const char *,
const char *), const char *format, va_list ap); const char *), void *w4opaque, const char *format, va_list ap);
/******************************************************************************/ /******************************************************************************/
@ -56,8 +56,8 @@ umax2s(uintmax_t x, unsigned base, char *s)
#ifdef JEMALLOC_STATS #ifdef JEMALLOC_STATS
static void static void
malloc_vcprintf(void (*write4)(const char *, const char *, const char *, malloc_vcprintf(void (*write4)(void *, const char *, const char *, const char *,
const char *), const char *format, va_list ap) const char *), void *w4opaque, const char *format, va_list ap)
{ {
char buf[4096]; char buf[4096];
@ -68,25 +68,26 @@ malloc_vcprintf(void (*write4)(const char *, const char *, const char *,
* inline function, so use malloc_message() directly here. * inline function, so use malloc_message() directly here.
*/ */
write4 = JEMALLOC_P(malloc_message); write4 = JEMALLOC_P(malloc_message);
w4opaque = NULL;
} }
vsnprintf(buf, sizeof(buf), format, ap); vsnprintf(buf, sizeof(buf), format, ap);
write4(buf, "", "", ""); write4(w4opaque, buf, "", "", "");
} }
/* /*
* Print to a callback function in such a way as to (hopefully) avoid memory * Print to a callback function in such a way as to (hopefully) avoid memory
* allocation. * allocation.
*/ */
JEMALLOC_ATTR(format(printf, 2, 3)) JEMALLOC_ATTR(format(printf, 3, 4))
void void
malloc_cprintf(void (*write4)(const char *, const char *, const char *, malloc_cprintf(void (*write4)(void *, const char *, const char *, const char *,
const char *), const char *format, ...) const char *), void *w4opaque, const char *format, ...)
{ {
va_list ap; va_list ap;
va_start(ap, format); va_start(ap, format);
malloc_vcprintf(write4, format, ap); malloc_vcprintf(write4, w4opaque, format, ap);
va_end(ap); va_end(ap);
} }
@ -100,7 +101,7 @@ malloc_printf(const char *format, ...)
va_list ap; va_list ap;
va_start(ap, format); va_start(ap, format);
malloc_vcprintf(NULL, format, ap); malloc_vcprintf(NULL, NULL, format, ap);
va_end(ap); va_end(ap);
} }
@ -108,8 +109,8 @@ malloc_printf(const char *format, ...)
JEMALLOC_ATTR(visibility("default")) JEMALLOC_ATTR(visibility("default"))
void void
JEMALLOC_P(malloc_stats_print)(void (*write4)(const char *, const char *, JEMALLOC_P(malloc_stats_print)(void (*write4)(void *, const char *,
const char *, const char *), const char *opts) const char *, const char *, const char *), void *w4opaque, const char *opts)
{ {
char s[UMAX2S_BUFSIZE]; char s[UMAX2S_BUFSIZE];
bool general = true; bool general = true;
@ -125,6 +126,7 @@ JEMALLOC_P(malloc_stats_print)(void (*write4)(const char *, const char *,
* inline function, so use malloc_message() directly here. * inline function, so use malloc_message() directly here.
*/ */
write4 = JEMALLOC_P(malloc_message); write4 = JEMALLOC_P(malloc_message);
w4opaque = NULL;
} }
if (opts != NULL) { if (opts != NULL) {
@ -152,87 +154,97 @@ JEMALLOC_P(malloc_stats_print)(void (*write4)(const char *, const char *,
} }
} }
write4("___ Begin jemalloc statistics ___\n", "", "", ""); write4(w4opaque, "___ Begin jemalloc statistics ___\n", "", "", "");
if (general) { if (general) {
write4("Assertions ", write4(w4opaque, "Assertions ",
#ifdef NDEBUG #ifdef NDEBUG
"disabled", "disabled",
#else #else
"enabled", "enabled",
#endif #endif
"\n", ""); "\n", "");
write4("Boolean JEMALLOC_OPTIONS: ", opt_abort ? "A" : "a", write4(w4opaque, "Boolean JEMALLOC_OPTIONS: ",
"", ""); opt_abort ? "A" : "a", "", "");
#ifdef JEMALLOC_FILL #ifdef JEMALLOC_FILL
write4(opt_junk ? "J" : "j", "", "", ""); write4(w4opaque, opt_junk ? "J" : "j", "", "", "");
#endif #endif
write4("P", "", "", ""); write4(w4opaque, "P", "", "", "");
#ifdef JEMALLOC_TCACHE #ifdef JEMALLOC_TCACHE
write4(opt_tcache_sort ? "S" : "s", "", "", ""); write4(w4opaque, opt_tcache_sort ? "S" : "s", "", "", "");
#endif #endif
#ifdef JEMALLOC_TRACE #ifdef JEMALLOC_TRACE
write4(opt_trace ? "T" : "t", "", "", ""); write4(w4opaque, opt_trace ? "T" : "t", "", "", "");
#endif #endif
#ifdef JEMALLOC_SYSV #ifdef JEMALLOC_SYSV
write4(opt_sysv ? "V" : "v", "", "", ""); write4(w4opaque, opt_sysv ? "V" : "v", "", "", "");
#endif #endif
#ifdef JEMALLOC_XMALLOC #ifdef JEMALLOC_XMALLOC
write4(opt_xmalloc ? "X" : "x", "", "", ""); write4(w4opaque, opt_xmalloc ? "X" : "x", "", "", "");
#endif #endif
#ifdef JEMALLOC_FILL #ifdef JEMALLOC_FILL
write4(opt_zero ? "Z" : "z", "", "", ""); write4(w4opaque, opt_zero ? "Z" : "z", "", "", "");
#endif #endif
write4("\n", "", "", ""); write4(w4opaque, "\n", "", "", "");
write4("CPUs: ", umax2s(ncpus, 10, s), "\n", ""); write4(w4opaque, "CPUs: ", umax2s(ncpus, 10, s), "\n", "");
write4("Max arenas: ", umax2s(narenas, 10, s), "\n", ""); write4(w4opaque, "Max arenas: ", umax2s(narenas, 10, s), "\n",
write4("Pointer size: ", umax2s(sizeof(void *), 10, s), "\n",
""); "");
write4("Quantum size: ", umax2s(QUANTUM, 10, s), "\n", ""); write4(w4opaque, "Pointer size: ", umax2s(sizeof(void *), 10,
write4("Cacheline size (assumed): ", umax2s(CACHELINE, 10, s), s), "\n", "");
write4(w4opaque, "Quantum size: ", umax2s(QUANTUM, 10, s), "\n",
"");
write4(w4opaque, "Cacheline size (assumed): ", umax2s(CACHELINE,
10, s),
"\n", ""); "\n", "");
write4("Subpage spacing: ", umax2s(SUBPAGE, 10, s), "\n", ""); write4(w4opaque, "Subpage spacing: ", umax2s(SUBPAGE, 10, s),
write4("Medium spacing: ", umax2s((1U << lg_mspace), 10, s),
"\n", ""); "\n", "");
write4(w4opaque, "Medium spacing: ", umax2s((1U << lg_mspace),
10, s), "\n", "");
#ifdef JEMALLOC_TINY #ifdef JEMALLOC_TINY
write4("Tiny 2^n-spaced sizes: [", umax2s((1U << LG_TINY_MIN), write4(w4opaque, "Tiny 2^n-spaced sizes: [", umax2s((1U <<
10, s), "..", ""); LG_TINY_MIN), 10, s), "..", "");
write4(umax2s((qspace_min >> 1), 10, s), "]\n", "", ""); write4(w4opaque, umax2s((qspace_min >> 1), 10, s), "]\n", "",
"");
#endif #endif
write4("Quantum-spaced sizes: [", umax2s(qspace_min, 10, s), write4(w4opaque, "Quantum-spaced sizes: [", umax2s(qspace_min,
10, s), "..", "");
write4(w4opaque, umax2s(qspace_max, 10, s), "]\n", "", "");
write4(w4opaque, "Cacheline-spaced sizes: [", umax2s(cspace_min,
10, s), "..", "");
write4(w4opaque, umax2s(cspace_max, 10, s), "]\n", "", "");
write4(w4opaque, "Subpage-spaced sizes: [", umax2s(sspace_min,
10, s), "..", "");
write4(w4opaque, umax2s(sspace_max, 10, s), "]\n", "", "");
write4(w4opaque, "Medium sizes: [", umax2s(medium_min, 10, s),
"..", ""); "..", "");
write4(umax2s(qspace_max, 10, s), "]\n", "", ""); write4(w4opaque, umax2s(medium_max, 10, s), "]\n", "", "");
write4("Cacheline-spaced sizes: [", umax2s(cspace_min, 10, s),
"..", "");
write4(umax2s(cspace_max, 10, s), "]\n", "", "");
write4("Subpage-spaced sizes: [", umax2s(sspace_min, 10, s),
"..", "");
write4(umax2s(sspace_max, 10, s), "]\n", "", "");
write4("Medium sizes: [", umax2s(medium_min, 10, s), "..", "");
write4(umax2s(medium_max, 10, s), "]\n", "", "");
if (opt_lg_dirty_mult >= 0) { if (opt_lg_dirty_mult >= 0) {
write4("Min active:dirty page ratio per arena: ", write4(w4opaque,
"Min active:dirty page ratio per arena: ",
umax2s((1U << opt_lg_dirty_mult), 10, s), ":1\n", umax2s((1U << opt_lg_dirty_mult), 10, s), ":1\n",
""); "");
} else { } else {
write4("Min active:dirty page ratio per arena: N/A\n", write4(w4opaque,
"", "", ""); "Min active:dirty page ratio per arena: N/A\n", "",
"", "");
} }
#ifdef JEMALLOC_TCACHE #ifdef JEMALLOC_TCACHE
write4("Thread cache slots per size class: ", write4(w4opaque, "Thread cache slots per size class: ",
tcache_nslots ? umax2s(tcache_nslots, 10, s) : "N/A", "\n", tcache_nslots ? umax2s(tcache_nslots, 10, s) : "N/A", "\n",
""); "");
write4("Thread cache GC sweep interval: ", write4(w4opaque, "Thread cache GC sweep interval: ",
(tcache_nslots && tcache_gc_incr > 0) ? (tcache_nslots && tcache_gc_incr > 0) ?
umax2s((1U << opt_lg_tcache_gc_sweep), 10, s) : "N/A", umax2s((1U << opt_lg_tcache_gc_sweep), 10, s) : "N/A",
"", ""); "", "");
write4(" (increment interval: ", write4(w4opaque, " (increment interval: ",
(tcache_nslots && tcache_gc_incr > 0) ? (tcache_nslots && tcache_gc_incr > 0) ?
umax2s(tcache_gc_incr, 10, s) : "N/A", umax2s(tcache_gc_incr, 10, s) : "N/A",
")\n", ""); ")\n", "");
#endif #endif
write4("Chunk size: ", umax2s(chunksize, 10, s), "", ""); write4(w4opaque, "Chunk size: ", umax2s(chunksize, 10, s), "",
write4(" (2^", umax2s(opt_lg_chunk, 10, s), ")\n", ""); "");
write4(w4opaque, " (2^", umax2s(opt_lg_chunk, 10, s), ")\n",
"");
} }
#ifdef JEMALLOC_STATS #ifdef JEMALLOC_STATS
@ -263,8 +275,8 @@ JEMALLOC_P(malloc_stats_print)(void (*write4)(const char *, const char *,
mapped += base_mapped; mapped += base_mapped;
malloc_mutex_unlock(&base_mtx); malloc_mutex_unlock(&base_mtx);
malloc_cprintf(write4, "Allocated: %zu, mapped: %zu\n", malloc_cprintf(write4, w4opaque,
allocated, mapped); "Allocated: %zu, mapped: %zu\n", allocated, mapped);
/* Print chunk stats. */ /* Print chunk stats. */
{ {
@ -274,18 +286,18 @@ JEMALLOC_P(malloc_stats_print)(void (*write4)(const char *, const char *,
chunks_stats = stats_chunks; chunks_stats = stats_chunks;
malloc_mutex_unlock(&huge_mtx); malloc_mutex_unlock(&huge_mtx);
malloc_cprintf(write4, "chunks: nchunks " malloc_cprintf(write4, w4opaque, "chunks: nchunks "
"highchunks curchunks\n"); "highchunks curchunks\n");
malloc_cprintf(write4, " %13llu%13lu%13lu\n", malloc_cprintf(write4, w4opaque, " %13llu%13lu%13lu\n",
chunks_stats.nchunks, chunks_stats.highchunks, chunks_stats.nchunks, chunks_stats.highchunks,
chunks_stats.curchunks); chunks_stats.curchunks);
} }
/* Print chunk stats. */ /* Print chunk stats. */
malloc_cprintf(write4, malloc_cprintf(write4, w4opaque,
"huge: nmalloc ndalloc allocated\n"); "huge: nmalloc ndalloc allocated\n");
malloc_cprintf(write4, " %12llu %12llu %12zu\n", huge_nmalloc, malloc_cprintf(write4, w4opaque, " %12llu %12llu %12zu\n",
huge_ndalloc, huge_allocated); huge_nmalloc, huge_ndalloc, huge_allocated);
if (merged) { if (merged) {
size_t nactive, ndirty; size_t nactive, ndirty;
@ -311,10 +323,11 @@ JEMALLOC_P(malloc_stats_print)(void (*write4)(const char *, const char *,
} }
} }
/* Print merged arena stats. */ /* Print merged arena stats. */
malloc_cprintf(write4, "\nMerge arenas stats:\n"); malloc_cprintf(write4, w4opaque,
"\nMerge arenas stats:\n");
/* arenas[0] is used only for invariant bin settings. */ /* arenas[0] is used only for invariant bin settings. */
arena_stats_mprint(arenas[0], nactive, ndirty, &astats, arena_stats_mprint(arenas[0], nactive, ndirty, &astats,
bstats, lstats, bins, large, write4); bstats, lstats, bins, large, write4, w4opaque);
} }
if (unmerged) { if (unmerged) {
@ -322,16 +335,16 @@ JEMALLOC_P(malloc_stats_print)(void (*write4)(const char *, const char *,
for (i = 0; i < narenas; i++) { for (i = 0; i < narenas; i++) {
arena = arenas[i]; arena = arenas[i];
if (arena != NULL) { if (arena != NULL) {
malloc_cprintf(write4, malloc_cprintf(write4, w4opaque,
"\narenas[%u]:\n", i); "\narenas[%u]:\n", i);
malloc_mutex_lock(&arena->lock); malloc_mutex_lock(&arena->lock);
arena_stats_print(arena, bins, large, arena_stats_print(arena, bins, large,
write4); write4, w4opaque);
malloc_mutex_unlock(&arena->lock); malloc_mutex_unlock(&arena->lock);
} }
} }
} }
} }
#endif /* #ifdef JEMALLOC_STATS */ #endif /* #ifdef JEMALLOC_STATS */
write4("--- End jemalloc statistics ---\n", "", "", ""); write4(w4opaque, "--- End jemalloc statistics ---\n", "", "", "");
} }