diff --git a/.gitignore b/.gitignore index b4681866..d6fa8fd1 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,10 @@ /jemalloc/config.log /jemalloc/config.status /jemalloc/configure +/jemalloc/doc/html.xsl +/jemalloc/doc/manpages.xsl +/jemalloc/doc/jemalloc.xml +/jemalloc/doc/jemalloc.html /jemalloc/doc/jemalloc.3 /jemalloc/lib/ /jemalloc/Makefile @@ -13,4 +17,7 @@ /jemalloc/src/*.[od] /jemalloc/test/*.[od] /jemalloc/test/*.out +/jemalloc/test/[a-z]* +!/jemalloc/test/*.c +!/jemalloc/test/*.exp /jemalloc/VERSION diff --git a/jemalloc/ChangeLog b/jemalloc/ChangeLog index 7b7da788..e32a5883 100644 --- a/jemalloc/ChangeLog +++ b/jemalloc/ChangeLog @@ -6,6 +6,23 @@ found in the git revision history: http://www.canonware.com/cgi-bin/gitweb.cgi?p=jemalloc.git git://canonware.com/jemalloc.git +* 2.1.0 + + This version incorporates some optimizations that can't quite be considered + bug fixes. + + New features: + - Use Linux's mremap(2) for huge object reallocation when possible. + - Avoid locking in mallctl*() when possible. + - Add the "thread.[de]allocatedp" mallctl's. + - Convert the manual page source from roff to DocBook, and generate both roff + and HTML manuals. + + Bug fixes: + - Fix a crash due to incorrect bootstrap ordering. This only impacted + --enable-debug --enable-dss configurations. + - Fix a minor statistics bug for mallctl("swap.avail", ...). + * 2.0.1 Bug fixes: diff --git a/jemalloc/INSTALL b/jemalloc/INSTALL index fafd7883..b77ebfd4 100644 --- a/jemalloc/INSTALL +++ b/jemalloc/INSTALL @@ -132,8 +132,11 @@ any of the following arguments (not a definitive list) to 'configure': --disable-tls Disable thread-local storage (TLS), which allows for fast access to thread-local variables via the __thread keyword. If TLS is available, - jemalloc uses it for several purposes. Note that disabling TLS implies - --disable-tcache. + jemalloc uses it for several purposes. + +--with-xslroot= + Specify where to find DocBook XSL stylesheets when building the + documentation. The following environment variables (not a definitive list) impact configure's behavior: @@ -172,7 +175,7 @@ To install only parts of jemalloc, use the following targets: install_bin install_include install_lib - install_man + install_doc To clean up build results to varying degrees, use the following make targets: @@ -232,11 +235,12 @@ directory, issue configuration and build commands: === Documentation ============================================================== -The manual page that the configure script generates can be manually formatted +The manual page is generated in both html and roff formats. Any web browser +can be used to view the html manual. The roff manual page can be formatted prior to installation via any of the following commands: - nroff -man -man-ext -t doc/jemalloc.3 + nroff -man -t doc/jemalloc.3 - groff -man -man-ext -t -Tps doc/jemalloc.3 | ps2pdf - doc/jemalloc.3.pdf + groff -man -t -Tps doc/jemalloc.3 | ps2pdf - doc/jemalloc.3.pdf (cd doc; groff -man -man-ext -t -Thtml jemalloc.3 > jemalloc.3.html) diff --git a/jemalloc/Makefile.in b/jemalloc/Makefile.in index 46eddf46..ee674b33 100644 --- a/jemalloc/Makefile.in +++ b/jemalloc/Makefile.in @@ -15,6 +15,7 @@ DESTDIR = BINDIR := $(DESTDIR)@BINDIR@ INCLUDEDIR := $(DESTDIR)@INCLUDEDIR@ LIBDIR := $(DESTDIR)@LIBDIR@ +DATADIR := $(DESTDIR)@DATADIR@ MANDIR := $(DESTDIR)@MANDIR@ # Build parameters. @@ -58,15 +59,34 @@ DSOS := @objroot@lib/libjemalloc@install_suffix@.$(SO).$(REV) \ @objroot@lib/libjemalloc@install_suffix@.$(SO) \ @objroot@lib/libjemalloc@install_suffix@_pic.a MAN3 := @objroot@doc/jemalloc@install_suffix@.3 +DOCS_XML := @objroot@doc/jemalloc@install_suffix@.xml +DOCS_HTML := $(DOCS_XML:@objroot@%.xml=@srcroot@%.html) +DOCS_MAN3 := $(DOCS_XML:@objroot@%.xml=@srcroot@%.3) +DOCS := $(DOCS_HTML) $(DOCS_MAN3) CTESTS := @srcroot@test/allocated.c @srcroot@test/allocm.c \ - @srcroot@test/posix_memalign.c \ + @srcroot@test/mremap.c @srcroot@test/posix_memalign.c \ @srcroot@test/rallocm.c @srcroot@test/thread_arena.c -.PHONY: all dist install check clean distclean relclean +.PHONY: all dist doc_html doc_man doc +.PHONY: install_bin install_include install_lib +.PHONY: install_html install_man install_doc install +.PHONY: tests check clean distclean relclean # Default target. all: $(DSOS) +dist: doc + +@srcroot@doc/%.html : @objroot@doc/%.xml @srcroot@doc/stylesheet.xsl @objroot@doc/html.xsl + @XSLTPROC@ -o $@ @objroot@doc/html.xsl $< + +@srcroot@doc/%.3 : @objroot@doc/%.xml @srcroot@doc/stylesheet.xsl @objroot@doc/manpages.xsl + @XSLTPROC@ -o $@ @objroot@doc/manpages.xsl $< + +doc_html: $(DOCS_HTML) +doc_man: $(DOCS_MAN3) +doc: $(DOCS) + # # Include generated dependency files. # @@ -123,14 +143,23 @@ install_lib: $(DSOS) ln -sf libjemalloc@install_suffix@.$(SO).$(REV) $(LIBDIR)/libjemalloc@install_suffix@.$(SO) install -m 755 @objroot@lib/libjemalloc@install_suffix@_pic.a $(LIBDIR) -install_man: - install -d $(MANDIR)/man3 - @for m in $(MAN3); do \ - echo "install -m 644 $$m $(MANDIR)/man3"; \ - install -m 644 $$m $(MANDIR)/man3; \ +install_html: + install -d $(DATADIR)/doc/jemalloc@install_suffix@ + @for d in $(DOCS_HTML); do \ + echo "install -m 644 $$d $(DATADIR)/doc/jemalloc@install_suffix@"; \ + install -m 644 $$d $(DATADIR)/doc/jemalloc@install_suffix@; \ done -install: install_bin install_include install_lib install_man +install_man: + install -d $(MANDIR)/man3 + @for d in $(DOCS_MAN3); do \ + echo "install -m 644 $$d $(MANDIR)/man3"; \ + install -m 644 $$d $(MANDIR)/man3; \ +done + +install_doc: install_html install_man + +install: install_bin install_include install_lib install_doc tests: $(CTESTS:@srcroot@%.c=@objroot@%) @@ -182,6 +211,8 @@ distclean: clean relclean: distclean rm -f @objroot@configure rm -f @srcroot@VERSION + rm -f $(DOCS_HTML) + rm -f $(DOCS_MAN3) #=============================================================================== # Re-configuration rules. diff --git a/jemalloc/configure.ac b/jemalloc/configure.ac index 0ed13739..46a2bd4f 100644 --- a/jemalloc/configure.ac +++ b/jemalloc/configure.ac @@ -80,6 +80,19 @@ MANDIR=`eval echo $mandir` MANDIR=`eval echo $MANDIR` AC_SUBST([MANDIR]) +dnl Support for building documentation. +AC_PATH_PROG([XSLTPROC], [xsltproc], , [$PATH]) +AC_ARG_WITH([xslroot], + [AS_HELP_STRING([--with-xslroot=], [XSL stylesheet root path])], +if test "x$with_xslroot" = "xno" ; then + XSLROOT="/usr/share/xml/docbook/stylesheet/docbook-xsl" +else + XSLROOT="${with_xslroot}" +fi, + XSLROOT="/usr/share/xml/docbook/stylesheet/docbook-xsl" +) +AC_SUBST([XSLROOT]) + dnl If CFLAGS isn't defined, set CFLAGS to something reasonable. Otherwise, dnl just prevent autoconf from molesting CFLAGS. CFLAGS=$CFLAGS @@ -214,6 +227,16 @@ esac AC_SUBST([abi]) AC_SUBST([RPATH]) +JE_COMPILABLE([mremap(...MREMAP_FIXED...)], [ +#define _GNU_SOURCE +#include +], [ +void *p = mremap((void *)0, 0, 0, MREMAP_MAYMOVE|MREMAP_FIXED, (void *)0); +], [mremap_fixed]) +if test "x${mremap_fixed}" = "xyes" ; then + AC_DEFINE([JEMALLOC_MREMAP_FIXED]) +fi + dnl Support optional additions to rpath. AC_ARG_WITH([rpath], [AS_HELP_STRING([--with-rpath=], [Colon-separated rpath (ELF systems only)])], @@ -275,17 +298,26 @@ AC_ARG_WITH([install_suffix], install_suffix="$INSTALL_SUFFIX" AC_SUBST([install_suffix]) -cfgoutputs_in="${srcroot}Makefile.in ${srcroot}doc/jemalloc.3.in" +cfgoutputs_in="${srcroot}Makefile.in" +cfgoutputs_in="${cfgoutputs_in} ${srcroot}doc/html.xsl.in" +cfgoutputs_in="${cfgoutputs_in} ${srcroot}doc/manpages.xsl.in" +cfgoutputs_in="${cfgoutputs_in} ${srcroot}doc/jemalloc.xml.in" cfgoutputs_in="${cfgoutputs_in} ${srcroot}include/jemalloc/jemalloc.h.in" cfgoutputs_in="${cfgoutputs_in} ${srcroot}include/jemalloc/internal/jemalloc_internal.h.in" cfgoutputs_in="${cfgoutputs_in} ${srcroot}test/jemalloc_test.h.in" -cfgoutputs_out="Makefile doc/jemalloc${install_suffix}.3" +cfgoutputs_out="Makefile" +cfgoutputs_out="${cfgoutputs_out} doc/html.xsl" +cfgoutputs_out="${cfgoutputs_out} doc/manpages.xsl" +cfgoutputs_out="${cfgoutputs_out} doc/jemalloc${install_suffix}.xml" cfgoutputs_out="${cfgoutputs_out} include/jemalloc/jemalloc${install_suffix}.h" cfgoutputs_out="${cfgoutputs_out} include/jemalloc/internal/jemalloc_internal.h" cfgoutputs_out="${cfgoutputs_out} test/jemalloc_test.h" -cfgoutputs_tup="Makefile doc/jemalloc${install_suffix}.3:doc/jemalloc.3.in" +cfgoutputs_tup="Makefile" +cfgoutputs_tup="${cfgoutputs_tup} doc/html.xsl:doc/html.xsl.in" +cfgoutputs_tup="${cfgoutputs_tup} doc/manpages.xsl:doc/manpages.xsl.in" +cfgoutputs_tup="${cfgoutputs_tup} doc/jemalloc${install_suffix}.xml:doc/jemalloc.xml.in" cfgoutputs_tup="${cfgoutputs_tup} include/jemalloc/jemalloc${install_suffix}.h:include/jemalloc/jemalloc.h.in" cfgoutputs_tup="${cfgoutputs_tup} include/jemalloc/internal/jemalloc_internal.h" cfgoutputs_tup="${cfgoutputs_tup} test/jemalloc_test.h:test/jemalloc_test.h.in" @@ -329,15 +361,6 @@ if test "x$enable_debug" = "x1" ; then AC_DEFINE([JEMALLOC_IVSALLOC], [ ]) fi 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. if test "x$enable_debug" = "x0" -a "x$no_CFLAGS" = "xyes" ; then @@ -369,12 +392,6 @@ if test "x$enable_stats" = "x1" ; then AC_DEFINE([JEMALLOC_STATS], [ ]) fi AC_SUBST([enable_stats]) -if test "x$enable_stats" = "x0" ; then - roff_stats=".\\\" " -else - roff_stats="" -fi -AC_SUBST([roff_stats]) dnl Do not enable profiling by default. AC_ARG_ENABLE([prof], @@ -438,15 +455,6 @@ if test "x$enable_prof" = "x1" ; then fi fi AC_SUBST([enable_prof]) -if test "x$enable_prof" = "x0" ; then - roff_prof=".\\\" " - roff_no_prof="" -else - roff_prof="" - roff_no_prof=".\\\" " -fi -AC_SUBST([roff_prof]) -AC_SUBST([roff_no_prof]) dnl If libunwind isn't enabled, try to use libgcc rather than gcc intrinsics dnl for backtracing. @@ -478,15 +486,6 @@ if test "x$enable_tiny" = "x1" ; then AC_DEFINE([JEMALLOC_TINY], [ ]) fi AC_SUBST([enable_tiny]) -if test "x$enable_tiny" = "x0" ; then - roff_tiny=".\\\" " - roff_no_tiny="" -else - roff_tiny="" - roff_no_tiny=".\\\" " -fi -AC_SUBST([roff_tiny]) -AC_SUBST([roff_no_tiny]) dnl Enable thread-specific caching by default. AC_ARG_ENABLE([tcache], @@ -503,15 +502,6 @@ if test "x$enable_tcache" = "x1" ; then AC_DEFINE([JEMALLOC_TCACHE], [ ]) fi AC_SUBST([enable_tcache]) -if test "x$enable_tcache" = "x0" ; then - roff_tcache=".\\\" " - roff_no_tcache="" -else - roff_tcache="" - roff_no_tcache=".\\\" " -fi -AC_SUBST([roff_tcache]) -AC_SUBST([roff_no_tcache]) dnl Do not enable mmap()ped swap files by default. AC_ARG_ENABLE([swap], @@ -528,12 +518,6 @@ if test "x$enable_swap" = "x1" ; then AC_DEFINE([JEMALLOC_SWAP], [ ]) fi AC_SUBST([enable_swap]) -if test "x$enable_swap" = "x0" ; then - roff_swap=".\\\" " -else - roff_swap="" -fi -AC_SUBST([roff_swap]) dnl Do not enable allocation from DSS by default. AC_ARG_ENABLE([dss], @@ -550,12 +534,6 @@ if test "x$enable_dss" = "x1" ; then AC_DEFINE([JEMALLOC_DSS], [ ]) fi AC_SUBST([enable_dss]) -if test "x$enable_dss" = "x0" ; then - roff_dss=".\\\" " -else - roff_dss="" -fi -AC_SUBST([roff_dss]) dnl Do not support the junk/zero filling option by default. AC_ARG_ENABLE([fill], @@ -572,12 +550,6 @@ if test "x$enable_fill" = "x1" ; then AC_DEFINE([JEMALLOC_FILL], [ ]) fi AC_SUBST([enable_fill]) -if test "x$enable_fill" = "x0" ; then - roff_fill=".\\\" " -else - roff_fill="" -fi -AC_SUBST([roff_fill]) dnl Do not support the xmalloc option by default. AC_ARG_ENABLE([xmalloc], @@ -594,12 +566,6 @@ if test "x$enable_xmalloc" = "x1" ; then AC_DEFINE([JEMALLOC_XMALLOC], [ ]) fi AC_SUBST([enable_xmalloc]) -if test "x$enable_xmalloc" = "x0" ; then - roff_xmalloc=".\\\" " -else - roff_xmalloc="" -fi -AC_SUBST([roff_xmalloc]) dnl Do not support the SYSV option by default. AC_ARG_ENABLE([sysv], @@ -616,12 +582,6 @@ if test "x$enable_sysv" = "x1" ; then AC_DEFINE([JEMALLOC_SYSV], [ ]) fi AC_SUBST([enable_sysv]) -if test "x$enable_sysv" = "x0" ; then - roff_sysv=".\\\" " -else - roff_sysv="" -fi -AC_SUBST([roff_sysv]) dnl Do not determine page shift at run time by default. AC_ARG_ENABLE([dynamic_page_shift], @@ -828,6 +788,9 @@ AC_MSG_RESULT([LDFLAGS : ${LDFLAGS}]) AC_MSG_RESULT([LIBS : ${LIBS}]) AC_MSG_RESULT([RPATH_EXTRA : ${RPATH_EXTRA}]) AC_MSG_RESULT([]) +AC_MSG_RESULT([XSLTPROC : ${XSLTPROC}]) +AC_MSG_RESULT([XSLROOT : ${XSLROOT}]) +AC_MSG_RESULT([]) AC_MSG_RESULT([PREFIX : ${PREFIX}]) AC_MSG_RESULT([BINDIR : ${BINDIR}]) AC_MSG_RESULT([INCLUDEDIR : ${INCLUDEDIR}]) diff --git a/jemalloc/doc/html.xsl.in b/jemalloc/doc/html.xsl.in new file mode 100644 index 00000000..a91d9746 --- /dev/null +++ b/jemalloc/doc/html.xsl.in @@ -0,0 +1,4 @@ + + + + diff --git a/jemalloc/doc/jemalloc.3.in b/jemalloc/doc/jemalloc.3.in deleted file mode 100644 index 62866642..00000000 --- a/jemalloc/doc/jemalloc.3.in +++ /dev/null @@ -1,1688 +0,0 @@ -.\" Copyright (c) 2006-2010 Jason Evans . -.\" All rights reserved. -.\" Copyright (c) 2009 Facebook, Inc. All rights reserved. -.\" -.\" See COPYING for licensing terms provided by the above copyright holders. -.\" -.\" Copyright (c) 1980, 1991, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" This code is derived from software contributed to Berkeley by -.\" the American National Standards Committee X3, on Information -.\" Processing Systems. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" @(#)malloc.3 8.1 (Berkeley) 6/4/93 -.\" $FreeBSD: head/lib/libc/stdlib/malloc.3 182225 2008-08-27 02:00:53Z jasone $ -.\" -.Dd October 24, 2010 -.Dt jemalloc 3 -.Os -.Sh NAME -.Nm @jemalloc_prefix@malloc , -.Nm @jemalloc_prefix@calloc , -.Nm @jemalloc_prefix@posix_memalign , -.Nm @jemalloc_prefix@realloc , -.Nm @jemalloc_prefix@free , -.Nm @jemalloc_prefix@malloc_usable_size , -.Nm @jemalloc_prefix@malloc_stats_print , -.Nm @jemalloc_prefix@mallctl , -.Nm @jemalloc_prefix@mallctlnametomib , -.Nm @jemalloc_prefix@mallctlbymib , -.Nm @jemalloc_prefix@allocm , -.Nm @jemalloc_prefix@rallocm , -.Nm @jemalloc_prefix@sallocm , -.Nm @jemalloc_prefix@dallocm -.Nd general purpose memory allocation functions -.Sh LIBRARY -.Sy libjemalloc@install_suffix@ -.Pp -This manual describes jemalloc @jemalloc_version@. -More information can be found at the -.UR http://\:www.canonware.com/\:jemalloc/ -jemalloc website -.UE . -.Sh SYNOPSIS -.In stdlib.h -.In jemalloc/jemalloc@install_suffix@.h -.Ss Standard API -.Ft void * -.Fn @jemalloc_prefix@malloc "size_t size" -.Ft void * -.Fn @jemalloc_prefix@calloc "size_t number" "size_t size" -.Ft int -.Fn @jemalloc_prefix@posix_memalign "void **ptr" "size_t alignment" "size_t size" -.Ft void * -.Fn @jemalloc_prefix@realloc "void *ptr" "size_t size" -.Ft void -.Fn @jemalloc_prefix@free "void *ptr" -.Ss Non-standard API -.Ft size_t -.Fn @jemalloc_prefix@malloc_usable_size "const void *ptr" -.Ft void -.Fn @jemalloc_prefix@malloc_stats_print "void (*write_cb)(void *" "const char *)" "void *cbopaque" "const char *opts" -.Ft int -.Fn @jemalloc_prefix@mallctl "const char *name" "void *oldp" "size_t *oldlenp" "void *newp" "size_t newlen" -.Ft int -.Fn @jemalloc_prefix@mallctlnametomib "const char *name" "int *mibp" "size_t *miblenp" -.Ft int -.Fn @jemalloc_prefix@mallctlbymib "const size_t *mib" "size_t miblen" "void *oldp" "size_t *oldlenp" "void *newp" "size_t newlen" -.Ft const char * -.Va @jemalloc_prefix@malloc_conf ; -.Ft void -.Fn \*(lp*@jemalloc_prefix@malloc_message\*(rp "void *cbopaque" "const char *s" -.Ss Experimental API -.Ft int -.Fn @jemalloc_prefix@allocm "void **ptr" "size_t *rsize" "size_t size" "int flags" -.Ft int -.Fn @jemalloc_prefix@rallocm "void **ptr" "size_t *rsize" "size_t size" "size_t extra" "int flags" -.Ft int -.Fn @jemalloc_prefix@sallocm "const void *ptr" "size_t *rsize" "int flags" -.Ft int -.Fn @jemalloc_prefix@dallocm "void *ptr" "int flags" -.Sh DESCRIPTION -.Ss Standard API -The -.Fn @jemalloc_prefix@malloc -function allocates -.Fa size -bytes of uninitialized memory. -The allocated space is suitably aligned -@roff_tiny@(after possible pointer coercion) -for storage of any type of object. -.Pp -The -.Fn @jemalloc_prefix@calloc -function allocates space for -.Fa number -objects, -each -.Fa size -bytes in length. -The result is identical to calling -.Fn @jemalloc_prefix@malloc -with an argument of -.Dq "number * size" , -with the exception that the allocated memory is explicitly initialized -to zero bytes. -.Pp -The -.Fn @jemalloc_prefix@posix_memalign -function allocates -.Fa size -bytes of memory such that the allocation's base address is an even multiple of -.Fa alignment , -and returns the allocation in the value pointed to by -.Fa ptr . -The requested -.Fa alignment -must be a power of 2 at least as large as -.Fn sizeof "void *" . -.Pp -The -.Fn @jemalloc_prefix@realloc -function changes the size of the previously allocated memory referenced by -.Fa ptr -to -.Fa size -bytes. -The contents of the memory are unchanged up to the lesser of the new and -old sizes. -If the new size is larger, -the contents of the newly allocated portion of the memory are undefined. -Upon success, the memory referenced by -.Fa ptr -is freed and a pointer to the newly allocated memory is returned. -Note that -.Fn @jemalloc_prefix@realloc -may move the memory allocation, resulting in a different return value than -.Fa ptr . -If -.Fa ptr -is -.Dv NULL , -the -.Fn @jemalloc_prefix@realloc -function behaves identically to -.Fn @jemalloc_prefix@malloc -for the specified size. -.Pp -The -.Fn @jemalloc_prefix@free -function causes the allocated memory referenced by -.Fa ptr -to be made available for future allocations. -If -.Fa ptr -is -.Dv NULL , -no action occurs. -.Ss Non-standard API -The -.Fn @jemalloc_prefix@malloc_usable_size -function returns the usable size of the allocation pointed to by -.Fa ptr . -The return value may be larger than the size that was requested during -allocation. -The -.Fn @jemalloc_prefix@malloc_usable_size -function is not a mechanism for in-place -.Fn @jemalloc_prefix@realloc ; -rather it is provided solely as a tool for introspection purposes. -Any discrepancy between the requested allocation size and the size reported by -.Fn @jemalloc_prefix@malloc_usable_size -should not be depended on, since such behavior is entirely -implementation-dependent. -.Pp -The -.Fn @jemalloc_prefix@malloc_stats_print -function writes human-readable summary statistics via the -.Fa write_cb -callback function pointer and -.Fa cbopaque -data passed to -.Fn write_cb , -or -.Fn @jemalloc_prefix@malloc_message -if -.Fa write_cb -is -.Dv NULL . -This function can be called repeatedly. -General information that never changes -during execution can be omitted by specifying -.Dq g -as a character within the -.Fa opts -string. -Note that -.Fn @jemalloc_prefix@malloc_message -uses the -.Fn @jemalloc_prefix@mallctl* -functions internally, so inconsistent statistics can be reported if multiple -threads use these functions simultaneously. -@roff_stats@.Dq m -@roff_stats@and -@roff_stats@.Dq a -@roff_stats@can be specified to omit merged arena and per arena statistics, -@roff_stats@respectively. -@roff_stats@.Dq b -@roff_stats@and -@roff_stats@.Dq l -@roff_stats@can be specified to omit per size class statistics for bins and -@roff_stats@large objects, respectively. -Unrecognized characters are silently ignored. -@roff_tcache@Note that thread caching may prevent some statistics from being -@roff_tcache@completely up to date, since extra locking would be required to -@roff_tcache@merge counters that track thread cache operations. -.Pp -The -.Fn @jemalloc_prefix@mallctl -function provides a general interface for introspecting the memory allocator, -as well as setting modifiable parameters and triggering actions. -The period-separated -.Fa name -argument specifies a location in a tree-structured namespace; see the -.Sx "MALLCTL NAMESPACE" -section for documentation on the tree contents. -To read a value, pass a pointer via -.Fa oldp -to adequate space to contain the value, and a pointer to its length via -.Fa oldlenp ; -otherwise pass -.Dv NULL -and -.Dv NULL . -Similarly, to write a value, pass a pointer to the value via -.Fa newp , -and its length via -.Fa newlen ; -otherwise pass -.Dv NULL -and 0. -.Pp -The -.Fn @jemalloc_prefix@mallctlnametomib -function provides a way to avoid repeated name lookups for applications that -repeatedly query the same portion of the namespace, by translating a name to a -.Dq Management Information Base -(MIB) that can be passed repeatedly to -.Fn @jemalloc_prefix@mallctlbymib . -Upon successful return from -.Fn @jemalloc_prefix@mallctlnametomib , -.Fa mibp -contains an array of -.Fa *miblenp -integers, where -.Fa *miblenp -is the lesser of the number of components in -.Fa name -and the input value of -.Fa *miblenp . -Thus it is possible to pass a -.Fa *miblenp -that is smaller than the number of period-separated name components, which -results in a partial MIB that can be used as the basis for constructing a -complete MIB. -For name components that are integers (e.g. the 2 in -.Qq arenas.bin.2.size ) , -the corresponding MIB component will always be that integer. -Therefore, it is legitimate to construct code like the following: -.Pp -.Bd -literal -offset indent -compact -unsigned nbins, i; -int mib[4]; -size_t len, miblen; - -len = sizeof(nbins); -@jemalloc_prefix@mallctl("arenas.nbins", &nbins, &len, NULL, 0); - -miblen = 4; -@jemalloc_prefix@mallnametomib("arenas.bin.0.size", mib, &miblen); -for (i = 0; i < nbins; i++) { - size_t bin_size; - - mib[2] = i; - len = sizeof(bin_size); - @jemalloc_prefix@mallctlbymib(mib, miblen, &bin_size, &len, NULL, 0); - /* Do something with bin_size... */ -} -.Ed -.Ss Experimental API -The experimental API is subject to change or removal without regard for -backward compatibility. -.Pp -The -.Fn @jemalloc_prefix@allocm , -.Fn @jemalloc_prefix@rallocm , -.Fn @jemalloc_prefix@sallocm , -and -.Fn @jemalloc_prefix@dallocm -functions all have a -.Fa flags -argument that can be used to specify options. -The functions only check the options that are contextually relevant. -Use bitwise or (|) operations to specify one or more of the following: -.Bl -tag -width ".Dv ALLOCM_LG_ALIGN(la)" -.It ALLOCM_LG_ALIGN(la) -Align the memory allocation to start at an address that is a multiple of -(1 << -.Fa la ) . -This macro does not validate that -.Fa la -is within the valid range. -.It ALLOCM_ALIGN(a) -Align the memory allocation to start at an address that is a multiple of -.Fa a , -where -.Fa a -is a power of two. -This macro does not validate that -.Fa a -is a power of 2. -.It ALLOCM_ZERO -Initialize newly allocated memory to contain zero bytes. -In the growing reallocation case, the real size prior to reallocation defines -the boundary between untouched bytes and those that are initialized to contain -zero bytes. -If this option is absent, newly allocated memory is uninitialized. -.It ALLOCM_NO_MOVE -For reallocation, fail rather than moving the object. -This constraint can apply to both growth and shrinkage. -.El -.Pp -The -.Fn @jemalloc_prefix@allocm -function allocates at least -.Fa size -bytes of memory, sets -.Fa *ptr -to the base address of the allocation, and sets -.Fa *rsize -to the real size of the allocation if -.Fa rsize -is not -.Dv NULL . -.Pp -The -.Fn @jemalloc_prefix@rallocm -function resizes the allocation at -.Fa *ptr -to be at least -.Fa size -bytes, sets -.Fa *ptr -to the base address of the allocation if it moved, and sets -.Fa *rsize -to the real size of the allocation if -.Fa rsize -is not -.Dv NULL . -If -.Fa extra -is non-zero, an attempt is made to resize the allocation to be at least -.Fa ( size -+ -.Fa extra ) -bytes, though inability to allocate the extra byte(s) will not by itself result -in failure. -Behavior is undefined if -.Fa ( size -+ -.Fa extra -> -.Dv SIZE_T_MAX ) . -.Pp -The -.Fn @jemalloc_prefix@sallocm -function sets -.Fa *rsize -to the real size of the allocation. -.Pp -The -.Fn @jemalloc_prefix@dallocm -function causes the memory referenced by -.Fa ptr -to be made available for future allocations. -.Sh TUNING -Once, when the first call is made to one of the memory allocation routines, the -allocator initializes its internals based in part on various options that can -be specified at compile- or run-time. -.Pp -The string pointed to by the global variable -.Va @jemalloc_prefix@malloc_conf , -the -.Dq name -of the file referenced by the symbolic link named -.Pa /etc/@jemalloc_prefix@malloc.conf , -and the value of the environment variable -.Ev @jemalloc_cprefix@MALLOC_CONF , -will be interpreted, in that order, from left to right as options. -.Pp -An options string is a comma-separated list of option:value pairs. -There is one key corresponding to each -.Dq opt.* -mallctl. -For example, -.Dq abort:true,narenas:1 -sets the -.Dq opt.abort -and -.Dq opt.narenas -options. -Some options have boolean values (true/false), others have integer values (base -8, 10, or 16, depending on prefix), and yet others have raw string values. -.Sh IMPLEMENTATION NOTES -@roff_dss@Traditionally, allocators have used -@roff_dss@.Xr sbrk 2 -@roff_dss@to obtain memory, which is suboptimal for several reasons, including -@roff_dss@race conditions, increased fragmentation, and artificial limitations -@roff_dss@on maximum usable memory. -@roff_dss@This allocator uses both -@roff_dss@.Xr sbrk 2 -@roff_dss@and -@roff_dss@.Xr mmap 2 , -@roff_dss@in that order of preference. -.Pp -This allocator uses multiple arenas in order to reduce lock contention for -threaded programs on multi-processor systems. -This works well with regard to threading scalability, but incurs some costs. -There is a small fixed per-arena overhead, and additionally, arenas manage -memory completely independently of each other, which means a small fixed -increase in overall memory fragmentation. -These overheads are not generally an issue, given the number of arenas normally -used. -Note that using substantially more arenas than the default is not likely to -improve performance, mainly due to reduced cache performance. -However, it may make sense to reduce the number of arenas if an application -does not make much use of the allocation functions. -.Pp -@roff_tcache@In addition to multiple arenas, this allocator supports -@roff_tcache@thread-specific caching for small and large objects, in order to -@roff_tcache@make it possible to completely avoid synchronization for most -@roff_tcache@allocation requests. -@roff_tcache@Such caching allows very fast allocation in the common case, but it -@roff_tcache@increases memory usage and fragmentation, since a bounded number of -@roff_tcache@objects can remain allocated in each thread cache. -@roff_tcache@.Pp -Memory is conceptually broken into equal-sized chunks, where the chunk size is -a power of two that is greater than the page size. -Chunks are always aligned to multiples of the chunk size. -This alignment makes it possible to find metadata for user objects very -quickly. -.Pp -User objects are broken into three categories according to size: small, large, -and huge. -Small objects are smaller than one page. -Large objects are smaller than the chunk size. -Huge objects are a multiple of the chunk size. -Small and large objects are managed by arenas; huge objects are managed -separately in a single data structure that is shared by all threads. -Huge objects are used by applications infrequently enough that this single -data structure is not a scalability issue. -.Pp -Each chunk that is managed by an arena tracks its contents as runs of -contiguous pages (unused, backing a set of small objects, or backing one large -object). -The combination of chunk alignment and chunk page maps makes it possible to -determine all metadata regarding small and large allocations in constant time. -.Pp -Small objects are managed in groups by page runs. -Each run maintains a frontier and free list to track which regions are in use. -@roff_tiny@Allocation requests that are no more than half the quantum (8 or 16, -@roff_tiny@depending on architecture) are rounded up to the nearest power of -@roff_tiny@two. -Allocation requests that are -@roff_tiny@more than half the quantum, but -no more than the minimum cacheline-multiple size class (see the -.Dq opt.lg_qspace_max -option) are rounded up to the nearest multiple of the -@roff_tiny@quantum. -@roff_no_tiny@quantum (8 or 16, depending on architecture). -Allocation requests that are more than the minimum cacheline-multiple size -class, but no more than the minimum subpage-multiple size class (see the -.Dq opt.lg_cspace_max -option) are rounded up to the nearest multiple of the cacheline size (64). -Allocation requests that are more than the minimum subpage-multiple size class, -but no more than the maximum subpage-multiple size class are rounded up to the -nearest multiple of the subpage size (256). -Allocation requests that are more than the maximum subpage-multiple size class, -but small enough to fit in an arena-managed chunk (see the -.Dq opt.lg_chunk -option), are rounded up to the nearest run size. -Allocation requests that are too large to fit in an arena-managed chunk are -rounded up to the nearest multiple of the chunk size. -.Pp -Allocations are packed tightly together, which can be an issue for -multi-threaded applications. -If you need to assure that allocations do not suffer from cacheline sharing, -round your allocation requests up to the nearest multiple of the cacheline -size, or specify cacheline alignment when allocating. -.Pp -Assuming 4 MiB chunks, 4 KiB pages, and a 16-byte quantum on a 64-bit system, -the size classes in each category are as follows: -.\"----------------------------------------------------------------------------- -.TS -allbox tab(;); -LLL -LLL -^LL -^LL -^LL -LsL -LsL. -Category;Subcategory;Size -@roff_tiny@Small;Tiny;[8] -@roff_no_tiny@Small;Tiny;[disabled] -;Quantum-spaced;[16, 32, 48, ..., 128] -;Cacheline-spaced;[192, 256, 320, ..., 512] -;Sub-page-spaced;[768, 1024, 1280, ..., 3840] -Large;[4 KiB, 8 KiB, 12 KiB, ..., 4072 KiB] -Huge;[4 MiB, 8 MiB, 12 MiB, ...] -.TE -.\"----------------------------------------------------------------------------- -.Sh MALLCTL NAMESPACE -The following names are defined in the namespace accessible via the -.Fn @jemalloc_prefix@mallctl* -functions. -Value types are specified in parentheses, and their readable/writable statuses -are encoded as rw, r-, -w, or --. -A name element encoded as or indicates an integer component, where the -integer varies from 0 to some upper value that must be determined via -introspection. -@roff_stats@In the case of -@roff_stats@.Dq stats.arenas..* , -@roff_stats@ equal to -@roff_stats@.Dq arenas.narenas -@roff_stats@can be used to access the summation of statistics from all arenas. -.Pp -Take special note of the -.Dq epoch -mallctl, which controls refreshing of cached dynamic statistics. -.Bl -ohang -.\"----------------------------------------------------------------------------- -.It Sy "version (const char *) r-" -.Bd -ragged -offset indent -compact -Return the jemalloc version string. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "epoch (uint64_t) rw" -.Bd -ragged -offset indent -compact -If a value is passed in, refresh the data from which the -.Fn @jemalloc_prefix@mallctl* -functions report values, and increment the epoch. -Return the current epoch. -This is useful for detecting whether another thread caused a refresh. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "config.debug (bool) r-" -.Bd -ragged -offset indent -compact ---enable-debug was specified during build configuration. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "config.dss (bool) r-" -.Bd -ragged -offset indent -compact ---enable-dss was specified during build configuration. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "config.dynamic_page_shift (bool) r-" -.Bd -ragged -offset indent -compact ---enable-dynamic-page-shift was specified during build configuration. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "config.fill (bool) r-" -.Bd -ragged -offset indent -compact ---enable-fill was specified during build configuration. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "config.lazy_lock (bool) r-" -.Bd -ragged -offset indent -compact ---enable-lazy-lock was specified during build configuration. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "config.prof (bool) r-" -.Bd -ragged -offset indent -compact ---enable-prof was specified during build configuration. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "config.prof_libgcc (bool) r-" -.Bd -ragged -offset indent -compact ---disable-prof-libgcc was not specified during build configuration. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "config.prof_libunwind (bool) r-" -.Bd -ragged -offset indent -compact ---enable-prof-libunwind was specified during build configuration. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "config.stats (bool) r-" -.Bd -ragged -offset indent -compact ---enable-stats was specified during build configuration. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "config.swap (bool) r-" -.Bd -ragged -offset indent -compact ---enable-swap was specified during build configuration. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "config.sysv (bool) r-" -.Bd -ragged -offset indent -compact ---enable-sysv was specified during build configuration. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "config.tcache (bool) r-" -.Bd -ragged -offset indent -compact ---disable-tcache was not specified during build configuration. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "config.tiny (bool) r-" -.Bd -ragged -offset indent -compact ---disable-tiny was not specified during build configuration. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "config.tls (bool) r-" -.Bd -ragged -offset indent -compact ---disable-tls was not specified during build configuration. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "config.xmalloc (bool) r-" -.Bd -ragged -offset indent -compact ---enable-xmalloc was specified during build configuration. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "opt.abort (bool) r-" -.Bd -ragged -offset indent -compact -Abort-on-warning enabled/disabled. -If true, most warnings are fatal. -The process will call -.Xr abort 3 -in these cases. -This option is -@roff_debug@enabled -@roff_no_debug@disabled -by default. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "opt.lg_qspace_max (size_t) r-" -.Bd -ragged -offset indent -compact -Size (log base 2) of the maximum size class that is a multiple of the quantum -(8 or 16 bytes, depending on architecture). -Above this size, cacheline spacing is used for size classes. -The default value is 128 bytes (2^7). -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "opt.lg_cspace_max (size_t) r-" -.Bd -ragged -offset indent -compact -Size (log base 2) of the maximum size class that is a multiple of the cacheline -size (64). -Above this size, subpage spacing (256 bytes) is used for size classes. -The default value is 512 bytes (2^9). -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "opt.lg_chunk (size_t) r-" -.Bd -ragged -offset indent -compact -Virtual memory chunk size (log base 2). -The default chunk size is 4 MiB (2^22). -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "opt.narenas (size_t) r-" -.Bd -ragged -offset indent -compact -Maximum number of arenas to use. -The default maximum number of arenas is four times the number of CPUs, or one -if there is a single CPU. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "opt.lg_dirty_mult (ssize_t) r-" -.Bd -ragged -offset indent -compact -Per-arena minimum ratio (log base 2) of active to dirty pages. -Some dirty unused pages may be allowed to accumulate, within the limit set by -the ratio (or one chunk worth of dirty pages, whichever is greater), before -informing the kernel about some of those pages via -.Xr madvise 2 -or a similar system call. -This provides the kernel with sufficient information to recycle dirty pages if -physical memory becomes scarce and the pages remain unused. -The default minimum ratio is 32:1 (2^5:1); an option value of -1 will disable -dirty page purging. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "opt.stats_print (bool) r-" -.Bd -ragged -offset indent -compact -Enable/disable statistics printing at exit. -If enabled, the -.Fn @jemalloc_prefix@malloc_stats_print -function is called at program exit via an -.Xr atexit 3 -function. -@roff_stats@This has the potential to cause deadlock for a multi-threaded -@roff_stats@process that exits while one or more threads are executing in the -@roff_stats@memory allocation functions. -@roff_stats@Therefore, this option should only be used with care; it is -@roff_stats@primarily intended as a performance tuning aid during application -@roff_stats@development. -This option is disabled by default. -.Ed -.\"----------------------------------------------------------------------------- -@roff_fill@.It Sy "opt.junk (bool) r-" -@roff_fill@.Bd -ragged -offset indent -compact -@roff_fill@Junk filling enabled/disabled. -@roff_fill@If enabled, each byte of uninitialized allocated memory will be -@roff_fill@initialized to 0xa5. -@roff_fill@All deallocated memory will be initialized to 0x5a. -@roff_fill@This is intended for debugging and will impact performance -@roff_fill@negatively. -@roff_fill@This option is -@roff_fill@@roff_debug@enabled -@roff_fill@@roff_no_debug@disabled -@roff_fill@by default. -@roff_fill@.Ed -.\"----------------------------------------------------------------------------- -@roff_fill@.It Sy "opt.zero (bool) r-" -@roff_fill@.Bd -ragged -offset indent -compact -@roff_fill@Zero filling enabled/disabled. -@roff_fill@If enabled, each byte of uninitialized allocated memory will be -@roff_fill@initialized to 0. -@roff_fill@Note that this initialization only happens once for each byte, so -@roff_fill@.Fn @jemalloc_prefix@realloc -@roff_fill@calls do not zero memory that was previously allocated. -@roff_fill@This is intended for debugging and will impact performance -@roff_fill@negatively. -@roff_fill@This option is disabled by default. -@roff_fill@.Ed -.\"----------------------------------------------------------------------------- -@roff_sysv@.It Sy "opt.sysv (bool) r-" -@roff_sysv@.Bd -ragged -offset indent -compact -@roff_sysv@If enabled, attempting to allocate zero bytes will return a -@roff_sysv@.Dv NULL -@roff_sysv@pointer instead of a valid pointer. -@roff_sysv@(The default behavior is to make a minimal allocation and return a -@roff_sysv@pointer to it.) -@roff_sysv@This option is provided for System V compatibility. -@roff_sysv@@roff_xmalloc@This option is incompatible with the -@roff_sysv@@roff_xmalloc@.Dq opt.xmalloc -@roff_sysv@@roff_xmalloc@option. -@roff_sysv@This option is disabled by default. -@roff_sysv@.Ed -.\"----------------------------------------------------------------------------- -@roff_xmalloc@.It Sy "opt.xmalloc (bool) r-" -@roff_xmalloc@.Bd -ragged -offset indent -compact -@roff_xmalloc@Abort-on-out-of-memory enabled/disabled. -@roff_xmalloc@If enabled, rather than returning failure for any allocation -@roff_xmalloc@function, display a diagnostic message on -@roff_xmalloc@.Dv STDERR_FILENO -@roff_xmalloc@and cause the program to drop core (using -@roff_xmalloc@.Xr abort 3 ) . -@roff_xmalloc@If an application is designed to depend on this behavior, set the -@roff_xmalloc@option at compile time by including the following in the source -@roff_xmalloc@code: -@roff_xmalloc@.Bd -literal -offset indent -@roff_xmalloc@@jemalloc_prefix@malloc_conf = "xmalloc:true"; -@roff_xmalloc@.Ed -@roff_xmalloc@.Pp -@roff_xmalloc@This option is disabled by default. -@roff_xmalloc@.Ed -.\"----------------------------------------------------------------------------- -@roff_tcache@.It Sy "opt.tcache (bool) r-" -@roff_tcache@.Bd -ragged -offset indent -compact -@roff_tcache@Thread-specific caching enabled/disabled. -@roff_tcache@When there are multiple threads, each thread uses a -@roff_tcache@thread-specific cache for objects up to a certain size. -@roff_tcache@Thread-specific caching allows many allocations to be satisfied -@roff_tcache@without performing any thread synchronization, at the cost of -@roff_tcache@increased memory use. -@roff_tcache@See the -@roff_tcache@.Dq opt.lg_tcache_gc_sweep -@roff_tcache@and -@roff_tcache@.Dq opt.tcache_max -@roff_tcache@options for related tuning information. -@roff_tcache@This option is enabled by default. -@roff_tcache@.Ed -.\"----------------------------------------------------------------------------- -@roff_tcache@.It Sy "opt.lg_tcache_gc_sweep (ssize_t) r-" -@roff_tcache@.Bd -ragged -offset indent -compact -@roff_tcache@Approximate interval (log base 2) between full thread-specific -@roff_tcache@cache garbage collection sweeps, counted in terms of -@roff_tcache@thread-specific cache allocation/deallocation events. -@roff_tcache@Garbage collection is actually performed incrementally, one size -@roff_tcache@class at a time, in order to avoid large collection pauses. -@roff_tcache@The default sweep interval is 8192 (2^13); setting this option to -@roff_tcache@-1 will disable garbage collection. -@roff_tcache@.Ed -.\"----------------------------------------------------------------------------- -@roff_tcache@.It Sy "opt.lg_tcache_max (size_t) r-" -@roff_tcache@.Bd -ragged -offset indent -compact -@roff_tcache@Maximum size class (log base 2) to cache in the thread-specific -@roff_tcache@cache. -@roff_tcache@At a minimum, all small size classes are cached, and at a maximum -@roff_tcache@all large size classes are cached. -@roff_tcache@The default maximum is 32 KiB (2^15). -@roff_tcache@.Ed -.\"----------------------------------------------------------------------------- -@roff_prof@.It Sy "opt.prof (bool) r-" -@roff_prof@.Bd -ragged -offset indent -compact -@roff_prof@Memory profiling enabled/disabled. -@roff_prof@If enabled, profile memory allocation activity, and use an -@roff_prof@.Xr atexit 3 -@roff_prof@function to dump final memory usage to a file named according to -@roff_prof@the pattern -@roff_prof@.Pa ...f.heap , -@roff_prof@where -@roff_prof@.Pa -@roff_prof@is controlled by the -@roff_prof@.Dq opt.prof_prefix -@roff_prof@option. -@roff_prof@See the -@roff_prof@.Dq opt.lg_prof_bt_max -@roff_prof@option for backtrace depth control. -@roff_prof@See the -@roff_prof@.Dq opt.prof_active -@roff_prof@option for on-the-fly activation/deactivation. -@roff_prof@See the -@roff_prof@.Dq opt.lg_prof_sample -@roff_prof@option for probabilistic sampling control. -@roff_prof@See the -@roff_prof@.Dq opt.prof_accum -@roff_prof@option for control of cumulative sample reporting. -@roff_prof@See the -@roff_prof@.Dq opt.lg_prof_tcmax -@roff_prof@option for control of per thread backtrace caching. -@roff_prof@See the -@roff_prof@.Dq opt.lg_prof_interval -@roff_prof@option for information on interval-triggered profile dumping, and the -@roff_prof@.Dq opt.prof_gdump -@roff_prof@option for information on high-water-triggered profile dumping. -@roff_prof@Profile output is compatible with the included pprof Perl script, -@roff_prof@which originates from the -@roff_prof@.UR http://\:code.google.com/\:p/\:google-perftools/ -@roff_prof@google-perftools package -@roff_prof@.UE . -@roff_prof@.Ed -.\"----------------------------------------------------------------------------- -@roff_prof@.It Sy "opt.prof_prefix (const char *) r-" -@roff_prof@.Bd -ragged -offset indent -compact -@roff_prof@Filename prefix for profile dumps. -@roff_prof@If the prefix is set to the empty string, no automatic dumps will -@roff_prof@occur; this is primarily useful for disabling the automatic final -@roff_prof@heap dump (which also disables leak reporting, if enabled). -@roff_prof@The default prefix is -@roff_prof@.Pa jeprof . -@roff_prof@.Ed -.\"----------------------------------------------------------------------------- -@roff_prof@.It Sy "opt.lg_prof_bt_max (size_t) r-" -@roff_prof@.Bd -ragged -offset indent -compact -@roff_prof@Maximum backtrace depth (log base 2) when profiling memory -@roff_prof@allocation activity. -@roff_prof@The default is 128 (2^7). -@roff_prof@.Ed -.\"----------------------------------------------------------------------------- -@roff_prof@.It Sy "opt.prof_active (bool) r-" -@roff_prof@.Bd -ragged -offset indent -compact -@roff_prof@Profiling activated/deactivated. -@roff_prof@This is a secondary control mechanism that makes it possible to -@roff_prof@start the application with profiling enabled (see the -@roff_prof@.Dq opt.prof -@roff_prof@option) but inactive, then toggle profiling at any time during -@roff_prof@program execution with the -@roff_prof@.Dq prof.active -@roff_prof@mallctl. -@roff_prof@This option is enabled by default. -@roff_prof@.Ed -.\"----------------------------------------------------------------------------- -@roff_prof@.It Sy "opt.lg_prof_sample (ssize_t) r-" -@roff_prof@.Bd -ragged -offset indent -compact -@roff_prof@Average interval (log base 2) between allocation samples, as -@roff_prof@measured in bytes of allocation activity. -@roff_prof@Increasing the sampling interval decreases profile fidelity, but -@roff_prof@also decreases the computational overhead. -@roff_prof@The default sample interval is 1 (2^0) (i.e. all allocations are -@roff_prof@sampled). -@roff_prof@.Ed -.\"----------------------------------------------------------------------------- -@roff_prof@.It Sy "opt.prof_accum (bool) r-" -@roff_prof@.Bd -ragged -offset indent -compact -@roff_prof@Reporting of cumulative object/byte counts in profile dumps -@roff_prof@enabled/disabled. -@roff_prof@If this option is enabled, every unique backtrace must be stored for -@roff_prof@the duration of execution. -@roff_prof@Depending on the application, this can impose a large memory -@roff_prof@overhead, and the cumulative counts are not always of interest. -@roff_prof@See the -@roff_prof@.Dq opt.lg_prof_tcmax -@roff_prof@option for control of per thread backtrace caching, which has -@roff_prof@important interactions. -@roff_prof@This option is enabled by default. -@roff_prof@.Ed -.\"----------------------------------------------------------------------------- -@roff_prof@.It Sy "opt.lg_prof_tcmax (ssize_t) r-" -@roff_prof@.Bd -ragged -offset indent -compact -@roff_prof@Maximum per thread backtrace cache (log base 2) used for heap -@roff_prof@profiling. -@roff_prof@A backtrace can only be discarded if the -@roff_prof@.Dq opt.prof_accum -@roff_prof@option is disabled, and no thread caches currently refer to the -@roff_prof@backtrace. -@roff_prof@Therefore, a backtrace cache limit should be imposed if the -@roff_prof@intention is to limit how much memory is used by backtraces. -@roff_prof@By default, no limit is imposed (encoded as -1). -@roff_prof@.Ed -.\"----------------------------------------------------------------------------- -@roff_prof@.It Sy "opt.lg_prof_interval (ssize_t) r-" -@roff_prof@.Bd -ragged -offset indent -compact -@roff_prof@Average interval (log base 2) between memory profile dumps, as -@roff_prof@measured in bytes of allocation activity. -@roff_prof@The actual interval between dumps may be sporadic because -@roff_prof@decentralized allocation counters are used to avoid synchronization -@roff_prof@bottlenecks. -@roff_prof@Profiles are dumped to files named according to the pattern -@roff_prof@.Pa ...i.heap , -@roff_prof@where -@roff_prof@.Pa -@roff_prof@is controlled by the -@roff_prof@.Dq opt.prof_prefix -@roff_prof@option. -@roff_prof@By default, interval-triggered profile dumping is disabled (encoded -@roff_prof@as -1). -@roff_prof@.Ed -.\"----------------------------------------------------------------------------- -@roff_prof@.It Sy "opt.prof_gdump (bool) r-" -@roff_prof@.Bd -ragged -offset indent -compact -@roff_prof@Trigger a memory profile dump every time the total virtual memory -@roff_prof@exceeds the previous maximum. -@roff_prof@Profiles are dumped to files named according to the pattern -@roff_prof@.Pa ...u.heap , -@roff_prof@where -@roff_prof@.Pa -@roff_prof@is controlled by the -@roff_prof@.Dq opt.prof_prefix -@roff_prof@option. -@roff_prof@This option is disabled by default. -@roff_prof@.Ed -.\"----------------------------------------------------------------------------- -@roff_prof@.It Sy "opt.prof_leak (bool) r-" -@roff_prof@.Bd -ragged -offset indent -compact -@roff_prof@Leak reporting enabled/disabled. -@roff_prof@If enabled, use an -@roff_prof@.Xr atexit 3 -@roff_prof@function to report memory leaks detected by allocation sampling. -@roff_prof@See the -@roff_prof@.Dq opt.lg_prof_bt_max -@roff_prof@option for backtrace depth control. -@roff_prof@See the -@roff_prof@.Dq opt.prof -@roff_prof@option for information on analyzing heap profile output. -@roff_prof@This option is disabled by default. -@roff_prof@.Ed -.\"----------------------------------------------------------------------------- -.It Sy "opt.overcommit (bool) r-" -.Bd -ragged -offset indent -compact -@roff_swap@Over-commit enabled/disabled. -@roff_swap@If enabled, over-commit memory as a side effect of using anonymous -@roff_swap@.Xr mmap 2 -@roff_swap@@roff_dss@ and -@roff_swap@@roff_dss@.Xr sbrk 2 -@roff_swap@for virtual memory allocation. -@roff_swap@In order for overcommit to be disabled, the -@roff_swap@.Dq swap.fds -@roff_swap@mallctl must have been successfully written to. -@roff_swap@This option is enabled by default. -.Ed -.\"----------------------------------------------------------------------------- -@roff_tcache@.It Sy "tcache.flush (void) --" -@roff_tcache@.Bd -ragged -offset indent -compact -@roff_tcache@Flush calling thread's tcache. -@roff_tcache@This interface releases all cached objects and internal data -@roff_tcache@structures associated with the calling thread's thread-specific -@roff_tcache@cache. -@roff_tcache@Ordinarily, this interface need not be called, since automatic -@roff_tcache@periodic incremental garbage collection occurs, and the thread -@roff_tcache@cache is automatically discarded when a thread exits. -@roff_tcache@However, garbage collection is triggered by allocation activity, -@roff_tcache@so it is possible for a thread that stops allocating/deallocating -@roff_tcache@to retain its cache indefinitely, in which case the developer may -@roff_tcache@find manual flushing useful. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "thread.arena (unsigned) rw" -.Bd -ragged -offset indent -compact -Get or set the arena associated with the calling thread. -The arena index must be less than the maximum number of arenas (see the -.Dq arenas.narenas -mallctl). -If the specified arena was not initialized beforehand (see the -.Dq arenas.initialized -mallctl), it will be automatically initialized as a side effect of calling this -interface. -.Ed -.\"----------------------------------------------------------------------------- -@roff_stats@.It Sy "thread.allocated (uint64_t) r-" -@roff_stats@.Bd -ragged -offset indent -compact -@roff_stats@Get the total number of bytes ever allocated by the calling thread. -@roff_stats@This counter has the potential to wrap around; it is up to the -@roff_stats@application to appropriately interpret the counter in such cases. -@roff_stats@.Ed -.\"----------------------------------------------------------------------------- -@roff_stats@.It Sy "thread.deallocated (uint64_t) r-" -@roff_stats@.Bd -ragged -offset indent -compact -@roff_stats@Get the total number of bytes ever deallocated by the calling -@roff_stats@thread. -@roff_stats@This counter has the potential to wrap around; it is up to the -@roff_stats@application to appropriately interpret the counter in such cases. -@roff_stats@.Ed -.\"----------------------------------------------------------------------------- -.It Sy "arenas.narenas (unsigned) r-" -.Bd -ragged -offset indent -compact -Maximum number of arenas. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "arenas.initialized (bool *) r-" -.Bd -ragged -offset indent -compact -An array of arenas.narenas booleans. -Each boolean indicates whether the corresponding arena is initialized. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "arenas.quantum (size_t) r-" -.Bd -ragged -offset indent -compact -Quantum size. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "arenas.cacheline (size_t) r-" -.Bd -ragged -offset indent -compact -Assumed cacheline size. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "arenas.subpage (size_t) r-" -.Bd -ragged -offset indent -compact -Subpage size class interval. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "arenas.pagesize (size_t) r-" -.Bd -ragged -offset indent -compact -Page size. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "arenas.chunksize (size_t) r-" -.Bd -ragged -offset indent -compact -Chunk size. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "arenas.tspace_min (size_t) r-" -.Bd -ragged -offset indent -compact -Minimum tiny size class. -Tiny size classes are powers of two. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "arenas.tspace_max (size_t) r-" -.Bd -ragged -offset indent -compact -Maximum tiny size class. -Tiny size classes are powers of two. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "arenas.qspace_min (size_t) r-" -.Bd -ragged -offset indent -compact -Minimum quantum-spaced size class. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "arenas.qspace_max (size_t) r-" -.Bd -ragged -offset indent -compact -Maximum quantum-spaced size class. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "arenas.cspace_min (size_t) r-" -.Bd -ragged -offset indent -compact -Minimum cacheline-spaced size class. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "arenas.cspace_max (size_t) r-" -.Bd -ragged -offset indent -compact -Maximum cacheline-spaced size class. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "arenas.sspace_min (size_t) r-" -.Bd -ragged -offset indent -compact -Minimum subpage-spaced size class. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "arenas.sspace_max (size_t) r-" -.Bd -ragged -offset indent -compact -Maximum subpage-spaced size class. -.Ed -.\"----------------------------------------------------------------------------- -@roff_tcache@.It Sy "arenas.tcache_max (size_t) r-" -@roff_tcache@.Bd -ragged -offset indent -compact -@roff_tcache@Maximum thread-cached size class. -@roff_tcache@.Ed -.\"----------------------------------------------------------------------------- -.It Sy "arenas.ntbins (unsigned) r-" -.Bd -ragged -offset indent -compact -Number of tiny bin size classes. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "arenas.nqbins (unsigned) r-" -.Bd -ragged -offset indent -compact -Number of quantum-spaced bin size classes. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "arenas.ncbins (unsigned) r-" -.Bd -ragged -offset indent -compact -Number of cacheline-spaced bin size classes. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "arenas.nsbins (unsigned) r-" -.Bd -ragged -offset indent -compact -Number of subpage-spaced bin size classes. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "arenas.nbins (unsigned) r-" -.Bd -ragged -offset indent -compact -Total number of bin size classes. -.Ed -.\"----------------------------------------------------------------------------- -@roff_tcache@.It Sy "arenas.nhbins (unsigned) r-" -@roff_tcache@.Bd -ragged -offset indent -compact -@roff_tcache@Total number of thread cache bin size classes. -@roff_tcache@.Ed -.\"----------------------------------------------------------------------------- -.It Sy "arenas.bin..size (size_t) r-" -.Bd -ragged -offset indent -compact -Maximum size supported by size class. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "arenas.bin..nregs (uint32_t) r-" -.Bd -ragged -offset indent -compact -Number of regions per page run. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "arenas.bin..run_size (size_t) r-" -.Bd -ragged -offset indent -compact -Number of bytes per page run. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "arenas.nlruns (size_t) r-" -.Bd -ragged -offset indent -compact -Total number of large size classes. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "arenas.lrun..size (size_t) r-" -.Bd -ragged -offset indent -compact -Maximum size supported by this large size class. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "arenas.purge (unsigned) -w" -.Bd -ragged -offset indent -compact -Purge unused dirty pages for the specified arena, or for all arenas if none is -specified. -.Ed -.\"----------------------------------------------------------------------------- -@roff_prof@.It Sy "prof.active (bool) rw" -@roff_prof@.Bd -ragged -offset indent -compact -@roff_prof@Control whether sampling is currently active. -@roff_prof@See the -@roff_prof@.Dq opt.prof_active -@roff_prof@option for additional information. -@roff_prof@.Ed -.\"----------------------------------------------------------------------------- -@roff_prof@.It Sy "prof.dump (const char *) -w" -@roff_prof@.Bd -ragged -offset indent -compact -@roff_prof@Dump a memory profile to the specified file, or if NULL is specified, -@roff_prof@to a file according to the pattern -@roff_prof@.Pa ...m.heap , -@roff_prof@where -@roff_prof@.Pa -@roff_prof@is controlled by the -@roff_prof@.Dq opt.prof_prefix -@roff_prof@option. -@roff_prof@.Ed -.\"----------------------------------------------------------------------------- -@roff_prof@.It Sy "prof.interval (uint64_t) r-" -@roff_prof@.Bd -ragged -offset indent -compact -@roff_prof@Average number of bytes allocated between inverval-based profile -@roff_prof@dumps. -@roff_prof@See the -@roff_prof@.Dq opt.lg_prof_interval -@roff_prof@option for additional information. -@roff_prof@.Ed -.\"----------------------------------------------------------------------------- -@roff_stats@.It Sy "stats.allocated (size_t) r-" -@roff_stats@.Bd -ragged -offset indent -compact -@roff_stats@Total number of bytes allocated by the application. -@roff_stats@.Ed -.\"----------------------------------------------------------------------------- -@roff_stats@.It Sy "stats.active (size_t) r-" -@roff_stats@.Bd -ragged -offset indent -compact -@roff_stats@Total number of bytes in active pages allocated by the application. -@roff_stats@This is a multiple of the page size, and greater than or equal to -@roff_stats@.Dq stats.allocated . -@roff_stats@.Ed -.\"----------------------------------------------------------------------------- -@roff_stats@.It Sy "stats.mapped (size_t) r-" -@roff_stats@.Bd -ragged -offset indent -compact -@roff_stats@Total number of bytes in chunks mapped on behalf of the application. -@roff_stats@This is a multiple of the chunk size, and is at least as large as -@roff_stats@.Dq stats.active . -@roff_stats@@roff_swap@This does not include inactive chunks backed by swap -@roff_stats@@roff_swap@files. -@roff_stats@@roff_dss@This does not include inactive chunks embedded in the DSS. -@roff_stats@.Ed -.\"----------------------------------------------------------------------------- -@roff_stats@.It Sy "stats.chunks.current (size_t) r-" -@roff_stats@.Bd -ragged -offset indent -compact -@roff_stats@Total number of chunks actively mapped on behalf of the application. -@roff_stats@@roff_swap@This does not include inactive chunks backed by swap -@roff_stats@@roff_swap@files. -@roff_stats@@roff_dss@This does not include inactive chunks embedded in the DSS. -@roff_stats@.Ed -.\"----------------------------------------------------------------------------- -@roff_stats@.It Sy "stats.chunks.total (uint64_t) r-" -@roff_stats@.Bd -ragged -offset indent -compact -@roff_stats@Cumulative number of chunks allocated. -@roff_stats@.Ed -.\"----------------------------------------------------------------------------- -@roff_stats@.It Sy "stats.chunks.high (size_t) r-" -@roff_stats@.Bd -ragged -offset indent -compact -@roff_stats@Maximum number of active chunks at any time thus far. -@roff_stats@.Ed -.\"----------------------------------------------------------------------------- -@roff_stats@.It Sy "stats.huge.allocated (size_t) r-" -@roff_stats@.Bd -ragged -offset indent -compact -@roff_stats@Number of bytes currently allocated by huge objects. -@roff_stats@.Ed -.\"----------------------------------------------------------------------------- -@roff_stats@.It Sy "stats.huge.nmalloc (uint64_t) r-" -@roff_stats@.Bd -ragged -offset indent -compact -@roff_stats@Cumulative number of huge allocation requests. -@roff_stats@.Ed -.\"----------------------------------------------------------------------------- -@roff_stats@.It Sy "stats.huge.ndalloc (uint64_t) r-" -@roff_stats@.Bd -ragged -offset indent -compact -@roff_stats@Cumulative number of huge deallocation requests. -@roff_stats@.Ed -.\"----------------------------------------------------------------------------- -.It Sy "stats.arenas..pactive (size_t) r-" -.Bd -ragged -offset indent -compact -Number of pages in active runs. -.Ed -.\"----------------------------------------------------------------------------- -.It Sy "stats.arenas..pdirty (size_t) r-" -.Bd -ragged -offset indent -compact -Number of pages within unused runs that are potentially dirty, and for which -.Fn madvise "..." "MADV_DONTNEED" -has not been called. -.Ed -.\"----------------------------------------------------------------------------- -@roff_stats@.It Sy "stats.arenas..mapped (size_t) r-" -@roff_stats@.Bd -ragged -offset indent -compact -@roff_stats@Number of mapped bytes. -@roff_stats@.Ed -.\"----------------------------------------------------------------------------- -@roff_stats@.It Sy "stats.arenas..npurge (uint64_t) r-" -@roff_stats@.Bd -ragged -offset indent -compact -@roff_stats@Number of dirty page purge sweeps performed. -@roff_stats@.Ed -.\"----------------------------------------------------------------------------- -@roff_stats@.It Sy "stats.arenas..nmadvise (uint64_t) r-" -@roff_stats@.Bd -ragged -offset indent -compact -@roff_stats@Number of -@roff_stats@.Fn madvise "..." "MADV_DONTNEED" -@roff_stats@calls made to purge dirty pages. -@roff_stats@.Ed -.\"----------------------------------------------------------------------------- -@roff_stats@.It Sy "stats.arenas..npurged (uint64_t) r-" -@roff_stats@.Bd -ragged -offset indent -compact -@roff_stats@Number of pages purged. -@roff_stats@.Ed -.\"----------------------------------------------------------------------------- -@roff_stats@.It Sy "stats.arenas..small.allocated (size_t) r-" -@roff_stats@.Bd -ragged -offset indent -compact -@roff_stats@Number of bytes currently allocated by small objects. -@roff_stats@.Ed -.\"----------------------------------------------------------------------------- -@roff_stats@.It Sy "stats.arenas..small.nmalloc (uint64_t) r-" -@roff_stats@.Bd -ragged -offset indent -compact -@roff_stats@Cumulative number of allocation requests served by small bins. -@roff_stats@.Ed -.\"----------------------------------------------------------------------------- -@roff_stats@.It Sy "stats.arenas..small.ndalloc (uint64_t) r-" -@roff_stats@.Bd -ragged -offset indent -compact -@roff_stats@Cumulative number of small objects returned to bins. -@roff_stats@.Ed -.\"----------------------------------------------------------------------------- -@roff_stats@.It Sy "stats.arenas..small.nrequests (uint64_t) r-" -@roff_stats@.Bd -ragged -offset indent -compact -@roff_stats@Cumulative number of small allocation requests. -@roff_stats@.Ed -.\"----------------------------------------------------------------------------- -@roff_stats@.It Sy "stats.arenas..large.allocated (size_t) r-" -@roff_stats@.Bd -ragged -offset indent -compact -@roff_stats@Number of bytes currently allocated by large objects. -@roff_stats@.Ed -.\"----------------------------------------------------------------------------- -@roff_stats@.It Sy "stats.arenas..large.nmalloc (uint64_t) r-" -@roff_stats@.Bd -ragged -offset indent -compact -@roff_stats@Cumulative number of large allocation requests served directly by -@roff_stats@the arena. -@roff_stats@.Ed -.\"----------------------------------------------------------------------------- -@roff_stats@.It Sy "stats.arenas..large.ndalloc (uint64_t) r-" -@roff_stats@.Bd -ragged -offset indent -compact -@roff_stats@Cumulative number of large deallocation requests served directly by -@roff_stats@the arena. -@roff_stats@.Ed -.\"----------------------------------------------------------------------------- -@roff_stats@.It Sy "stats.arenas..large.nrequests (uint64_t) r-" -@roff_stats@.Bd -ragged -offset indent -compact -@roff_stats@Cumulative number of large allocation requests. -@roff_stats@.Ed -.\"----------------------------------------------------------------------------- -@roff_stats@.It Sy "stats.arenas..bins..allocated (size_t) r-" -@roff_stats@.Bd -ragged -offset indent -compact -@roff_stats@Current number of bytes allocated by bin. -@roff_stats@.Ed -.\"----------------------------------------------------------------------------- -@roff_stats@.It Sy "stats.arenas..bins..nmalloc (uint64_t) r-" -@roff_stats@.Bd -ragged -offset indent -compact -@roff_stats@Cumulative number of allocations served by bin. -@roff_stats@.Ed -.\"----------------------------------------------------------------------------- -@roff_stats@.It Sy "stats.arenas..bins..ndalloc (uint64_t) r-" -@roff_stats@.Bd -ragged -offset indent -compact -@roff_stats@Cumulative number of allocations returned to bin. -@roff_stats@.Ed -.\"----------------------------------------------------------------------------- -@roff_stats@.It Sy "stats.arenas..bins..nrequests (uint64_t) r-" -@roff_stats@.Bd -ragged -offset indent -compact -@roff_stats@Cumulative number of allocation requests. -@roff_stats@.Ed -.\"----------------------------------------------------------------------------- -@roff_stats@@roff_tcache@.It Sy "stats.arenas..bins..nfills (uint64_t) r-" -@roff_stats@@roff_tcache@.Bd -ragged -offset indent -compact -@roff_stats@@roff_tcache@Cumulative number of tcache fills. -@roff_stats@@roff_tcache@.Ed -.\"----------------------------------------------------------------------------- -@roff_stats@@roff_tcache@.It Sy "stats.arenas..bins..nflushes (uint64_t) r-" -@roff_stats@@roff_tcache@.Bd -ragged -offset indent -compact -@roff_stats@@roff_tcache@Cumulative number of tcache flushes. -@roff_stats@@roff_tcache@.Ed -.\"----------------------------------------------------------------------------- -@roff_stats@.It Sy "stats.arenas..bins..nruns (uint64_t) r-" -@roff_stats@.Bd -ragged -offset indent -compact -@roff_stats@Cumulative number of runs created. -@roff_stats@.Ed -.\"----------------------------------------------------------------------------- -@roff_stats@.It Sy "stats.arenas..bins..nreruns (uint64_t) r-" -@roff_stats@.Bd -ragged -offset indent -compact -@roff_stats@Cumulative number of times the current run from which to allocate -@roff_stats@changed. -@roff_stats@.Ed -.\"----------------------------------------------------------------------------- -@roff_stats@.It Sy "stats.arenas..bins..highruns (size_t) r-" -@roff_stats@.Bd -ragged -offset indent -compact -@roff_stats@Maximum number of runs at any time thus far. -@roff_stats@.Ed -.\"----------------------------------------------------------------------------- -@roff_stats@.It Sy "stats.arenas..bins..curruns (size_t) r-" -@roff_stats@.Bd -ragged -offset indent -compact -@roff_stats@Current number of runs. -@roff_stats@.Ed -.\"----------------------------------------------------------------------------- -@roff_stats@.It Sy "stats.arenas..lruns..nmalloc (uint64_t) r-" -@roff_stats@.Bd -ragged -offset indent -compact -@roff_stats@Cumulative number of allocation requests for this size class served -@roff_stats@directly by the arena. -@roff_stats@.Ed -.\"----------------------------------------------------------------------------- -@roff_stats@.It Sy "stats.arenas..lruns..ndalloc (uint64_t) r-" -@roff_stats@.Bd -ragged -offset indent -compact -@roff_stats@Cumulative number of deallocation requests for this size class -@roff_stats@served directly by the arena. -@roff_stats@.Ed -.\"----------------------------------------------------------------------------- -@roff_stats@.It Sy "stats.arenas..lruns..nrequests (uint64_t) r-" -@roff_stats@.Bd -ragged -offset indent -compact -@roff_stats@Cumulative number of allocation requests for this size class. -@roff_stats@.Ed -.\"----------------------------------------------------------------------------- -@roff_stats@.It Sy "stats.arenas..lruns..highruns (size_t) r-" -@roff_stats@.Bd -ragged -offset indent -compact -@roff_stats@Maximum number of runs at any time thus far for this size class. -@roff_stats@.Ed -.\"----------------------------------------------------------------------------- -@roff_stats@.It Sy "stats.arenas..lruns..curruns (size_t) r-" -@roff_stats@.Bd -ragged -offset indent -compact -@roff_stats@Current number of runs for this size class. -@roff_stats@.Ed -.\"----------------------------------------------------------------------------- -@roff_stats@@roff_swap@.It Sy "swap.avail (size_t) r-" -@roff_stats@@roff_swap@.Bd -ragged -offset indent -compact -@roff_stats@@roff_swap@Number of swap file bytes that are currently not -@roff_stats@@roff_swap@associated with any chunk (i.e. mapped, but otherwise -@roff_stats@@roff_swap@completely unmanaged). -@roff_stats@@roff_swap@.Ed -.\"----------------------------------------------------------------------------- -@roff_swap@.It Sy "swap.prezeroed (bool) rw" -@roff_swap@.Bd -ragged -offset indent -compact -@roff_swap@If true, the allocator assumes that the swap file(s) contain nothing -@roff_swap@but nil bytes. -@roff_swap@If this assumption is violated, allocator behavior is undefined. -@roff_swap@This value becomes read-only after -@roff_swap@.Dq swap.fds -@roff_swap@is successfully written to. -@roff_swap@.Ed -.\"----------------------------------------------------------------------------- -@roff_swap@.It Sy "swap.nfds (size_t) r-" -@roff_swap@.Bd -ragged -offset indent -compact -@roff_swap@Number of file descriptors in use for swap. -@roff_swap@.Ed -.\"----------------------------------------------------------------------------- -@roff_swap@.It Sy "swap.fds (int *) r-" -@roff_swap@.Bd -ragged -offset indent -compact -@roff_swap@When written to, the files associated with the specified file -@roff_swap@descriptors are contiguously mapped via -@roff_swap@.Xr mmap 2 . -@roff_swap@The resulting virtual memory region is preferred over anonymous -@roff_swap@.Xr mmap 2 -@roff_swap@@roff_dss@and -@roff_swap@@roff_dss@.Xr sbrk 2 -@roff_swap@memory. -@roff_swap@Note that if a file's size is not a multiple of the page size, it is -@roff_swap@automatically truncated to the nearest page size multiple. -@roff_swap@See the -@roff_swap@.Dq swap.prezeroed -@roff_swap@interface for specifying that the files are pre-zeroed. -@roff_swap@.Ed -.\"----------------------------------------------------------------------------- -.El -.Sh DEBUGGING MALLOC PROBLEMS -Start by setting the -.Dq opt.abort -option, which forces a coredump (if possible) at the first sign of trouble, -rather than the normal policy of trying to continue if at all possible. -.Pp -It is probably also a good idea to recompile the program with suitable -options and symbols for debugger support. -.Pp -@roff_fill@If the program starts to give unusual results, coredump or generally -@roff_fill@behave differently without emitting any of the messages mentioned in -@roff_fill@the next section, it is likely because the program depends on the -@roff_fill@storage being filled with zero bytes. -@roff_fill@Try running it with the -@roff_fill@.Dq opt.zero -@roff_fill@option set; -@roff_fill@if that improves the situation, this diagnosis has been confirmed. -@roff_fill@If the program still misbehaves, -@roff_fill@the likely problem is accessing memory outside the allocated area. -@roff_fill@.Pp -@roff_fill@Alternatively, if the symptoms are not easy to reproduce, setting the -@roff_fill@.Dq opt.junk -@roff_fill@option may help provoke the problem. -@roff_fill@.Pp -This implementation does not provide much detail about the problems it detects, -because the performance impact for storing such information would be -prohibitive. -There are a number of allocator implementations available on the Internet -which focus on detecting and pinpointing problems by trading performance for -extra sanity checks and detailed diagnostics. -.Sh DIAGNOSTIC MESSAGES -If any of the memory allocation/deallocation functions detect an error or -warning condition, a message will be printed to file descriptor -.Dv STDERR_FILENO . -Errors will result in the process dumping core. -If the -.Dq opt.abort -option is set, most warnings are treated as errors. -.Pp -The -.Va @jemalloc_prefix@malloc_message -variable allows the programmer to override the function which emits the text -strings forming the errors and warnings if for some reason the -.Dv STDERR_FILENO -file descriptor is not suitable for this. -.Va @jemalloc_prefix@malloc_message -takes the -.Fa cbopaque -pointer argument that is -.Dv NULL -unless overridden by the arguments in a call to -.Fn @jemalloc_prefix@malloc_stats_print , -followed by a string pointer. -Please note that doing anything which tries to allocate memory in this function -is likely to result in a crash or deadlock. -.Pp -All messages are prefixed by -.Dq : . -.Sh RETURN VALUES -.Ss Standard API -The -.Fn @jemalloc_prefix@malloc -and -.Fn @jemalloc_prefix@calloc -functions return a pointer to the allocated memory if successful; otherwise -a -.Dv NULL -pointer is returned and -.Va errno -is set to -.Er ENOMEM . -.Pp -The -.Fn @jemalloc_prefix@posix_memalign -function returns the value 0 if successful; otherwise it returns an error value. -The -.Fn @jemalloc_prefix@posix_memalign -function will fail if: -.Bl -tag -width Er -.It Bq Er EINVAL -The -.Fa alignment -parameter is not a power of 2 at least as large as -.Fn sizeof "void *" . -.It Bq Er ENOMEM -Memory allocation error. -.El -.Pp -The -.Fn @jemalloc_prefix@realloc -function returns a pointer, possibly identical to -.Fa ptr , -to the allocated memory -if successful; otherwise a -.Dv NULL -pointer is returned, and -.Va errno -is set to -.Er ENOMEM -if the error was the result of an allocation failure. -The -.Fn @jemalloc_prefix@realloc -function always leaves the original buffer intact -when an error occurs. -.Pp -The -.Fn @jemalloc_prefix@free -function returns no value. -.Ss Non-standard API -The -.Fn @jemalloc_prefix@malloc_usable_size -function returns the usable size of the allocation pointed to by -.Fa ptr . -.Pp -The -.Fn @jemalloc_prefix@mallctl , -.Fn @jemalloc_prefix@mallctlnametomib , -and -.Fn @jemalloc_prefix@mallctlbymib -functions return 0 on success; otherwise they return an error value. -The functions will fail if: -.Bl -tag -width Er -.It Bq Er EINVAL -.Fa newp -is -.Dv non-NULL , -and -.Fa newlen -is too large or too small. -Alternatively, -.Fa *oldlenp -is too large or too small; in this case as much data as possible are read -despite the error. -.It Bq Er ENOMEM -.Fa *oldlenp -is too short to hold the requested value. -.It Bq Er ENOENT -.Fa name -or -.Fa mib -specifies an unknown/invalid value. -.It Bq Er EPERM -Attempt to read or write void value, or attempt to write read-only value. -.It Bq Er EAGAIN -A memory allocation failure occurred. -.It Bq Er EFAULT -An interface with side effects failed in some way not directly related to -.Fn @jemalloc_prefix@mallctl* -read/write processing. -.El -.Ss Experimental API -The -.Fn @jemalloc_prefix@allocm , -.Fn @jemalloc_prefix@rallocm , -.Fn @jemalloc_prefix@sallocm , -and -.Fn @jemalloc_prefix@dallocm -functions return -.Dv ALLOCM_SUCCESS -on success; otherwise they return an error value. -The -.Fn @jemalloc_prefix@allocm -and -.Fn @jemalloc_prefix@rallocm -functions will fail if: -.Bl -tag -width ".Bq Er ALLOCM_ERR_OOM" -.It Bq Er ALLOCM_ERR_OOM -Out of memory. -Insufficient contiguous memory was available to service the allocation request. -The -.Fn @jemalloc_prefix@allocm -function additionally sets -.Fa *ptr -to -.Dv NULL , -whereas the -.Fn @jemalloc_prefix@rallocm -function leaves -.Fa *ptr -unmodified. -.El -.Pp -The -.Fn @jemalloc_prefix@rallocm -function will also fail if: -.Bl -tag -width ".Bq Er ALLOCM_ERR_NOT_MOVED" -.It Bq Er ALLOCM_ERR_NOT_MOVED -.Dv ALLOCM_NO_MOVE -was specified, but the reallocation request could not be serviced without -moving the object. -.El -.Sh ENVIRONMENT -The following environment variable affects the execution of the allocation -functions: -.Bl -tag -width ".Ev @jemalloc_cprefix@MALLOC_CONF" -.It Ev @jemalloc_cprefix@MALLOC_CONF -If the environment variable -.Ev @jemalloc_cprefix@MALLOC_CONF -is set, the characters it contains will be interpreted as options. -.El -.Sh EXAMPLES -To dump core whenever a problem occurs: -.Pp -.Bd -literal -offset indent -ln -s 'abort:true' /etc/@jemalloc_prefix@malloc.conf -.Ed -.Pp -To specify in the source a chunk size that is 16 MiB: -.Bd -literal -offset indent -@jemalloc_prefix@malloc_conf = "lg_chunk:24"; -.Ed -.Sh SEE ALSO -.Xr madvise 2 , -.Xr mmap 2 , -@roff_dss@.Xr sbrk 2 , -.Xr alloca 3 , -.Xr atexit 3 , -.Xr getpagesize 3 -.Sh STANDARDS -The -.Fn @jemalloc_prefix@malloc , -.Fn @jemalloc_prefix@calloc , -.Fn @jemalloc_prefix@realloc -and -.Fn @jemalloc_prefix@free -functions conform to -.St -isoC . -.Pp -The -.Fn @jemalloc_prefix@posix_memalign -function conforms to -.St -p1003.1-2001 . diff --git a/jemalloc/doc/jemalloc.xml.in b/jemalloc/doc/jemalloc.xml.in new file mode 100644 index 00000000..97893c16 --- /dev/null +++ b/jemalloc/doc/jemalloc.xml.in @@ -0,0 +1,2251 @@ + + + + + + + User Manual + jemalloc + @jemalloc_version@ + + + Jason + Evans + Author + + + + + JEMALLOC + 3 + + + jemalloc + jemalloc + + general purpose memory allocation functions + + + LIBRARY + This manual describes jemalloc @jemalloc_version@. More information + can be found at the jemalloc website. + + + SYNOPSIS + + #include <stdlib.h> +#include <jemalloc/jemalloc.h> + + Standard API + + void *malloc + size_t size + + + void *calloc + size_t number + size_t size + + + int posix_memalign + void **ptr + size_t alignment + size_t size + + + void *realloc + void *ptr + size_t size + + + void free + void *ptr + + + + Non-standard API + + size_t malloc_usable_size + const void *ptr + + + void malloc_stats_print + void (*write_cb) + void *, const char * + + void *cbopaque + const char *opts + + + int mallctl + const char *name + void *oldp + size_t *oldlenp + void *newp + size_t newlen + + + int mallctlnametomib + const char *name + size_t *mibp + size_t *miblenp + + + int mallctlbymib + const size_t *mib + size_t miblen + void *oldp + size_t *oldlenp + void *newp + size_t newlen + + + void (*malloc_message) + void *cbopaque + const char *s + + const char *malloc_conf; + + + Experimental API + + int allocm + void **ptr + size_t *rsize + size_t size + int flags + + + int rallocm + void **ptr + size_t *rsize + size_t size + size_t extra + int flags + + + int sallocm + const void *ptr + size_t *rsize + int flags + + + int dallocm + void *ptr + int flags + + + + + + DESCRIPTION + + Standard API + + The malloc function allocates + size bytes of uninitialized memory. The allocated + space is suitably aligned (after possible pointer coercion) for storage + of any type of object. + + The calloc function allocates + space for number objects, each + size bytes in length. The result is identical to + calling malloc with an argument of + number * size, with the + exception that the allocated memory is explicitly initialized to zero + bytes. + + The posix_memalign function + allocates size bytes of memory such that the + allocation's base address is an even multiple of + alignment, and returns the allocation in the value + pointed to by ptr. The requested + alignment must be a power of 2 at least as large + as sizeof(void *). + + The realloc function changes the + size of the previously allocated memory referenced by + ptr to size bytes. The + contents of the memory are unchanged up to the lesser of the new and old + sizes. If the new size is larger, the contents of the newly allocated + portion of the memory are undefined. Upon success, the memory referenced + by ptr is freed and a pointer to the newly + allocated memory is returned. Note that + realloc may move the memory allocation, + resulting in a different return value than ptr. + If ptr is NULL, the + realloc function behaves identically to + malloc for the specified size. + + The free function causes the + allocated memory referenced by ptr to be made + available for future allocations. If ptr is + NULL, no action occurs. + + + Non-standard API + + The malloc_usable_size function + returns the usable size of the allocation pointed to by + ptr. The return value may be larger than the size + that was requested during allocation. The + malloc_usable_size function is not a + mechanism for in-place realloc; rather + it is provided solely as a tool for introspection purposes. Any + discrepancy between the requested allocation size and the size reported + by malloc_usable_size should not be + depended on, since such behavior is entirely implementation-dependent. + + + The malloc_stats_print function + writes human-readable summary statistics via the + write_cb callback function pointer and + cbopaque data passed to + write_cb, or + malloc_message if + write_cb is NULL. This + function can be called repeatedly. General information that never + changes during execution can be omitted by specifying "g" as a character + within the opts string. Note that + malloc_message uses the + mallctl* functions internally, so + inconsistent statistics can be reported if multiple threads use these + functions simultaneously. If is + specified during configuration, “m” and “a” can + be specified to omit merged arena and per arena statistics, respectively; + “b” and “l” can be specified to omit per size + class statistics for bins and large objects, respectively. Unrecognized + characters are silently ignored. Note that thread caching may prevent + some statistics from being completely up to date, since extra locking + would be required to merge counters that track thread cache operations. + + + The mallctl function provides a + general interface for introspecting the memory allocator, as well as + setting modifiable parameters and triggering actions. The + period-separated name argument specifies a + location in a tree-structured namespace; see the section for + documentation on the tree contents. To read a value, pass a pointer via + oldp to adequate space to contain the value, and a + pointer to its length via oldlenp; otherwise pass + NULL and NULL. Similarly, to + write a value, pass a pointer to the value via + newp, and its length via + newlen; otherwise pass NULL + and 0. + + The mallctlnametomib function + provides a way to avoid repeated name lookups for applications that + repeatedly query the same portion of the namespace, by translating a name + to a “Management Information Base” (MIB) that can be passed + repeatedly to mallctlbymib. Upon + successful return from mallctlnametomib, + mibp contains an array of + *miblenp integers, where + *miblenp is the lesser of the number of components + in name and the input value of + *miblenp. Thus it is possible to pass a + *miblenp that is smaller than the number of + period-separated name components, which results in a partial MIB that can + be used as the basis for constructing a complete MIB. For name + components that are integers (e.g. the 2 in + arenas.bin.2.size), + the corresponding MIB component will always be that integer. Therefore, + it is legitimate to construct code like the following: + + + Experimental API + The experimental API is subject to change or removal without regard + for backward compatibility. + + The allocm, + rallocm, + sallocm, and + dallocm functions all have a + flags argument that can be used to specify + options. The functions only check the options that are contextually + relevant. Use bitwise or (|) operations to + specify one or more of the following: + + + ALLOCM_LG_ALIGN(la) + + + Align the memory allocation to start at an address + that is a multiple of (1 << + la). This macro does not validate + that la is within the valid + range. + + + ALLOCM_ALIGN(a) + + + Align the memory allocation to start at an address + that is a multiple of a, where + a is a power of two. This macro does not + validate that a is a power of 2. + + + + ALLOCM_ZERO + + Initialize newly allocated memory to contain zero + bytes. In the growing reallocation case, the real size prior to + reallocation defines the boundary between untouched bytes and those + that are initialized to contain zero bytes. If this option is + absent, newly allocated memory is uninitialized. + + + ALLOCM_NO_MOVE + + For reallocation, fail rather than moving the + object. This constraint can apply to both growth and + shrinkage. + + + + + The allocm function allocates at + least size bytes of memory, sets + *ptr to the base address of the allocation, and + sets *rsize to the real size of the allocation if + rsize is not NULL. + + The rallocm function resizes the + allocation at *ptr to be at least + size bytes, sets *ptr to + the base address of the allocation if it moved, and sets + *rsize to the real size of the allocation if + rsize is not NULL. If + extra is non-zero, an attempt is made to resize + the allocation to be at least size + + extra) bytes, though inability to allocate + the extra byte(s) will not by itself result in failure. Behavior is + undefined if (size + + extra > + SIZE_T_MAX). + + The sallocm function sets + *rsize to the real size of the allocation. + + The dallocm function causes the + memory referenced by ptr to be made available for + future allocations. + + + + TUNING + Once, when the first call is made to one of the memory allocation + routines, the allocator initializes its internals based in part on various + options that can be specified at compile- or run-time. + + The string pointed to by the global variable + malloc_conf, the “name” of the file + referenced by the symbolic link named /etc/malloc.conf, and the value of the + environment variable MALLOC_CONF, will be interpreted, in + that order, from left to right as options. + + An options string is a comma-separated list of option:value pairs. + There is one key corresponding to each opt.* mallctl (see the section for options + documentation). For example, abort:true,narenas:1 sets + the opt.abort and opt.narenas options. Some + options have boolean values (true/false), others have integer values (base + 8, 10, or 16, depending on prefix), and yet others have raw string + values. + + + IMPLEMENTATION NOTES + Traditionally, allocators have used + sbrk + 2 to obtain memory, which is + suboptimal for several reasons, including race conditions, increased + fragmentation, and artificial limitations on maximum usable memory. If + is specified during configuration, this + allocator uses both sbrk + 2 and + mmap + 2, in that order of preference; + otherwise only mmap + 2 is used. + + This allocator uses multiple arenas in order to reduce lock + contention for threaded programs on multi-processor systems. This works + well with regard to threading scalability, but incurs some costs. There is + a small fixed per-arena overhead, and additionally, arenas manage memory + completely independently of each other, which means a small fixed increase + in overall memory fragmentation. These overheads are not generally an + issue, given the number of arenas normally used. Note that using + substantially more arenas than the default is not likely to improve + performance, mainly due to reduced cache performance. However, it may make + sense to reduce the number of arenas if an application does not make much + use of the allocation functions. + + In addition to multiple arenas, unless + is specified during configuration, this + allocator supports thread-specific caching for small and large objects, in + order to make it possible to completely avoid synchronization for most + allocation requests. Such caching allows very fast allocation in the + common case, but it increases memory usage and fragmentation, since a + bounded number of objects can remain allocated in each thread cache. + + Memory is conceptually broken into equal-sized chunks, where the + chunk size is a power of two that is greater than the page size. Chunks + are always aligned to multiples of the chunk size. This alignment makes it + possible to find metadata for user objects very quickly. + + User objects are broken into three categories according to size: + small, large, and huge. Small objects are smaller than one page. Large + objects are smaller than the chunk size. Huge objects are a multiple of + the chunk size. Small and large objects are managed by arenas; huge + objects are managed separately in a single data structure that is shared by + all threads. Huge objects are used by applications infrequently enough + that this single data structure is not a scalability issue. + + Each chunk that is managed by an arena tracks its contents as runs of + contiguous pages (unused, backing a set of small objects, or backing one + large object). The combination of chunk alignment and chunk page maps + makes it possible to determine all metadata regarding small and large + allocations in constant time. + + Small objects are managed in groups by page runs. Each run maintains + a frontier and free list to track which regions are in use. Unless + is specified during configuration, + allocation requests that are no more than half the quantum (8 or 16, + depending on architecture) are rounded up to the nearest power of two that + is at least sizeof(void *). + Allocation requests that are more than half the quantum, but no more than + the minimum cacheline-multiple size class (see the opt.lg_qspace_max + option) are rounded up to the nearest multiple of the quantum. Allocation + requests that are more than the minimum cacheline-multiple size class, but + no more than the minimum subpage-multiple size class (see the opt.lg_cspace_max + option) are rounded up to the nearest multiple of the cacheline size (64). + Allocation requests that are more than the minimum subpage-multiple size + class, but no more than the maximum subpage-multiple size class are rounded + up to the nearest multiple of the subpage size (256). Allocation requests + that are more than the maximum subpage-multiple size class, but small + enough to fit in an arena-managed chunk (see the opt.lg_chunk option), are + rounded up to the nearest run size. Allocation requests that are too large + to fit in an arena-managed chunk are rounded up to the nearest multiple of + the chunk size. + + Allocations are packed tightly together, which can be an issue for + multi-threaded applications. If you need to assure that allocations do not + suffer from cacheline sharing, round your allocation requests up to the + nearest multiple of the cacheline size, or specify cacheline alignment when + allocating. + + Assuming 4 MiB chunks, 4 KiB pages, and a 16-byte quantum on a 64-bit + system, the size classes in each category are as shown in . + + + Size classes + + + + + + + Category + Subcategory + Size + + + + + Small + Tiny + [8] + + + Quantum-spaced + [16, 32, 48, ..., 128] + + + Cacheline-spaced + [192, 256, 320, ..., 512] + + + Subpage-spaced + [768, 1024, 1280, ..., 3840] + + + Large + [4 KiB, 8 KiB, 12 KiB, ..., 4072 KiB] + + + Huge + [4 MiB, 8 MiB, 12 MiB, ...] + + + +
+
+ + MALLCTL NAMESPACE + The following names are defined in the namespace accessible via the + mallctl* functions. Value types are + specified in parentheses, their readable/writable statuses are encoded as + rw, r-, -w, or + --, and required build configuration flags follow, if + any. A name element encoded as <i> or + <j> indicates an integer component, where the + integer varies from 0 to some upper value that must be determined via + introspection. In the case of stats.arenas.<i>.*, + <i> equal to arenas.narenas can be + used to access the summation of statistics from all arenas. Take special + note of the epoch mallctl, + which controls refreshing of cached dynamic statistics. + + + + + version + (const char *) + r- + + Return the jemalloc version string. + + + + + epoch + (uint64_t) + rw + + If a value is passed in, refresh the data from which + the mallctl* functions report values, + and increment the epoch. Return the current epoch. This is useful for + detecting whether another thread caused a refresh. + + + + + config.debug + (bool) + r- + + was specified during + build configuration. + + + + + config.dss + (bool) + r- + + was specified during + build configuration. + + + + + config.dynamic_page_shift + (bool) + r- + + was + specified during build configuration. + + + + + config.fill + (bool) + r- + + was specified during + build configuration. + + + + + config.lazy_lock + (bool) + r- + + was specified + during build configuration. + + + + + config.prof + (bool) + r- + + was specified during + build configuration. + + + + + config.prof_libgcc + (bool) + r- + + was not + specified during build configuration. + + + + + config.prof_libunwind + (bool) + r- + + was specified + during build configuration. + + + + + config.stats + (bool) + r- + + was specified during + build configuration. + + + + + config.swap + (bool) + r- + + was specified during + build configuration. + + + + + config.sysv + (bool) + r- + + was specified during + build configuration. + + + + + config.tcache + (bool) + r- + + was not specified + during build configuration. + + + + + config.tiny + (bool) + r- + + was not specified + during build configuration. + + + + + config.tls + (bool) + r- + + was not specified during + build configuration. + + + + + config.xmalloc + (bool) + r- + + was specified during + build configuration. + + + + + opt.abort + (bool) + r- + + Abort-on-warning enabled/disabled. If true, most + warnings are fatal. The process will call + abort + 3 in these cases. This option is + disabled by default unless is + specified during configuration, in which case it is enabled by default. + + + + + + opt.lg_qspace_max + (size_t) + r- + + Size (log base 2) of the maximum size class that is a + multiple of the quantum (8 or 16 bytes, depending on architecture). + Above this size, cacheline spacing is used for size classes. The + default value is 128 bytes (2^7). + + + + + opt.lg_cspace_max + (size_t) + r- + + Size (log base 2) of the maximum size class that is a + multiple of the cacheline size (64). Above this size, subpage spacing + (256 bytes) is used for size classes. The default value is 512 bytes + (2^9). + + + + + opt.lg_chunk + (size_t) + r- + + Virtual memory chunk size (log base 2). The default + chunk size is 4 MiB (2^22). + + + + + opt.narenas + (size_t) + r- + + Maximum number of arenas to use. The default maximum + number of arenas is four times the number of CPUs, or one if there is a + single CPU. + + + + + opt.lg_dirty_mult + (ssize_t) + r- + + Per-arena minimum ratio (log base 2) of active to dirty + pages. Some dirty unused pages may be allowed to accumulate, within + the limit set by the ratio (or one chunk worth of dirty pages, + whichever is greater), before informing the kernel about some of those + pages via madvise + 2 or a similar system call. This + provides the kernel with sufficient information to recycle dirty pages + if physical memory becomes scarce and the pages remain unused. The + default minimum ratio is 32:1 (2^5:1); an option value of -1 will + disable dirty page purging. + + + + + opt.stats_print + (bool) + r- + + Enable/disable statistics printing at exit. If + enabled, the malloc_stats_print + function is called at program exit via an + atexit + 3 function. If + is specified during configuration, this + has the potential to cause deadlock for a multi-threaded process that + exits while one or more threads are executing in the memory allocation + functions. Therefore, this option should only be used with care; it is + primarily intended as a performance tuning aid during application + development. This option is disabled by default. + + + + + opt.junk + (bool) + r- + [] + + Junk filling enabled/disabled. If enabled, each byte + of uninitialized allocated memory will be initialized to + 0xa5. All deallocated memory will be initialized to + 0x5a. This is intended for debugging and will + impact performance negatively. This option is disabled by default + unless is specified during + configuration, in which case it is enabled by default. + + + + + opt.zero + (bool) + r- + [] + + Zero filling enabled/disabled. If enabled, each byte + of uninitialized allocated memory will be initialized to 0. Note that + this initialization only happens once for each byte, so + realloc and + rallocm calls do not zero memory that + was previously allocated. This is intended for debugging and will + impact performance negatively. This option is disabled by default. + + + + + + opt.sysv + (bool) + r- + [] + + If enabled, attempting to allocate zero bytes will + return a NULL pointer instead of a valid pointer. + (The default behavior is to make a minimal allocation and return a + pointer to it.) This option is provided for System V compatibility. + This option is incompatible with the opt.xmalloc option. + This option is disabled by default. + + + + + opt.xmalloc + (bool) + r- + [] + + Abort-on-out-of-memory enabled/disabled. If enabled, + rather than returning failure for any allocation function, display a + diagnostic message on STDERR_FILENO and cause the + program to drop core (using + abort + 3). If an application is + designed to depend on this behavior, set the option at compile time by + including the following in the source code: + + This option is disabled by default. + + + + + opt.tcache + (bool) + r- + [] + + Thread-specific caching enabled/disabled. When there + are multiple threads, each thread uses a thread-specific cache for + objects up to a certain size. Thread-specific caching allows many + allocations to be satisfied without performing any thread + synchronization, at the cost of increased memory use. See the + opt.lg_tcache_gc_sweep + and opt.lg_tcache_max + options for related tuning information. This option is enabled by + default. + + + + + opt.lg_tcache_gc_sweep + (ssize_t) + r- + [] + + Approximate interval (log base 2) between full + thread-specific cache garbage collection sweeps, counted in terms of + thread-specific cache allocation/deallocation events. Garbage + collection is actually performed incrementally, one size class at a + time, in order to avoid large collection pauses. The default sweep + interval is 8192 (2^13); setting this option to -1 will disable garbage + collection. + + + + + opt.lg_tcache_max + (size_t) + r- + [] + + Maximum size class (log base 2) to cache in the + thread-specific cache. At a minimum, all small size classes are + cached, and at a maximum all large size classes are cached. The + default maximum is 32 KiB (2^15). + + + + + opt.prof + (bool) + r- + [] + + Memory profiling enabled/disabled. If enabled, profile + memory allocation activity, and use an + atexit + 3 function to dump final memory + usage to a file named according to the pattern + <prefix>.<pid>.<seq>.f.heap, + where <prefix> is controlled by the opt.prof_prefix + option. See the opt.lg_prof_bt_max + option for backtrace depth control. See the opt.prof_active + option for on-the-fly activation/deactivation. See the opt.lg_prof_sample + option for probabilistic sampling control. See the opt.prof_accum + option for control of cumulative sample reporting. See the opt.lg_prof_tcmax + option for control of per thread backtrace caching. See the opt.lg_prof_interval + option for information on interval-triggered profile dumping, and the + opt.prof_gdump + option for information on high-water-triggered profile dumping. + Profile output is compatible with the included pprof + Perl script, which originates from the google-perftools + package. + + + + + opt.prof_prefix + (const char *) + r- + [] + + Filename prefix for profile dumps. If the prefix is + set to the empty string, no automatic dumps will occur; this is + primarily useful for disabling the automatic final heap dump (which + also disables leak reporting, if enabled). The default prefix is + jeprof. + + + + + opt.lg_prof_bt_max + (size_t) + r- + [] + + Maximum backtrace depth (log base 2) when profiling + memory allocation activity. The default is 128 (2^7). + + + + + opt.prof_active + (bool) + r- + [] + + Profiling activated/deactivated. This is a secondary + control mechanism that makes it possible to start the application with + profiling enabled (see the opt.prof option) but + inactive, then toggle profiling at any time during program execution + with the prof.active mallctl. + This option is enabled by default. + + + + + opt.lg_prof_sample + (ssize_t) + r- + [] + + Average interval (log base 2) between allocation + samples, as measured in bytes of allocation activity. Increasing the + sampling interval decreases profile fidelity, but also decreases the + computational overhead. The default sample interval is 1 (2^0) (i.e. + all allocations are sampled). + + + + + opt.prof_accum + (bool) + r- + [] + + Reporting of cumulative object/byte counts in profile + dumps enabled/disabled. If this option is enabled, every unique + backtrace must be stored for the duration of execution. Depending on + the application, this can impose a large memory overhead, and the + cumulative counts are not always of interest. See the + opt.lg_prof_tcmax + option for control of per thread backtrace caching, which has important + interactions. This option is enabled by default. + + + + + opt.lg_prof_tcmax + (ssize_t) + r- + [] + + Maximum per thread backtrace cache (log base 2) used + for heap profiling. A backtrace can only be discarded if the + opt.prof_accum + option is disabled, and no thread caches currently refer to the + backtrace. Therefore, a backtrace cache limit should be imposed if the + intention is to limit how much memory is used by backtraces. By + default, no limit is imposed (encoded as -1). + + + + + + opt.lg_prof_interval + (ssize_t) + r- + [] + + Average interval (log base 2) between memory profile + dumps, as measured in bytes of allocation activity. The actual + interval between dumps may be sporadic because decentralized allocation + counters are used to avoid synchronization bottlenecks. Profiles are + dumped to files named according to the pattern + <prefix>.<pid>.<seq>.i<iseq>.heap, + where <prefix> is controlled by the + opt.prof_prefix + option. By default, interval-triggered profile dumping is disabled + (encoded as -1). + + + + + + opt.prof_gdump + (bool) + r- + [] + + Trigger a memory profile dump every time the total + virtual memory exceeds the previous maximum. Profiles are dumped to + files named according to the pattern + <prefix>.<pid>.<seq>.u<useq>.heap, + where <prefix> is controlled by the opt.prof_prefix + option. This option is disabled by default. + + + + + opt.prof_leak + (bool) + r- + [] + + Leak reporting enabled/disabled. If enabled, use an + atexit + 3 function to report memory leaks + detected by allocation sampling. See the + opt.lg_prof_bt_max + option for backtrace depth control. See the + opt.prof option for + information on analyzing heap profile output. This option is disabled + by default. + + + + + opt.overcommit + (bool) + r- + [] + + Over-commit enabled/disabled. If enabled, over-commit + memory as a side effect of using anonymous + mmap + 2 or + sbrk + 2 for virtual memory allocation. + In order for overcommit to be disabled, the swap.fds mallctl must have + been successfully written to. This option is enabled by + default. + + + + + tcache.flush + (void) + -- + [] + + Flush calling thread's tcache. This interface releases + all cached objects and internal data structures associated with the + calling thread's thread-specific cache. Ordinarily, this interface + need not be called, since automatic periodic incremental garbage + collection occurs, and the thread cache is automatically discarded when + a thread exits. However, garbage collection is triggered by allocation + activity, so it is possible for a thread that stops + allocating/deallocating to retain its cache indefinitely, in which case + the developer may find manual flushing useful. + + + + + thread.arena + (unsigned) + rw + + Get or set the arena associated with the calling + thread. The arena index must be less than the maximum number of arenas + (see the arenas.narenas + mallctl). If the specified arena was not initialized beforehand (see + the arenas.initialized + mallctl), it will be automatically initialized as a side effect of + calling this interface. + + + + + thread.allocated + (uint64_t) + r- + [] + + Get the total number of bytes ever allocated by the + calling thread. This counter has the potential to wrap around; it is + up to the application to appropriately interpret the counter in such + cases. + + + + + thread.allocatedp + (uint64_t *) + r- + [] + + Get a pointer to the the value that is returned by the + thread.allocated + mallctl. This is useful for avoiding the overhead of repeated + mallctl* calls. + + + + + thread.deallocated + (uint64_t) + r- + [] + + Get the total number of bytes ever deallocated by the + calling thread. This counter has the potential to wrap around; it is + up to the application to appropriately interpret the counter in such + cases. + + + + + thread.deallocatedp + (uint64_t *) + r- + [] + + Get a pointer to the the value that is returned by the + thread.deallocated + mallctl. This is useful for avoiding the overhead of repeated + mallctl* calls. + + + + + arenas.narenas + (unsigned) + r- + + Maximum number of arenas. + + + + + arenas.initialized + (bool *) + r- + + An array of arenas.narenas + booleans. Each boolean indicates whether the corresponding arena is + initialized. + + + + + arenas.quantum + (size_t) + r- + + Quantum size. + + + + + arenas.cacheline + (size_t) + r- + + Assumed cacheline size. + + + + + arenas.subpage + (size_t) + r- + + Subpage size class interval. + + + + + arenas.pagesize + (size_t) + r- + + Page size. + + + + + arenas.chunksize + (size_t) + r- + + Chunk size. + + + + + arenas.tspace_min + (size_t) + r- + + Minimum tiny size class. Tiny size classes are powers + of two. + + + + + arenas.tspace_max + (size_t) + r- + + Maximum tiny size class. Tiny size classes are powers + of two. + + + + + arenas.qspace_min + (size_t) + r- + + Minimum quantum-spaced size class. + + + + + arenas.qspace_max + (size_t) + r- + + Maximum quantum-spaced size class. + + + + + arenas.cspace_min + (size_t) + r- + + Minimum cacheline-spaced size class. + + + + + arenas.cspace_max + (size_t) + r- + + Maximum cacheline-spaced size class. + + + + + arenas.sspace_min + (size_t) + r- + + Minimum subpage-spaced size class. + + + + + arenas.sspace_max + (size_t) + r- + + Maximum subpage-spaced size class. + + + + + arenas.tcache_max + (size_t) + r- + [] + + Maximum thread-cached size class. + + + + + arenas.ntbins + (unsigned) + r- + + Number of tiny bin size classes. + + + + + arenas.nqbins + (unsigned) + r- + + Number of quantum-spaced bin size + classes. + + + + + arenas.ncbins + (unsigned) + r- + + Number of cacheline-spaced bin size + classes. + + + + + arenas.nsbins + (unsigned) + r- + + Number of subpage-spaced bin size + classes. + + + + + arenas.nbins + (unsigned) + r- + + Total number of bin size classes. + + + + + arenas.nhbins + (unsigned) + r- + [] + + Total number of thread cache bin size + classes. + + + + + arenas.bin.<i>.size + (size_t) + r- + + Maximum size supported by size class. + + + + + arenas.bin.<i>.nregs + (uint32_t) + r- + + Number of regions per page run. + + + + + arenas.bin.<i>.run_size + (size_t) + r- + + Number of bytes per page run. + + + + + arenas.nlruns + (size_t) + r- + + Total number of large size classes. + + + + + arenas.lrun.<i>.size + (size_t) + r- + + Maximum size supported by this large size + class. + + + + + arenas.purge + (unsigned) + -w + + Purge unused dirty pages for the specified arena, or + for all arenas if none is specified. + + + + + prof.active + (bool) + rw + [] + + Control whether sampling is currently active. See the + opt.prof_active + option for additional information. + + + + + + prof.dump + (const char *) + -w + [] + + Dump a memory profile to the specified file, or if NULL + is specified, to a file according to the pattern + <prefix>.<pid>.<seq>.m<mseq>.heap, + where <prefix> is controlled by the + opt.prof_prefix + option. + + + + + prof.interval + (uint64_t) + r- + [] + + Average number of bytes allocated between + inverval-based profile dumps. See the + opt.lg_prof_interval + option for additional information. + + + + + stats.allocated + (size_t) + r- + [] + + Total number of bytes allocated by the + application. + + + + + stats.active + (size_t) + r- + [] + + Total number of bytes in active pages allocated by the + application. This is a multiple of the page size, and greater than or + equal to stats.allocated. + + + + + + stats.mapped + (size_t) + r- + [] + + Total number of bytes in chunks mapped on behalf of the + application. This is a multiple of the chunk size, and is at least as + large as stats.active. This + does not include inactive chunks backed by swap files. his does not + include inactive chunks embedded in the DSS. + + + + + stats.chunks.current + (size_t) + r- + [] + + Total number of chunks actively mapped on behalf of the + application. This does not include inactive chunks backed by swap + files. This does not include inactive chunks embedded in the DSS. + + + + + + stats.chunks.total + (uint64_t) + r- + [] + + Cumulative number of chunks allocated. + + + + + stats.chunks.high + (size_t) + r- + [] + + Maximum number of active chunks at any time thus far. + + + + + + stats.huge.allocated + (size_t) + r- + [] + + Number of bytes currently allocated by huge objects. + + + + + + stats.huge.nmalloc + (uint64_t) + r- + [] + + Cumulative number of huge allocation requests. + + + + + + stats.huge.ndalloc + (uint64_t) + r- + [] + + Cumulative number of huge deallocation requests. + + + + + + stats.arenas.<i>.pactive + (size_t) + r- + + Number of pages in active runs. + + + + + stats.arenas.<i>.pdirty + (size_t) + r- + + Number of pages within unused runs that are potentially + dirty, and for which madvise... + MADV_DONTNEED or + similar has not been called. + + + + + stats.arenas.<i>.mapped + (size_t) + r- + [] + + Number of mapped bytes. + + + + + stats.arenas.<i>.npurge + (uint64_t) + r- + [] + + Number of dirty page purge sweeps performed. + + + + + + stats.arenas.<i>.nmadvise + (uint64_t) + r- + [] + + Number of madvise... + MADV_DONTNEED or + similar calls made to purge dirty pages. + + + + + stats.arenas.<i>.npurged + (uint64_t) + r- + [] + + Number of pages purged. + + + + + stats.arenas.<i>.small.allocated + (size_t) + r- + [] + + Number of bytes currently allocated by small objects. + + + + + + stats.arenas.<i>.small.nmalloc + (uint64_t) + r- + [] + + Cumulative number of allocation requests served by + small bins. + + + + + stats.arenas.<i>.small.ndalloc + (uint64_t) + r- + [] + + Cumulative number of small objects returned to bins. + + + + + + stats.arenas.<i>.small.nrequests + (uint64_t) + r- + [] + + Cumulative number of small allocation requests. + + + + + + stats.arenas.<i>.large.allocated + (size_t) + r- + [] + + Number of bytes currently allocated by large objects. + + + + + + stats.arenas.<i>.large.nmalloc + (uint64_t) + r- + [] + + Cumulative number of large allocation requests served + directly by the arena. + + + + + stats.arenas.<i>.large.ndalloc + (uint64_t) + r- + [] + + Cumulative number of large deallocation requests served + directly by the arena. + + + + + stats.arenas.<i>.large.nrequests + (uint64_t) + r- + [] + + Cumulative number of large allocation requests. + + + + + + stats.arenas.<i>.bins.<j>.allocated + (size_t) + r- + [] + + Current number of bytes allocated by + bin. + + + + + stats.arenas.<i>.bins.<j>.nmalloc + (uint64_t) + r- + [] + + Cumulative number of allocations served by bin. + + + + + + stats.arenas.<i>.bins.<j>.ndalloc + (uint64_t) + r- + [] + + Cumulative number of allocations returned to bin. + + + + + + stats.arenas.<i>.bins.<j>.nrequests + (uint64_t) + r- + [] + + Cumulative number of allocation + requests. + + + + + stats.arenas.<i>.bins.<j>.nfills + (uint64_t) + r- + [ ] + + Cumulative number of tcache fills. + + + + + stats.arenas.<i>.bins.<j>.nflushes + (uint64_t) + r- + [ ] + + Cumulative number of tcache flushes. + + + + + stats.arenas.<i>.bins.<j>.nruns + (uint64_t) + r- + [] + + Cumulative number of runs created. + + + + + stats.arenas.<i>.bins.<j>.nreruns + (uint64_t) + r- + [] + + Cumulative number of times the current run from which + to allocate changed. + + + + + stats.arenas.<i>.bins.<j>.highruns + (size_t) + r- + [] + + Maximum number of runs at any time thus far. + + + + + + stats.arenas.<i>.bins.<j>.curruns + (size_t) + r- + [] + + Current number of runs. + + + + + stats.arenas.<i>.lruns.<j>.nmalloc + (uint64_t) + r- + [] + + Cumulative number of allocation requests for this size + class served directly by the arena. + + + + + stats.arenas.<i>.lruns.<j>.ndalloc + (uint64_t) + r- + [] + + Cumulative number of deallocation requests for this + size class served directly by the arena. + + + + + stats.arenas.<i>.lruns.<j>.nrequests + (uint64_t) + r- + [] + + Cumulative number of allocation requests for this size + class. + + + + + stats.arenas.<i>.lruns.<j>.highruns + (size_t) + r- + [] + + Maximum number of runs at any time thus far for this + size class. + + + + + stats.arenas.<i>.lruns.<j>.curruns + (size_t) + r- + [] + + Current number of runs for this size class. + + + + + + swap.avail + (size_t) + r- + [] + + Number of swap file bytes that are currently not + associated with any chunk (i.e. mapped, but otherwise completely + unmanaged). + + + + + swap.prezeroed + (bool) + rw + [] + + If true, the allocator assumes that the swap file(s) + contain nothing but nil bytes. If this assumption is violated, + allocator behavior is undefined. This value becomes read-only after + swap.fds is + successfully written to. + + + + + swap.nfds + (size_t) + r- + [] + + Number of file descriptors in use for swap. + + + + + + swap.fds + (int *) + r- + [] + + When written to, the files associated with the + specified file descriptors are contiguously mapped via + mmap + 2. The resulting virtual memory + region is preferred over anonymous + mmap + 2 and + sbrk + 2 memory. Note that if a file's + size is not a multiple of the page size, it is automatically truncated + to the nearest page size multiple. See the + swap.prezeroed + mallctl for specifying that the files are pre-zeroed. + + + + + DEBUGGING MALLOC PROBLEMS + When debugging, it is a good idea to configure/build jemalloc with + the and + options, and recompile the program with suitable options and symbols for + debugger support. When so configured, jemalloc incorporates a wide variety + of run-time assertions that catch application errors such as double-free, + write-after-free, etc. + + Programs often accidentally depend on “uninitialized” + memory actually being filled with zero bytes. Junk filling + (see the opt.junk + option) tends to expose such bugs in the form of obviously incorrect + results and/or coredumps. Conversely, zero + filling (see the opt.zero option) eliminates + the symptoms of such bugs. Between these two options, it is usually + possible to quickly detect, diagnose, and eliminate such bugs. + + This implementation does not provide much detail about the problems + it detects, because the performance impact for storing such information + would be prohibitive. There are a number of allocator implementations + available on the Internet which focus on detecting and pinpointing problems + by trading performance for extra sanity checks and detailed + diagnostics. + + + DIAGNOSTIC MESSAGES + If any of the memory allocation/deallocation functions detect an + error or warning condition, a message will be printed to file descriptor + STDERR_FILENO. Errors will result in the process + dumping core. If the opt.abort option is set, most + warnings are treated as errors. + + The malloc_message variable allows the programmer + to override the function which emits the text strings forming the errors + and warnings if for some reason the STDERR_FILENO file + descriptor is not suitable for this. + malloc_message takes the + cbopaque pointer argument that is + NULL unless overridden by the arguments in a call to + malloc_stats_print, followed by a string + pointer. Please note that doing anything which tries to allocate memory in + this function is likely to result in a crash or deadlock. + + All messages are prefixed by + “<jemalloc>: ”. + + + RETURN VALUES + + Standard API + The malloc and + calloc functions return a pointer to the + allocated memory if successful; otherwise a NULL + pointer is returned and errno is set to + ENOMEM. + + The posix_memalign function + returns the value 0 if successful; otherwise it returns an error value. + The posix_memalign function will fail + if: + + + EINVAL + + The alignment parameter is + not a power of 2 at least as large as + sizeof(void *). + + + + ENOMEM + + Memory allocation error. + + + + + The realloc function returns a + pointer, possibly identical to ptr, to the + allocated memory if successful; otherwise a NULL + pointer is returned, and errno is set to + ENOMEM if the error was the result of an + allocation failure. The realloc + function always leaves the original buffer intact when an error occurs. + + + The free function returns no + value. + + + Non-standard API + The malloc_usable_size function + returns the usable size of the allocation pointed to by + ptr. + + The mallctl, + mallctlnametomib, and + mallctlbymib functions return 0 on + success; otherwise they return an error value. The functions will fail + if: + + + EINVAL + + newp is not + NULL, and newlen is too + large or too small. Alternatively, *oldlenp + is too large or too small; in this case as much data as possible + are read despite the error. + + + ENOMEM + + *oldlenp is too short to + hold the requested value. + + + ENOENT + + name or + mib specifies an unknown/invalid + value. + + + EPERM + + Attempt to read or write void value, or attempt to + write read-only value. + + + EAGAIN + + A memory allocation failure + occurred. + + + EFAULT + + An interface with side effects failed in some way + not directly related to mallctl* + read/write processing. + + + + + + Experimental API + The allocm, + rallocm, + sallocm, and + dallocm functions return + ALLOCM_SUCCESS on success; otherwise they return an + error value. The allocm and + rallocm functions will fail if: + + + ALLOCM_ERR_OOM + + Out of memory. Insufficient contiguous memory was + available to service the allocation request. The + allocm function additionally sets + *ptr to NULL, whereas + the rallocm function leaves + *ptr unmodified. + + + The rallocm function will also + fail if: + + + ALLOCM_ERR_NOT_MOVED + + ALLOCM_NO_MOVE was specified, + but the reallocation request could not be serviced without moving + the object. + + + + + + + ENVIRONMENT + The following environment variable affects the execution of the + allocation functions: + + + MALLOC_CONF + + If the environment variable + MALLOC_CONF is set, the characters it contains + will be interpreted as options. + + + + + + EXAMPLES + To dump core whenever a problem occurs: + ln -s 'abort:true' /etc/malloc.conf + + To specify in the source a chunk size that is 16 MiB: + + + + SEE ALSO + madvise + 2, + mmap + 2, + sbrk + 2, + alloca + 3, + atexit + 3, + getpagesize + 3 + + + STANDARDS + The malloc, + calloc, + realloc, and + free functions conform to ISO/IEC + 9899:1990 (“ISO C90”). + + The posix_memalign function conforms + to IEEE Std 1003.1-2001 (“POSIX.1”). + +
diff --git a/jemalloc/doc/manpages.xsl.in b/jemalloc/doc/manpages.xsl.in new file mode 100644 index 00000000..88b2626b --- /dev/null +++ b/jemalloc/doc/manpages.xsl.in @@ -0,0 +1,4 @@ + + + + diff --git a/jemalloc/doc/stylesheet.xsl b/jemalloc/doc/stylesheet.xsl new file mode 100644 index 00000000..4e334a86 --- /dev/null +++ b/jemalloc/doc/stylesheet.xsl @@ -0,0 +1,7 @@ + + ansi + + + "" + + diff --git a/jemalloc/include/jemalloc/internal/chunk_dss.h b/jemalloc/include/jemalloc/internal/chunk_dss.h index 6be4ad1f..6f005222 100644 --- a/jemalloc/include/jemalloc/internal/chunk_dss.h +++ b/jemalloc/include/jemalloc/internal/chunk_dss.h @@ -17,6 +17,7 @@ extern malloc_mutex_t dss_mtx; void *chunk_alloc_dss(size_t size, bool *zero); +bool chunk_in_dss(void *chunk); bool chunk_dealloc_dss(void *chunk, size_t size); bool chunk_dss_boot(void); diff --git a/jemalloc/include/jemalloc/internal/chunk_swap.h b/jemalloc/include/jemalloc/internal/chunk_swap.h index d50cb197..9faa739f 100644 --- a/jemalloc/include/jemalloc/internal/chunk_swap.h +++ b/jemalloc/include/jemalloc/internal/chunk_swap.h @@ -20,6 +20,7 @@ extern size_t swap_avail; #endif void *chunk_alloc_swap(size_t size, bool *zero); +bool chunk_in_swap(void *chunk); bool chunk_dealloc_swap(void *chunk, size_t size); bool chunk_swap_enable(const int *fds, unsigned nfds, bool prezeroed); bool chunk_swap_boot(void); diff --git a/jemalloc/include/jemalloc/internal/huge.h b/jemalloc/include/jemalloc/internal/huge.h index bf231274..66544cf8 100644 --- a/jemalloc/include/jemalloc/internal/huge.h +++ b/jemalloc/include/jemalloc/internal/huge.h @@ -25,7 +25,7 @@ void *huge_ralloc_no_move(void *ptr, size_t oldsize, size_t size, size_t extra); void *huge_ralloc(void *ptr, size_t oldsize, size_t size, size_t extra, size_t alignment, bool zero); -void huge_dalloc(void *ptr); +void huge_dalloc(void *ptr, bool unmap); size_t huge_salloc(const void *ptr); #ifdef JEMALLOC_PROF prof_ctx_t *huge_prof_ctx_get(const void *ptr); diff --git a/jemalloc/include/jemalloc/internal/jemalloc_internal.h.in b/jemalloc/include/jemalloc/internal/jemalloc_internal.h.in index 3d253001..0680b43e 100644 --- a/jemalloc/include/jemalloc/internal/jemalloc_internal.h.in +++ b/jemalloc/include/jemalloc/internal/jemalloc_internal.h.in @@ -666,7 +666,7 @@ idalloc(void *ptr) if (chunk != ptr) arena_dalloc(chunk->arena, chunk, ptr); else - huge_dalloc(ptr); + huge_dalloc(ptr, true); } JEMALLOC_INLINE void * diff --git a/jemalloc/include/jemalloc/jemalloc_defs.h.in b/jemalloc/include/jemalloc/jemalloc_defs.h.in index b8f3f36b..5f46c5c9 100644 --- a/jemalloc/include/jemalloc/jemalloc_defs.h.in +++ b/jemalloc/include/jemalloc/jemalloc_defs.h.in @@ -115,6 +115,9 @@ #undef JEMALLOC_ZONE #undef JEMALLOC_ZONE_VERSION +/* If defined, use mremap(...MREMAP_FIXED...) for huge realloc(). */ +#undef JEMALLOC_MREMAP_FIXED + /* * Methods for purging unused pages differ between operating systems. * diff --git a/jemalloc/src/chunk.c b/jemalloc/src/chunk.c index 00bf50a0..301519e8 100644 --- a/jemalloc/src/chunk.c +++ b/jemalloc/src/chunk.c @@ -146,11 +146,6 @@ chunk_boot(void) chunksize_mask = chunksize - 1; chunk_npages = (chunksize >> PAGE_SHIFT); -#ifdef JEMALLOC_IVSALLOC - chunks_rtree = rtree_new((ZU(1) << (LG_SIZEOF_PTR+3)) - opt_lg_chunk); - if (chunks_rtree == NULL) - return (true); -#endif #if (defined(JEMALLOC_STATS) || defined(JEMALLOC_PROF)) if (malloc_mutex_init(&chunks_mtx)) return (true); @@ -166,6 +161,11 @@ chunk_boot(void) if (chunk_dss_boot()) return (true); #endif +#ifdef JEMALLOC_IVSALLOC + chunks_rtree = rtree_new((ZU(1) << (LG_SIZEOF_PTR+3)) - opt_lg_chunk); + if (chunks_rtree == NULL) + return (true); +#endif return (false); } diff --git a/jemalloc/src/chunk_dss.c b/jemalloc/src/chunk_dss.c index d9bd63c3..5c0e290e 100644 --- a/jemalloc/src/chunk_dss.c +++ b/jemalloc/src/chunk_dss.c @@ -199,6 +199,22 @@ chunk_dealloc_dss_record(void *chunk, size_t size) return (node); } +bool +chunk_in_dss(void *chunk) +{ + bool ret; + + malloc_mutex_lock(&dss_mtx); + if ((uintptr_t)chunk >= (uintptr_t)dss_base + && (uintptr_t)chunk < (uintptr_t)dss_max) + ret = true; + else + ret = false; + malloc_mutex_unlock(&dss_mtx); + + return (ret); +} + bool chunk_dealloc_dss(void *chunk, size_t size) { diff --git a/jemalloc/src/chunk_swap.c b/jemalloc/src/chunk_swap.c index ee038ba9..cb25ae0d 100644 --- a/jemalloc/src/chunk_swap.c +++ b/jemalloc/src/chunk_swap.c @@ -184,6 +184,24 @@ chunk_dealloc_swap_record(void *chunk, size_t size) return (node); } +bool +chunk_in_swap(void *chunk) +{ + bool ret; + + assert(swap_enabled); + + malloc_mutex_lock(&swap_mtx); + if ((uintptr_t)chunk >= (uintptr_t)swap_base + && (uintptr_t)chunk < (uintptr_t)swap_max) + ret = true; + else + ret = false; + malloc_mutex_unlock(&swap_mtx); + + return (ret); +} + bool chunk_dealloc_swap(void *chunk, size_t size) { @@ -219,15 +237,15 @@ chunk_dealloc_swap(void *chunk, size_t size) } else madvise(chunk, size, MADV_DONTNEED); +#ifdef JEMALLOC_STATS + swap_avail += size; +#endif ret = false; goto RETURN; } ret = true; RETURN: -#ifdef JEMALLOC_STATS - swap_avail += size; -#endif malloc_mutex_unlock(&swap_mtx); return (ret); } diff --git a/jemalloc/src/ctl.c b/jemalloc/src/ctl.c index c83ee4f1..3c8adab9 100644 --- a/jemalloc/src/ctl.c +++ b/jemalloc/src/ctl.c @@ -4,6 +4,13 @@ /******************************************************************************/ /* Data. */ +/* + * ctl_mtx protects the following: + * - ctl_stats.* + * - opt_prof_active + * - swap_enabled + * - swap_prezeroed + */ static malloc_mutex_t ctl_mtx; static bool ctl_initialized; static uint64_t ctl_epoch; @@ -44,7 +51,9 @@ CTL_PROTO(tcache_flush) CTL_PROTO(thread_arena) #ifdef JEMALLOC_STATS CTL_PROTO(thread_allocated) +CTL_PROTO(thread_allocatedp) CTL_PROTO(thread_deallocated) +CTL_PROTO(thread_deallocatedp) #endif CTL_PROTO(config_debug) CTL_PROTO(config_dss) @@ -223,7 +232,9 @@ static const ctl_node_t thread_node[] = { #ifdef JEMALLOC_STATS , {NAME("allocated"), CTL(thread_allocated)}, - {NAME("deallocated"), CTL(thread_deallocated)} + {NAME("allocatedp"), CTL(thread_allocatedp)}, + {NAME("deallocated"), CTL(thread_deallocated)}, + {NAME("deallocatedp"), CTL(thread_deallocatedp)} #endif }; @@ -680,7 +691,9 @@ ctl_refresh(void) static bool ctl_init(void) { + bool ret; + malloc_mutex_lock(&ctl_mtx); if (ctl_initialized == false) { #ifdef JEMALLOC_STATS unsigned i; @@ -692,8 +705,10 @@ ctl_init(void) */ ctl_stats.arenas = (ctl_arena_stats_t *)base_alloc( (narenas + 1) * sizeof(ctl_arena_stats_t)); - if (ctl_stats.arenas == NULL) - return (true); + if (ctl_stats.arenas == NULL) { + ret = true; + goto RETURN; + } memset(ctl_stats.arenas, 0, (narenas + 1) * sizeof(ctl_arena_stats_t)); @@ -704,8 +719,10 @@ ctl_init(void) */ #ifdef JEMALLOC_STATS for (i = 0; i <= narenas; i++) { - if (ctl_arena_init(&ctl_stats.arenas[i])) - return (true); + if (ctl_arena_init(&ctl_stats.arenas[i])) { + ret = true; + goto RETURN; + } } #endif ctl_stats.arenas[narenas].initialized = true; @@ -715,7 +732,10 @@ ctl_init(void) ctl_initialized = true; } - return (false); + ret = false; +RETURN: + malloc_mutex_unlock(&ctl_mtx); + return (ret); } static int @@ -825,8 +845,7 @@ ctl_byname(const char *name, void *oldp, size_t *oldlenp, void *newp, ctl_node_t const *nodes[CTL_MAX_DEPTH]; size_t mib[CTL_MAX_DEPTH]; - malloc_mutex_lock(&ctl_mtx); - if (ctl_init()) { + if (ctl_initialized == false && ctl_init()) { ret = EAGAIN; goto RETURN; } @@ -841,10 +860,9 @@ ctl_byname(const char *name, void *oldp, size_t *oldlenp, void *newp, ret = ENOENT; goto RETURN; } - ret = nodes[depth-1]->ctl(mib, depth, oldp, oldlenp, newp, newlen); + ret = nodes[depth-1]->ctl(mib, depth, oldp, oldlenp, newp, newlen); RETURN: - malloc_mutex_unlock(&ctl_mtx); return(ret); } @@ -853,16 +871,13 @@ ctl_nametomib(const char *name, size_t *mibp, size_t *miblenp) { int ret; - malloc_mutex_lock(&ctl_mtx); - if (ctl_init()) { + if (ctl_initialized == false && ctl_init()) { ret = EAGAIN; goto RETURN; } ret = ctl_lookup(name, NULL, mibp, miblenp); - RETURN: - malloc_mutex_unlock(&ctl_mtx); return(ret); } @@ -874,8 +889,7 @@ ctl_bymib(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, const ctl_node_t *node; size_t i; - malloc_mutex_lock(&ctl_mtx); - if (ctl_init()) { + if (ctl_initialized == false && ctl_init()) { ret = EAGAIN; goto RETURN; } @@ -912,7 +926,6 @@ ctl_bymib(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, ret = node->ctl(mib, miblen, oldp, oldlenp, newp, newlen); RETURN: - malloc_mutex_unlock(&ctl_mtx); return(ret); } @@ -975,6 +988,29 @@ ctl_boot(void) #define CTL_RO_GEN(n, v, t) \ static int \ +n##_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, \ + void *newp, size_t newlen) \ +{ \ + int ret; \ + t oldval; \ + \ + malloc_mutex_lock(&ctl_mtx); \ + READONLY(); \ + oldval = v; \ + READ(oldval, t); \ + \ + ret = 0; \ +RETURN: \ + malloc_mutex_unlock(&ctl_mtx); \ + return (ret); \ +} + +/* + * ctl_mtx is not acquired, under the assumption that no pertinent data will + * mutate during the call. + */ +#define CTL_RO_NL_GEN(n, v, t) \ +static int \ n##_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, \ void *newp, size_t newlen) \ { \ @@ -1024,7 +1060,7 @@ RETURN: \ return (ret); \ } -CTL_RO_GEN(version, JEMALLOC_VERSION, const char *) +CTL_RO_NL_GEN(version, JEMALLOC_VERSION, const char *) static int epoch_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, @@ -1033,6 +1069,7 @@ epoch_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, int ret; uint64_t newval; + malloc_mutex_lock(&ctl_mtx); newval = 0; WRITE(newval, uint64_t); if (newval != 0) @@ -1041,6 +1078,7 @@ epoch_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, ret = 0; RETURN: + malloc_mutex_unlock(&ctl_mtx); return (ret); } @@ -1107,8 +1145,10 @@ RETURN: } #ifdef JEMALLOC_STATS -CTL_RO_GEN(thread_allocated, ALLOCATED_GET(), uint64_t); -CTL_RO_GEN(thread_deallocated, DEALLOCATED_GET(), uint64_t); +CTL_RO_NL_GEN(thread_allocated, ALLOCATED_GET(), uint64_t); +CTL_RO_NL_GEN(thread_allocatedp, &ALLOCATED_GET(), uint64_t *); +CTL_RO_NL_GEN(thread_deallocated, DEALLOCATED_GET(), uint64_t); +CTL_RO_NL_GEN(thread_deallocatedp, &DEALLOCATED_GET(), uint64_t *); #endif /******************************************************************************/ @@ -1205,48 +1245,48 @@ CTL_RO_FALSE_GEN(config_xmalloc) /******************************************************************************/ -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) +CTL_RO_NL_GEN(opt_abort, opt_abort, bool) +CTL_RO_NL_GEN(opt_lg_qspace_max, opt_lg_qspace_max, size_t) +CTL_RO_NL_GEN(opt_lg_cspace_max, opt_lg_cspace_max, size_t) +CTL_RO_NL_GEN(opt_lg_chunk, opt_lg_chunk, size_t) +CTL_RO_NL_GEN(opt_narenas, opt_narenas, size_t) +CTL_RO_NL_GEN(opt_lg_dirty_mult, opt_lg_dirty_mult, ssize_t) +CTL_RO_NL_GEN(opt_stats_print, opt_stats_print, bool) #ifdef JEMALLOC_FILL -CTL_RO_GEN(opt_junk, opt_junk, bool) -CTL_RO_GEN(opt_zero, opt_zero, bool) +CTL_RO_NL_GEN(opt_junk, opt_junk, bool) +CTL_RO_NL_GEN(opt_zero, opt_zero, bool) #endif #ifdef JEMALLOC_SYSV -CTL_RO_GEN(opt_sysv, opt_sysv, bool) +CTL_RO_NL_GEN(opt_sysv, opt_sysv, bool) #endif #ifdef JEMALLOC_XMALLOC -CTL_RO_GEN(opt_xmalloc, opt_xmalloc, bool) +CTL_RO_NL_GEN(opt_xmalloc, opt_xmalloc, bool) #endif #ifdef JEMALLOC_TCACHE -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_NL_GEN(opt_tcache, opt_tcache, bool) +CTL_RO_NL_GEN(opt_lg_tcache_gc_sweep, opt_lg_tcache_gc_sweep, ssize_t) #endif #ifdef JEMALLOC_PROF -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_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_interval, opt_lg_prof_interval, ssize_t) -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_accum, opt_prof_accum, bool) -CTL_RO_GEN(opt_lg_prof_tcmax, opt_lg_prof_tcmax, ssize_t) +CTL_RO_NL_GEN(opt_prof, opt_prof, bool) +CTL_RO_NL_GEN(opt_prof_prefix, opt_prof_prefix, const char *) +CTL_RO_GEN(opt_prof_active, opt_prof_active, bool) /* Mutable. */ +CTL_RO_NL_GEN(opt_lg_prof_bt_max, opt_lg_prof_bt_max, size_t) +CTL_RO_NL_GEN(opt_lg_prof_sample, opt_lg_prof_sample, size_t) +CTL_RO_NL_GEN(opt_lg_prof_interval, opt_lg_prof_interval, ssize_t) +CTL_RO_NL_GEN(opt_prof_gdump, opt_prof_gdump, bool) +CTL_RO_NL_GEN(opt_prof_leak, opt_prof_leak, bool) +CTL_RO_NL_GEN(opt_prof_accum, opt_prof_accum, bool) +CTL_RO_NL_GEN(opt_lg_prof_tcmax, opt_lg_prof_tcmax, ssize_t) #endif #ifdef JEMALLOC_SWAP -CTL_RO_GEN(opt_overcommit, opt_overcommit, bool) +CTL_RO_NL_GEN(opt_overcommit, opt_overcommit, bool) #endif /******************************************************************************/ -CTL_RO_GEN(arenas_bin_i_size, arenas[0]->bins[mib[2]].reg_size, size_t) -CTL_RO_GEN(arenas_bin_i_nregs, arenas[0]->bins[mib[2]].nregs, uint32_t) -CTL_RO_GEN(arenas_bin_i_run_size, arenas[0]->bins[mib[2]].run_size, size_t) +CTL_RO_NL_GEN(arenas_bin_i_size, arenas[0]->bins[mib[2]].reg_size, size_t) +CTL_RO_NL_GEN(arenas_bin_i_nregs, arenas[0]->bins[mib[2]].nregs, uint32_t) +CTL_RO_NL_GEN(arenas_bin_i_run_size, arenas[0]->bins[mib[2]].run_size, size_t) const ctl_node_t * arenas_bin_i_index(const size_t *mib, size_t miblen, size_t i) { @@ -1256,7 +1296,7 @@ arenas_bin_i_index(const size_t *mib, size_t miblen, size_t i) return (super_arenas_bin_i_node); } -CTL_RO_GEN(arenas_lrun_i_size, ((mib[2]+1) << PAGE_SHIFT), size_t) +CTL_RO_NL_GEN(arenas_lrun_i_size, ((mib[2]+1) << PAGE_SHIFT), size_t) const ctl_node_t * arenas_lrun_i_index(const size_t *mib, size_t miblen, size_t i) { @@ -1266,7 +1306,7 @@ arenas_lrun_i_index(const size_t *mib, size_t miblen, size_t i) return (super_arenas_lrun_i_node); } -CTL_RO_GEN(arenas_narenas, narenas, unsigned) +CTL_RO_NL_GEN(arenas_narenas, narenas, unsigned) static int arenas_initialized_ctl(const size_t *mib, size_t miblen, void *oldp, @@ -1275,6 +1315,7 @@ arenas_initialized_ctl(const size_t *mib, size_t miblen, void *oldp, int ret; unsigned nread, i; + malloc_mutex_lock(&ctl_mtx); READONLY(); if (*oldlenp != narenas * sizeof(bool)) { ret = EINVAL; @@ -1289,36 +1330,37 @@ arenas_initialized_ctl(const size_t *mib, size_t miblen, void *oldp, ((bool *)oldp)[i] = ctl_stats.arenas[i].initialized; RETURN: + malloc_mutex_unlock(&ctl_mtx); return (ret); } -CTL_RO_GEN(arenas_quantum, QUANTUM, size_t) -CTL_RO_GEN(arenas_cacheline, CACHELINE, size_t) -CTL_RO_GEN(arenas_subpage, SUBPAGE, size_t) -CTL_RO_GEN(arenas_pagesize, PAGE_SIZE, size_t) -CTL_RO_GEN(arenas_chunksize, chunksize, size_t) +CTL_RO_NL_GEN(arenas_quantum, QUANTUM, size_t) +CTL_RO_NL_GEN(arenas_cacheline, CACHELINE, size_t) +CTL_RO_NL_GEN(arenas_subpage, SUBPAGE, size_t) +CTL_RO_NL_GEN(arenas_pagesize, PAGE_SIZE, size_t) +CTL_RO_NL_GEN(arenas_chunksize, chunksize, size_t) #ifdef JEMALLOC_TINY -CTL_RO_GEN(arenas_tspace_min, (1U << LG_TINY_MIN), size_t) -CTL_RO_GEN(arenas_tspace_max, (qspace_min >> 1), size_t) +CTL_RO_NL_GEN(arenas_tspace_min, (1U << LG_TINY_MIN), size_t) +CTL_RO_NL_GEN(arenas_tspace_max, (qspace_min >> 1), size_t) #endif -CTL_RO_GEN(arenas_qspace_min, qspace_min, size_t) -CTL_RO_GEN(arenas_qspace_max, qspace_max, size_t) -CTL_RO_GEN(arenas_cspace_min, cspace_min, size_t) -CTL_RO_GEN(arenas_cspace_max, cspace_max, size_t) -CTL_RO_GEN(arenas_sspace_min, sspace_min, size_t) -CTL_RO_GEN(arenas_sspace_max, sspace_max, size_t) +CTL_RO_NL_GEN(arenas_qspace_min, qspace_min, size_t) +CTL_RO_NL_GEN(arenas_qspace_max, qspace_max, size_t) +CTL_RO_NL_GEN(arenas_cspace_min, cspace_min, size_t) +CTL_RO_NL_GEN(arenas_cspace_max, cspace_max, size_t) +CTL_RO_NL_GEN(arenas_sspace_min, sspace_min, size_t) +CTL_RO_NL_GEN(arenas_sspace_max, sspace_max, size_t) #ifdef JEMALLOC_TCACHE -CTL_RO_GEN(arenas_tcache_max, tcache_maxclass, size_t) +CTL_RO_NL_GEN(arenas_tcache_max, tcache_maxclass, size_t) #endif -CTL_RO_GEN(arenas_ntbins, ntbins, unsigned) -CTL_RO_GEN(arenas_nqbins, nqbins, unsigned) -CTL_RO_GEN(arenas_ncbins, ncbins, unsigned) -CTL_RO_GEN(arenas_nsbins, nsbins, unsigned) -CTL_RO_GEN(arenas_nbins, nbins, unsigned) +CTL_RO_NL_GEN(arenas_ntbins, ntbins, unsigned) +CTL_RO_NL_GEN(arenas_nqbins, nqbins, unsigned) +CTL_RO_NL_GEN(arenas_ncbins, ncbins, unsigned) +CTL_RO_NL_GEN(arenas_nsbins, nsbins, unsigned) +CTL_RO_NL_GEN(arenas_nbins, nbins, unsigned) #ifdef JEMALLOC_TCACHE -CTL_RO_GEN(arenas_nhbins, nhbins, unsigned) +CTL_RO_NL_GEN(arenas_nhbins, nhbins, unsigned) #endif -CTL_RO_GEN(arenas_nlruns, nlclasses, size_t) +CTL_RO_NL_GEN(arenas_nlruns, nlclasses, size_t) static int arenas_purge_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, @@ -1368,6 +1410,7 @@ prof_active_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, int ret; bool oldval; + malloc_mutex_lock(&ctl_mtx); /* Protect opt_prof_active. */ oldval = opt_prof_active; if (newp != NULL) { /* @@ -1382,6 +1425,7 @@ prof_active_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, ret = 0; RETURN: + malloc_mutex_unlock(&ctl_mtx); return (ret); } @@ -1405,7 +1449,7 @@ RETURN: return (ret); } -CTL_RO_GEN(prof_interval, prof_interval, uint64_t) +CTL_RO_NL_GEN(prof_interval, prof_interval, uint64_t) #endif /******************************************************************************/ @@ -1503,10 +1547,18 @@ CTL_RO_GEN(stats_arenas_i_purged, ctl_stats.arenas[mib[2]].astats.purged, const ctl_node_t * stats_arenas_i_index(const size_t *mib, size_t miblen, size_t i) { + const ctl_node_t * ret; - if (ctl_stats.arenas[i].initialized == false) - return (NULL); - return (super_stats_arenas_i_node); + malloc_mutex_lock(&ctl_mtx); + if (ctl_stats.arenas[i].initialized == false) { + ret = NULL; + goto RETURN; + } + + ret = super_stats_arenas_i_node; +RETURN: + malloc_mutex_unlock(&ctl_mtx); + return (ret); } #ifdef JEMALLOC_STATS @@ -1528,6 +1580,7 @@ swap_prezeroed_ctl(const size_t *mib, size_t miblen, void *oldp, { int ret; + malloc_mutex_lock(&ctl_mtx); if (swap_enabled) { READONLY(); } else { @@ -1545,6 +1598,7 @@ swap_prezeroed_ctl(const size_t *mib, size_t miblen, void *oldp, ret = 0; RETURN: + malloc_mutex_unlock(&ctl_mtx); return (ret); } @@ -1556,6 +1610,7 @@ swap_fds_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, { int ret; + malloc_mutex_lock(&ctl_mtx); if (swap_enabled) { READONLY(); } else if (newp != NULL) { @@ -1586,6 +1641,7 @@ swap_fds_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, ret = 0; RETURN: + malloc_mutex_unlock(&ctl_mtx); return (ret); } #endif diff --git a/jemalloc/src/huge.c b/jemalloc/src/huge.c index a0351975..0aadc433 100644 --- a/jemalloc/src/huge.c +++ b/jemalloc/src/huge.c @@ -215,13 +215,56 @@ huge_ralloc(void *ptr, size_t oldsize, size_t size, size_t extra, * expectation that the extra bytes will be reliably preserved. */ copysize = (size < oldsize) ? size : oldsize; - memcpy(ret, ptr, copysize); - idalloc(ptr); + + /* + * Use mremap(2) if this is a huge-->huge reallocation, and neither the + * source nor the destination are in swap or dss. + */ +#ifdef JEMALLOC_MREMAP_FIXED + if (oldsize >= chunksize +# ifdef JEMALLOC_SWAP + && (swap_enabled == false || (chunk_in_swap(ptr) == false && + chunk_in_swap(ret) == false)) +# endif +# ifdef JEMALLOC_DSS + && chunk_in_dss(ptr) == false && chunk_in_dss(ret) == false +# endif + ) { + size_t newsize = huge_salloc(ret); + + if (mremap(ptr, oldsize, newsize, MREMAP_MAYMOVE|MREMAP_FIXED, + ret) == MAP_FAILED) { + /* + * Assuming no chunk management bugs in the allocator, + * the only documented way an error can occur here is + * if the application changed the map type for a + * portion of the old allocation. This is firmly in + * undefined behavior territory, so write a diagnostic + * message, and optionally abort. + */ + char buf[BUFERROR_BUF]; + + buferror(errno, buf, sizeof(buf)); + malloc_write(": Error in mremap(): "); + malloc_write(buf); + malloc_write("\n"); + if (opt_abort) + abort(); + memcpy(ret, ptr, copysize); + idalloc(ptr); + } else + huge_dalloc(ptr, false); + } else +#endif + { + memcpy(ret, ptr, copysize); + idalloc(ptr); + } return (ret); } void -huge_dalloc(void *ptr) +huge_dalloc(void *ptr, bool unmap) { extent_node_t *node, key; @@ -241,14 +284,16 @@ huge_dalloc(void *ptr) malloc_mutex_unlock(&huge_mtx); + if (unmap) { /* Unmap chunk. */ #ifdef JEMALLOC_FILL #if (defined(JEMALLOC_SWAP) || defined(JEMALLOC_DSS)) - if (opt_junk) - memset(node->addr, 0x5a, node->size); + if (opt_junk) + memset(node->addr, 0x5a, node->size); #endif #endif - chunk_dealloc(node->addr, node->size); + chunk_dealloc(node->addr, node->size); + } base_node_dealloc(node); } diff --git a/jemalloc/test/mremap.c b/jemalloc/test/mremap.c new file mode 100644 index 00000000..146c66f4 --- /dev/null +++ b/jemalloc/test/mremap.c @@ -0,0 +1,67 @@ +#include +#include +#include +#include +#include + +#define JEMALLOC_MANGLE +#include "jemalloc_test.h" + +int +main(void) +{ + int ret, err; + size_t sz, lg_chunk, chunksize, i; + char *p, *q; + + fprintf(stderr, "Test begin\n"); + + sz = sizeof(lg_chunk); + if ((err = JEMALLOC_P(mallctl)("opt.lg_chunk", &lg_chunk, &sz, NULL, + 0))) { + assert(err != ENOENT); + fprintf(stderr, "%s(): Error in mallctl(): %s\n", __func__, + strerror(err)); + ret = 1; + goto RETURN; + } + chunksize = ((size_t)1U) << lg_chunk; + + p = (char *)malloc(chunksize); + if (p == NULL) { + fprintf(stderr, "malloc(%zu) --> %p\n", chunksize, p); + ret = 1; + goto RETURN; + } + memset(p, 'a', chunksize); + + q = (char *)realloc(p, chunksize * 2); + if (q == NULL) { + fprintf(stderr, "realloc(%p, %zu) --> %p\n", p, chunksize * 2, + q); + ret = 1; + goto RETURN; + } + for (i = 0; i < chunksize; i++) { + assert(q[i] == 'a'); + } + + p = q; + + q = (char *)realloc(p, chunksize); + if (q == NULL) { + fprintf(stderr, "realloc(%p, %zu) --> %p\n", p, chunksize, q); + ret = 1; + goto RETURN; + } + for (i = 0; i < chunksize; i++) { + assert(q[i] == 'a'); + } + + free(q); + + ret = 0; +RETURN: + fprintf(stderr, "Test end\n"); + return (ret); +} diff --git a/jemalloc/test/mremap.exp b/jemalloc/test/mremap.exp new file mode 100644 index 00000000..369a88dd --- /dev/null +++ b/jemalloc/test/mremap.exp @@ -0,0 +1,2 @@ +Test begin +Test end