Simplify malloc_message().

Rather than passing four strings to malloc_message(), malloc_write4(),
and all the functions that use them, only pass one string.
This commit is contained in:
Jason Evans 2010-03-03 17:45:38 -08:00
parent cfeccd34a3
commit 698805c525
13 changed files with 270 additions and 248 deletions

View File

@ -71,7 +71,7 @@
.Ft size_t
.Fn @jemalloc_prefix@malloc_usable_size "const void *ptr"
.Ft void
.Fn @jemalloc_prefix@malloc_stats_print "void (*write4)(void *" "const char *" "const char *" "const char *" "const char *)" "const char *opts"
.Fn @jemalloc_prefix@malloc_stats_print "void (*write_cb)(void *" "const char *)" "const char *opts"
.Ft int
.Fn @jemalloc_prefix@mallctl "const char *name" "void *oldp" "size_t *oldlenp" "void *newp" "size_t newlen"
.Ft int
@ -81,7 +81,7 @@
.Ft const char *
.Va @jemalloc_prefix@malloc_options ;
.Ft void
.Fn \*(lp*@jemalloc_prefix@malloc_message\*(rp "void *w4opaque" "const char *p1" "const char *p2" "const char *p3" "const char *p4"
.Fn \*(lp*@jemalloc_prefix@malloc_message\*(rp "void *cbopaque" "const char *s"
.Sh DESCRIPTION
The
.Fn @jemalloc_prefix@malloc
@ -178,15 +178,15 @@ implementation-dependent.
The
.Fn @jemalloc_prefix@malloc_stats_print
function writes human-readable summary statistics via the
.Fa write4
.Fa write_cb
callback function pointer and
.Fa w4opaque
.Fa cbopaque
data passed to
.Fn write4 ,
.Fn write_cb ,
or
.Fn @jemalloc_prefix@malloc_message
if
.Fa write4
.Fa write_cb
is
.Dv NULL .
This function can be called repeatedly.
@ -1315,12 +1315,12 @@ strings forming the errors and warnings if for some reason the
file descriptor is not suitable for this.
.Va @jemalloc_prefix@malloc_message
takes the
.Fa w4opaque
.Fa cbopaque
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.
followed by a string pointer.
Please note that doing anything which tries to allocate memory in this function
is likely to result in a crash or deadlock.
.Pp

View File

@ -75,17 +75,19 @@ bool ctl_boot(void);
#define xmallctl(name, oldp, oldlenp, newp, newlen) do { \
if (JEMALLOC_P(mallctl)(name, oldp, oldlenp, newp, newlen) \
!= 0) { \
malloc_write4("<jemalloc>: Invalid xmallctl(\"", name, \
"\", ...) call\n", ""); \
malloc_write("<jemalloc>: Invalid xmallctl(\""); \
malloc_write(name); \
malloc_write("\", ...) call\n"); \
abort(); \
} \
} while (0)
#define xmallctlnametomib(name, mibp, miblenp) do { \
if (JEMALLOC_P(mallctlnametomib)(name, mibp, miblenp) != 0) { \
malloc_write4( \
"<jemalloc>: Invalid xmallctlnametomib(\"", name, \
"\", ...) call\n", ""); \
malloc_write( \
"<jemalloc>: Invalid xmallctlnametomib(\""); \
malloc_write(name); \
malloc_write("\", ...) call\n"); \
abort(); \
} \
} while (0)
@ -93,9 +95,8 @@ bool ctl_boot(void);
#define xmallctlbymib(mib, miblen, oldp, oldlenp, newp, newlen) do { \
if (JEMALLOC_P(mallctlbymib)(mib, miblen, oldp, oldlenp, newp, \
newlen) != 0) { \
malloc_write4( \
"<jemalloc>: Invalid xmallctlbymib() call\n", "", \
"", ""); \
malloc_write( \
"<jemalloc>: Invalid xmallctlbymib() call\n"); \
abort(); \
} \
} while (0)

View File

@ -36,8 +36,7 @@
#include "jemalloc/internal/qr.h"
#include "jemalloc/internal/ql.h"
extern void (*JEMALLOC_P(malloc_message))(void *w4opaque, const char *p1,
const char *p2, const char *p3, const char *p4);
extern void (*JEMALLOC_P(malloc_message))(void *wcbopaque, const char *s);
/*
* Define a custom assert() in order to reduce the chances of deadlock during
@ -47,10 +46,14 @@ extern void (*JEMALLOC_P(malloc_message))(void *w4opaque, const char *p1,
# define assert(e) do { \
if (!(e)) { \
char line_buf[UMAX2S_BUFSIZE]; \
malloc_write4("<jemalloc>: ", __FILE__, ":", \
umax2s(__LINE__, 10, line_buf)); \
malloc_write4(": Failed assertion: ", "\"", #e, \
"\"\n"); \
malloc_write("<jemalloc>: "); \
malloc_write(__FILE__); \
malloc_write(":"); \
malloc_write(umax2s(__LINE__, 10, line_buf)); \
malloc_write(": Failed assertion: "); \
malloc_write("\""); \
malloc_write(#e); \
malloc_write("\"\n"); \
abort(); \
} \
} while (0)
@ -282,8 +285,7 @@ arena_t *choose_arena_hard(void);
#include "jemalloc/internal/huge.h"
#ifndef JEMALLOC_ENABLE_INLINE
void malloc_write4(const char *p1, const char *p2, const char *p3,
const char *p4);
void malloc_write(const char *s);
arena_t *choose_arena(void);
#endif
@ -293,10 +295,10 @@ arena_t *choose_arena(void);
* JEMALLOC_P(malloc_message)(...) throughout the code.
*/
JEMALLOC_INLINE void
malloc_write4(const char *p1, const char *p2, const char *p3, const char *p4)
malloc_write(const char *s)
{
JEMALLOC_P(malloc_message)(NULL, p1, p2, p3, p4);
JEMALLOC_P(malloc_message)(NULL, s);
}
/*

View File

@ -136,14 +136,13 @@ extern bool opt_stats_print;
char *umax2s(uintmax_t x, unsigned base, char *s);
#ifdef JEMALLOC_STATS
void malloc_cprintf(void (*write4)(void *, const char *, const char *,
const char *, const char *), void *w4opaque, const char *format, ...)
JEMALLOC_ATTR(format(printf, 3, 4));
void malloc_cprintf(void (*write)(void *, const char *), void *cbopaque,
const char *format, ...) JEMALLOC_ATTR(format(printf, 3, 4));
void malloc_printf(const char *format, ...)
JEMALLOC_ATTR(format(printf, 1, 2));
#endif
void stats_print(void (*write4)(void *, const char *, const char *,
const char *, const char *), void *w4opaque, const char *opts);
void stats_print(void (*write)(void *, const char *), void *cbopaque,
const char *opts);
#endif /* JEMALLOC_H_EXTERNS */
/******************************************************************************/

View File

@ -17,8 +17,7 @@ extern "C" {
#endif
extern const char *JEMALLOC_P(malloc_options);
extern void (*JEMALLOC_P(malloc_message))(void *, const char *p1,
const char *p2, const char *p3, const char *p4);
extern void (*JEMALLOC_P(malloc_message))(void *, const char *);
void *JEMALLOC_P(malloc)(size_t size) JEMALLOC_ATTR(malloc);
void *JEMALLOC_P(calloc)(size_t num, size_t size) JEMALLOC_ATTR(malloc);
@ -28,9 +27,8 @@ void *JEMALLOC_P(realloc)(void *ptr, size_t size);
void JEMALLOC_P(free)(void *ptr);
size_t JEMALLOC_P(malloc_usable_size)(const void *ptr);
void JEMALLOC_P(malloc_stats_print)(void (*write4)(void *, const char *,
const char *, const char *, const char *), void *w4opaque,
const char *opts);
void JEMALLOC_P(malloc_stats_print)(void (*write_cb)(void *, const char *),
void *cbopaque, const char *opts);
int JEMALLOC_P(mallctl)(const char *name, void *oldp, size_t *oldlenp,
void *newp, size_t newlen);
int JEMALLOC_P(mallctlnametomib)(const char *name, size_t *mibp,

View File

@ -2326,8 +2326,9 @@ arena_boot(void)
*/
if (mbin0 > 256) {
char line_buf[UMAX2S_BUFSIZE];
malloc_write4("<jemalloc>: Too many small size classes (",
umax2s(mbin0, 10, line_buf), " > max 256)\n", "");
malloc_write("<jemalloc>: Too many small size classes (");
malloc_write(umax2s(mbin0, 10, line_buf));
malloc_write(" > max 256)\n");
abort();
}

View File

@ -52,8 +52,9 @@ pages_map(void *addr, size_t size)
char buf[STRERROR_BUF];
strerror_r(errno, buf, sizeof(buf));
malloc_write4("<jemalloc>", ": Error in munmap(): ",
buf, "\n");
malloc_write("<jemalloc>: Error in munmap(): ");
malloc_write(buf);
malloc_write("\n");
if (opt_abort)
abort();
}
@ -73,7 +74,9 @@ pages_unmap(void *addr, size_t size)
char buf[STRERROR_BUF];
strerror_r(errno, buf, sizeof(buf));
malloc_write4("<jemalloc>", ": Error in munmap(): ", buf, "\n");
malloc_write("<jemalloc>: Error in munmap(): ");
malloc_write(buf);
malloc_write("\n");
if (opt_abort)
abort();
}

View File

@ -297,15 +297,17 @@ chunk_swap_enable(const int *fds, unsigned nfds, bool prezeroed)
char buf[STRERROR_BUF];
strerror_r(errno, buf, sizeof(buf));
malloc_write4("<jemalloc>",
": Error in mmap(..., MAP_FIXED, ...): ",
buf, "\n");
malloc_write(
"<jemalloc>: Error in mmap(..., MAP_FIXED, ...): ");
malloc_write(buf);
malloc_write("\n");
if (opt_abort)
abort();
if (munmap(vaddr, voff) == -1) {
strerror_r(errno, buf, sizeof(buf));
malloc_write4("<jemalloc>",
": Error in munmap(): ", buf, "\n");
malloc_write("<jemalloc>: Error in munmap(): ");
malloc_write(buf);
malloc_write("\n");
}
ret = true;
goto RETURN;

View File

@ -151,8 +151,7 @@ static int opt_narenas_lshift = 0;
/******************************************************************************/
/* Function prototypes for non-inline static functions. */
static void wrtmessage(void *w4opaque, const char *p1, const char *p2,
const char *p3, const char *p4);
static void wrtmessage(void *cbopaque, const char *s);
static void stats_print_atexit(void);
static unsigned malloc_ncpus(void);
static bool malloc_init_hard(void);
@ -168,20 +167,14 @@ JEMALLOC_ATTR(visibility("hidden"))
static
#endif
void
wrtmessage(void *w4opaque, const char *p1, const char *p2, const char *p3,
const char *p4)
wrtmessage(void *cbopaque, const char *s)
{
if (write(STDERR_FILENO, p1, strlen(p1)) < 0
|| write(STDERR_FILENO, p2, strlen(p2)) < 0
|| write(STDERR_FILENO, p3, strlen(p3)) < 0
|| write(STDERR_FILENO, p4, strlen(p4)) < 0)
return;
write(STDERR_FILENO, s, strlen(s));
}
void (*JEMALLOC_P(malloc_message))(void *, const char *p1, const char *p2,
const char *p3, const char *p4) JEMALLOC_ATTR(visibility("default")) =
wrtmessage;
void (*JEMALLOC_P(malloc_message))(void *, const char *s)
JEMALLOC_ATTR(visibility("default")) = wrtmessage;
/******************************************************************************/
/*
@ -209,7 +202,7 @@ arenas_extend(unsigned ind)
* by using arenas[0]. In practice, this is an extremely unlikely
* failure.
*/
malloc_write4("<jemalloc>", ": Error initializing arena\n", "", "");
malloc_write("<jemalloc>: Error initializing arena\n");
if (opt_abort)
abort();
@ -627,10 +620,11 @@ MALLOC_OUT:
cbuf[0] = opts[j];
cbuf[1] = '\0';
malloc_write4("<jemalloc>",
": Unsupported character "
"in malloc options: '", cbuf,
"'\n");
malloc_write(
"<jemalloc>: Unsupported character "
"in malloc options: '");
malloc_write(cbuf);
malloc_write("'\n");
}
}
}
@ -640,8 +634,7 @@ MALLOC_OUT:
/* Register fork handlers. */
if (pthread_atfork(jemalloc_prefork, jemalloc_postfork,
jemalloc_postfork) != 0) {
malloc_write4("<jemalloc>", ": Error in pthread_atfork()\n", "",
"");
malloc_write("<jemalloc>: Error in pthread_atfork()\n");
if (opt_abort)
abort();
}
@ -654,8 +647,7 @@ MALLOC_OUT:
if (opt_stats_print) {
/* Print statistics at exit. */
if (atexit(stats_print_atexit) != 0) {
malloc_write4("<jemalloc>", ": Error in atexit()\n", "",
"");
malloc_write("<jemalloc>: Error in atexit()\n");
if (opt_abort)
abort();
}
@ -866,9 +858,8 @@ JEMALLOC_P(malloc)(size_t size)
else {
# ifdef JEMALLOC_XMALLOC
if (opt_xmalloc) {
malloc_write4("<jemalloc>",
": Error in malloc(): invalid size 0\n", "",
"");
malloc_write("<jemalloc>: Error in malloc(): "
"invalid size 0\n");
abort();
}
# endif
@ -891,9 +882,8 @@ OOM:
if (ret == NULL) {
#ifdef JEMALLOC_XMALLOC
if (opt_xmalloc) {
malloc_write4("<jemalloc>",
": Error in malloc(): out of memory\n", "",
"");
malloc_write("<jemalloc>: Error in malloc(): "
"out of memory\n");
abort();
}
#endif
@ -933,9 +923,9 @@ JEMALLOC_P(posix_memalign)(void **memptr, size_t alignment, size_t size)
else {
# ifdef JEMALLOC_XMALLOC
if (opt_xmalloc) {
malloc_write4("<jemalloc>",
": Error in posix_memalign(): "
"invalid size 0\n", "", "");
malloc_write("<jemalloc>: Error in "
"posix_memalign(): invalid size "
"0\n");
abort();
}
# endif
@ -952,9 +942,8 @@ JEMALLOC_P(posix_memalign)(void **memptr, size_t alignment, size_t size)
|| alignment < sizeof(void *)) {
#ifdef JEMALLOC_XMALLOC
if (opt_xmalloc) {
malloc_write4("<jemalloc>",
": Error in posix_memalign(): "
"invalid alignment\n", "", "");
malloc_write("<jemalloc>: Error in "
"posix_memalign(): invalid alignment\n");
abort();
}
#endif
@ -976,9 +965,8 @@ JEMALLOC_P(posix_memalign)(void **memptr, size_t alignment, size_t size)
if (result == NULL) {
#ifdef JEMALLOC_XMALLOC
if (opt_xmalloc) {
malloc_write4("<jemalloc>",
": Error in posix_memalign(): out of memory\n",
"", "");
malloc_write("<jemalloc>: Error in posix_memalign(): "
"out of memory\n");
abort();
}
#endif
@ -1051,9 +1039,8 @@ RETURN:
if (ret == NULL) {
#ifdef JEMALLOC_XMALLOC
if (opt_xmalloc) {
malloc_write4("<jemalloc>",
": Error in calloc(): out of memory\n", "",
"");
malloc_write("<jemalloc>: Error in calloc(): out of "
"memory\n");
abort();
}
#endif
@ -1130,9 +1117,8 @@ OOM:
if (ret == NULL) {
#ifdef JEMALLOC_XMALLOC
if (opt_xmalloc) {
malloc_write4("<jemalloc>",
": Error in realloc(): out of "
"memory\n", "", "");
malloc_write("<jemalloc>: Error in realloc(): "
"out of memory\n");
abort();
}
#endif
@ -1163,9 +1149,8 @@ OOM:
if (ret == NULL) {
#ifdef JEMALLOC_XMALLOC
if (opt_xmalloc) {
malloc_write4("<jemalloc>",
": Error in realloc(): out of "
"memory\n", "", "");
malloc_write("<jemalloc>: Error in realloc(): "
"out of memory\n");
abort();
}
#endif
@ -1239,11 +1224,11 @@ JEMALLOC_P(malloc_swap_enable)(const int *fds, unsigned nfds, int prezeroed)
JEMALLOC_ATTR(visibility("default"))
void
JEMALLOC_P(malloc_stats_print)(void (*write4)(void *, const char *,
const char *, const char *, const char *), void *w4opaque, const char *opts)
JEMALLOC_P(malloc_stats_print)(void (*write_cb)(void *, const char *),
void *cbopaque, const char *opts)
{
stats_print(write4, w4opaque, opts);
stats_print(write_cb, cbopaque, opts);
}
JEMALLOC_ATTR(visibility("default"))

View File

@ -28,9 +28,8 @@ pthread_create_once(void)
pthread_create_fptr = dlsym(RTLD_NEXT, "pthread_create");
if (pthread_create_fptr == NULL) {
malloc_write4("<jemalloc>",
": Error in dlsym(RTLD_NEXT, \"pthread_create\")\n", "",
"");
malloc_write("<jemalloc>: Error in dlsym(RTLD_NEXT, "
"\"pthread_create\")\n");
abort();
}

View File

@ -738,9 +738,8 @@ prof_flush(bool propagate_err)
err = write(prof_dump_fd, prof_dump_buf, prof_dump_buf_end);
if (err == -1) {
if (propagate_err == false) {
malloc_write4("<jemalloc>",
": write() failed during heap profile flush", "\n",
"");
malloc_write("<jemalloc>: write() failed during heap "
"profile flush\n");
if (opt_abort)
abort();
}
@ -924,8 +923,9 @@ prof_dump(const char *filename, bool leakcheck, bool propagate_err)
prof_dump_fd = creat(filename, 0644);
if (prof_dump_fd == -1) {
if (propagate_err == false) {
malloc_write4("<jemalloc>",
": creat(\"", filename, "\", 0644) failed\n");
malloc_write("<jemalloc>: creat(\"");
malloc_write(filename);
malloc_write("\", 0644) failed\n");
if (opt_abort)
abort();
}
@ -980,15 +980,17 @@ prof_dump(const char *filename, bool leakcheck, bool propagate_err)
prof_leave();
if (leakcheck && cnt_all.curbytes != 0) {
malloc_write4("<jemalloc>: Leak summary: ",
umax2s(cnt_all.curbytes, 10, buf),
(cnt_all.curbytes != 1) ? " bytes" : " byte", ", ");
malloc_write4(umax2s(cnt_all.curobjs, 10, buf),
(cnt_all.curobjs != 1) ? " objects" : " object", ", ", "");
malloc_write4(umax2s(leak_nctx, 10, buf),
(leak_nctx != 1) ? " contexts" : " context", "\n", "");
malloc_write4("<jemalloc>: Run pprof on \"",
filename, "\" for leak detail\n", "");
malloc_write("<jemalloc>: Leak summary: ");
malloc_write(umax2s(cnt_all.curbytes, 10, buf));
malloc_write((cnt_all.curbytes != 1) ? " bytes, " : " byte, ");
malloc_write(umax2s(cnt_all.curobjs, 10, buf));
malloc_write((cnt_all.curobjs != 1) ? " objects, " :
" object, ");
malloc_write(umax2s(leak_nctx, 10, buf));
malloc_write((leak_nctx != 1) ? " contexts\n" : " context\n");
malloc_write("<jemalloc>: Run pprof on \"");
malloc_write(filename);
malloc_write("\" for leak detail\n");
}
return (false);
@ -1284,8 +1286,8 @@ prof_boot1(void)
return (true);
if (pthread_key_create(&bt2cnt_tsd, bt2cnt_thread_cleanup)
!= 0) {
malloc_write4("<jemalloc>",
": Error in pthread_key_create()\n", "", "");
malloc_write(
"<jemalloc>: Error in pthread_key_create()\n");
abort();
}
@ -1300,8 +1302,7 @@ prof_boot1(void)
enq_udump = false;
if (atexit(prof_fdump) != 0) {
malloc_write4("<jemalloc>", ": Error in atexit()\n", "",
"");
malloc_write("<jemalloc>: Error in atexit()\n");
if (opt_abort)
abort();
}

View File

@ -43,15 +43,14 @@ bool opt_stats_print = false;
/* Function prototypes for non-inline static functions. */
#ifdef JEMALLOC_STATS
static void malloc_vcprintf(void (*write4)(void *, const char *,
const char *, const char *, const char *), void *w4opaque,
const char *format, va_list ap);
static void stats_arena_bins_print(void (*write4)(void *, const char *,
const char *, const char *, const char *), void *w4opaque, unsigned i);
static void stats_arena_lruns_print(void (*write4)(void *, const char *,
const char *, const char *, const char *), void *w4opaque, unsigned i);
static void stats_arena_print(void (*write4)(void *, const char *,
const char *, const char *, const char *), void *w4opaque, unsigned i);
static void malloc_vcprintf(void (*write_cb)(void *, const char *),
void *cbopaque, const char *format, va_list ap);
static void stats_arena_bins_print(void (*write_cb)(void *, const char *),
void *cbopaque, unsigned i);
static void stats_arena_lruns_print(void (*write_cb)(void *, const char *),
void *cbopaque, unsigned i);
static void stats_arena_print(void (*write_cb)(void *, const char *),
void *cbopaque, unsigned i);
#endif
/******************************************************************************/
@ -97,23 +96,23 @@ umax2s(uintmax_t x, unsigned base, char *s)
#ifdef JEMALLOC_STATS
static void
malloc_vcprintf(void (*write4)(void *, const char *, const char *, const char *,
const char *), void *w4opaque, const char *format, va_list ap)
malloc_vcprintf(void (*write_cb)(void *, const char *), void *cbopaque,
const char *format, va_list ap)
{
char buf[4096];
if (write4 == NULL) {
if (write_cb == NULL) {
/*
* The caller did not provide an alternate write4 callback
* function, so use the default one. malloc_write4() is an
* The caller did not provide an alternate write_cb callback
* function, so use the default one. malloc_write() is an
* inline function, so use malloc_message() directly here.
*/
write4 = JEMALLOC_P(malloc_message);
w4opaque = NULL;
write_cb = JEMALLOC_P(malloc_message);
cbopaque = NULL;
}
vsnprintf(buf, sizeof(buf), format, ap);
write4(w4opaque, buf, "", "", "");
write_cb(cbopaque, buf);
}
/*
@ -122,13 +121,13 @@ malloc_vcprintf(void (*write4)(void *, const char *, const char *, const char *,
*/
JEMALLOC_ATTR(format(printf, 3, 4))
void
malloc_cprintf(void (*write4)(void *, const char *, const char *, const char *,
const char *), void *w4opaque, const char *format, ...)
malloc_cprintf(void (*write_cb)(void *, const char *), void *cbopaque,
const char *format, ...)
{
va_list ap;
va_start(ap, format);
malloc_vcprintf(write4, w4opaque, format, ap);
malloc_vcprintf(write_cb, cbopaque, format, ap);
va_end(ap);
}
@ -149,8 +148,8 @@ malloc_printf(const char *format, ...)
#ifdef JEMALLOC_STATS
static void
stats_arena_bins_print(void (*write4)(void *, const char *, const char *,
const char *, const char *), void *w4opaque, unsigned i)
stats_arena_bins_print(void (*write_cb)(void *, const char *), void *cbopaque,
unsigned i)
{
size_t pagesize;
bool config_tcache;
@ -160,11 +159,11 @@ stats_arena_bins_print(void (*write4)(void *, const char *, const char *,
CTL_GET("config.tcache", &config_tcache, bool);
if (config_tcache) {
malloc_cprintf(write4, w4opaque,
malloc_cprintf(write_cb, cbopaque,
"bins: bin size regs pgs nrequests "
"nfills nflushes newruns reruns maxruns curruns\n");
} else {
malloc_cprintf(write4, w4opaque,
malloc_cprintf(write_cb, cbopaque,
"bins: bin size regs pgs nrequests "
"newruns reruns maxruns curruns\n");
}
@ -186,12 +185,12 @@ stats_arena_bins_print(void (*write4)(void *, const char *, const char *,
if (gap_start != UINT_MAX) {
if (j > gap_start + 1) {
/* Gap of more than one size class. */
malloc_cprintf(write4, w4opaque,
malloc_cprintf(write_cb, cbopaque,
"[%u..%u]\n", gap_start,
j - 1);
} else {
/* Gap of one size class. */
malloc_cprintf(write4, w4opaque,
malloc_cprintf(write_cb, cbopaque,
"[%u]\n", gap_start);
}
gap_start = UINT_MAX;
@ -218,7 +217,7 @@ stats_arena_bins_print(void (*write4)(void *, const char *, const char *,
CTL_IJ_GET("stats.arenas.0.bins.0.curruns", &curruns,
size_t);
if (config_tcache) {
malloc_cprintf(write4, w4opaque,
malloc_cprintf(write_cb, cbopaque,
"%13u %1s %5zu %4u %3zu %10"PRIu64
" %9"PRIu64" %9"PRIu64" %9"PRIu64""
" %9"PRIu64" %7zu %7zu\n",
@ -231,7 +230,7 @@ stats_arena_bins_print(void (*write4)(void *, const char *, const char *,
nrequests, nfills, nflushes, nruns, reruns,
highruns, curruns);
} else {
malloc_cprintf(write4, w4opaque,
malloc_cprintf(write_cb, cbopaque,
"%13u %1s %5zu %4u %3zu %10"PRIu64
" %9"PRIu64" %9"PRIu64" %7zu %7zu\n",
j,
@ -248,25 +247,25 @@ stats_arena_bins_print(void (*write4)(void *, const char *, const char *,
if (gap_start != UINT_MAX) {
if (j > gap_start + 1) {
/* Gap of more than one size class. */
malloc_cprintf(write4, w4opaque, "[%u..%u]\n",
malloc_cprintf(write_cb, cbopaque, "[%u..%u]\n",
gap_start, j - 1);
} else {
/* Gap of one size class. */
malloc_cprintf(write4, w4opaque, "[%u]\n", gap_start);
malloc_cprintf(write_cb, cbopaque, "[%u]\n", gap_start);
}
}
}
static void
stats_arena_lruns_print(void (*write4)(void *, const char *, const char *,
const char *, const char *), void *w4opaque, unsigned i)
stats_arena_lruns_print(void (*write_cb)(void *, const char *), void *cbopaque,
unsigned i)
{
size_t pagesize, nlruns, j;
ssize_t gap_start;
CTL_GET("arenas.pagesize", &pagesize, size_t);
malloc_cprintf(write4, w4opaque,
malloc_cprintf(write_cb, cbopaque,
"large: size pages nrequests maxruns curruns\n");
CTL_GET("arenas.nlruns", &nlruns, size_t);
for (j = 0, gap_start = -1; j < nlruns; j++) {
@ -285,23 +284,23 @@ stats_arena_lruns_print(void (*write4)(void *, const char *, const char *,
CTL_IJ_GET("stats.arenas.0.lruns.0.curruns", &curruns,
size_t);
if (gap_start != -1) {
malloc_cprintf(write4, w4opaque, "[%zu]\n",
malloc_cprintf(write_cb, cbopaque, "[%zu]\n",
j - gap_start);
gap_start = -1;
}
malloc_cprintf(write4, w4opaque,
malloc_cprintf(write_cb, cbopaque,
"%13zu %5zu %9"PRIu64" %9zu %9zu\n",
run_size, run_size / pagesize, nrequests, highruns,
curruns);
}
}
if (gap_start != -1)
malloc_cprintf(write4, w4opaque, "[%zu]\n", j - gap_start);
malloc_cprintf(write_cb, cbopaque, "[%zu]\n", j - gap_start);
}
static void
stats_arena_print(void (*write4)(void *, const char *, const char *,
const char *, const char *), void *w4opaque, unsigned i)
stats_arena_print(void (*write_cb)(void *, const char *), void *cbopaque,
unsigned i)
{
size_t pagesize, pactive, pdirty, mapped;
uint64_t npurge, nmadvise, purged;
@ -319,50 +318,50 @@ stats_arena_print(void (*write4)(void *, const char *, const char *,
CTL_I_GET("stats.arenas.0.npurge", &npurge, uint64_t);
CTL_I_GET("stats.arenas.0.nmadvise", &nmadvise, uint64_t);
CTL_I_GET("stats.arenas.0.purged", &purged, uint64_t);
malloc_cprintf(write4, w4opaque,
malloc_cprintf(write_cb, cbopaque,
"dirty pages: %zu:%zu active:dirty, %"PRIu64" sweep%s,"
" %"PRIu64" madvise%s, %"PRIu64" purged\n",
pactive, pdirty, npurge, npurge == 1 ? "" : "s",
nmadvise, nmadvise == 1 ? "" : "s", purged);
malloc_cprintf(write4, w4opaque,
malloc_cprintf(write_cb, cbopaque,
" allocated nmalloc ndalloc\n");
CTL_I_GET("stats.arenas.0.small.allocated", &small_allocated, size_t);
CTL_I_GET("stats.arenas.0.small.nmalloc", &small_nmalloc, uint64_t);
CTL_I_GET("stats.arenas.0.small.ndalloc", &small_ndalloc, uint64_t);
malloc_cprintf(write4, w4opaque,
malloc_cprintf(write_cb, cbopaque,
"small: %12zu %12"PRIu64" %12"PRIu64"\n",
small_allocated, small_nmalloc, small_ndalloc);
CTL_I_GET("stats.arenas.0.medium.allocated", &medium_allocated, size_t);
CTL_I_GET("stats.arenas.0.medium.nmalloc", &medium_nmalloc, uint64_t);
CTL_I_GET("stats.arenas.0.medium.ndalloc", &medium_ndalloc, uint64_t);
malloc_cprintf(write4, w4opaque,
malloc_cprintf(write_cb, cbopaque,
"medium: %12zu %12"PRIu64" %12"PRIu64"\n",
medium_allocated, medium_nmalloc, medium_ndalloc);
CTL_I_GET("stats.arenas.0.large.allocated", &large_allocated, size_t);
CTL_I_GET("stats.arenas.0.large.nmalloc", &large_nmalloc, uint64_t);
CTL_I_GET("stats.arenas.0.large.ndalloc", &large_ndalloc, uint64_t);
malloc_cprintf(write4, w4opaque,
malloc_cprintf(write_cb, cbopaque,
"large: %12zu %12"PRIu64" %12"PRIu64"\n",
large_allocated, large_nmalloc, large_ndalloc);
malloc_cprintf(write4, w4opaque,
malloc_cprintf(write_cb, cbopaque,
"total: %12zu %12"PRIu64" %12"PRIu64"\n",
small_allocated + medium_allocated + large_allocated,
small_nmalloc + medium_nmalloc + large_nmalloc,
small_ndalloc + medium_ndalloc + large_ndalloc);
malloc_cprintf(write4, w4opaque, "active: %12zu\n",
malloc_cprintf(write_cb, cbopaque, "active: %12zu\n",
pactive * pagesize );
CTL_I_GET("stats.arenas.0.mapped", &mapped, size_t);
malloc_cprintf(write4, w4opaque, "mapped: %12zu\n", mapped);
malloc_cprintf(write_cb, cbopaque, "mapped: %12zu\n", mapped);
stats_arena_bins_print(write4, w4opaque, i);
stats_arena_lruns_print(write4, w4opaque, i);
stats_arena_bins_print(write_cb, cbopaque, i);
stats_arena_lruns_print(write_cb, cbopaque, i);
}
#endif
void
stats_print(void (*write4)(void *, const char *, const char *, const char *,
const char *), void *w4opaque, const char *opts)
stats_print(void (*write_cb)(void *, const char *), void *cbopaque,
const char *opts)
{
uint64_t epoch;
size_t u64sz;
@ -378,14 +377,14 @@ stats_print(void (*write4)(void *, const char *, const char *, const char *,
u64sz = sizeof(uint64_t);
xmallctl("epoch", &epoch, &u64sz, &epoch, sizeof(uint64_t));
if (write4 == NULL) {
if (write_cb == NULL) {
/*
* The caller did not provide an alternate write4 callback
* function, so use the default one. malloc_write4() is an
* The caller did not provide an alternate write_cb callback
* function, so use the default one. malloc_write() is an
* inline function, so use malloc_message() directly here.
*/
write4 = JEMALLOC_P(malloc_message);
w4opaque = NULL;
write_cb = JEMALLOC_P(malloc_message);
cbopaque = NULL;
}
if (opts != NULL) {
@ -413,7 +412,7 @@ stats_print(void (*write4)(void *, const char *, const char *, const char *,
}
}
write4(w4opaque, "___ Begin jemalloc statistics ___\n", "", "", "");
write_cb(cbopaque, "___ Begin jemalloc statistics ___\n");
if (general) {
int err;
bool bv;
@ -425,141 +424,173 @@ stats_print(void (*write4)(void *, const char *, const char *, const char *,
ssz = sizeof(size_t);
CTL_GET("config.debug", &bv, bool);
write4(w4opaque, "Assertions ", bv ? "enabled" : "disabled",
"\n", "");
write_cb(cbopaque, "Assertions ");
write_cb(cbopaque, bv ? "enabled" : "disabled");
write_cb(cbopaque, "\n");
write4(w4opaque, "Boolean JEMALLOC_OPTIONS: ", "", "", "");
write_cb(cbopaque, "Boolean JEMALLOC_OPTIONS: ");
if ((err = JEMALLOC_P(mallctl)("opt.abort", &bv, &bsz, NULL, 0))
== 0)
write4(w4opaque, bv ? "A" : "a", "", "", "");
write_cb(cbopaque, bv ? "A" : "a");
if ((err = JEMALLOC_P(mallctl)("opt.prof", &bv, &bsz, NULL, 0))
== 0)
write4(w4opaque, bv ? "F" : "f", "", "", "");
write_cb(cbopaque, bv ? "F" : "f");
if ((err = JEMALLOC_P(mallctl)("opt.junk", &bv, &bsz, NULL, 0))
== 0)
write4(w4opaque, bv ? "J" : "j", "", "", "");
write_cb(cbopaque, bv ? "J" : "j");
if ((err = JEMALLOC_P(mallctl)("opt.prof_leak", &bv, &bsz, NULL,
0)) == 0)
write4(w4opaque, bv ? "L" : "l", "", "", "");
write_cb(cbopaque, bv ? "L" : "l");
if ((err = JEMALLOC_P(mallctl)("opt.overcommit", &bv, &bsz,
NULL, 0)) == 0)
write4(w4opaque, bv ? "O" : "o", "", "", "");
write4(w4opaque, "P", "", "", "");
write_cb(cbopaque, bv ? "O" : "o");
write_cb(cbopaque, "P");
if ((err = JEMALLOC_P(mallctl)("opt.prof_udump", &bv, &bsz,
NULL, 0)) == 0)
write4(w4opaque, bv ? "U" : "u", "", "", "");
write_cb(cbopaque, bv ? "U" : "u");
if ((err = JEMALLOC_P(mallctl)("opt.sysv", &bv, &bsz, NULL, 0))
== 0)
write4(w4opaque, bv ? "V" : "v", "", "", "");
write_cb(cbopaque, bv ? "V" : "v");
if ((err = JEMALLOC_P(mallctl)("opt.xmalloc", &bv, &bsz, NULL,
0)) == 0)
write4(w4opaque, bv ? "X" : "x", "", "", "");
write_cb(cbopaque, bv ? "X" : "x");
if ((err = JEMALLOC_P(mallctl)("opt.zero", &bv, &bsz, NULL, 0))
== 0)
write4(w4opaque, bv ? "Z" : "z", "", "", "");
write4(w4opaque, "\n", "", "", "");
write_cb(cbopaque, bv ? "Z" : "z");
write_cb(cbopaque, "\n");
write4(w4opaque, "CPUs: ", umax2s(ncpus, 10, s), "\n", "");
write_cb(cbopaque, "CPUs: ");
write_cb(cbopaque, umax2s(ncpus, 10, s));
write_cb(cbopaque, "\n");
CTL_GET("arenas.narenas", &uv, unsigned);
write4(w4opaque, "Max arenas: ", umax2s(uv, 10, s), "\n", "");
write_cb(cbopaque, "Max arenas: ");
write_cb(cbopaque, umax2s(uv, 10, s));
write_cb(cbopaque, "\n");
write4(w4opaque, "Pointer size: ", umax2s(sizeof(void *), 10,
s), "\n", "");
write_cb(cbopaque, "Pointer size: ");
write_cb(cbopaque, umax2s(sizeof(void *), 10, s));
write_cb(cbopaque, "\n");
CTL_GET("arenas.quantum", &sv, size_t);
write4(w4opaque, "Quantum size: ", umax2s(sv, 10, s), "\n", "");
write_cb(cbopaque, "Quantum size: ");
write_cb(cbopaque, umax2s(sv, 10, s));
write_cb(cbopaque, "\n");
CTL_GET("arenas.cacheline", &sv, size_t);
write4(w4opaque, "Cacheline size (assumed): ", umax2s(sv, 10,
s), "\n", "");
write_cb(cbopaque, "Cacheline size (assumed): ");
write_cb(cbopaque, umax2s(sv, 10, s));
write_cb(cbopaque, "\n");
CTL_GET("arenas.subpage", &sv, size_t);
write4(w4opaque, "Subpage spacing: ", umax2s(sv, 10, s), "\n",
"");
write_cb(cbopaque, "Subpage spacing: ");
write_cb(cbopaque, umax2s(sv, 10, s));
write_cb(cbopaque, "\n");
CTL_GET("arenas.medium", &sv, size_t);
write4(w4opaque, "Medium spacing: ", umax2s(sv, 10, s), "\n",
"");
write_cb(cbopaque, "Medium spacing: ");
write_cb(cbopaque, umax2s(sv, 10, s));
write_cb(cbopaque, "\n");
if ((err = JEMALLOC_P(mallctl)("arenas.tspace_min", &sv, &ssz,
NULL, 0)) == 0) {
write4(w4opaque, "Tiny 2^n-spaced sizes: [", umax2s(sv,
10, s), "..", "");
write_cb(cbopaque, "Tiny 2^n-spaced sizes: [");
write_cb(cbopaque, umax2s(sv, 10, s));
write_cb(cbopaque, "..");
CTL_GET("arenas.tspace_max", &sv, size_t);
write4(w4opaque, umax2s(sv, 10, s), "]\n", "", "");
write_cb(cbopaque, umax2s(sv, 10, s));
write_cb(cbopaque, "]\n");
}
CTL_GET("arenas.qspace_min", &sv, size_t);
write4(w4opaque, "Quantum-spaced sizes: [", umax2s(sv, 10, s),
"..", "");
write_cb(cbopaque, "Quantum-spaced sizes: [");
write_cb(cbopaque, umax2s(sv, 10, s));
write_cb(cbopaque, "..");
CTL_GET("arenas.qspace_max", &sv, size_t);
write4(w4opaque, umax2s(sv, 10, s), "]\n", "", "");
write_cb(cbopaque, umax2s(sv, 10, s));
write_cb(cbopaque, "]\n");
CTL_GET("arenas.cspace_min", &sv, size_t);
write4(w4opaque, "Cacheline-spaced sizes: [", umax2s(sv, 10, s),
"..", "");
write_cb(cbopaque, "Cacheline-spaced sizes: [");
write_cb(cbopaque, umax2s(sv, 10, s));
write_cb(cbopaque, "..");
CTL_GET("arenas.cspace_max", &sv, size_t);
write4(w4opaque, umax2s(sv, 10, s), "]\n", "", "");
write_cb(cbopaque, umax2s(sv, 10, s));
write_cb(cbopaque, "]\n");
CTL_GET("arenas.sspace_min", &sv, size_t);
write4(w4opaque, "Subpage-spaced sizes: [", umax2s(sv, 10, s),
"..", "");
write_cb(cbopaque, "Subpage-spaced sizes: [");
write_cb(cbopaque, umax2s(sv, 10, s));
write_cb(cbopaque, "..");
CTL_GET("arenas.sspace_max", &sv, size_t);
write4(w4opaque, umax2s(sv, 10, s), "]\n", "", "");
write_cb(cbopaque, umax2s(sv, 10, s));
write_cb(cbopaque, "]\n");
CTL_GET("arenas.medium_min", &sv, size_t);
write4(w4opaque, "Medium sizes: [", umax2s(sv, 10, s), "..",
"");
write_cb(cbopaque, "Medium sizes: [");
write_cb(cbopaque, umax2s(sv, 10, s));
write_cb(cbopaque, "..");
CTL_GET("arenas.medium_max", &sv, size_t);
write4(w4opaque, umax2s(sv, 10, s), "]\n", "", "");
write_cb(cbopaque, umax2s(sv, 10, s));
write_cb(cbopaque, "]\n");
CTL_GET("opt.lg_dirty_mult", &ssv, ssize_t);
if (ssv >= 0) {
write4(w4opaque,
"Min active:dirty page ratio per arena: ",
umax2s((1U << ssv), 10, s), ":1\n", "");
write_cb(cbopaque,
"Min active:dirty page ratio per arena: ");
write_cb(cbopaque, umax2s((1U << ssv), 10, s));
write_cb(cbopaque, ":1\n");
} else {
write4(w4opaque,
"Min active:dirty page ratio per arena: N/A\n", "",
"", "");
write_cb(cbopaque,
"Min active:dirty page ratio per arena: N/A\n");
}
if ((err = JEMALLOC_P(mallctl)("opt.lg_tcache_nslots", &sv,
&ssz, NULL, 0)) == 0) {
size_t tcache_nslots, tcache_gc_sweep;
tcache_nslots = (1U << sv);
write4(w4opaque, "Thread cache slots per size class: ",
tcache_nslots ? umax2s(tcache_nslots, 10, s) :
"N/A", "\n", "");
write_cb(cbopaque,
"Thread cache slots per size class: ");
write_cb(cbopaque, tcache_nslots ?
umax2s(tcache_nslots, 10, s) : "N/A");
write_cb(cbopaque, "\n");
CTL_GET("opt.lg_tcache_gc_sweep", &ssv, ssize_t);
tcache_gc_sweep = (1U << ssv);
write4(w4opaque, "Thread cache GC sweep interval: ",
tcache_nslots && ssv >= 0 ? umax2s(tcache_gc_sweep,
10, s) : "N/A", "\n", "");
write_cb(cbopaque, "Thread cache GC sweep interval: ");
write_cb(cbopaque, tcache_nslots && ssv >= 0 ?
umax2s(tcache_gc_sweep, 10, s) : "N/A");
write_cb(cbopaque, "\n");
}
if ((err = JEMALLOC_P(mallctl)("opt.prof", &bv, &bsz, NULL, 0))
== 0 && bv) {
xmallctl("opt.lg_prof_bt_max", &sv, &ssz, NULL, 0);
write4(w4opaque, "Maximum profile backtrace depth: ",
umax2s((1U << sv), 10, s), "\n", "");
write_cb(cbopaque, "Maximum profile backtrace depth: ");
write_cb(cbopaque, umax2s((1U << sv), 10, s));
write_cb(cbopaque, "\n");
xmallctl("opt.lg_prof_sample", &sv, &ssz, NULL, 0);
write4(w4opaque, "Average profile sample interval: ",
umax2s((1U << sv), 10, s), "", "");
write4(w4opaque, " (2^", umax2s(sv, 10, s), ")\n", "");
write_cb(cbopaque, "Average profile sample interval: ");
write_cb(cbopaque, umax2s((1U << sv), 10, s));
write_cb(cbopaque, " (2^");
write_cb(cbopaque, umax2s(sv, 10, s));
write_cb(cbopaque, ")\n");
xmallctl("opt.lg_prof_interval", &sv, &ssz, NULL, 0);
write4(w4opaque, "Average profile dump interval: ",
umax2s((1U << sv), 10, s), "", "");
write4(w4opaque, " (2^", umax2s(sv, 10, s), ")\n", "");
write_cb(cbopaque, "Average profile dump interval: ");
write_cb(cbopaque, umax2s((1U << sv), 10, s));
write_cb(cbopaque, " (2^");
write_cb(cbopaque, umax2s(sv, 10, s));
write_cb(cbopaque, ")\n");
}
CTL_GET("arenas.chunksize", &sv, size_t);
write4(w4opaque, "Chunk size: ", umax2s(sv, 10, s), "", "");
write_cb(cbopaque, "Chunk size: ");
write_cb(cbopaque, umax2s(sv, 10, s));
CTL_GET("opt.lg_chunk", &sv, size_t);
write4(w4opaque, " (2^", umax2s(sv, 10, s), ")\n", "");
write_cb(cbopaque, " (2^");
write_cb(cbopaque, umax2s(sv, 10, s));
write_cb(cbopaque, ")\n");
}
#ifdef JEMALLOC_STATS
@ -577,7 +608,7 @@ stats_print(void (*write4)(void *, const char *, const char *, const char *,
CTL_GET("stats.allocated", &allocated, size_t);
CTL_GET("stats.active", &active, size_t);
CTL_GET("stats.mapped", &mapped, size_t);
malloc_cprintf(write4, w4opaque,
malloc_cprintf(write_cb, cbopaque,
"Allocated: %zu, active: %zu, mapped: %zu\n", allocated,
active, mapped);
@ -589,17 +620,17 @@ stats_print(void (*write4)(void *, const char *, const char *, const char *,
NULL, 0)) == 0) {
size_t lg_chunk;
malloc_cprintf(write4, w4opaque, "chunks: nchunks "
malloc_cprintf(write_cb, cbopaque, "chunks: nchunks "
"highchunks curchunks swap_avail\n");
CTL_GET("opt.lg_chunk", &lg_chunk, size_t);
malloc_cprintf(write4, w4opaque,
malloc_cprintf(write_cb, cbopaque,
" %13"PRIu64"%13zu%13zu%13zu\n",
chunks_total, chunks_high, chunks_current,
swap_avail << lg_chunk);
} else {
malloc_cprintf(write4, w4opaque, "chunks: nchunks "
malloc_cprintf(write_cb, cbopaque, "chunks: nchunks "
"highchunks curchunks\n");
malloc_cprintf(write4, w4opaque,
malloc_cprintf(write_cb, cbopaque,
" %13"PRIu64"%13zu%13zu\n",
chunks_total, chunks_high, chunks_current);
}
@ -608,9 +639,9 @@ stats_print(void (*write4)(void *, const char *, const char *, const char *,
CTL_GET("stats.huge.nmalloc", &huge_nmalloc, uint64_t);
CTL_GET("stats.huge.ndalloc", &huge_ndalloc, uint64_t);
CTL_GET("stats.huge.allocated", &huge_allocated, size_t);
malloc_cprintf(write4, w4opaque,
malloc_cprintf(write_cb, cbopaque,
"huge: nmalloc ndalloc allocated\n");
malloc_cprintf(write4, w4opaque,
malloc_cprintf(write_cb, cbopaque,
" %12"PRIu64" %12"PRIu64" %12zu\n",
huge_nmalloc, huge_ndalloc, huge_allocated);
@ -633,9 +664,9 @@ stats_print(void (*write4)(void *, const char *, const char *, const char *,
if (ninitialized > 1) {
/* Print merged arena stats. */
malloc_cprintf(write4, w4opaque,
malloc_cprintf(write_cb, cbopaque,
"\nMerged arenas stats:\n");
stats_arena_print(write4, w4opaque,
stats_arena_print(write_cb, cbopaque,
narenas);
}
}
@ -658,15 +689,15 @@ stats_print(void (*write4)(void *, const char *, const char *, const char *,
for (i = 0; i < narenas; i++) {
if (initialized[i]) {
malloc_cprintf(write4, w4opaque,
malloc_cprintf(write_cb, cbopaque,
"\narenas[%u]:\n", i);
stats_arena_print(write4,
w4opaque, i);
stats_arena_print(write_cb,
cbopaque, i);
}
}
}
}
}
#endif /* #ifdef JEMALLOC_STATS */
write4(w4opaque, "--- End jemalloc statistics ---\n", "", "", "");
write_cb(cbopaque, "--- End jemalloc statistics ---\n");
}

View File

@ -325,8 +325,8 @@ tcache_boot(void)
if (tcache_nslots != 0) {
if (pthread_key_create(&tcache_tsd, tcache_thread_cleanup) !=
0) {
malloc_write4("<jemalloc>",
": Error in pthread_key_create()\n", "", "");
malloc_write(
"<jemalloc>: Error in pthread_key_create()\n");
abort();
}
}