Replace JEMALLOC_OPTIONS with MALLOC_CONF.
Replace the single-character run-time flags with key/value pairs, which can be set via the malloc_conf global, /etc/malloc.conf, and the MALLOC_CONF environment variable. Replace the JEMALLOC_PROF_PREFIX environment variable with the "opt.prof_prefix" option. Replace umax2s() with u2s().
This commit is contained in:
parent
e4f7846f1f
commit
e73397062a
@ -27,9 +27,17 @@ any of the following arguments (not a definitive list) to 'configure':
|
|||||||
it is linked to. This works only on ELF-based systems.
|
it is linked to. This works only on ELF-based systems.
|
||||||
|
|
||||||
--with-jemalloc-prefix=<prefix>
|
--with-jemalloc-prefix=<prefix>
|
||||||
Prefix all public APIs with <prefix>, so that, for example, malloc()
|
Prefix all public APIs with <prefix>. For example, if <prefix> is
|
||||||
becomes <prefix>malloc(). This makes it possible to use jemalloc at the
|
"prefix_", the API changes like the following occur:
|
||||||
same time as the system allocator.
|
|
||||||
|
malloc() --> prefix_malloc()
|
||||||
|
malloc_conf --> prefix_malloc_conf
|
||||||
|
/etc/malloc.conf --> /etc/prefix_malloc.conf
|
||||||
|
MALLOC_CONF --> PREFIX_MALLOC_CONF
|
||||||
|
|
||||||
|
This makes it possible to use jemalloc at the same time as the
|
||||||
|
system allocator, or even to use multiple copies of jemalloc
|
||||||
|
simultaneously.
|
||||||
|
|
||||||
By default, the prefix is "", except on OS X, where it is "je_". On OS X,
|
By default, the prefix is "", except on OS X, where it is "je_". On OS X,
|
||||||
jemalloc overlays the default malloc zone, but makes no attempt to actually
|
jemalloc overlays the default malloc zone, but makes no attempt to actually
|
||||||
|
@ -256,9 +256,13 @@ else
|
|||||||
fi]
|
fi]
|
||||||
)
|
)
|
||||||
if test "x$JEMALLOC_PREFIX" != "x" ; then
|
if test "x$JEMALLOC_PREFIX" != "x" ; then
|
||||||
AC_DEFINE([JEMALLOC_PREFIX], [ ])
|
JEMALLOC_CPREFIX=`echo ${JEMALLOC_PREFIX} | tr "a-z" "A-Z"`
|
||||||
|
AC_DEFINE_UNQUOTED([JEMALLOC_PREFIX], ["$JEMALLOC_PREFIX"])
|
||||||
|
AC_DEFINE_UNQUOTED([JEMALLOC_CPREFIX], ["$JEMALLOC_CPREFIX"])
|
||||||
jemalloc_prefix="$JEMALLOC_PREFIX"
|
jemalloc_prefix="$JEMALLOC_PREFIX"
|
||||||
|
jemalloc_cprefix="$JEMALLOC_CPREFIX"
|
||||||
AC_SUBST([jemalloc_prefix])
|
AC_SUBST([jemalloc_prefix])
|
||||||
|
AC_SUBST([jemalloc_cprefix])
|
||||||
AC_DEFINE_UNQUOTED([JEMALLOC_P(string_that_no_one_should_want_to_use_as_a_jemalloc_API_prefix)], [${JEMALLOC_PREFIX}##string_that_no_one_should_want_to_use_as_a_jemalloc_API_prefix])
|
AC_DEFINE_UNQUOTED([JEMALLOC_P(string_that_no_one_should_want_to_use_as_a_jemalloc_API_prefix)], [${JEMALLOC_PREFIX}##string_that_no_one_should_want_to_use_as_a_jemalloc_API_prefix])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -325,6 +329,15 @@ if test "x$enable_debug" = "x1" ; then
|
|||||||
AC_DEFINE([JEMALLOC_IVSALLOC], [ ])
|
AC_DEFINE([JEMALLOC_IVSALLOC], [ ])
|
||||||
fi
|
fi
|
||||||
AC_SUBST([enable_debug])
|
AC_SUBST([enable_debug])
|
||||||
|
if test "x$enable_debug" = "x0" ; then
|
||||||
|
roff_debug=".\\\" "
|
||||||
|
roff_no_debug=""
|
||||||
|
else
|
||||||
|
roff_debug=""
|
||||||
|
roff_no_debug=".\\\" "
|
||||||
|
fi
|
||||||
|
AC_SUBST([roff_debug])
|
||||||
|
AC_SUBST([roff_no_debug])
|
||||||
|
|
||||||
dnl Only optimize if not debugging.
|
dnl Only optimize if not debugging.
|
||||||
if test "x$enable_debug" = "x0" -a "x$no_CFLAGS" = "xyes" ; then
|
if test "x$enable_debug" = "x0" -a "x$no_CFLAGS" = "xyes" ; then
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -82,9 +82,9 @@ 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_write("<jemalloc>: Invalid xmallctl(\""); \
|
malloc_write("<jemalloc>: Failure in xmallctl(\""); \
|
||||||
malloc_write(name); \
|
malloc_write(name); \
|
||||||
malloc_write("\", ...) call\n"); \
|
malloc_write("\", ...)\n"); \
|
||||||
abort(); \
|
abort(); \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
@ -92,9 +92,9 @@ bool ctl_boot(void);
|
|||||||
#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_write( \
|
malloc_write( \
|
||||||
"<jemalloc>: Invalid xmallctlnametomib(\""); \
|
"<jemalloc>: Failure in xmallctlnametomib(\""); \
|
||||||
malloc_write(name); \
|
malloc_write(name); \
|
||||||
malloc_write("\", ...) call\n"); \
|
malloc_write("\", ...)\n"); \
|
||||||
abort(); \
|
abort(); \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
@ -103,7 +103,7 @@ bool ctl_boot(void);
|
|||||||
if (JEMALLOC_P(mallctlbymib)(mib, miblen, oldp, oldlenp, newp, \
|
if (JEMALLOC_P(mallctlbymib)(mib, miblen, oldp, oldlenp, newp, \
|
||||||
newlen) != 0) { \
|
newlen) != 0) { \
|
||||||
malloc_write( \
|
malloc_write( \
|
||||||
"<jemalloc>: Invalid xmallctlbymib() call\n"); \
|
"<jemalloc>: Failure in xmallctlbymib()\n"); \
|
||||||
abort(); \
|
abort(); \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
|
#include <ctype.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
@ -61,7 +62,7 @@ extern void (*JEMALLOC_P(malloc_message))(void *wcbopaque, const char *s);
|
|||||||
malloc_write("<jemalloc>: "); \
|
malloc_write("<jemalloc>: "); \
|
||||||
malloc_write(__FILE__); \
|
malloc_write(__FILE__); \
|
||||||
malloc_write(":"); \
|
malloc_write(":"); \
|
||||||
malloc_write(umax2s(__LINE__, 10, line_buf)); \
|
malloc_write(u2s(__LINE__, 10, line_buf)); \
|
||||||
malloc_write(": Failed assertion: "); \
|
malloc_write(": Failed assertion: "); \
|
||||||
malloc_write("\""); \
|
malloc_write("\""); \
|
||||||
malloc_write(#e); \
|
malloc_write(#e); \
|
||||||
@ -256,6 +257,7 @@ extern bool opt_xmalloc;
|
|||||||
#ifdef JEMALLOC_FILL
|
#ifdef JEMALLOC_FILL
|
||||||
extern bool opt_zero;
|
extern bool opt_zero;
|
||||||
#endif
|
#endif
|
||||||
|
extern size_t opt_narenas;
|
||||||
|
|
||||||
#ifdef DYNAMIC_PAGE_SHIFT
|
#ifdef DYNAMIC_PAGE_SHIFT
|
||||||
extern size_t pagesize;
|
extern size_t pagesize;
|
||||||
|
@ -9,6 +9,7 @@ typedef struct prof_ctx_s prof_ctx_t;
|
|||||||
typedef struct prof_tdata_s prof_tdata_t;
|
typedef struct prof_tdata_s prof_tdata_t;
|
||||||
|
|
||||||
/* Option defaults. */
|
/* Option defaults. */
|
||||||
|
#define PROF_PREFIX_DEFAULT "jeprof"
|
||||||
#define LG_PROF_BT_MAX_DEFAULT 7
|
#define LG_PROF_BT_MAX_DEFAULT 7
|
||||||
#define LG_PROF_SAMPLE_DEFAULT 0
|
#define LG_PROF_SAMPLE_DEFAULT 0
|
||||||
#define LG_PROF_INTERVAL_DEFAULT -1
|
#define LG_PROF_INTERVAL_DEFAULT -1
|
||||||
@ -164,10 +165,11 @@ extern bool opt_prof_active;
|
|||||||
extern size_t opt_lg_prof_bt_max; /* Maximum backtrace depth. */
|
extern size_t opt_lg_prof_bt_max; /* Maximum backtrace depth. */
|
||||||
extern size_t opt_lg_prof_sample; /* Mean bytes between samples. */
|
extern size_t opt_lg_prof_sample; /* Mean bytes between samples. */
|
||||||
extern ssize_t opt_lg_prof_interval; /* lg(prof_interval). */
|
extern ssize_t opt_lg_prof_interval; /* lg(prof_interval). */
|
||||||
extern bool opt_prof_udump; /* High-water memory dumping. */
|
extern bool opt_prof_gdump; /* High-water memory dumping. */
|
||||||
extern bool opt_prof_leak; /* Dump leak summary at exit. */
|
extern bool opt_prof_leak; /* Dump leak summary at exit. */
|
||||||
extern bool opt_prof_accum; /* Report cumulative bytes. */
|
extern bool opt_prof_accum; /* Report cumulative bytes. */
|
||||||
extern ssize_t opt_lg_prof_tcmax; /* lg(max per thread bactrace cache) */
|
extern ssize_t opt_lg_prof_tcmax; /* lg(max per thread bactrace cache) */
|
||||||
|
extern char opt_prof_prefix[PATH_MAX + 1];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Profile dump interval, measured in bytes allocated. Each arena triggers a
|
* Profile dump interval, measured in bytes allocated. Each arena triggers a
|
||||||
@ -215,10 +217,11 @@ void prof_backtrace(prof_bt_t *bt, unsigned nignore, unsigned max);
|
|||||||
prof_thr_cnt_t *prof_lookup(prof_bt_t *bt);
|
prof_thr_cnt_t *prof_lookup(prof_bt_t *bt);
|
||||||
void prof_idump(void);
|
void prof_idump(void);
|
||||||
bool prof_mdump(const char *filename);
|
bool prof_mdump(const char *filename);
|
||||||
void prof_udump(void);
|
void prof_gdump(void);
|
||||||
prof_tdata_t *prof_tdata_init(void);
|
prof_tdata_t *prof_tdata_init(void);
|
||||||
void prof_boot0(void);
|
void prof_boot0(void);
|
||||||
bool prof_boot1(void);
|
void prof_boot1(void);
|
||||||
|
bool prof_boot2(void);
|
||||||
|
|
||||||
#endif /* JEMALLOC_H_EXTERNS */
|
#endif /* JEMALLOC_H_EXTERNS */
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -154,7 +154,7 @@ struct chunk_stats_s {
|
|||||||
|
|
||||||
extern bool opt_stats_print;
|
extern bool opt_stats_print;
|
||||||
|
|
||||||
char *umax2s(uintmax_t x, unsigned base, char *s);
|
char *u2s(uint64_t x, unsigned base, char *s);
|
||||||
#ifdef JEMALLOC_STATS
|
#ifdef JEMALLOC_STATS
|
||||||
void malloc_cprintf(void (*write)(void *, const char *), void *cbopaque,
|
void malloc_cprintf(void (*write)(void *, const char *), void *cbopaque,
|
||||||
const char *format, ...) JEMALLOC_ATTR(format(printf, 3, 4));
|
const char *format, ...) JEMALLOC_ATTR(format(printf, 3, 4));
|
||||||
|
@ -17,7 +17,7 @@ typedef struct tcache_s tcache_t;
|
|||||||
/* Number of cache slots for large size classes. */
|
/* Number of cache slots for large size classes. */
|
||||||
#define TCACHE_NSLOTS_LARGE 20
|
#define TCACHE_NSLOTS_LARGE 20
|
||||||
|
|
||||||
/* (1U << opt_lg_tcache_maxclass) is used to compute tcache_maxclass. */
|
/* (1U << opt_lg_tcache_max) is used to compute tcache_maxclass. */
|
||||||
#define LG_TCACHE_MAXCLASS_DEFAULT 15
|
#define LG_TCACHE_MAXCLASS_DEFAULT 15
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -61,7 +61,7 @@ struct tcache_s {
|
|||||||
#ifdef JEMALLOC_H_EXTERNS
|
#ifdef JEMALLOC_H_EXTERNS
|
||||||
|
|
||||||
extern bool opt_tcache;
|
extern bool opt_tcache;
|
||||||
extern ssize_t opt_lg_tcache_maxclass;
|
extern ssize_t opt_lg_tcache_max;
|
||||||
extern ssize_t opt_lg_tcache_gc_sweep;
|
extern ssize_t opt_lg_tcache_gc_sweep;
|
||||||
|
|
||||||
/* Map of thread-specific caches. */
|
/* Map of thread-specific caches. */
|
||||||
|
@ -32,7 +32,7 @@ extern "C" {
|
|||||||
#define ALLOCM_ERR_OOM 1
|
#define ALLOCM_ERR_OOM 1
|
||||||
#define ALLOCM_ERR_NOT_MOVED 2
|
#define ALLOCM_ERR_NOT_MOVED 2
|
||||||
|
|
||||||
extern const char *JEMALLOC_P(malloc_options);
|
extern const char *JEMALLOC_P(malloc_conf);
|
||||||
extern void (*JEMALLOC_P(malloc_message))(void *, const char *);
|
extern void (*JEMALLOC_P(malloc_message))(void *, const char *);
|
||||||
|
|
||||||
void *JEMALLOC_P(malloc)(size_t size) JEMALLOC_ATTR(malloc);
|
void *JEMALLOC_P(malloc)(size_t size) JEMALLOC_ATTR(malloc);
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
* the API prefixing.
|
* the API prefixing.
|
||||||
*/
|
*/
|
||||||
#undef JEMALLOC_PREFIX
|
#undef JEMALLOC_PREFIX
|
||||||
|
#undef JEMALLOC_CPREFIX
|
||||||
#if (defined(JEMALLOC_PREFIX) && defined(JEMALLOC_MANGLE))
|
#if (defined(JEMALLOC_PREFIX) && defined(JEMALLOC_MANGLE))
|
||||||
#undef JEMALLOC_P
|
#undef JEMALLOC_P
|
||||||
#endif
|
#endif
|
||||||
|
@ -290,7 +290,7 @@ arena_run_reg_dalloc(arena_run_t *run, void *ptr)
|
|||||||
assert((uintptr_t)ptr >= (uintptr_t)run +
|
assert((uintptr_t)ptr >= (uintptr_t)run +
|
||||||
(uintptr_t)run->bin->reg0_offset);
|
(uintptr_t)run->bin->reg0_offset);
|
||||||
/*
|
/*
|
||||||
* Freeing a pointer in the run's wilderness can cause assertion
|
* Freeing a pointer past in the run's frontier can cause assertion
|
||||||
* failure.
|
* failure.
|
||||||
*/
|
*/
|
||||||
assert((uintptr_t)ptr < (uintptr_t)run->next);
|
assert((uintptr_t)ptr < (uintptr_t)run->next);
|
||||||
@ -2532,7 +2532,7 @@ arena_boot(void)
|
|||||||
if (nbins > 255) {
|
if (nbins > 255) {
|
||||||
char line_buf[UMAX2S_BUFSIZE];
|
char line_buf[UMAX2S_BUFSIZE];
|
||||||
malloc_write("<jemalloc>: Too many small size classes (");
|
malloc_write("<jemalloc>: Too many small size classes (");
|
||||||
malloc_write(umax2s(nbins, 10, line_buf));
|
malloc_write(u2s(nbins, 10, line_buf));
|
||||||
malloc_write(" > max 255)\n");
|
malloc_write(" > max 255)\n");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
@ -2541,7 +2541,7 @@ arena_boot(void)
|
|||||||
if (nbins > 256) {
|
if (nbins > 256) {
|
||||||
char line_buf[UMAX2S_BUFSIZE];
|
char line_buf[UMAX2S_BUFSIZE];
|
||||||
malloc_write("<jemalloc>: Too many small size classes (");
|
malloc_write("<jemalloc>: Too many small size classes (");
|
||||||
malloc_write(umax2s(nbins, 10, line_buf));
|
malloc_write(u2s(nbins, 10, line_buf));
|
||||||
malloc_write(" > max 256)\n");
|
malloc_write(" > max 256)\n");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ RETURN:
|
|||||||
#if (defined(JEMALLOC_STATS) || defined(JEMALLOC_PROF))
|
#if (defined(JEMALLOC_STATS) || defined(JEMALLOC_PROF))
|
||||||
if (ret != NULL) {
|
if (ret != NULL) {
|
||||||
# ifdef JEMALLOC_PROF
|
# ifdef JEMALLOC_PROF
|
||||||
bool udump;
|
bool gdump;
|
||||||
# endif
|
# endif
|
||||||
malloc_mutex_lock(&chunks_mtx);
|
malloc_mutex_lock(&chunks_mtx);
|
||||||
# ifdef JEMALLOC_STATS
|
# ifdef JEMALLOC_STATS
|
||||||
@ -88,17 +88,17 @@ RETURN:
|
|||||||
if (stats_chunks.curchunks > stats_chunks.highchunks) {
|
if (stats_chunks.curchunks > stats_chunks.highchunks) {
|
||||||
stats_chunks.highchunks = stats_chunks.curchunks;
|
stats_chunks.highchunks = stats_chunks.curchunks;
|
||||||
# ifdef JEMALLOC_PROF
|
# ifdef JEMALLOC_PROF
|
||||||
udump = true;
|
gdump = true;
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
# ifdef JEMALLOC_PROF
|
# ifdef JEMALLOC_PROF
|
||||||
else
|
else
|
||||||
udump = false;
|
gdump = false;
|
||||||
# endif
|
# endif
|
||||||
malloc_mutex_unlock(&chunks_mtx);
|
malloc_mutex_unlock(&chunks_mtx);
|
||||||
# ifdef JEMALLOC_PROF
|
# ifdef JEMALLOC_PROF
|
||||||
if (opt_prof && opt_prof_udump && udump)
|
if (opt_prof && opt_prof_gdump && gdump)
|
||||||
prof_udump();
|
prof_gdump();
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -62,8 +62,15 @@ CTL_PROTO(config_tiny)
|
|||||||
CTL_PROTO(config_tls)
|
CTL_PROTO(config_tls)
|
||||||
CTL_PROTO(config_xmalloc)
|
CTL_PROTO(config_xmalloc)
|
||||||
CTL_PROTO(opt_abort)
|
CTL_PROTO(opt_abort)
|
||||||
|
CTL_PROTO(opt_lg_qspace_max)
|
||||||
|
CTL_PROTO(opt_lg_cspace_max)
|
||||||
|
CTL_PROTO(opt_lg_chunk)
|
||||||
|
CTL_PROTO(opt_narenas)
|
||||||
|
CTL_PROTO(opt_lg_dirty_mult)
|
||||||
|
CTL_PROTO(opt_stats_print)
|
||||||
#ifdef JEMALLOC_FILL
|
#ifdef JEMALLOC_FILL
|
||||||
CTL_PROTO(opt_junk)
|
CTL_PROTO(opt_junk)
|
||||||
|
CTL_PROTO(opt_zero)
|
||||||
#endif
|
#endif
|
||||||
#ifdef JEMALLOC_SYSV
|
#ifdef JEMALLOC_SYSV
|
||||||
CTL_PROTO(opt_sysv)
|
CTL_PROTO(opt_sysv)
|
||||||
@ -71,29 +78,22 @@ CTL_PROTO(opt_sysv)
|
|||||||
#ifdef JEMALLOC_XMALLOC
|
#ifdef JEMALLOC_XMALLOC
|
||||||
CTL_PROTO(opt_xmalloc)
|
CTL_PROTO(opt_xmalloc)
|
||||||
#endif
|
#endif
|
||||||
#ifdef JEMALLOC_ZERO
|
|
||||||
CTL_PROTO(opt_zero)
|
|
||||||
#endif
|
|
||||||
#ifdef JEMALLOC_TCACHE
|
#ifdef JEMALLOC_TCACHE
|
||||||
CTL_PROTO(opt_tcache)
|
CTL_PROTO(opt_tcache)
|
||||||
CTL_PROTO(opt_lg_tcache_gc_sweep)
|
CTL_PROTO(opt_lg_tcache_gc_sweep)
|
||||||
#endif
|
#endif
|
||||||
#ifdef JEMALLOC_PROF
|
#ifdef JEMALLOC_PROF
|
||||||
CTL_PROTO(opt_prof)
|
CTL_PROTO(opt_prof)
|
||||||
|
CTL_PROTO(opt_prof_prefix)
|
||||||
CTL_PROTO(opt_prof_active)
|
CTL_PROTO(opt_prof_active)
|
||||||
CTL_PROTO(opt_lg_prof_bt_max)
|
CTL_PROTO(opt_lg_prof_bt_max)
|
||||||
CTL_PROTO(opt_lg_prof_sample)
|
CTL_PROTO(opt_lg_prof_sample)
|
||||||
CTL_PROTO(opt_lg_prof_interval)
|
CTL_PROTO(opt_lg_prof_interval)
|
||||||
CTL_PROTO(opt_prof_udump)
|
CTL_PROTO(opt_prof_gdump)
|
||||||
CTL_PROTO(opt_prof_leak)
|
CTL_PROTO(opt_prof_leak)
|
||||||
CTL_PROTO(opt_prof_accum)
|
CTL_PROTO(opt_prof_accum)
|
||||||
CTL_PROTO(opt_lg_prof_tcmax)
|
CTL_PROTO(opt_lg_prof_tcmax)
|
||||||
#endif
|
#endif
|
||||||
CTL_PROTO(opt_stats_print)
|
|
||||||
CTL_PROTO(opt_lg_qspace_max)
|
|
||||||
CTL_PROTO(opt_lg_cspace_max)
|
|
||||||
CTL_PROTO(opt_lg_dirty_mult)
|
|
||||||
CTL_PROTO(opt_lg_chunk)
|
|
||||||
#ifdef JEMALLOC_SWAP
|
#ifdef JEMALLOC_SWAP
|
||||||
CTL_PROTO(opt_overcommit)
|
CTL_PROTO(opt_overcommit)
|
||||||
#endif
|
#endif
|
||||||
@ -247,38 +247,43 @@ static const ctl_node_t config_node[] = {
|
|||||||
|
|
||||||
static const ctl_node_t opt_node[] = {
|
static const ctl_node_t opt_node[] = {
|
||||||
{NAME("abort"), CTL(opt_abort)},
|
{NAME("abort"), CTL(opt_abort)},
|
||||||
|
{NAME("lg_qspace_max"), CTL(opt_lg_qspace_max)},
|
||||||
|
{NAME("lg_cspace_max"), CTL(opt_lg_cspace_max)},
|
||||||
|
{NAME("lg_chunk"), CTL(opt_lg_chunk)},
|
||||||
|
{NAME("narenas"), CTL(opt_narenas)},
|
||||||
|
{NAME("lg_dirty_mult"), CTL(opt_lg_dirty_mult)},
|
||||||
|
{NAME("stats_print"), CTL(opt_stats_print)}
|
||||||
#ifdef JEMALLOC_FILL
|
#ifdef JEMALLOC_FILL
|
||||||
|
,
|
||||||
{NAME("junk"), CTL(opt_junk)},
|
{NAME("junk"), CTL(opt_junk)},
|
||||||
|
{NAME("zero"), CTL(opt_zero)}
|
||||||
#endif
|
#endif
|
||||||
#ifdef JEMALLOC_SYSV
|
#ifdef JEMALLOC_SYSV
|
||||||
{NAME("sysv"), CTL(opt_sysv)},
|
,
|
||||||
|
{NAME("sysv"), CTL(opt_sysv)}
|
||||||
#endif
|
#endif
|
||||||
#ifdef JEMALLOC_XMALLOC
|
#ifdef JEMALLOC_XMALLOC
|
||||||
{NAME("xmalloc"), CTL(opt_xmalloc)},
|
,
|
||||||
#endif
|
{NAME("xmalloc"), CTL(opt_xmalloc)}
|
||||||
#ifdef JEMALLOC_ZERO
|
|
||||||
{NAME("zero"), CTL(opt_zero)},
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef JEMALLOC_TCACHE
|
#ifdef JEMALLOC_TCACHE
|
||||||
|
,
|
||||||
{NAME("tcache"), CTL(opt_tcache)},
|
{NAME("tcache"), CTL(opt_tcache)},
|
||||||
{NAME("lg_tcache_gc_sweep"), CTL(opt_lg_tcache_gc_sweep)},
|
{NAME("lg_tcache_gc_sweep"), CTL(opt_lg_tcache_gc_sweep)}
|
||||||
#endif
|
#endif
|
||||||
#ifdef JEMALLOC_PROF
|
#ifdef JEMALLOC_PROF
|
||||||
|
,
|
||||||
{NAME("prof"), CTL(opt_prof)},
|
{NAME("prof"), CTL(opt_prof)},
|
||||||
|
{NAME("prof_prefix"), CTL(opt_prof_prefix)},
|
||||||
{NAME("prof_active"), CTL(opt_prof_active)},
|
{NAME("prof_active"), CTL(opt_prof_active)},
|
||||||
{NAME("lg_prof_bt_max"), CTL(opt_lg_prof_bt_max)},
|
{NAME("lg_prof_bt_max"), CTL(opt_lg_prof_bt_max)},
|
||||||
{NAME("lg_prof_sample"), CTL(opt_lg_prof_sample)},
|
{NAME("lg_prof_sample"), CTL(opt_lg_prof_sample)},
|
||||||
{NAME("lg_prof_interval"), CTL(opt_lg_prof_interval)},
|
{NAME("lg_prof_interval"), CTL(opt_lg_prof_interval)},
|
||||||
{NAME("prof_udump"), CTL(opt_prof_udump)},
|
{NAME("prof_gdump"), CTL(opt_prof_gdump)},
|
||||||
{NAME("prof_leak"), CTL(opt_prof_leak)},
|
{NAME("prof_leak"), CTL(opt_prof_leak)},
|
||||||
{NAME("prof_accum"), CTL(opt_prof_accum)},
|
{NAME("prof_accum"), CTL(opt_prof_accum)},
|
||||||
{NAME("lg_prof_tcmax"), CTL(opt_lg_prof_tcmax)},
|
{NAME("lg_prof_tcmax"), CTL(opt_lg_prof_tcmax)}
|
||||||
#endif
|
#endif
|
||||||
{NAME("stats_print"), CTL(opt_stats_print)},
|
|
||||||
{NAME("lg_qspace_max"), CTL(opt_lg_qspace_max)},
|
|
||||||
{NAME("lg_cspace_max"), CTL(opt_lg_cspace_max)},
|
|
||||||
{NAME("lg_dirty_mult"), CTL(opt_lg_dirty_mult)},
|
|
||||||
{NAME("lg_chunk"), CTL(opt_lg_chunk)}
|
|
||||||
#ifdef JEMALLOC_SWAP
|
#ifdef JEMALLOC_SWAP
|
||||||
,
|
,
|
||||||
{NAME("overcommit"), CTL(opt_overcommit)}
|
{NAME("overcommit"), CTL(opt_overcommit)}
|
||||||
@ -1201,8 +1206,15 @@ CTL_RO_FALSE_GEN(config_xmalloc)
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
CTL_RO_GEN(opt_abort, opt_abort, bool)
|
CTL_RO_GEN(opt_abort, opt_abort, bool)
|
||||||
|
CTL_RO_GEN(opt_lg_qspace_max, opt_lg_qspace_max, size_t)
|
||||||
|
CTL_RO_GEN(opt_lg_cspace_max, opt_lg_cspace_max, size_t)
|
||||||
|
CTL_RO_GEN(opt_lg_chunk, opt_lg_chunk, size_t)
|
||||||
|
CTL_RO_GEN(opt_narenas, opt_narenas, size_t)
|
||||||
|
CTL_RO_GEN(opt_lg_dirty_mult, opt_lg_dirty_mult, ssize_t)
|
||||||
|
CTL_RO_GEN(opt_stats_print, opt_stats_print, bool)
|
||||||
#ifdef JEMALLOC_FILL
|
#ifdef JEMALLOC_FILL
|
||||||
CTL_RO_GEN(opt_junk, opt_junk, bool)
|
CTL_RO_GEN(opt_junk, opt_junk, bool)
|
||||||
|
CTL_RO_GEN(opt_zero, opt_zero, bool)
|
||||||
#endif
|
#endif
|
||||||
#ifdef JEMALLOC_SYSV
|
#ifdef JEMALLOC_SYSV
|
||||||
CTL_RO_GEN(opt_sysv, opt_sysv, bool)
|
CTL_RO_GEN(opt_sysv, opt_sysv, bool)
|
||||||
@ -1210,29 +1222,22 @@ CTL_RO_GEN(opt_sysv, opt_sysv, bool)
|
|||||||
#ifdef JEMALLOC_XMALLOC
|
#ifdef JEMALLOC_XMALLOC
|
||||||
CTL_RO_GEN(opt_xmalloc, opt_xmalloc, bool)
|
CTL_RO_GEN(opt_xmalloc, opt_xmalloc, bool)
|
||||||
#endif
|
#endif
|
||||||
#ifdef JEMALLOC_ZERO
|
|
||||||
CTL_RO_GEN(opt_zero, opt_zero, bool)
|
|
||||||
#endif
|
|
||||||
#ifdef JEMALLOC_TCACHE
|
#ifdef JEMALLOC_TCACHE
|
||||||
CTL_RO_GEN(opt_tcache, opt_tcache, bool)
|
CTL_RO_GEN(opt_tcache, opt_tcache, bool)
|
||||||
CTL_RO_GEN(opt_lg_tcache_gc_sweep, opt_lg_tcache_gc_sweep, ssize_t)
|
CTL_RO_GEN(opt_lg_tcache_gc_sweep, opt_lg_tcache_gc_sweep, ssize_t)
|
||||||
#endif
|
#endif
|
||||||
#ifdef JEMALLOC_PROF
|
#ifdef JEMALLOC_PROF
|
||||||
CTL_RO_GEN(opt_prof, opt_prof, bool)
|
CTL_RO_GEN(opt_prof, opt_prof, bool)
|
||||||
|
CTL_RO_GEN(opt_prof_prefix, opt_prof_prefix, const char *)
|
||||||
CTL_RO_GEN(opt_prof_active, opt_prof_active, bool)
|
CTL_RO_GEN(opt_prof_active, opt_prof_active, bool)
|
||||||
CTL_RO_GEN(opt_lg_prof_bt_max, opt_lg_prof_bt_max, size_t)
|
CTL_RO_GEN(opt_lg_prof_bt_max, opt_lg_prof_bt_max, size_t)
|
||||||
CTL_RO_GEN(opt_lg_prof_sample, opt_lg_prof_sample, size_t)
|
CTL_RO_GEN(opt_lg_prof_sample, opt_lg_prof_sample, size_t)
|
||||||
CTL_RO_GEN(opt_lg_prof_interval, opt_lg_prof_interval, ssize_t)
|
CTL_RO_GEN(opt_lg_prof_interval, opt_lg_prof_interval, ssize_t)
|
||||||
CTL_RO_GEN(opt_prof_udump, opt_prof_udump, bool)
|
CTL_RO_GEN(opt_prof_gdump, opt_prof_gdump, bool)
|
||||||
CTL_RO_GEN(opt_prof_leak, opt_prof_leak, bool)
|
CTL_RO_GEN(opt_prof_leak, opt_prof_leak, bool)
|
||||||
CTL_RO_GEN(opt_prof_accum, opt_prof_accum, bool)
|
CTL_RO_GEN(opt_prof_accum, opt_prof_accum, bool)
|
||||||
CTL_RO_GEN(opt_lg_prof_tcmax, opt_lg_prof_tcmax, ssize_t)
|
CTL_RO_GEN(opt_lg_prof_tcmax, opt_lg_prof_tcmax, ssize_t)
|
||||||
#endif
|
#endif
|
||||||
CTL_RO_GEN(opt_stats_print, opt_stats_print, bool)
|
|
||||||
CTL_RO_GEN(opt_lg_qspace_max, opt_lg_qspace_max, size_t)
|
|
||||||
CTL_RO_GEN(opt_lg_cspace_max, opt_lg_cspace_max, size_t)
|
|
||||||
CTL_RO_GEN(opt_lg_dirty_mult, opt_lg_dirty_mult, ssize_t)
|
|
||||||
CTL_RO_GEN(opt_lg_chunk, opt_lg_chunk, size_t)
|
|
||||||
#ifdef JEMALLOC_SWAP
|
#ifdef JEMALLOC_SWAP
|
||||||
CTL_RO_GEN(opt_overcommit, opt_overcommit, bool)
|
CTL_RO_GEN(opt_overcommit, opt_overcommit, bool)
|
||||||
#endif
|
#endif
|
||||||
|
@ -41,8 +41,7 @@ size_t lg_pagesize;
|
|||||||
unsigned ncpus;
|
unsigned ncpus;
|
||||||
|
|
||||||
/* Runtime configuration options. */
|
/* Runtime configuration options. */
|
||||||
const char *JEMALLOC_P(malloc_options)
|
const char *JEMALLOC_P(malloc_conf) JEMALLOC_ATTR(visibility("default"));
|
||||||
JEMALLOC_ATTR(visibility("default"));
|
|
||||||
#ifdef JEMALLOC_DEBUG
|
#ifdef JEMALLOC_DEBUG
|
||||||
bool opt_abort = true;
|
bool opt_abort = true;
|
||||||
# ifdef JEMALLOC_FILL
|
# ifdef JEMALLOC_FILL
|
||||||
@ -63,7 +62,7 @@ bool opt_xmalloc = false;
|
|||||||
#ifdef JEMALLOC_FILL
|
#ifdef JEMALLOC_FILL
|
||||||
bool opt_zero = false;
|
bool opt_zero = false;
|
||||||
#endif
|
#endif
|
||||||
static int opt_narenas_lshift = 0;
|
size_t opt_narenas = 0;
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/* Function prototypes for non-inline static functions. */
|
/* Function prototypes for non-inline static functions. */
|
||||||
@ -74,6 +73,11 @@ static unsigned malloc_ncpus(void);
|
|||||||
#if (defined(JEMALLOC_STATS) && defined(NO_TLS))
|
#if (defined(JEMALLOC_STATS) && defined(NO_TLS))
|
||||||
static void thread_allocated_cleanup(void *arg);
|
static void thread_allocated_cleanup(void *arg);
|
||||||
#endif
|
#endif
|
||||||
|
static bool malloc_conf_next(char const **opts_p, char const **k_p,
|
||||||
|
size_t *klen_p, char const **v_p, size_t *vlen_p);
|
||||||
|
static void malloc_conf_error(const char *msg, const char *k, size_t klen,
|
||||||
|
const char *v, size_t vlen);
|
||||||
|
static void malloc_conf_init(void);
|
||||||
static bool malloc_init_hard(void);
|
static bool malloc_init_hard(void);
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
@ -260,12 +264,323 @@ malloc_init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
malloc_init_hard(void)
|
malloc_conf_next(char const **opts_p, char const **k_p, size_t *klen_p,
|
||||||
|
char const **v_p, size_t *vlen_p)
|
||||||
|
{
|
||||||
|
bool accept;
|
||||||
|
const char *opts = *opts_p;
|
||||||
|
|
||||||
|
*k_p = opts;
|
||||||
|
|
||||||
|
for (accept = false; accept == false;) {
|
||||||
|
switch (*opts) {
|
||||||
|
case 'A': case 'B': case 'C': case 'D': case 'E':
|
||||||
|
case 'F': case 'G': case 'H': case 'I': case 'J':
|
||||||
|
case 'K': case 'L': case 'M': case 'N': case 'O':
|
||||||
|
case 'P': case 'Q': case 'R': case 'S': case 'T':
|
||||||
|
case 'U': case 'V': case 'W': case 'X': case 'Y':
|
||||||
|
case 'Z':
|
||||||
|
case 'a': case 'b': case 'c': case 'd': case 'e':
|
||||||
|
case 'f': case 'g': case 'h': case 'i': case 'j':
|
||||||
|
case 'k': case 'l': case 'm': case 'n': case 'o':
|
||||||
|
case 'p': case 'q': case 'r': case 's': case 't':
|
||||||
|
case 'u': case 'v': case 'w': case 'x': case 'y':
|
||||||
|
case 'z':
|
||||||
|
case '0': case '1': case '2': case '3': case '4':
|
||||||
|
case '5': case '6': case '7': case '8': case '9':
|
||||||
|
case '_':
|
||||||
|
opts++;
|
||||||
|
break;
|
||||||
|
case ':':
|
||||||
|
opts++;
|
||||||
|
*klen_p = (uintptr_t)opts - 1 - (uintptr_t)*k_p;
|
||||||
|
*v_p = opts;
|
||||||
|
accept = true;
|
||||||
|
break;
|
||||||
|
case '\0':
|
||||||
|
if (opts != *opts_p) {
|
||||||
|
malloc_write("<jemalloc>: Conf string "
|
||||||
|
"ends with key\n");
|
||||||
|
}
|
||||||
|
return (true);
|
||||||
|
default:
|
||||||
|
malloc_write("<jemalloc>: Malformed conf "
|
||||||
|
"string\n");
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (accept = false; accept == false;) {
|
||||||
|
switch (*opts) {
|
||||||
|
case ',':
|
||||||
|
opts++;
|
||||||
|
/*
|
||||||
|
* Look ahead one character here, because the
|
||||||
|
* next time this function is called, it will
|
||||||
|
* assume that end of input has been cleanly
|
||||||
|
* reached if no input remains, but we have
|
||||||
|
* optimistically already consumed the comma if
|
||||||
|
* one exists.
|
||||||
|
*/
|
||||||
|
if (*opts == '\0') {
|
||||||
|
malloc_write("<jemalloc>: Conf string "
|
||||||
|
"ends with comma\n");
|
||||||
|
}
|
||||||
|
*vlen_p = (uintptr_t)opts - 1 - (uintptr_t)*v_p;
|
||||||
|
accept = true;
|
||||||
|
break;
|
||||||
|
case '\0':
|
||||||
|
*vlen_p = (uintptr_t)opts - (uintptr_t)*v_p;
|
||||||
|
accept = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
opts++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*opts_p = opts;
|
||||||
|
return (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
malloc_conf_error(const char *msg, const char *k, size_t klen, const char *v,
|
||||||
|
size_t vlen)
|
||||||
|
{
|
||||||
|
char buf[PATH_MAX + 1];
|
||||||
|
|
||||||
|
malloc_write("<jemalloc>: ");
|
||||||
|
malloc_write(msg);
|
||||||
|
malloc_write(": ");
|
||||||
|
memcpy(buf, k, klen);
|
||||||
|
memcpy(&buf[klen], ":", 1);
|
||||||
|
memcpy(&buf[klen+1], v, vlen);
|
||||||
|
buf[klen+1+vlen] = '\0';
|
||||||
|
malloc_write(buf);
|
||||||
|
malloc_write("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
malloc_conf_init(void)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
int linklen;
|
|
||||||
char buf[PATH_MAX + 1];
|
char buf[PATH_MAX + 1];
|
||||||
const char *opts;
|
const char *opts, *k, *v;
|
||||||
|
size_t klen, vlen;
|
||||||
|
|
||||||
|
for (i = 0; i < 3; i++) {
|
||||||
|
/* Get runtime configuration. */
|
||||||
|
switch (i) {
|
||||||
|
case 0:
|
||||||
|
if (JEMALLOC_P(malloc_conf) != NULL) {
|
||||||
|
/*
|
||||||
|
* Use options that were compiled into the
|
||||||
|
* program.
|
||||||
|
*/
|
||||||
|
opts = JEMALLOC_P(malloc_conf);
|
||||||
|
} else {
|
||||||
|
/* No configuration specified. */
|
||||||
|
buf[0] = '\0';
|
||||||
|
opts = buf;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1: {
|
||||||
|
int linklen;
|
||||||
|
const char *linkname =
|
||||||
|
#ifdef JEMALLOC_PREFIX
|
||||||
|
"/etc/"JEMALLOC_PREFIX"malloc.conf"
|
||||||
|
#else
|
||||||
|
"/etc/malloc.conf"
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
|
||||||
|
if ((linklen = readlink(linkname, buf,
|
||||||
|
sizeof(buf) - 1)) != -1) {
|
||||||
|
/*
|
||||||
|
* Use the contents of the "/etc/malloc.conf"
|
||||||
|
* symbolic link's name.
|
||||||
|
*/
|
||||||
|
buf[linklen] = '\0';
|
||||||
|
opts = buf;
|
||||||
|
} else {
|
||||||
|
/* No configuration specified. */
|
||||||
|
buf[0] = '\0';
|
||||||
|
opts = buf;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2: {
|
||||||
|
const char *envname =
|
||||||
|
#ifdef JEMALLOC_PREFIX
|
||||||
|
JEMALLOC_CPREFIX"MALLOC_CONF"
|
||||||
|
#else
|
||||||
|
"MALLOC_CONF"
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
|
||||||
|
if ((opts = getenv(envname)) != NULL) {
|
||||||
|
/*
|
||||||
|
* Do nothing; opts is already initialized to
|
||||||
|
* the value of the JEMALLOC_OPTIONS
|
||||||
|
* environment variable.
|
||||||
|
*/
|
||||||
|
} else {
|
||||||
|
/* No configuration specified. */
|
||||||
|
buf[0] = '\0';
|
||||||
|
opts = buf;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
/* NOTREACHED */
|
||||||
|
assert(false);
|
||||||
|
buf[0] = '\0';
|
||||||
|
opts = buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*opts != '\0' && malloc_conf_next(&opts, &k, &klen, &v,
|
||||||
|
&vlen) == false) {
|
||||||
|
#define CONF_HANDLE_BOOL(n) \
|
||||||
|
if (sizeof(#n)-1 == klen && strncmp(#n, k, \
|
||||||
|
klen) == 0) { \
|
||||||
|
if (strncmp("true", v, vlen) == 0 && \
|
||||||
|
vlen == sizeof("true")-1) \
|
||||||
|
opt_##n = true; \
|
||||||
|
else if (strncmp("false", v, vlen) == \
|
||||||
|
0 && vlen == sizeof("false")-1) \
|
||||||
|
opt_##n = false; \
|
||||||
|
else { \
|
||||||
|
malloc_conf_error( \
|
||||||
|
"Invalid conf value", \
|
||||||
|
k, klen, v, vlen); \
|
||||||
|
} \
|
||||||
|
continue; \
|
||||||
|
}
|
||||||
|
#define CONF_HANDLE_SIZE_T(n, min, max) \
|
||||||
|
if (sizeof(#n)-1 == klen && strncmp(#n, k, \
|
||||||
|
klen) == 0) { \
|
||||||
|
unsigned long ul; \
|
||||||
|
char *end; \
|
||||||
|
\
|
||||||
|
errno = 0; \
|
||||||
|
ul = strtoul(v, &end, 0); \
|
||||||
|
if (errno != 0 || (uintptr_t)end - \
|
||||||
|
(uintptr_t)v != vlen) { \
|
||||||
|
malloc_conf_error( \
|
||||||
|
"Invalid conf value", \
|
||||||
|
k, klen, v, vlen); \
|
||||||
|
} else if (ul < min || ul > max) { \
|
||||||
|
malloc_conf_error( \
|
||||||
|
"Out-of-range conf value", \
|
||||||
|
k, klen, v, vlen); \
|
||||||
|
} else \
|
||||||
|
opt_##n = ul; \
|
||||||
|
continue; \
|
||||||
|
}
|
||||||
|
#define CONF_HANDLE_SSIZE_T(n, min, max) \
|
||||||
|
if (sizeof(#n)-1 == klen && strncmp(#n, k, \
|
||||||
|
klen) == 0) { \
|
||||||
|
long l; \
|
||||||
|
char *end; \
|
||||||
|
\
|
||||||
|
errno = 0; \
|
||||||
|
l = strtol(v, &end, 0); \
|
||||||
|
if (errno != 0 || (uintptr_t)end - \
|
||||||
|
(uintptr_t)v != vlen) { \
|
||||||
|
malloc_conf_error( \
|
||||||
|
"Invalid conf value", \
|
||||||
|
k, klen, v, vlen); \
|
||||||
|
} else if (l < (ssize_t)min || l > \
|
||||||
|
(ssize_t)max) { \
|
||||||
|
malloc_conf_error( \
|
||||||
|
"Out-of-range conf value", \
|
||||||
|
k, klen, v, vlen); \
|
||||||
|
} else \
|
||||||
|
opt_##n = l; \
|
||||||
|
continue; \
|
||||||
|
}
|
||||||
|
#define CONF_HANDLE_CHAR_P(n, d) \
|
||||||
|
if (sizeof(#n)-1 == klen && strncmp(#n, k, \
|
||||||
|
klen) == 0) { \
|
||||||
|
size_t cpylen = (vlen <= \
|
||||||
|
sizeof(opt_##n)-1) ? vlen : \
|
||||||
|
sizeof(opt_##n)-1; \
|
||||||
|
strncpy(opt_##n, v, cpylen); \
|
||||||
|
opt_##n[cpylen] = '\0'; \
|
||||||
|
continue; \
|
||||||
|
}
|
||||||
|
|
||||||
|
CONF_HANDLE_BOOL(abort)
|
||||||
|
CONF_HANDLE_SIZE_T(lg_qspace_max, LG_QUANTUM,
|
||||||
|
PAGE_SHIFT-1)
|
||||||
|
CONF_HANDLE_SIZE_T(lg_cspace_max, LG_QUANTUM,
|
||||||
|
PAGE_SHIFT-1)
|
||||||
|
/*
|
||||||
|
* Chunks always require at least one * header page,
|
||||||
|
* plus one data page.
|
||||||
|
*/
|
||||||
|
CONF_HANDLE_SIZE_T(lg_chunk, PAGE_SHIFT+1,
|
||||||
|
(sizeof(size_t) << 3) - 1)
|
||||||
|
CONF_HANDLE_SIZE_T(narenas, 1, SIZE_T_MAX)
|
||||||
|
CONF_HANDLE_SSIZE_T(lg_dirty_mult, -1,
|
||||||
|
(sizeof(size_t) << 3) - 1)
|
||||||
|
CONF_HANDLE_BOOL(stats_print)
|
||||||
|
#ifdef JEMALLOC_FILL
|
||||||
|
CONF_HANDLE_BOOL(junk)
|
||||||
|
CONF_HANDLE_BOOL(zero)
|
||||||
|
#endif
|
||||||
|
#ifdef JEMALLOC_SYSV
|
||||||
|
CONF_HANDLE_BOOL(sysv)
|
||||||
|
#endif
|
||||||
|
#ifdef JEMALLOC_XMALLOC
|
||||||
|
CONF_HANDLE_BOOL(xmalloc)
|
||||||
|
#endif
|
||||||
|
#ifdef JEMALLOC_TCACHE
|
||||||
|
CONF_HANDLE_BOOL(tcache)
|
||||||
|
CONF_HANDLE_SSIZE_T(lg_tcache_gc_sweep, -1,
|
||||||
|
(sizeof(size_t) << 3) - 1)
|
||||||
|
CONF_HANDLE_SSIZE_T(lg_tcache_max, -1,
|
||||||
|
(sizeof(size_t) << 3) - 1)
|
||||||
|
#endif
|
||||||
|
#ifdef JEMALLOC_PROF
|
||||||
|
CONF_HANDLE_BOOL(prof)
|
||||||
|
CONF_HANDLE_CHAR_P(prof_prefix, "jeprof")
|
||||||
|
CONF_HANDLE_SIZE_T(lg_prof_bt_max, 0, LG_PROF_BT_MAX)
|
||||||
|
CONF_HANDLE_BOOL(prof_active)
|
||||||
|
CONF_HANDLE_SSIZE_T(lg_prof_sample, 0,
|
||||||
|
(sizeof(uint64_t) << 3) - 1)
|
||||||
|
CONF_HANDLE_BOOL(prof_accum)
|
||||||
|
CONF_HANDLE_SSIZE_T(lg_prof_tcmax, -1,
|
||||||
|
(sizeof(size_t) << 3) - 1)
|
||||||
|
CONF_HANDLE_SSIZE_T(lg_prof_interval, -1,
|
||||||
|
(sizeof(uint64_t) << 3) - 1)
|
||||||
|
CONF_HANDLE_BOOL(prof_gdump)
|
||||||
|
CONF_HANDLE_BOOL(prof_leak)
|
||||||
|
#endif
|
||||||
|
#ifdef JEMALLOC_SWAP
|
||||||
|
CONF_HANDLE_BOOL(overcommit)
|
||||||
|
#endif
|
||||||
|
malloc_conf_error("Invalid conf pair", k, klen, v,
|
||||||
|
vlen);
|
||||||
|
#undef CONF_HANDLE_BOOL
|
||||||
|
#undef CONF_HANDLE_SIZE_T
|
||||||
|
#undef CONF_HANDLE_SSIZE_T
|
||||||
|
#undef CONF_HANDLE_CHAR_P
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Validate configuration of options that are inter-related. */
|
||||||
|
if (opt_lg_qspace_max+1 >= opt_lg_cspace_max) {
|
||||||
|
malloc_write("<jemalloc>: Invalid lg_[qc]space_max "
|
||||||
|
"relationship; restoring defaults\n");
|
||||||
|
opt_lg_qspace_max = LG_QSPACE_MAX_DEFAULT;
|
||||||
|
opt_lg_cspace_max = LG_CSPACE_MAX_DEFAULT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
malloc_init_hard(void)
|
||||||
|
{
|
||||||
arena_t *init_arenas[1];
|
arena_t *init_arenas[1];
|
||||||
|
|
||||||
malloc_mutex_lock(&init_lock);
|
malloc_mutex_lock(&init_lock);
|
||||||
@ -308,302 +623,9 @@ malloc_init_hard(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < 3; i++) {
|
prof_boot0();
|
||||||
unsigned j;
|
|
||||||
|
|
||||||
/* Get runtime configuration. */
|
malloc_conf_init();
|
||||||
switch (i) {
|
|
||||||
case 0:
|
|
||||||
if ((linklen = readlink("/etc/jemalloc.conf", buf,
|
|
||||||
sizeof(buf) - 1)) != -1) {
|
|
||||||
/*
|
|
||||||
* Use the contents of the "/etc/jemalloc.conf"
|
|
||||||
* symbolic link's name.
|
|
||||||
*/
|
|
||||||
buf[linklen] = '\0';
|
|
||||||
opts = buf;
|
|
||||||
} else {
|
|
||||||
/* No configuration specified. */
|
|
||||||
buf[0] = '\0';
|
|
||||||
opts = buf;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
if ((opts = getenv("JEMALLOC_OPTIONS")) != NULL) {
|
|
||||||
/*
|
|
||||||
* Do nothing; opts is already initialized to
|
|
||||||
* the value of the JEMALLOC_OPTIONS
|
|
||||||
* environment variable.
|
|
||||||
*/
|
|
||||||
} else {
|
|
||||||
/* No configuration specified. */
|
|
||||||
buf[0] = '\0';
|
|
||||||
opts = buf;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
if (JEMALLOC_P(malloc_options) != NULL) {
|
|
||||||
/*
|
|
||||||
* Use options that were compiled into the
|
|
||||||
* program.
|
|
||||||
*/
|
|
||||||
opts = JEMALLOC_P(malloc_options);
|
|
||||||
} else {
|
|
||||||
/* No configuration specified. */
|
|
||||||
buf[0] = '\0';
|
|
||||||
opts = buf;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* NOTREACHED */
|
|
||||||
assert(false);
|
|
||||||
buf[0] = '\0';
|
|
||||||
opts = buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (j = 0; opts[j] != '\0'; j++) {
|
|
||||||
unsigned k, nreps;
|
|
||||||
bool nseen;
|
|
||||||
|
|
||||||
/* Parse repetition count, if any. */
|
|
||||||
for (nreps = 0, nseen = false;; j++, nseen = true) {
|
|
||||||
switch (opts[j]) {
|
|
||||||
case '0': case '1': case '2': case '3':
|
|
||||||
case '4': case '5': case '6': case '7':
|
|
||||||
case '8': case '9':
|
|
||||||
nreps *= 10;
|
|
||||||
nreps += opts[j] - '0';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
goto MALLOC_OUT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MALLOC_OUT:
|
|
||||||
if (nseen == false)
|
|
||||||
nreps = 1;
|
|
||||||
|
|
||||||
for (k = 0; k < nreps; k++) {
|
|
||||||
switch (opts[j]) {
|
|
||||||
case 'a':
|
|
||||||
opt_abort = false;
|
|
||||||
break;
|
|
||||||
case 'A':
|
|
||||||
opt_abort = true;
|
|
||||||
break;
|
|
||||||
#ifdef JEMALLOC_PROF
|
|
||||||
case 'b':
|
|
||||||
if (opt_lg_prof_bt_max > 0)
|
|
||||||
opt_lg_prof_bt_max--;
|
|
||||||
break;
|
|
||||||
case 'B':
|
|
||||||
if (opt_lg_prof_bt_max < LG_PROF_BT_MAX)
|
|
||||||
opt_lg_prof_bt_max++;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
case 'c':
|
|
||||||
if (opt_lg_cspace_max - 1 >
|
|
||||||
opt_lg_qspace_max &&
|
|
||||||
opt_lg_cspace_max >
|
|
||||||
LG_CACHELINE)
|
|
||||||
opt_lg_cspace_max--;
|
|
||||||
break;
|
|
||||||
case 'C':
|
|
||||||
if (opt_lg_cspace_max < PAGE_SHIFT
|
|
||||||
- 1)
|
|
||||||
opt_lg_cspace_max++;
|
|
||||||
break;
|
|
||||||
case 'd':
|
|
||||||
if (opt_lg_dirty_mult + 1 <
|
|
||||||
(sizeof(size_t) << 3))
|
|
||||||
opt_lg_dirty_mult++;
|
|
||||||
break;
|
|
||||||
case 'D':
|
|
||||||
if (opt_lg_dirty_mult >= 0)
|
|
||||||
opt_lg_dirty_mult--;
|
|
||||||
break;
|
|
||||||
#ifdef JEMALLOC_PROF
|
|
||||||
case 'e':
|
|
||||||
opt_prof_active = false;
|
|
||||||
break;
|
|
||||||
case 'E':
|
|
||||||
opt_prof_active = true;
|
|
||||||
break;
|
|
||||||
case 'f':
|
|
||||||
opt_prof = false;
|
|
||||||
break;
|
|
||||||
case 'F':
|
|
||||||
opt_prof = true;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#ifdef JEMALLOC_TCACHE
|
|
||||||
case 'g':
|
|
||||||
if (opt_lg_tcache_gc_sweep >= 0)
|
|
||||||
opt_lg_tcache_gc_sweep--;
|
|
||||||
break;
|
|
||||||
case 'G':
|
|
||||||
if (opt_lg_tcache_gc_sweep + 1 <
|
|
||||||
(sizeof(size_t) << 3))
|
|
||||||
opt_lg_tcache_gc_sweep++;
|
|
||||||
break;
|
|
||||||
case 'h':
|
|
||||||
opt_tcache = false;
|
|
||||||
break;
|
|
||||||
case 'H':
|
|
||||||
opt_tcache = true;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#ifdef JEMALLOC_PROF
|
|
||||||
case 'i':
|
|
||||||
if (opt_lg_prof_interval >= 0)
|
|
||||||
opt_lg_prof_interval--;
|
|
||||||
break;
|
|
||||||
case 'I':
|
|
||||||
if (opt_lg_prof_interval + 1 <
|
|
||||||
(sizeof(uint64_t) << 3))
|
|
||||||
opt_lg_prof_interval++;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#ifdef JEMALLOC_FILL
|
|
||||||
case 'j':
|
|
||||||
opt_junk = false;
|
|
||||||
break;
|
|
||||||
case 'J':
|
|
||||||
opt_junk = true;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
case 'k':
|
|
||||||
/*
|
|
||||||
* Chunks always require at least one
|
|
||||||
* header page, plus one data page.
|
|
||||||
*/
|
|
||||||
if ((1U << (opt_lg_chunk - 1)) >=
|
|
||||||
(2U << PAGE_SHIFT))
|
|
||||||
opt_lg_chunk--;
|
|
||||||
break;
|
|
||||||
case 'K':
|
|
||||||
if (opt_lg_chunk + 1 <
|
|
||||||
(sizeof(size_t) << 3))
|
|
||||||
opt_lg_chunk++;
|
|
||||||
break;
|
|
||||||
#ifdef JEMALLOC_PROF
|
|
||||||
case 'l':
|
|
||||||
opt_prof_leak = false;
|
|
||||||
break;
|
|
||||||
case 'L':
|
|
||||||
opt_prof_leak = true;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#ifdef JEMALLOC_TCACHE
|
|
||||||
case 'm':
|
|
||||||
if (opt_lg_tcache_maxclass >= 0)
|
|
||||||
opt_lg_tcache_maxclass--;
|
|
||||||
break;
|
|
||||||
case 'M':
|
|
||||||
if (opt_lg_tcache_maxclass + 1 <
|
|
||||||
(sizeof(size_t) << 3))
|
|
||||||
opt_lg_tcache_maxclass++;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
case 'n':
|
|
||||||
opt_narenas_lshift--;
|
|
||||||
break;
|
|
||||||
case 'N':
|
|
||||||
opt_narenas_lshift++;
|
|
||||||
break;
|
|
||||||
#ifdef JEMALLOC_SWAP
|
|
||||||
case 'o':
|
|
||||||
opt_overcommit = false;
|
|
||||||
break;
|
|
||||||
case 'O':
|
|
||||||
opt_overcommit = true;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
case 'p':
|
|
||||||
opt_stats_print = false;
|
|
||||||
break;
|
|
||||||
case 'P':
|
|
||||||
opt_stats_print = true;
|
|
||||||
break;
|
|
||||||
case 'q':
|
|
||||||
if (opt_lg_qspace_max > LG_QUANTUM)
|
|
||||||
opt_lg_qspace_max--;
|
|
||||||
break;
|
|
||||||
case 'Q':
|
|
||||||
if (opt_lg_qspace_max + 1 <
|
|
||||||
opt_lg_cspace_max)
|
|
||||||
opt_lg_qspace_max++;
|
|
||||||
break;
|
|
||||||
#ifdef JEMALLOC_PROF
|
|
||||||
case 'r':
|
|
||||||
opt_prof_accum = false;
|
|
||||||
break;
|
|
||||||
case 'R':
|
|
||||||
opt_prof_accum = true;
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
if (opt_lg_prof_sample > 0)
|
|
||||||
opt_lg_prof_sample--;
|
|
||||||
break;
|
|
||||||
case 'S':
|
|
||||||
if (opt_lg_prof_sample + 1 <
|
|
||||||
(sizeof(uint64_t) << 3))
|
|
||||||
opt_lg_prof_sample++;
|
|
||||||
break;
|
|
||||||
case 't':
|
|
||||||
if (opt_lg_prof_tcmax >= 0)
|
|
||||||
opt_lg_prof_tcmax--;
|
|
||||||
break;
|
|
||||||
case 'T':
|
|
||||||
if (opt_lg_prof_tcmax + 1 <
|
|
||||||
(sizeof(size_t) << 3))
|
|
||||||
opt_lg_prof_tcmax++;
|
|
||||||
break;
|
|
||||||
case 'u':
|
|
||||||
opt_prof_udump = false;
|
|
||||||
break;
|
|
||||||
case 'U':
|
|
||||||
opt_prof_udump = true;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#ifdef JEMALLOC_SYSV
|
|
||||||
case 'v':
|
|
||||||
opt_sysv = false;
|
|
||||||
break;
|
|
||||||
case 'V':
|
|
||||||
opt_sysv = true;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#ifdef JEMALLOC_XMALLOC
|
|
||||||
case 'x':
|
|
||||||
opt_xmalloc = false;
|
|
||||||
break;
|
|
||||||
case 'X':
|
|
||||||
opt_xmalloc = true;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
#ifdef JEMALLOC_FILL
|
|
||||||
case 'z':
|
|
||||||
opt_zero = false;
|
|
||||||
break;
|
|
||||||
case 'Z':
|
|
||||||
opt_zero = true;
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default: {
|
|
||||||
char cbuf[2];
|
|
||||||
|
|
||||||
cbuf[0] = opts[j];
|
|
||||||
cbuf[1] = '\0';
|
|
||||||
malloc_write(
|
|
||||||
"<jemalloc>: Unsupported character "
|
|
||||||
"in malloc options: '");
|
|
||||||
malloc_write(cbuf);
|
|
||||||
malloc_write("'\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Register fork handlers. */
|
/* Register fork handlers. */
|
||||||
if (pthread_atfork(jemalloc_prefork, jemalloc_postfork,
|
if (pthread_atfork(jemalloc_prefork, jemalloc_postfork,
|
||||||
@ -638,7 +660,7 @@ MALLOC_OUT:
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef JEMALLOC_PROF
|
#ifdef JEMALLOC_PROF
|
||||||
prof_boot0();
|
prof_boot1();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (arena_boot()) {
|
if (arena_boot()) {
|
||||||
@ -692,7 +714,7 @@ MALLOC_OUT:
|
|||||||
malloc_mutex_init(&arenas_lock);
|
malloc_mutex_init(&arenas_lock);
|
||||||
|
|
||||||
#ifdef JEMALLOC_PROF
|
#ifdef JEMALLOC_PROF
|
||||||
if (prof_boot1()) {
|
if (prof_boot2()) {
|
||||||
malloc_mutex_unlock(&init_lock);
|
malloc_mutex_unlock(&init_lock);
|
||||||
return (true);
|
return (true);
|
||||||
}
|
}
|
||||||
@ -704,31 +726,29 @@ MALLOC_OUT:
|
|||||||
ncpus = malloc_ncpus();
|
ncpus = malloc_ncpus();
|
||||||
malloc_mutex_lock(&init_lock);
|
malloc_mutex_lock(&init_lock);
|
||||||
|
|
||||||
if (ncpus > 1) {
|
if (opt_narenas == 0) {
|
||||||
/*
|
/*
|
||||||
* For SMP systems, create more than one arena per CPU by
|
* For SMP systems, create more than one arena per CPU by
|
||||||
* default.
|
* default.
|
||||||
*/
|
*/
|
||||||
opt_narenas_lshift += 2;
|
if (ncpus > 1)
|
||||||
|
opt_narenas = ncpus << 2;
|
||||||
|
else
|
||||||
|
opt_narenas = 1;
|
||||||
}
|
}
|
||||||
|
narenas = opt_narenas;
|
||||||
|
/*
|
||||||
|
* Make sure that the arenas array can be allocated. In practice, this
|
||||||
|
* limit is enough to allow the allocator to function, but the ctl
|
||||||
|
* machinery will fail to allocate memory at far lower limits.
|
||||||
|
*/
|
||||||
|
if (narenas > chunksize / sizeof(arena_t *)) {
|
||||||
|
char buf[UMAX2S_BUFSIZE];
|
||||||
|
|
||||||
/* Determine how many arenas to use. */
|
narenas = chunksize / sizeof(arena_t *);
|
||||||
narenas = ncpus;
|
malloc_write("<jemalloc>: Reducing narenas to limit (");
|
||||||
if (opt_narenas_lshift > 0) {
|
malloc_write(u2s(narenas, 10, buf));
|
||||||
if ((narenas << opt_narenas_lshift) > narenas)
|
malloc_write(")\n");
|
||||||
narenas <<= opt_narenas_lshift;
|
|
||||||
/*
|
|
||||||
* Make sure not to exceed the limits of what base_alloc() can
|
|
||||||
* handle.
|
|
||||||
*/
|
|
||||||
if (narenas * sizeof(arena_t *) > chunksize)
|
|
||||||
narenas = chunksize / sizeof(arena_t *);
|
|
||||||
} else if (opt_narenas_lshift < 0) {
|
|
||||||
if ((narenas >> -opt_narenas_lshift) < narenas)
|
|
||||||
narenas >>= -opt_narenas_lshift;
|
|
||||||
/* Make sure there is at least one arena. */
|
|
||||||
if (narenas == 0)
|
|
||||||
narenas = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
next_arena = (narenas > 0) ? 1 : 0;
|
next_arena = (narenas > 0) ? 1 : 0;
|
||||||
|
@ -20,10 +20,11 @@ bool opt_prof_active = true;
|
|||||||
size_t opt_lg_prof_bt_max = LG_PROF_BT_MAX_DEFAULT;
|
size_t opt_lg_prof_bt_max = LG_PROF_BT_MAX_DEFAULT;
|
||||||
size_t opt_lg_prof_sample = LG_PROF_SAMPLE_DEFAULT;
|
size_t opt_lg_prof_sample = LG_PROF_SAMPLE_DEFAULT;
|
||||||
ssize_t opt_lg_prof_interval = LG_PROF_INTERVAL_DEFAULT;
|
ssize_t opt_lg_prof_interval = LG_PROF_INTERVAL_DEFAULT;
|
||||||
bool opt_prof_udump = false;
|
bool opt_prof_gdump = false;
|
||||||
bool opt_prof_leak = false;
|
bool opt_prof_leak = false;
|
||||||
bool opt_prof_accum = true;
|
bool opt_prof_accum = true;
|
||||||
ssize_t opt_lg_prof_tcmax = LG_PROF_TCMAX_DEFAULT;
|
ssize_t opt_lg_prof_tcmax = LG_PROF_TCMAX_DEFAULT;
|
||||||
|
char opt_prof_prefix[PATH_MAX + 1];
|
||||||
|
|
||||||
uint64_t prof_interval;
|
uint64_t prof_interval;
|
||||||
bool prof_promote;
|
bool prof_promote;
|
||||||
@ -64,7 +65,7 @@ static bool prof_booted = false;
|
|||||||
static malloc_mutex_t enq_mtx;
|
static malloc_mutex_t enq_mtx;
|
||||||
static bool enq;
|
static bool enq;
|
||||||
static bool enq_idump;
|
static bool enq_idump;
|
||||||
static bool enq_udump;
|
static bool enq_gdump;
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/* Function prototypes for non-inline static functions. */
|
/* Function prototypes for non-inline static functions. */
|
||||||
@ -150,7 +151,7 @@ prof_enter(void)
|
|||||||
static inline void
|
static inline void
|
||||||
prof_leave(void)
|
prof_leave(void)
|
||||||
{
|
{
|
||||||
bool idump, udump;
|
bool idump, gdump;
|
||||||
|
|
||||||
malloc_mutex_unlock(&bt2ctx_mtx);
|
malloc_mutex_unlock(&bt2ctx_mtx);
|
||||||
|
|
||||||
@ -158,14 +159,14 @@ prof_leave(void)
|
|||||||
enq = false;
|
enq = false;
|
||||||
idump = enq_idump;
|
idump = enq_idump;
|
||||||
enq_idump = false;
|
enq_idump = false;
|
||||||
udump = enq_udump;
|
gdump = enq_gdump;
|
||||||
enq_udump = false;
|
enq_gdump = false;
|
||||||
malloc_mutex_unlock(&enq_mtx);
|
malloc_mutex_unlock(&enq_mtx);
|
||||||
|
|
||||||
if (idump)
|
if (idump)
|
||||||
prof_idump();
|
prof_idump();
|
||||||
if (udump)
|
if (gdump)
|
||||||
prof_udump();
|
prof_gdump();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef JEMALLOC_PROF_LIBGCC
|
#ifdef JEMALLOC_PROF_LIBGCC
|
||||||
@ -681,22 +682,22 @@ prof_dump_ctx(prof_ctx_t *ctx, prof_bt_t *bt, bool propagate_err)
|
|||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prof_write(umax2s(ctx->cnt_summed.curobjs, 10, buf), propagate_err)
|
if (prof_write(u2s(ctx->cnt_summed.curobjs, 10, buf), propagate_err)
|
||||||
|| prof_write(": ", propagate_err)
|
|| prof_write(": ", propagate_err)
|
||||||
|| prof_write(umax2s(ctx->cnt_summed.curbytes, 10, buf),
|
|| prof_write(u2s(ctx->cnt_summed.curbytes, 10, buf),
|
||||||
propagate_err)
|
propagate_err)
|
||||||
|| prof_write(" [", propagate_err)
|
|| prof_write(" [", propagate_err)
|
||||||
|| prof_write(umax2s(ctx->cnt_summed.accumobjs, 10, buf),
|
|| prof_write(u2s(ctx->cnt_summed.accumobjs, 10, buf),
|
||||||
propagate_err)
|
propagate_err)
|
||||||
|| prof_write(": ", propagate_err)
|
|| prof_write(": ", propagate_err)
|
||||||
|| prof_write(umax2s(ctx->cnt_summed.accumbytes, 10, buf),
|
|| prof_write(u2s(ctx->cnt_summed.accumbytes, 10, buf),
|
||||||
propagate_err)
|
propagate_err)
|
||||||
|| prof_write("] @", propagate_err))
|
|| prof_write("] @", propagate_err))
|
||||||
return (true);
|
return (true);
|
||||||
|
|
||||||
for (i = 0; i < bt->len; i++) {
|
for (i = 0; i < bt->len; i++) {
|
||||||
if (prof_write(" 0x", propagate_err)
|
if (prof_write(" 0x", propagate_err)
|
||||||
|| prof_write(umax2s((uintptr_t)bt->vec[i], 16, buf),
|
|| prof_write(u2s((uintptr_t)bt->vec[i], 16, buf),
|
||||||
propagate_err))
|
propagate_err))
|
||||||
return (true);
|
return (true);
|
||||||
}
|
}
|
||||||
@ -725,7 +726,7 @@ prof_dump_maps(bool propagate_err)
|
|||||||
memcpy(&mpath[i], s, slen);
|
memcpy(&mpath[i], s, slen);
|
||||||
i += slen;
|
i += slen;
|
||||||
|
|
||||||
s = umax2s(getpid(), 10, buf);
|
s = u2s(getpid(), 10, buf);
|
||||||
slen = strlen(s);
|
slen = strlen(s);
|
||||||
memcpy(&mpath[i], s, slen);
|
memcpy(&mpath[i], s, slen);
|
||||||
i += slen;
|
i += slen;
|
||||||
@ -799,13 +800,13 @@ prof_dump(const char *filename, bool leakcheck, bool propagate_err)
|
|||||||
|
|
||||||
/* Dump profile header. */
|
/* Dump profile header. */
|
||||||
if (prof_write("heap profile: ", propagate_err)
|
if (prof_write("heap profile: ", propagate_err)
|
||||||
|| prof_write(umax2s(cnt_all.curobjs, 10, buf), propagate_err)
|
|| prof_write(u2s(cnt_all.curobjs, 10, buf), propagate_err)
|
||||||
|| prof_write(": ", propagate_err)
|
|| prof_write(": ", propagate_err)
|
||||||
|| prof_write(umax2s(cnt_all.curbytes, 10, buf), propagate_err)
|
|| prof_write(u2s(cnt_all.curbytes, 10, buf), propagate_err)
|
||||||
|| prof_write(" [", propagate_err)
|
|| prof_write(" [", propagate_err)
|
||||||
|| prof_write(umax2s(cnt_all.accumobjs, 10, buf), propagate_err)
|
|| prof_write(u2s(cnt_all.accumobjs, 10, buf), propagate_err)
|
||||||
|| prof_write(": ", propagate_err)
|
|| prof_write(": ", propagate_err)
|
||||||
|| prof_write(umax2s(cnt_all.accumbytes, 10, buf), propagate_err))
|
|| prof_write(u2s(cnt_all.accumbytes, 10, buf), propagate_err))
|
||||||
goto ERROR;
|
goto ERROR;
|
||||||
|
|
||||||
if (opt_lg_prof_sample == 0) {
|
if (opt_lg_prof_sample == 0) {
|
||||||
@ -813,7 +814,7 @@ prof_dump(const char *filename, bool leakcheck, bool propagate_err)
|
|||||||
goto ERROR;
|
goto ERROR;
|
||||||
} else {
|
} else {
|
||||||
if (prof_write("] @ heap_v2/", propagate_err)
|
if (prof_write("] @ heap_v2/", propagate_err)
|
||||||
|| prof_write(umax2s((uint64_t)1U << opt_lg_prof_sample, 10,
|
|| prof_write(u2s((uint64_t)1U << opt_lg_prof_sample, 10,
|
||||||
buf), propagate_err)
|
buf), propagate_err)
|
||||||
|| prof_write("\n", propagate_err))
|
|| prof_write("\n", propagate_err))
|
||||||
goto ERROR;
|
goto ERROR;
|
||||||
@ -837,12 +838,12 @@ prof_dump(const char *filename, bool leakcheck, bool propagate_err)
|
|||||||
|
|
||||||
if (leakcheck && cnt_all.curbytes != 0) {
|
if (leakcheck && cnt_all.curbytes != 0) {
|
||||||
malloc_write("<jemalloc>: Leak summary: ");
|
malloc_write("<jemalloc>: Leak summary: ");
|
||||||
malloc_write(umax2s(cnt_all.curbytes, 10, buf));
|
malloc_write(u2s(cnt_all.curbytes, 10, buf));
|
||||||
malloc_write((cnt_all.curbytes != 1) ? " bytes, " : " byte, ");
|
malloc_write((cnt_all.curbytes != 1) ? " bytes, " : " byte, ");
|
||||||
malloc_write(umax2s(cnt_all.curobjs, 10, buf));
|
malloc_write(u2s(cnt_all.curobjs, 10, buf));
|
||||||
malloc_write((cnt_all.curobjs != 1) ? " objects, " :
|
malloc_write((cnt_all.curobjs != 1) ? " objects, " :
|
||||||
" object, ");
|
" object, ");
|
||||||
malloc_write(umax2s(leak_nctx, 10, buf));
|
malloc_write(u2s(leak_nctx, 10, buf));
|
||||||
malloc_write((leak_nctx != 1) ? " contexts\n" : " context\n");
|
malloc_write((leak_nctx != 1) ? " contexts\n" : " context\n");
|
||||||
malloc_write("<jemalloc>: Run pprof on \"");
|
malloc_write("<jemalloc>: Run pprof on \"");
|
||||||
malloc_write(filename);
|
malloc_write(filename);
|
||||||
@ -872,31 +873,11 @@ prof_dump_filename(char *filename, char v, int64_t vseq)
|
|||||||
* Construct a filename of the form:
|
* Construct a filename of the form:
|
||||||
*
|
*
|
||||||
* <prefix>.<pid>.<seq>.v<vseq>.heap\0
|
* <prefix>.<pid>.<seq>.v<vseq>.heap\0
|
||||||
* or
|
|
||||||
* jeprof.<pid>.<seq>.v<vseq>.heap\0
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
/*
|
s = opt_prof_prefix;
|
||||||
* Use JEMALLOC_PROF_PREFIX if it's set, and if it is short enough to
|
|
||||||
* avoid overflowing DUMP_FILENAME_BUFSIZE. The result may exceed
|
|
||||||
* PATH_MAX, but creat(2) will catch that problem.
|
|
||||||
*/
|
|
||||||
if ((s = getenv("JEMALLOC_PROF_PREFIX")) != NULL
|
|
||||||
&& strlen(s) + (DUMP_FILENAME_BUFSIZE - PATH_MAX) <= PATH_MAX) {
|
|
||||||
slen = strlen(s);
|
|
||||||
memcpy(&filename[i], s, slen);
|
|
||||||
i += slen;
|
|
||||||
|
|
||||||
s = ".";
|
|
||||||
} else
|
|
||||||
s = "jeprof.";
|
|
||||||
slen = strlen(s);
|
|
||||||
memcpy(&filename[i], s, slen);
|
|
||||||
i += slen;
|
|
||||||
|
|
||||||
s = umax2s(getpid(), 10, buf);
|
|
||||||
slen = strlen(s);
|
slen = strlen(s);
|
||||||
memcpy(&filename[i], s, slen);
|
memcpy(&filename[i], s, slen);
|
||||||
i += slen;
|
i += slen;
|
||||||
@ -906,7 +887,17 @@ prof_dump_filename(char *filename, char v, int64_t vseq)
|
|||||||
memcpy(&filename[i], s, slen);
|
memcpy(&filename[i], s, slen);
|
||||||
i += slen;
|
i += slen;
|
||||||
|
|
||||||
s = umax2s(prof_dump_seq, 10, buf);
|
s = u2s(getpid(), 10, buf);
|
||||||
|
slen = strlen(s);
|
||||||
|
memcpy(&filename[i], s, slen);
|
||||||
|
i += slen;
|
||||||
|
|
||||||
|
s = ".";
|
||||||
|
slen = strlen(s);
|
||||||
|
memcpy(&filename[i], s, slen);
|
||||||
|
i += slen;
|
||||||
|
|
||||||
|
s = u2s(prof_dump_seq, 10, buf);
|
||||||
prof_dump_seq++;
|
prof_dump_seq++;
|
||||||
slen = strlen(s);
|
slen = strlen(s);
|
||||||
memcpy(&filename[i], s, slen);
|
memcpy(&filename[i], s, slen);
|
||||||
@ -921,7 +912,7 @@ prof_dump_filename(char *filename, char v, int64_t vseq)
|
|||||||
i++;
|
i++;
|
||||||
|
|
||||||
if (vseq != 0xffffffffffffffffLLU) {
|
if (vseq != 0xffffffffffffffffLLU) {
|
||||||
s = umax2s(vseq, 10, buf);
|
s = u2s(vseq, 10, buf);
|
||||||
slen = strlen(s);
|
slen = strlen(s);
|
||||||
memcpy(&filename[i], s, slen);
|
memcpy(&filename[i], s, slen);
|
||||||
i += slen;
|
i += slen;
|
||||||
@ -943,10 +934,12 @@ prof_fdump(void)
|
|||||||
if (prof_booted == false)
|
if (prof_booted == false)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
malloc_mutex_lock(&prof_dump_seq_mtx);
|
if (opt_prof_prefix[0] != '\0') {
|
||||||
prof_dump_filename(filename, 'f', 0xffffffffffffffffLLU);
|
malloc_mutex_lock(&prof_dump_seq_mtx);
|
||||||
malloc_mutex_unlock(&prof_dump_seq_mtx);
|
prof_dump_filename(filename, 'f', 0xffffffffffffffffLLU);
|
||||||
prof_dump(filename, opt_prof_leak, false);
|
malloc_mutex_unlock(&prof_dump_seq_mtx);
|
||||||
|
prof_dump(filename, opt_prof_leak, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -964,11 +957,13 @@ prof_idump(void)
|
|||||||
}
|
}
|
||||||
malloc_mutex_unlock(&enq_mtx);
|
malloc_mutex_unlock(&enq_mtx);
|
||||||
|
|
||||||
malloc_mutex_lock(&prof_dump_seq_mtx);
|
if (opt_prof_prefix[0] != '\0') {
|
||||||
prof_dump_filename(filename, 'i', prof_dump_iseq);
|
malloc_mutex_lock(&prof_dump_seq_mtx);
|
||||||
prof_dump_iseq++;
|
prof_dump_filename(filename, 'i', prof_dump_iseq);
|
||||||
malloc_mutex_unlock(&prof_dump_seq_mtx);
|
prof_dump_iseq++;
|
||||||
prof_dump(filename, false, false);
|
malloc_mutex_unlock(&prof_dump_seq_mtx);
|
||||||
|
prof_dump(filename, false, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -981,6 +976,8 @@ prof_mdump(const char *filename)
|
|||||||
|
|
||||||
if (filename == NULL) {
|
if (filename == NULL) {
|
||||||
/* No filename specified, so automatically generate one. */
|
/* No filename specified, so automatically generate one. */
|
||||||
|
if (opt_prof_prefix[0] == '\0')
|
||||||
|
return (true);
|
||||||
malloc_mutex_lock(&prof_dump_seq_mtx);
|
malloc_mutex_lock(&prof_dump_seq_mtx);
|
||||||
prof_dump_filename(filename_buf, 'm', prof_dump_mseq);
|
prof_dump_filename(filename_buf, 'm', prof_dump_mseq);
|
||||||
prof_dump_mseq++;
|
prof_dump_mseq++;
|
||||||
@ -991,7 +988,7 @@ prof_mdump(const char *filename)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
prof_udump(void)
|
prof_gdump(void)
|
||||||
{
|
{
|
||||||
char filename[DUMP_FILENAME_BUFSIZE];
|
char filename[DUMP_FILENAME_BUFSIZE];
|
||||||
|
|
||||||
@ -999,17 +996,19 @@ prof_udump(void)
|
|||||||
return;
|
return;
|
||||||
malloc_mutex_lock(&enq_mtx);
|
malloc_mutex_lock(&enq_mtx);
|
||||||
if (enq) {
|
if (enq) {
|
||||||
enq_udump = true;
|
enq_gdump = true;
|
||||||
malloc_mutex_unlock(&enq_mtx);
|
malloc_mutex_unlock(&enq_mtx);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
malloc_mutex_unlock(&enq_mtx);
|
malloc_mutex_unlock(&enq_mtx);
|
||||||
|
|
||||||
malloc_mutex_lock(&prof_dump_seq_mtx);
|
if (opt_prof_prefix[0] != '\0') {
|
||||||
prof_dump_filename(filename, 'u', prof_dump_useq);
|
malloc_mutex_lock(&prof_dump_seq_mtx);
|
||||||
prof_dump_useq++;
|
prof_dump_filename(filename, 'u', prof_dump_useq);
|
||||||
malloc_mutex_unlock(&prof_dump_seq_mtx);
|
prof_dump_useq++;
|
||||||
prof_dump(filename, false, false);
|
malloc_mutex_unlock(&prof_dump_seq_mtx);
|
||||||
|
prof_dump(filename, false, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1120,6 +1119,14 @@ prof_tdata_cleanup(void *arg)
|
|||||||
|
|
||||||
void
|
void
|
||||||
prof_boot0(void)
|
prof_boot0(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
memcpy(opt_prof_prefix, PROF_PREFIX_DEFAULT,
|
||||||
|
sizeof(PROF_PREFIX_DEFAULT));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
prof_boot1(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1133,7 +1140,7 @@ prof_boot0(void)
|
|||||||
* automatically dumped.
|
* automatically dumped.
|
||||||
*/
|
*/
|
||||||
opt_prof = true;
|
opt_prof = true;
|
||||||
opt_prof_udump = false;
|
opt_prof_gdump = false;
|
||||||
prof_interval = 0;
|
prof_interval = 0;
|
||||||
} else if (opt_prof) {
|
} else if (opt_prof) {
|
||||||
if (opt_lg_prof_interval >= 0) {
|
if (opt_lg_prof_interval >= 0) {
|
||||||
@ -1147,7 +1154,7 @@ prof_boot0(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
prof_boot1(void)
|
prof_boot2(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (opt_prof) {
|
if (opt_prof) {
|
||||||
@ -1171,7 +1178,7 @@ prof_boot1(void)
|
|||||||
return (true);
|
return (true);
|
||||||
enq = false;
|
enq = false;
|
||||||
enq_idump = false;
|
enq_idump = false;
|
||||||
enq_udump = false;
|
enq_gdump = false;
|
||||||
|
|
||||||
if (atexit(prof_fdump) != 0) {
|
if (atexit(prof_fdump) != 0) {
|
||||||
malloc_write("<jemalloc>: Error in atexit()\n");
|
malloc_write("<jemalloc>: Error in atexit()\n");
|
||||||
|
@ -57,12 +57,12 @@ static void stats_arena_print(void (*write_cb)(void *, const char *),
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* We don't want to depend on vsnprintf() for production builds, since that can
|
* We don't want to depend on vsnprintf() for production builds, since that can
|
||||||
* cause unnecessary bloat for static binaries. umax2s() provides minimal
|
* cause unnecessary bloat for static binaries. u2s() provides minimal integer
|
||||||
* integer printing functionality, so that malloc_printf() use can be limited to
|
* printing functionality, so that malloc_printf() use can be limited to
|
||||||
* JEMALLOC_STATS code.
|
* JEMALLOC_STATS code.
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
umax2s(uintmax_t x, unsigned base, char *s)
|
u2s(uint64_t x, unsigned base, char *s)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
@ -72,8 +72,8 @@ umax2s(uintmax_t x, unsigned base, char *s)
|
|||||||
case 10:
|
case 10:
|
||||||
do {
|
do {
|
||||||
i--;
|
i--;
|
||||||
s[i] = "0123456789"[x % 10];
|
s[i] = "0123456789"[x % (uint64_t)10];
|
||||||
x /= 10;
|
x /= (uint64_t)10;
|
||||||
} while (x > 0);
|
} while (x > 0);
|
||||||
break;
|
break;
|
||||||
case 16:
|
case 16:
|
||||||
@ -86,8 +86,9 @@ umax2s(uintmax_t x, unsigned base, char *s)
|
|||||||
default:
|
default:
|
||||||
do {
|
do {
|
||||||
i--;
|
i--;
|
||||||
s[i] = "0123456789abcdefghijklmnopqrstuvwxyz"[x % base];
|
s[i] = "0123456789abcdefghijklmnopqrstuvwxyz"[x %
|
||||||
x /= base;
|
(uint64_t)base];
|
||||||
|
x /= (uint64_t)base;
|
||||||
} while (x > 0);
|
} while (x > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -374,6 +375,7 @@ void
|
|||||||
stats_print(void (*write_cb)(void *, const char *), void *cbopaque,
|
stats_print(void (*write_cb)(void *, const char *), void *cbopaque,
|
||||||
const char *opts)
|
const char *opts)
|
||||||
{
|
{
|
||||||
|
int err;
|
||||||
uint64_t epoch;
|
uint64_t epoch;
|
||||||
size_t u64sz;
|
size_t u64sz;
|
||||||
char s[UMAX2S_BUFSIZE];
|
char s[UMAX2S_BUFSIZE];
|
||||||
@ -383,10 +385,27 @@ stats_print(void (*write_cb)(void *, const char *), void *cbopaque,
|
|||||||
bool bins = true;
|
bool bins = true;
|
||||||
bool large = true;
|
bool large = true;
|
||||||
|
|
||||||
/* Refresh stats, in case mallctl() was called by the application. */
|
/*
|
||||||
|
* Refresh stats, in case mallctl() was called by the application.
|
||||||
|
*
|
||||||
|
* Check for OOM here, since refreshing the ctl cache can trigger
|
||||||
|
* allocation. In practice, none of the subsequent mallctl()-related
|
||||||
|
* calls in this function will cause OOM if this one succeeds.
|
||||||
|
* */
|
||||||
epoch = 1;
|
epoch = 1;
|
||||||
u64sz = sizeof(uint64_t);
|
u64sz = sizeof(uint64_t);
|
||||||
xmallctl("epoch", &epoch, &u64sz, &epoch, sizeof(uint64_t));
|
err = JEMALLOC_P(mallctl)("epoch", &epoch, &u64sz, &epoch,
|
||||||
|
sizeof(uint64_t));
|
||||||
|
if (err != 0) {
|
||||||
|
if (err == EAGAIN) {
|
||||||
|
malloc_write("<jemalloc>: Memory allocation failure in "
|
||||||
|
"mallctl(\"epoch\", ...)\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
malloc_write("<jemalloc>: Failure in mallctl(\"epoch\", "
|
||||||
|
"...)\n");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
if (write_cb == NULL) {
|
if (write_cb == NULL) {
|
||||||
/*
|
/*
|
||||||
@ -430,10 +449,12 @@ stats_print(void (*write_cb)(void *, const char *), void *cbopaque,
|
|||||||
bool bv;
|
bool bv;
|
||||||
unsigned uv;
|
unsigned uv;
|
||||||
ssize_t ssv;
|
ssize_t ssv;
|
||||||
size_t sv, bsz, ssz;
|
size_t sv, bsz, ssz, sssz, cpsz;
|
||||||
|
|
||||||
bsz = sizeof(bool);
|
bsz = sizeof(bool);
|
||||||
ssz = sizeof(size_t);
|
ssz = sizeof(size_t);
|
||||||
|
sssz = sizeof(ssize_t);
|
||||||
|
cpsz = sizeof(const char *);
|
||||||
|
|
||||||
CTL_GET("version", &cpv, const char *);
|
CTL_GET("version", &cpv, const char *);
|
||||||
write_cb(cbopaque, "Version: ");
|
write_cb(cbopaque, "Version: ");
|
||||||
@ -444,116 +465,140 @@ stats_print(void (*write_cb)(void *, const char *), void *cbopaque,
|
|||||||
write_cb(cbopaque, bv ? "enabled" : "disabled");
|
write_cb(cbopaque, bv ? "enabled" : "disabled");
|
||||||
write_cb(cbopaque, "\n");
|
write_cb(cbopaque, "\n");
|
||||||
|
|
||||||
write_cb(cbopaque, "Boolean JEMALLOC_OPTIONS: ");
|
#define OPT_WRITE_BOOL(n) \
|
||||||
if ((err = JEMALLOC_P(mallctl)("opt.abort", &bv, &bsz, NULL, 0))
|
if ((err = JEMALLOC_P(mallctl)("opt."#n, &bv, &bsz, \
|
||||||
== 0)
|
NULL, 0)) == 0) { \
|
||||||
write_cb(cbopaque, bv ? "A" : "a");
|
write_cb(cbopaque, " opt."#n": "); \
|
||||||
if ((err = JEMALLOC_P(mallctl)("prof.active", &bv, &bsz,
|
write_cb(cbopaque, bv ? "true" : "false"); \
|
||||||
NULL, 0)) == 0)
|
write_cb(cbopaque, "\n"); \
|
||||||
write_cb(cbopaque, bv ? "E" : "e");
|
}
|
||||||
if ((err = JEMALLOC_P(mallctl)("opt.prof", &bv, &bsz, NULL, 0))
|
#define OPT_WRITE_SIZE_T(n) \
|
||||||
== 0)
|
if ((err = JEMALLOC_P(mallctl)("opt."#n, &sv, &ssz, \
|
||||||
write_cb(cbopaque, bv ? "F" : "f");
|
NULL, 0)) == 0) { \
|
||||||
if ((err = JEMALLOC_P(mallctl)("opt.tcache", &bv, &bsz, NULL,
|
write_cb(cbopaque, " opt."#n": "); \
|
||||||
0)) == 0)
|
write_cb(cbopaque, u2s(sv, 10, s)); \
|
||||||
write_cb(cbopaque, bv ? "H" : "h");
|
write_cb(cbopaque, "\n"); \
|
||||||
if ((err = JEMALLOC_P(mallctl)("opt.junk", &bv, &bsz, NULL, 0))
|
}
|
||||||
== 0)
|
#define OPT_WRITE_SSIZE_T(n) \
|
||||||
write_cb(cbopaque, bv ? "J" : "j");
|
if ((err = JEMALLOC_P(mallctl)("opt."#n, &ssv, &sssz, \
|
||||||
if ((err = JEMALLOC_P(mallctl)("opt.prof_leak", &bv, &bsz, NULL,
|
NULL, 0)) == 0) { \
|
||||||
0)) == 0)
|
if (ssv >= 0) { \
|
||||||
write_cb(cbopaque, bv ? "L" : "l");
|
write_cb(cbopaque, " opt."#n": "); \
|
||||||
if ((err = JEMALLOC_P(mallctl)("opt.overcommit", &bv, &bsz,
|
write_cb(cbopaque, u2s(ssv, 10, s)); \
|
||||||
NULL, 0)) == 0)
|
} else { \
|
||||||
write_cb(cbopaque, bv ? "O" : "o");
|
write_cb(cbopaque, " opt."#n": -"); \
|
||||||
if ((err = JEMALLOC_P(mallctl)("opt.stats_print", &bv, &bsz,
|
write_cb(cbopaque, u2s(-ssv, 10, s)); \
|
||||||
NULL, 0)) == 0)
|
} \
|
||||||
write_cb(cbopaque, bv ? "P" : "p");
|
write_cb(cbopaque, "\n"); \
|
||||||
if ((err = JEMALLOC_P(mallctl)("opt.prof_accum", &bv, &bsz,
|
}
|
||||||
NULL, 0)) == 0)
|
#define OPT_WRITE_CHAR_P(n) \
|
||||||
write_cb(cbopaque, bv ? "R" : "r");
|
if ((err = JEMALLOC_P(mallctl)("opt."#n, &cpv, &cpsz, \
|
||||||
if ((err = JEMALLOC_P(mallctl)("opt.prof_udump", &bv, &bsz,
|
NULL, 0)) == 0) { \
|
||||||
NULL, 0)) == 0)
|
write_cb(cbopaque, " opt."#n": \""); \
|
||||||
write_cb(cbopaque, bv ? "U" : "u");
|
write_cb(cbopaque, cpv); \
|
||||||
if ((err = JEMALLOC_P(mallctl)("opt.sysv", &bv, &bsz, NULL, 0))
|
write_cb(cbopaque, "\"\n"); \
|
||||||
== 0)
|
}
|
||||||
write_cb(cbopaque, bv ? "V" : "v");
|
|
||||||
if ((err = JEMALLOC_P(mallctl)("opt.xmalloc", &bv, &bsz, NULL,
|
write_cb(cbopaque, "Run-time option settings:\n");
|
||||||
0)) == 0)
|
OPT_WRITE_BOOL(abort)
|
||||||
write_cb(cbopaque, bv ? "X" : "x");
|
OPT_WRITE_SIZE_T(lg_qspace_max)
|
||||||
if ((err = JEMALLOC_P(mallctl)("opt.zero", &bv, &bsz, NULL, 0))
|
OPT_WRITE_SIZE_T(lg_cspace_max)
|
||||||
== 0)
|
OPT_WRITE_SIZE_T(lg_chunk)
|
||||||
write_cb(cbopaque, bv ? "Z" : "z");
|
OPT_WRITE_SIZE_T(narenas)
|
||||||
write_cb(cbopaque, "\n");
|
OPT_WRITE_SSIZE_T(lg_dirty_mult)
|
||||||
|
OPT_WRITE_BOOL(stats_print)
|
||||||
|
OPT_WRITE_BOOL(junk)
|
||||||
|
OPT_WRITE_BOOL(zero)
|
||||||
|
OPT_WRITE_BOOL(sysv)
|
||||||
|
OPT_WRITE_BOOL(xmalloc)
|
||||||
|
OPT_WRITE_BOOL(tcache)
|
||||||
|
OPT_WRITE_SSIZE_T(lg_tcache_gc_sweep)
|
||||||
|
OPT_WRITE_SSIZE_T(lg_tcache_max)
|
||||||
|
OPT_WRITE_BOOL(prof)
|
||||||
|
OPT_WRITE_CHAR_P(prof_prefix)
|
||||||
|
OPT_WRITE_SIZE_T(lg_prof_bt_max)
|
||||||
|
OPT_WRITE_BOOL(prof_active)
|
||||||
|
OPT_WRITE_SSIZE_T(lg_prof_sample)
|
||||||
|
OPT_WRITE_BOOL(prof_accum)
|
||||||
|
OPT_WRITE_SSIZE_T(lg_prof_tcmax)
|
||||||
|
OPT_WRITE_SSIZE_T(lg_prof_interval)
|
||||||
|
OPT_WRITE_BOOL(prof_gdump)
|
||||||
|
OPT_WRITE_BOOL(prof_leak)
|
||||||
|
OPT_WRITE_BOOL(overcommit)
|
||||||
|
|
||||||
|
#undef OPT_WRITE_BOOL
|
||||||
|
#undef OPT_WRITE_SIZE_T
|
||||||
|
#undef OPT_WRITE_SSIZE_T
|
||||||
|
#undef OPT_WRITE_CHAR_P
|
||||||
|
|
||||||
write_cb(cbopaque, "CPUs: ");
|
write_cb(cbopaque, "CPUs: ");
|
||||||
write_cb(cbopaque, umax2s(ncpus, 10, s));
|
write_cb(cbopaque, u2s(ncpus, 10, s));
|
||||||
write_cb(cbopaque, "\n");
|
write_cb(cbopaque, "\n");
|
||||||
|
|
||||||
CTL_GET("arenas.narenas", &uv, unsigned);
|
CTL_GET("arenas.narenas", &uv, unsigned);
|
||||||
write_cb(cbopaque, "Max arenas: ");
|
write_cb(cbopaque, "Max arenas: ");
|
||||||
write_cb(cbopaque, umax2s(uv, 10, s));
|
write_cb(cbopaque, u2s(uv, 10, s));
|
||||||
write_cb(cbopaque, "\n");
|
write_cb(cbopaque, "\n");
|
||||||
|
|
||||||
write_cb(cbopaque, "Pointer size: ");
|
write_cb(cbopaque, "Pointer size: ");
|
||||||
write_cb(cbopaque, umax2s(sizeof(void *), 10, s));
|
write_cb(cbopaque, u2s(sizeof(void *), 10, s));
|
||||||
write_cb(cbopaque, "\n");
|
write_cb(cbopaque, "\n");
|
||||||
|
|
||||||
CTL_GET("arenas.quantum", &sv, size_t);
|
CTL_GET("arenas.quantum", &sv, size_t);
|
||||||
write_cb(cbopaque, "Quantum size: ");
|
write_cb(cbopaque, "Quantum size: ");
|
||||||
write_cb(cbopaque, umax2s(sv, 10, s));
|
write_cb(cbopaque, u2s(sv, 10, s));
|
||||||
write_cb(cbopaque, "\n");
|
write_cb(cbopaque, "\n");
|
||||||
|
|
||||||
CTL_GET("arenas.cacheline", &sv, size_t);
|
CTL_GET("arenas.cacheline", &sv, size_t);
|
||||||
write_cb(cbopaque, "Cacheline size (assumed): ");
|
write_cb(cbopaque, "Cacheline size (assumed): ");
|
||||||
write_cb(cbopaque, umax2s(sv, 10, s));
|
write_cb(cbopaque, u2s(sv, 10, s));
|
||||||
write_cb(cbopaque, "\n");
|
write_cb(cbopaque, "\n");
|
||||||
|
|
||||||
CTL_GET("arenas.subpage", &sv, size_t);
|
CTL_GET("arenas.subpage", &sv, size_t);
|
||||||
write_cb(cbopaque, "Subpage spacing: ");
|
write_cb(cbopaque, "Subpage spacing: ");
|
||||||
write_cb(cbopaque, umax2s(sv, 10, s));
|
write_cb(cbopaque, u2s(sv, 10, s));
|
||||||
write_cb(cbopaque, "\n");
|
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) {
|
||||||
write_cb(cbopaque, "Tiny 2^n-spaced sizes: [");
|
write_cb(cbopaque, "Tiny 2^n-spaced sizes: [");
|
||||||
write_cb(cbopaque, umax2s(sv, 10, s));
|
write_cb(cbopaque, u2s(sv, 10, s));
|
||||||
write_cb(cbopaque, "..");
|
write_cb(cbopaque, "..");
|
||||||
|
|
||||||
CTL_GET("arenas.tspace_max", &sv, size_t);
|
CTL_GET("arenas.tspace_max", &sv, size_t);
|
||||||
write_cb(cbopaque, umax2s(sv, 10, s));
|
write_cb(cbopaque, u2s(sv, 10, s));
|
||||||
write_cb(cbopaque, "]\n");
|
write_cb(cbopaque, "]\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
CTL_GET("arenas.qspace_min", &sv, size_t);
|
CTL_GET("arenas.qspace_min", &sv, size_t);
|
||||||
write_cb(cbopaque, "Quantum-spaced sizes: [");
|
write_cb(cbopaque, "Quantum-spaced sizes: [");
|
||||||
write_cb(cbopaque, umax2s(sv, 10, s));
|
write_cb(cbopaque, u2s(sv, 10, s));
|
||||||
write_cb(cbopaque, "..");
|
write_cb(cbopaque, "..");
|
||||||
CTL_GET("arenas.qspace_max", &sv, size_t);
|
CTL_GET("arenas.qspace_max", &sv, size_t);
|
||||||
write_cb(cbopaque, umax2s(sv, 10, s));
|
write_cb(cbopaque, u2s(sv, 10, s));
|
||||||
write_cb(cbopaque, "]\n");
|
write_cb(cbopaque, "]\n");
|
||||||
|
|
||||||
CTL_GET("arenas.cspace_min", &sv, size_t);
|
CTL_GET("arenas.cspace_min", &sv, size_t);
|
||||||
write_cb(cbopaque, "Cacheline-spaced sizes: [");
|
write_cb(cbopaque, "Cacheline-spaced sizes: [");
|
||||||
write_cb(cbopaque, umax2s(sv, 10, s));
|
write_cb(cbopaque, u2s(sv, 10, s));
|
||||||
write_cb(cbopaque, "..");
|
write_cb(cbopaque, "..");
|
||||||
CTL_GET("arenas.cspace_max", &sv, size_t);
|
CTL_GET("arenas.cspace_max", &sv, size_t);
|
||||||
write_cb(cbopaque, umax2s(sv, 10, s));
|
write_cb(cbopaque, u2s(sv, 10, s));
|
||||||
write_cb(cbopaque, "]\n");
|
write_cb(cbopaque, "]\n");
|
||||||
|
|
||||||
CTL_GET("arenas.sspace_min", &sv, size_t);
|
CTL_GET("arenas.sspace_min", &sv, size_t);
|
||||||
write_cb(cbopaque, "Subpage-spaced sizes: [");
|
write_cb(cbopaque, "Subpage-spaced sizes: [");
|
||||||
write_cb(cbopaque, umax2s(sv, 10, s));
|
write_cb(cbopaque, u2s(sv, 10, s));
|
||||||
write_cb(cbopaque, "..");
|
write_cb(cbopaque, "..");
|
||||||
CTL_GET("arenas.sspace_max", &sv, size_t);
|
CTL_GET("arenas.sspace_max", &sv, size_t);
|
||||||
write_cb(cbopaque, umax2s(sv, 10, s));
|
write_cb(cbopaque, u2s(sv, 10, s));
|
||||||
write_cb(cbopaque, "]\n");
|
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) {
|
||||||
write_cb(cbopaque,
|
write_cb(cbopaque,
|
||||||
"Min active:dirty page ratio per arena: ");
|
"Min active:dirty page ratio per arena: ");
|
||||||
write_cb(cbopaque, umax2s((1U << ssv), 10, s));
|
write_cb(cbopaque, u2s((1U << ssv), 10, s));
|
||||||
write_cb(cbopaque, ":1\n");
|
write_cb(cbopaque, ":1\n");
|
||||||
} else {
|
} else {
|
||||||
write_cb(cbopaque,
|
write_cb(cbopaque,
|
||||||
@ -563,7 +608,7 @@ stats_print(void (*write_cb)(void *, const char *), void *cbopaque,
|
|||||||
&ssz, NULL, 0)) == 0) {
|
&ssz, NULL, 0)) == 0) {
|
||||||
write_cb(cbopaque,
|
write_cb(cbopaque,
|
||||||
"Maximum thread-cached size class: ");
|
"Maximum thread-cached size class: ");
|
||||||
write_cb(cbopaque, umax2s(sv, 10, s));
|
write_cb(cbopaque, u2s(sv, 10, s));
|
||||||
write_cb(cbopaque, "\n");
|
write_cb(cbopaque, "\n");
|
||||||
}
|
}
|
||||||
if ((err = JEMALLOC_P(mallctl)("opt.lg_tcache_gc_sweep", &ssv,
|
if ((err = JEMALLOC_P(mallctl)("opt.lg_tcache_gc_sweep", &ssv,
|
||||||
@ -573,50 +618,51 @@ stats_print(void (*write_cb)(void *, const char *), void *cbopaque,
|
|||||||
CTL_GET("opt.tcache", &tcache_enabled, bool);
|
CTL_GET("opt.tcache", &tcache_enabled, bool);
|
||||||
write_cb(cbopaque, "Thread cache GC sweep interval: ");
|
write_cb(cbopaque, "Thread cache GC sweep interval: ");
|
||||||
write_cb(cbopaque, tcache_enabled && ssv >= 0 ?
|
write_cb(cbopaque, tcache_enabled && ssv >= 0 ?
|
||||||
umax2s(tcache_gc_sweep, 10, s) : "N/A");
|
u2s(tcache_gc_sweep, 10, s) : "N/A");
|
||||||
write_cb(cbopaque, "\n");
|
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) {
|
||||||
CTL_GET("opt.lg_prof_bt_max", &sv, size_t);
|
CTL_GET("opt.lg_prof_bt_max", &sv, size_t);
|
||||||
write_cb(cbopaque, "Maximum profile backtrace depth: ");
|
write_cb(cbopaque, "Maximum profile backtrace depth: ");
|
||||||
write_cb(cbopaque, umax2s((1U << sv), 10, s));
|
write_cb(cbopaque, u2s((1U << sv), 10, s));
|
||||||
write_cb(cbopaque, "\n");
|
write_cb(cbopaque, "\n");
|
||||||
|
|
||||||
CTL_GET("opt.lg_prof_tcmax", &ssv, ssize_t);
|
CTL_GET("opt.lg_prof_tcmax", &ssv, ssize_t);
|
||||||
write_cb(cbopaque,
|
write_cb(cbopaque,
|
||||||
"Maximum per thread backtrace cache: ");
|
"Maximum per thread backtrace cache: ");
|
||||||
if (ssv >= 0) {
|
if (ssv >= 0) {
|
||||||
write_cb(cbopaque, umax2s((1U << ssv), 10, s));
|
write_cb(cbopaque, u2s((1U << ssv), 10, s));
|
||||||
write_cb(cbopaque, " (2^");
|
write_cb(cbopaque, " (2^");
|
||||||
write_cb(cbopaque, umax2s(ssv, 10, s));
|
write_cb(cbopaque, u2s(ssv, 10, s));
|
||||||
write_cb(cbopaque, ")\n");
|
write_cb(cbopaque, ")\n");
|
||||||
} else
|
} else
|
||||||
write_cb(cbopaque, "N/A\n");
|
write_cb(cbopaque, "N/A\n");
|
||||||
|
|
||||||
CTL_GET("opt.lg_prof_sample", &sv, size_t);
|
CTL_GET("opt.lg_prof_sample", &sv, size_t);
|
||||||
write_cb(cbopaque, "Average profile sample interval: ");
|
write_cb(cbopaque, "Average profile sample interval: ");
|
||||||
write_cb(cbopaque, umax2s((1U << sv), 10, s));
|
write_cb(cbopaque, u2s((((uint64_t)1U) << sv), 10, s));
|
||||||
write_cb(cbopaque, " (2^");
|
write_cb(cbopaque, " (2^");
|
||||||
write_cb(cbopaque, umax2s(sv, 10, s));
|
write_cb(cbopaque, u2s(sv, 10, s));
|
||||||
write_cb(cbopaque, ")\n");
|
write_cb(cbopaque, ")\n");
|
||||||
|
|
||||||
CTL_GET("opt.lg_prof_interval", &ssv, ssize_t);
|
CTL_GET("opt.lg_prof_interval", &ssv, ssize_t);
|
||||||
write_cb(cbopaque, "Average profile dump interval: ");
|
write_cb(cbopaque, "Average profile dump interval: ");
|
||||||
if (ssv >= 0) {
|
if (ssv >= 0) {
|
||||||
write_cb(cbopaque, umax2s((1U << ssv), 10, s));
|
write_cb(cbopaque, u2s((((uint64_t)1U) << ssv),
|
||||||
|
10, s));
|
||||||
write_cb(cbopaque, " (2^");
|
write_cb(cbopaque, " (2^");
|
||||||
write_cb(cbopaque, umax2s(ssv, 10, s));
|
write_cb(cbopaque, u2s(ssv, 10, s));
|
||||||
write_cb(cbopaque, ")\n");
|
write_cb(cbopaque, ")\n");
|
||||||
} else
|
} else
|
||||||
write_cb(cbopaque, "N/A\n");
|
write_cb(cbopaque, "N/A\n");
|
||||||
}
|
}
|
||||||
CTL_GET("arenas.chunksize", &sv, size_t);
|
CTL_GET("arenas.chunksize", &sv, size_t);
|
||||||
write_cb(cbopaque, "Chunk size: ");
|
write_cb(cbopaque, "Chunk size: ");
|
||||||
write_cb(cbopaque, umax2s(sv, 10, s));
|
write_cb(cbopaque, u2s(sv, 10, s));
|
||||||
CTL_GET("opt.lg_chunk", &sv, size_t);
|
CTL_GET("opt.lg_chunk", &sv, size_t);
|
||||||
write_cb(cbopaque, " (2^");
|
write_cb(cbopaque, " (2^");
|
||||||
write_cb(cbopaque, umax2s(sv, 10, s));
|
write_cb(cbopaque, u2s(sv, 10, s));
|
||||||
write_cb(cbopaque, ")\n");
|
write_cb(cbopaque, ")\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
/* Data. */
|
/* Data. */
|
||||||
|
|
||||||
bool opt_tcache = true;
|
bool opt_tcache = true;
|
||||||
ssize_t opt_lg_tcache_maxclass = LG_TCACHE_MAXCLASS_DEFAULT;
|
ssize_t opt_lg_tcache_max = LG_TCACHE_MAXCLASS_DEFAULT;
|
||||||
ssize_t opt_lg_tcache_gc_sweep = LG_TCACHE_GC_SWEEP_DEFAULT;
|
ssize_t opt_lg_tcache_gc_sweep = LG_TCACHE_GC_SWEEP_DEFAULT;
|
||||||
|
|
||||||
/* Map of thread-specific caches. */
|
/* Map of thread-specific caches. */
|
||||||
@ -384,16 +384,16 @@ tcache_boot(void)
|
|||||||
|
|
||||||
if (opt_tcache) {
|
if (opt_tcache) {
|
||||||
/*
|
/*
|
||||||
* If necessary, clamp opt_lg_tcache_maxclass, now that
|
* If necessary, clamp opt_lg_tcache_max, now that
|
||||||
* small_maxclass and arena_maxclass are known.
|
* small_maxclass and arena_maxclass are known.
|
||||||
*/
|
*/
|
||||||
if (opt_lg_tcache_maxclass < 0 || (1U <<
|
if (opt_lg_tcache_max < 0 || (1U <<
|
||||||
opt_lg_tcache_maxclass) < small_maxclass)
|
opt_lg_tcache_max) < small_maxclass)
|
||||||
tcache_maxclass = small_maxclass;
|
tcache_maxclass = small_maxclass;
|
||||||
else if ((1U << opt_lg_tcache_maxclass) > arena_maxclass)
|
else if ((1U << opt_lg_tcache_max) > arena_maxclass)
|
||||||
tcache_maxclass = arena_maxclass;
|
tcache_maxclass = arena_maxclass;
|
||||||
else
|
else
|
||||||
tcache_maxclass = (1U << opt_lg_tcache_maxclass);
|
tcache_maxclass = (1U << opt_lg_tcache_max);
|
||||||
|
|
||||||
nhbins = nbins + (tcache_maxclass >> PAGE_SHIFT);
|
nhbins = nbins + (tcache_maxclass >> PAGE_SHIFT);
|
||||||
|
|
||||||
|
@ -14,14 +14,14 @@ main(void)
|
|||||||
|
|
||||||
fprintf(stderr, "Test begin\n");
|
fprintf(stderr, "Test begin\n");
|
||||||
|
|
||||||
r = allocm(&p, &sz, 42, 0);
|
r = JEMALLOC_P(allocm)(&p, &sz, 42, 0);
|
||||||
if (r != ALLOCM_SUCCESS) {
|
if (r != ALLOCM_SUCCESS) {
|
||||||
fprintf(stderr, "Unexpected allocm() error\n");
|
fprintf(stderr, "Unexpected allocm() error\n");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
q = p;
|
q = p;
|
||||||
r = rallocm(&q, &tsz, sz, 0, ALLOCM_NO_MOVE);
|
r = JEMALLOC_P(rallocm)(&q, &tsz, sz, 0, ALLOCM_NO_MOVE);
|
||||||
if (r != ALLOCM_SUCCESS)
|
if (r != ALLOCM_SUCCESS)
|
||||||
fprintf(stderr, "Unexpected rallocm() error\n");
|
fprintf(stderr, "Unexpected rallocm() error\n");
|
||||||
if (q != p)
|
if (q != p)
|
||||||
@ -32,7 +32,7 @@ main(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
q = p;
|
q = p;
|
||||||
r = rallocm(&q, &tsz, sz, 5, ALLOCM_NO_MOVE);
|
r = JEMALLOC_P(rallocm)(&q, &tsz, sz, 5, ALLOCM_NO_MOVE);
|
||||||
if (r != ALLOCM_SUCCESS)
|
if (r != ALLOCM_SUCCESS)
|
||||||
fprintf(stderr, "Unexpected rallocm() error\n");
|
fprintf(stderr, "Unexpected rallocm() error\n");
|
||||||
if (q != p)
|
if (q != p)
|
||||||
@ -43,7 +43,7 @@ main(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
q = p;
|
q = p;
|
||||||
r = rallocm(&q, &tsz, sz + 5, 0, ALLOCM_NO_MOVE);
|
r = JEMALLOC_P(rallocm)(&q, &tsz, sz + 5, 0, ALLOCM_NO_MOVE);
|
||||||
if (r != ALLOCM_ERR_NOT_MOVED)
|
if (r != ALLOCM_ERR_NOT_MOVED)
|
||||||
fprintf(stderr, "Unexpected rallocm() result\n");
|
fprintf(stderr, "Unexpected rallocm() result\n");
|
||||||
if (q != p)
|
if (q != p)
|
||||||
@ -54,7 +54,7 @@ main(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
q = p;
|
q = p;
|
||||||
r = rallocm(&q, &tsz, sz + 5, 0, 0);
|
r = JEMALLOC_P(rallocm)(&q, &tsz, sz + 5, 0, 0);
|
||||||
if (r != ALLOCM_SUCCESS)
|
if (r != ALLOCM_SUCCESS)
|
||||||
fprintf(stderr, "Unexpected rallocm() error\n");
|
fprintf(stderr, "Unexpected rallocm() error\n");
|
||||||
if (q == p)
|
if (q == p)
|
||||||
@ -66,7 +66,7 @@ main(void)
|
|||||||
p = q;
|
p = q;
|
||||||
sz = tsz;
|
sz = tsz;
|
||||||
|
|
||||||
r = rallocm(&q, &tsz, 8192, 0, 0);
|
r = JEMALLOC_P(rallocm)(&q, &tsz, 8192, 0, 0);
|
||||||
if (r != ALLOCM_SUCCESS)
|
if (r != ALLOCM_SUCCESS)
|
||||||
fprintf(stderr, "Unexpected rallocm() error\n");
|
fprintf(stderr, "Unexpected rallocm() error\n");
|
||||||
if (q == p)
|
if (q == p)
|
||||||
@ -78,7 +78,7 @@ main(void)
|
|||||||
p = q;
|
p = q;
|
||||||
sz = tsz;
|
sz = tsz;
|
||||||
|
|
||||||
r = rallocm(&q, &tsz, 16384, 0, 0);
|
r = JEMALLOC_P(rallocm)(&q, &tsz, 16384, 0, 0);
|
||||||
if (r != ALLOCM_SUCCESS)
|
if (r != ALLOCM_SUCCESS)
|
||||||
fprintf(stderr, "Unexpected rallocm() error\n");
|
fprintf(stderr, "Unexpected rallocm() error\n");
|
||||||
if (tsz == sz) {
|
if (tsz == sz) {
|
||||||
@ -88,7 +88,7 @@ main(void)
|
|||||||
p = q;
|
p = q;
|
||||||
sz = tsz;
|
sz = tsz;
|
||||||
|
|
||||||
r = rallocm(&q, &tsz, 8192, 0, ALLOCM_NO_MOVE);
|
r = JEMALLOC_P(rallocm)(&q, &tsz, 8192, 0, ALLOCM_NO_MOVE);
|
||||||
if (r != ALLOCM_SUCCESS)
|
if (r != ALLOCM_SUCCESS)
|
||||||
fprintf(stderr, "Unexpected rallocm() error\n");
|
fprintf(stderr, "Unexpected rallocm() error\n");
|
||||||
if (q != p)
|
if (q != p)
|
||||||
@ -99,7 +99,7 @@ main(void)
|
|||||||
}
|
}
|
||||||
sz = tsz;
|
sz = tsz;
|
||||||
|
|
||||||
r = rallocm(&q, &tsz, 16384, 0, ALLOCM_NO_MOVE);
|
r = JEMALLOC_P(rallocm)(&q, &tsz, 16384, 0, ALLOCM_NO_MOVE);
|
||||||
if (r != ALLOCM_SUCCESS)
|
if (r != ALLOCM_SUCCESS)
|
||||||
fprintf(stderr, "Unexpected rallocm() error\n");
|
fprintf(stderr, "Unexpected rallocm() error\n");
|
||||||
if (q != p)
|
if (q != p)
|
||||||
@ -110,7 +110,7 @@ main(void)
|
|||||||
}
|
}
|
||||||
sz = tsz;
|
sz = tsz;
|
||||||
|
|
||||||
dallocm(p, 0);
|
JEMALLOC_P(dallocm)(p, 0);
|
||||||
|
|
||||||
fprintf(stderr, "Test end\n");
|
fprintf(stderr, "Test end\n");
|
||||||
return (0);
|
return (0);
|
||||||
|
Loading…
Reference in New Issue
Block a user