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 .Ft size_t
.Fn @jemalloc_prefix@malloc_usable_size "const void *ptr" .Fn @jemalloc_prefix@malloc_usable_size "const void *ptr"
.Ft void .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 .Ft int
.Fn @jemalloc_prefix@mallctl "const char *name" "void *oldp" "size_t *oldlenp" "void *newp" "size_t newlen" .Fn @jemalloc_prefix@mallctl "const char *name" "void *oldp" "size_t *oldlenp" "void *newp" "size_t newlen"
.Ft int .Ft int
@ -81,7 +81,7 @@
.Ft const char * .Ft const char *
.Va @jemalloc_prefix@malloc_options ; .Va @jemalloc_prefix@malloc_options ;
.Ft void .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 .Sh DESCRIPTION
The The
.Fn @jemalloc_prefix@malloc .Fn @jemalloc_prefix@malloc
@ -178,15 +178,15 @@ implementation-dependent.
The 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 write_cb
callback function pointer and callback function pointer and
.Fa w4opaque .Fa cbopaque
data passed to data passed to
.Fn write4 , .Fn write_cb ,
or or
.Fn @jemalloc_prefix@malloc_message .Fn @jemalloc_prefix@malloc_message
if if
.Fa write4 .Fa write_cb
is is
.Dv NULL . .Dv NULL .
This function can be called repeatedly. 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. file descriptor is not suitable for this.
.Va @jemalloc_prefix@malloc_message .Va @jemalloc_prefix@malloc_message
takes the takes the
.Fa w4opaque .Fa cbopaque
pointer argument that is pointer argument that is
.Dv NULL .Dv NULL
unless overridden by the arguments in a call to unless overridden by the arguments in a call to
.Fn @jemalloc_prefix@malloc_stats_print , .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 Please note that doing anything which tries to allocate memory in this function
is likely to result in a crash or deadlock. is likely to result in a crash or deadlock.
.Pp .Pp

View File

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

View File

@ -36,8 +36,7 @@
#include "jemalloc/internal/qr.h" #include "jemalloc/internal/qr.h"
#include "jemalloc/internal/ql.h" #include "jemalloc/internal/ql.h"
extern void (*JEMALLOC_P(malloc_message))(void *w4opaque, const char *p1, extern void (*JEMALLOC_P(malloc_message))(void *wcbopaque, const char *s);
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
@ -47,10 +46,14 @@ extern void (*JEMALLOC_P(malloc_message))(void *w4opaque, const char *p1,
# define assert(e) do { \ # define assert(e) do { \
if (!(e)) { \ if (!(e)) { \
char line_buf[UMAX2S_BUFSIZE]; \ char line_buf[UMAX2S_BUFSIZE]; \
malloc_write4("<jemalloc>: ", __FILE__, ":", \ malloc_write("<jemalloc>: "); \
umax2s(__LINE__, 10, line_buf)); \ malloc_write(__FILE__); \
malloc_write4(": Failed assertion: ", "\"", #e, \ malloc_write(":"); \
"\"\n"); \ malloc_write(umax2s(__LINE__, 10, line_buf)); \
malloc_write(": Failed assertion: "); \
malloc_write("\""); \
malloc_write(#e); \
malloc_write("\"\n"); \
abort(); \ abort(); \
} \ } \
} while (0) } while (0)
@ -282,8 +285,7 @@ arena_t *choose_arena_hard(void);
#include "jemalloc/internal/huge.h" #include "jemalloc/internal/huge.h"
#ifndef JEMALLOC_ENABLE_INLINE #ifndef JEMALLOC_ENABLE_INLINE
void malloc_write4(const char *p1, const char *p2, const char *p3, void malloc_write(const char *s);
const char *p4);
arena_t *choose_arena(void); arena_t *choose_arena(void);
#endif #endif
@ -293,10 +295,10 @@ arena_t *choose_arena(void);
* JEMALLOC_P(malloc_message)(...) throughout the code. * JEMALLOC_P(malloc_message)(...) throughout the code.
*/ */
JEMALLOC_INLINE void 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); char *umax2s(uintmax_t x, unsigned base, char *s);
#ifdef JEMALLOC_STATS #ifdef JEMALLOC_STATS
void malloc_cprintf(void (*write4)(void *, const char *, const char *, void malloc_cprintf(void (*write)(void *, const char *), void *cbopaque,
const char *, const char *), void *w4opaque, const char *format, ...) const char *format, ...) JEMALLOC_ATTR(format(printf, 3, 4));
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
void stats_print(void (*write4)(void *, const char *, const char *, void stats_print(void (*write)(void *, const char *), void *cbopaque,
const char *, const char *), void *w4opaque, const char *opts); const char *opts);
#endif /* JEMALLOC_H_EXTERNS */ #endif /* JEMALLOC_H_EXTERNS */
/******************************************************************************/ /******************************************************************************/

View File

@ -17,8 +17,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))(void *, const char *p1, extern void (*JEMALLOC_P(malloc_message))(void *, const char *);
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);
void *JEMALLOC_P(calloc)(size_t num, 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); void JEMALLOC_P(free)(void *ptr);
size_t JEMALLOC_P(malloc_usable_size)(const void *ptr); size_t JEMALLOC_P(malloc_usable_size)(const void *ptr);
void JEMALLOC_P(malloc_stats_print)(void (*write4)(void *, const char *, void JEMALLOC_P(malloc_stats_print)(void (*write_cb)(void *, const char *),
const char *, const char *, const char *), void *w4opaque, void *cbopaque, const char *opts);
const char *opts);
int JEMALLOC_P(mallctl)(const char *name, void *oldp, size_t *oldlenp, int JEMALLOC_P(mallctl)(const char *name, void *oldp, size_t *oldlenp,
void *newp, size_t newlen); void *newp, size_t newlen);
int JEMALLOC_P(mallctlnametomib)(const char *name, size_t *mibp, int JEMALLOC_P(mallctlnametomib)(const char *name, size_t *mibp,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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