├── COPYING ├── ckh.c ├── ctl.c ├── mb.c ├── tsd.c ├── arena.c ├── base.c ├── chunk.c ├── hash.c ├── huge.c ├── internal ├── config.stamp.in ├── .gitattributes ├── test │ ├── unit │ │ ├── junk_alloc.c │ │ ├── junk_free.c │ │ ├── decay.sh │ │ ├── arena_reset.sh │ │ ├── prof_tctx.sh │ │ ├── prof_thread_name.sh │ │ ├── prof_reset.sh │ │ ├── prof_gdump.sh │ │ ├── junk.sh │ │ ├── zero.sh │ │ ├── junk_alloc.sh │ │ ├── junk_free.sh │ │ ├── prof_active.sh │ │ ├── prof_accum.sh │ │ ├── pack.sh │ │ ├── prof_idump.sh │ │ ├── quarantine.sh │ │ ├── lg_chunk.sh │ │ ├── a0.c │ │ ├── lg_chunk.c │ │ ├── pages.c │ │ ├── prof_idump.c │ │ ├── mtx.c │ │ ├── fork.c │ │ ├── zero.c │ │ ├── prof_accum.c │ │ ├── mq.c │ │ ├── prof_gdump.c │ │ ├── ticker.c │ │ ├── tsd.c │ │ ├── quarantine.c │ │ ├── extent_quantize.c │ │ ├── smoothstep.c │ │ └── atomic.c │ ├── src │ │ ├── math.c │ │ ├── btalloc_0.c │ │ ├── btalloc_1.c │ │ ├── btalloc.c │ │ ├── mq.c │ │ ├── thd.c │ │ ├── timer.c │ │ ├── mtx.c │ │ └── test.c │ ├── integration │ │ ├── chunk.sh │ │ ├── mallocx.sh │ │ ├── xallocx.sh │ │ ├── sdallocx.c │ │ ├── overflow.c │ │ ├── MALLOCX_ARENA.c │ │ ├── thread_arena.c │ │ ├── thread_tcache_enabled.c │ │ ├── posix_memalign.c │ │ └── allocated.c │ ├── include │ │ └── test │ │ │ ├── thd.h │ │ │ ├── jemalloc_test_defs.h.in │ │ │ ├── timer.h │ │ │ ├── mtx.h │ │ │ ├── btalloc.h │ │ │ └── mq.h │ └── test.sh.in ├── src │ ├── mb.c │ ├── hash.c │ ├── prng.c │ ├── spin.c │ ├── atomic.c │ ├── ticker.c │ ├── valgrind.c │ ├── chunk_mmap.c │ ├── extent.c │ └── bitmap.c ├── msvc │ ├── projects │ │ └── vc2015 │ │ │ └── test_threads │ │ │ ├── test_threads.h │ │ │ ├── test_threads_main.cpp │ │ │ ├── test_threads.vcxproj.filters │ │ │ └── test_threads.cpp │ └── ReadMe.txt ├── .autom4te.cfg ├── include │ ├── jemalloc │ │ ├── internal │ │ │ ├── private_unnamespace.sh │ │ │ ├── private_namespace.sh │ │ │ ├── public_unnamespace.sh │ │ │ ├── public_namespace.sh │ │ │ ├── chunk_mmap.h │ │ │ ├── base.h │ │ │ ├── pages.h │ │ │ ├── assert.h │ │ │ ├── chunk_dss.h │ │ │ ├── spin.h │ │ │ ├── huge.h │ │ │ ├── quarantine.h │ │ │ ├── jemalloc_internal_macros.h │ │ │ ├── nstime.h │ │ │ ├── jemalloc_internal_decls.h │ │ │ ├── ticker.h │ │ │ ├── qr.h │ │ │ ├── ql.h │ │ │ ├── ckh.h │ │ │ ├── mb.h │ │ │ └── chunk.h │ │ ├── jemalloc_rename.sh │ │ ├── jemalloc.sh │ │ ├── jemalloc_defs.h.in │ │ ├── jemalloc_mangle.sh │ │ ├── jemalloc_typedefs.h.in │ │ └── jemalloc_protos.h.in │ └── msvc_compat │ │ ├── windows_extra.h │ │ ├── C99 │ │ └── stdbool.h │ │ └── strings.h ├── bin │ ├── jemalloc.sh.in │ └── jemalloc-config.in ├── doc │ ├── manpages.xsl.in │ ├── html.xsl.in │ └── stylesheet.xsl ├── autogen.sh ├── coverage.sh ├── jemalloc.pc.in ├── README ├── .appveyor.yml ├── COPYING ├── .gitignore ├── scripts │ └── gen_travis.py └── .travis.yml ├── mutex.c ├── pages.c ├── prng.c ├── prof.c ├── rtree.c ├── spin.c ├── stats.c ├── util.c ├── atomic.c ├── bitmap.c ├── extent.c ├── jemalloc.c ├── nstime.c ├── tcache.c ├── ticker.c ├── witness.c ├── chunk_dss.c ├── chunk_mmap.c ├── quarantine.c ├── zone.c ├── Makefile ├── circle.yml ├── README.md ├── darwin_includes └── internal │ └── include │ └── jemalloc │ ├── internal │ ├── public_unnamespace.h │ ├── public_symbols.txt │ └── public_namespace.h │ ├── jemalloc_rename.h │ ├── jemalloc_defs.h │ ├── jemalloc_typedefs.h │ ├── jemalloc_mangle.h │ ├── jemalloc_mangle_jet.h │ ├── jemalloc_protos.h │ └── jemalloc_protos_jet.h ├── freebsd_includes └── internal │ └── include │ └── jemalloc │ ├── internal │ ├── public_unnamespace.h │ ├── public_symbols.txt │ └── public_namespace.h │ ├── jemalloc_rename.h │ ├── jemalloc_defs.h │ ├── jemalloc_typedefs.h │ ├── jemalloc_mangle.h │ ├── jemalloc_mangle_jet.h │ ├── jemalloc_protos.h │ └── jemalloc_protos_jet.h ├── linux_includes └── internal │ └── include │ └── jemalloc │ ├── internal │ ├── public_unnamespace.h │ ├── public_symbols.txt │ └── public_namespace.h │ ├── jemalloc_rename.h │ ├── jemalloc_defs.h │ ├── jemalloc_typedefs.h │ ├── jemalloc_mangle.h │ ├── jemalloc_mangle_jet.h │ ├── jemalloc_protos.h │ └── jemalloc_protos_jet.h ├── cgo_flags.go └── import.sh /COPYING: -------------------------------------------------------------------------------- 1 | internal/COPYING -------------------------------------------------------------------------------- /ckh.c: -------------------------------------------------------------------------------- 1 | internal/src/ckh.c -------------------------------------------------------------------------------- /ctl.c: -------------------------------------------------------------------------------- 1 | internal/src/ctl.c -------------------------------------------------------------------------------- /mb.c: -------------------------------------------------------------------------------- 1 | internal/src/mb.c -------------------------------------------------------------------------------- /tsd.c: -------------------------------------------------------------------------------- 1 | internal/src/tsd.c -------------------------------------------------------------------------------- /arena.c: -------------------------------------------------------------------------------- 1 | internal/src/arena.c -------------------------------------------------------------------------------- /base.c: -------------------------------------------------------------------------------- 1 | internal/src/base.c -------------------------------------------------------------------------------- /chunk.c: -------------------------------------------------------------------------------- 1 | internal/src/chunk.c -------------------------------------------------------------------------------- /hash.c: -------------------------------------------------------------------------------- 1 | internal/src/hash.c -------------------------------------------------------------------------------- /huge.c: -------------------------------------------------------------------------------- 1 | internal/src/huge.c -------------------------------------------------------------------------------- /internal/config.stamp.in: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /mutex.c: -------------------------------------------------------------------------------- 1 | internal/src/mutex.c -------------------------------------------------------------------------------- /pages.c: -------------------------------------------------------------------------------- 1 | internal/src/pages.c -------------------------------------------------------------------------------- /prng.c: -------------------------------------------------------------------------------- 1 | internal/src/prng.c -------------------------------------------------------------------------------- /prof.c: -------------------------------------------------------------------------------- 1 | internal/src/prof.c -------------------------------------------------------------------------------- /rtree.c: -------------------------------------------------------------------------------- 1 | internal/src/rtree.c -------------------------------------------------------------------------------- /spin.c: -------------------------------------------------------------------------------- 1 | internal/src/spin.c -------------------------------------------------------------------------------- /stats.c: -------------------------------------------------------------------------------- 1 | internal/src/stats.c -------------------------------------------------------------------------------- /util.c: -------------------------------------------------------------------------------- 1 | internal/src/util.c -------------------------------------------------------------------------------- /atomic.c: -------------------------------------------------------------------------------- 1 | internal/src/atomic.c -------------------------------------------------------------------------------- /bitmap.c: -------------------------------------------------------------------------------- 1 | internal/src/bitmap.c -------------------------------------------------------------------------------- /extent.c: -------------------------------------------------------------------------------- 1 | internal/src/extent.c -------------------------------------------------------------------------------- /jemalloc.c: -------------------------------------------------------------------------------- 1 | internal/src/jemalloc.c -------------------------------------------------------------------------------- /nstime.c: -------------------------------------------------------------------------------- 1 | internal/src/nstime.c -------------------------------------------------------------------------------- /tcache.c: -------------------------------------------------------------------------------- 1 | internal/src/tcache.c -------------------------------------------------------------------------------- /ticker.c: -------------------------------------------------------------------------------- 1 | internal/src/ticker.c -------------------------------------------------------------------------------- /witness.c: -------------------------------------------------------------------------------- 1 | internal/src/witness.c -------------------------------------------------------------------------------- /chunk_dss.c: -------------------------------------------------------------------------------- 1 | internal/src/chunk_dss.c -------------------------------------------------------------------------------- /chunk_mmap.c: -------------------------------------------------------------------------------- 1 | internal/src/chunk_mmap.c -------------------------------------------------------------------------------- /quarantine.c: -------------------------------------------------------------------------------- 1 | internal/src/quarantine.c -------------------------------------------------------------------------------- /internal/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | -------------------------------------------------------------------------------- /internal/test/unit/junk_alloc.c: -------------------------------------------------------------------------------- 1 | #include "junk.c" 2 | -------------------------------------------------------------------------------- /internal/test/unit/junk_free.c: -------------------------------------------------------------------------------- 1 | #include "junk.c" 2 | -------------------------------------------------------------------------------- /zone.c: -------------------------------------------------------------------------------- 1 | // +build darwin 2 | 3 | #include "internal/src/zone.c" 4 | -------------------------------------------------------------------------------- /internal/test/src/math.c: -------------------------------------------------------------------------------- 1 | #define MATH_C_ 2 | #include "test/jemalloc_test.h" 3 | -------------------------------------------------------------------------------- /internal/test/src/btalloc_0.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | btalloc_n_gen(0) 4 | -------------------------------------------------------------------------------- /internal/test/src/btalloc_1.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | btalloc_n_gen(1) 4 | -------------------------------------------------------------------------------- /internal/src/mb.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_MB_C_ 2 | #include "jemalloc/internal/jemalloc_internal.h" 3 | -------------------------------------------------------------------------------- /internal/test/unit/decay.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | export MALLOC_CONF="purge:decay,decay_time:1" 4 | -------------------------------------------------------------------------------- /internal/msvc/projects/vc2015/test_threads/test_threads.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | int test_threads(); 4 | -------------------------------------------------------------------------------- /internal/src/hash.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_HASH_C_ 2 | #include "jemalloc/internal/jemalloc_internal.h" 3 | -------------------------------------------------------------------------------- /internal/src/prng.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_PRNG_C_ 2 | #include "jemalloc/internal/jemalloc_internal.h" 3 | -------------------------------------------------------------------------------- /internal/src/spin.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_SPIN_C_ 2 | #include "jemalloc/internal/jemalloc_internal.h" 3 | -------------------------------------------------------------------------------- /internal/src/atomic.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_ATOMIC_C_ 2 | #include "jemalloc/internal/jemalloc_internal.h" 3 | -------------------------------------------------------------------------------- /internal/src/ticker.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_TICKER_C_ 2 | #include "jemalloc/internal/jemalloc_internal.h" 3 | -------------------------------------------------------------------------------- /internal/.autom4te.cfg: -------------------------------------------------------------------------------- 1 | begin-language: "Autoconf-without-aclocal-m4" 2 | args: --no-cache 3 | end-language: "Autoconf-without-aclocal-m4" 4 | -------------------------------------------------------------------------------- /internal/test/integration/chunk.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "x${enable_fill}" = "x1" ] ; then 4 | export MALLOC_CONF="junk:false" 5 | fi 6 | -------------------------------------------------------------------------------- /internal/test/integration/mallocx.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "x${enable_fill}" = "x1" ] ; then 4 | export MALLOC_CONF="junk:false" 5 | fi 6 | -------------------------------------------------------------------------------- /internal/test/integration/xallocx.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "x${enable_fill}" = "x1" ] ; then 4 | export MALLOC_CONF="junk:false" 5 | fi 6 | -------------------------------------------------------------------------------- /internal/include/jemalloc/internal/private_unnamespace.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | for symbol in `cat $1` ; do 4 | echo "#undef ${symbol}" 5 | done 6 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | include internal/Makefile.in 2 | 3 | sources: 4 | @for source_file in $(C_SRCS); do \ 5 | echo internal/$${source_file##*@}; \ 6 | done 7 | -------------------------------------------------------------------------------- /internal/test/unit/arena_reset.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "x${enable_prof}" = "x1" ] ; then 4 | export MALLOC_CONF="prof:true,lg_prof_sample:0" 5 | fi 6 | -------------------------------------------------------------------------------- /internal/test/unit/prof_tctx.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "x${enable_prof}" = "x1" ] ; then 4 | export MALLOC_CONF="prof:true,lg_prof_sample:0" 5 | fi 6 | -------------------------------------------------------------------------------- /internal/test/unit/prof_thread_name.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "x${enable_prof}" = "x1" ] ; then 4 | export MALLOC_CONF="prof:true,prof_active:false" 5 | fi 6 | -------------------------------------------------------------------------------- /internal/include/jemalloc/internal/private_namespace.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | for symbol in `cat $1` ; do 4 | echo "#define ${symbol} JEMALLOC_N(${symbol})" 5 | done 6 | -------------------------------------------------------------------------------- /internal/test/src/btalloc.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | void * 4 | btalloc(size_t size, unsigned bits) 5 | { 6 | 7 | return (btalloc_0(size, bits)); 8 | } 9 | -------------------------------------------------------------------------------- /internal/test/unit/prof_reset.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "x${enable_prof}" = "x1" ] ; then 4 | export MALLOC_CONF="prof:true,prof_active:false,lg_prof_sample:0" 5 | fi 6 | -------------------------------------------------------------------------------- /internal/test/unit/prof_gdump.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "x${enable_prof}" = "x1" ] ; then 4 | export MALLOC_CONF="prof:true,prof_active:false,prof_gdump:true" 5 | fi 6 | 7 | -------------------------------------------------------------------------------- /internal/test/unit/junk.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "x${enable_fill}" = "x1" ] ; then 4 | export MALLOC_CONF="abort:false,zero:false,redzone:true,quarantine:0,junk:true" 5 | fi 6 | -------------------------------------------------------------------------------- /internal/test/unit/zero.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "x${enable_fill}" = "x1" ] ; then 4 | export MALLOC_CONF="abort:false,junk:false,zero:true,redzone:false,quarantine:0" 5 | fi 6 | -------------------------------------------------------------------------------- /internal/test/unit/junk_alloc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "x${enable_fill}" = "x1" ] ; then 4 | export MALLOC_CONF="abort:false,zero:false,redzone:true,quarantine:0,junk:alloc" 5 | fi 6 | -------------------------------------------------------------------------------- /internal/test/unit/junk_free.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "x${enable_fill}" = "x1" ] ; then 4 | export MALLOC_CONF="abort:false,zero:false,redzone:true,quarantine:0,junk:free" 5 | fi 6 | -------------------------------------------------------------------------------- /internal/test/unit/prof_active.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "x${enable_prof}" = "x1" ] ; then 4 | export MALLOC_CONF="prof:true,prof_thread_active_init:false,lg_prof_sample:0" 5 | fi 6 | -------------------------------------------------------------------------------- /internal/include/jemalloc/internal/public_unnamespace.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | for nm in `cat $1` ; do 4 | n=`echo ${nm} |tr ':' ' ' |awk '{print $1}'` 5 | echo "#undef je_${n}" 6 | done 7 | -------------------------------------------------------------------------------- /internal/test/unit/prof_accum.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "x${enable_prof}" = "x1" ] ; then 4 | export MALLOC_CONF="prof:true,prof_accum:true,prof_active:false,lg_prof_sample:0" 5 | fi 6 | -------------------------------------------------------------------------------- /internal/include/msvc_compat/windows_extra.h: -------------------------------------------------------------------------------- 1 | #ifndef MSVC_COMPAT_WINDOWS_EXTRA_H 2 | #define MSVC_COMPAT_WINDOWS_EXTRA_H 3 | 4 | #include 5 | 6 | #endif /* MSVC_COMPAT_WINDOWS_EXTRA_H */ 7 | -------------------------------------------------------------------------------- /internal/include/jemalloc/internal/public_namespace.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | for nm in `cat $1` ; do 4 | n=`echo ${nm} |tr ':' ' ' |awk '{print $1}'` 5 | echo "#define je_${n} JEMALLOC_N(${n})" 6 | done 7 | -------------------------------------------------------------------------------- /internal/test/unit/pack.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Use smallest possible chunk size. Immediately purge to minimize 4 | # fragmentation. 5 | export MALLOC_CONF="lg_chunk:0,lg_dirty_mult:-1,decay_time:-1" 6 | -------------------------------------------------------------------------------- /internal/test/unit/prof_idump.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "x${enable_prof}" = "x1" ] ; then 4 | export MALLOC_CONF="prof:true,prof_accum:true,prof_active:false,lg_prof_sample:0,lg_prof_interval:0" 5 | fi 6 | 7 | 8 | -------------------------------------------------------------------------------- /internal/bin/jemalloc.sh.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | prefix=@prefix@ 4 | exec_prefix=@exec_prefix@ 5 | libdir=@libdir@ 6 | 7 | @LD_PRELOAD_VAR@=${libdir}/libjemalloc.@SOREV@ 8 | export @LD_PRELOAD_VAR@ 9 | exec "$@" 10 | -------------------------------------------------------------------------------- /internal/doc/manpages.xsl.in: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /internal/test/unit/quarantine.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Keep in sync with definition in quarantine.c. 4 | export QUARANTINE_SIZE=8192 5 | 6 | if [ "x${enable_fill}" = "x1" ] ; then 7 | export MALLOC_CONF="abort:false,junk:true,redzone:true,quarantine:${QUARANTINE_SIZE}" 8 | fi 9 | -------------------------------------------------------------------------------- /internal/doc/html.xsl.in: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /internal/test/include/test/thd.h: -------------------------------------------------------------------------------- 1 | /* Abstraction layer for threading in tests. */ 2 | #ifdef _WIN32 3 | typedef HANDLE thd_t; 4 | #else 5 | typedef pthread_t thd_t; 6 | #endif 7 | 8 | void thd_create(thd_t *thd, void *(*proc)(void *), void *arg); 9 | void thd_join(thd_t thd, void **ret); 10 | -------------------------------------------------------------------------------- /internal/test/unit/lg_chunk.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Make sure that opt.lg_chunk clamping is sufficient. In practice, this test 4 | # program will fail a debug assertion during initialization and abort (rather 5 | # than the test soft-failing) if clamping is insufficient. 6 | export MALLOC_CONF="lg_chunk:0" 7 | -------------------------------------------------------------------------------- /internal/msvc/projects/vc2015/test_threads/test_threads_main.cpp: -------------------------------------------------------------------------------- 1 | #include "test_threads.h" 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std::chrono_literals; 7 | 8 | int main(int argc, char** argv) 9 | { 10 | int rc = test_threads(); 11 | return rc; 12 | } 13 | -------------------------------------------------------------------------------- /circle.yml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | pre: 3 | - git clone --depth 1 https://chromium.googlesource.com/chromium/src/tools/clang 4 | - clang/scripts/update.py 5 | 6 | machine: 7 | environment: 8 | CC: $HOME/third_party/llvm-build/Release+Asserts/bin/clang 9 | CXX: $HOME/third_party/llvm-build/Release+Asserts/bin/clang++ 10 | -------------------------------------------------------------------------------- /internal/test/unit/a0.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | TEST_BEGIN(test_a0) 4 | { 5 | void *p; 6 | 7 | p = a0malloc(1); 8 | assert_ptr_not_null(p, "Unexpected a0malloc() error"); 9 | a0dalloc(p); 10 | } 11 | TEST_END 12 | 13 | int 14 | main(void) 15 | { 16 | 17 | return (test_no_malloc_init( 18 | test_a0)); 19 | } 20 | -------------------------------------------------------------------------------- /internal/autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | for i in autoconf; do 4 | echo "$i" 5 | $i 6 | if [ $? -ne 0 ]; then 7 | echo "Error $? in $i" 8 | exit 1 9 | fi 10 | done 11 | 12 | echo "./configure --enable-autogen $@" 13 | ./configure --enable-autogen $@ 14 | if [ $? -ne 0 ]; then 15 | echo "Error $? in ./configure" 16 | exit 1 17 | fi 18 | -------------------------------------------------------------------------------- /internal/test/unit/lg_chunk.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | TEST_BEGIN(test_lg_chunk_clamp) 4 | { 5 | void *p; 6 | 7 | p = mallocx(1, 0); 8 | assert_ptr_not_null(p, "Unexpected mallocx() failure"); 9 | dallocx(p, 0); 10 | } 11 | TEST_END 12 | 13 | int 14 | main(void) 15 | { 16 | 17 | return (test( 18 | test_lg_chunk_clamp)); 19 | } 20 | -------------------------------------------------------------------------------- /internal/test/include/test/jemalloc_test_defs.h.in: -------------------------------------------------------------------------------- 1 | #include "jemalloc/internal/jemalloc_internal_defs.h" 2 | #include "jemalloc/internal/jemalloc_internal_decls.h" 3 | 4 | /* 5 | * For use by SFMT. configure.ac doesn't actually define HAVE_SSE2 because its 6 | * dependencies are notoriously unportable in practice. 7 | */ 8 | #undef HAVE_SSE2 9 | #undef HAVE_ALTIVEC 10 | -------------------------------------------------------------------------------- /internal/test/include/test/timer.h: -------------------------------------------------------------------------------- 1 | /* Simple timer, for use in benchmark reporting. */ 2 | 3 | typedef struct { 4 | nstime_t t0; 5 | nstime_t t1; 6 | } timedelta_t; 7 | 8 | void timer_start(timedelta_t *timer); 9 | void timer_stop(timedelta_t *timer); 10 | uint64_t timer_usec(const timedelta_t *timer); 11 | void timer_ratio(timedelta_t *a, timedelta_t *b, char *buf, size_t buflen); 12 | -------------------------------------------------------------------------------- /internal/coverage.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | objdir=$1 6 | suffix=$2 7 | shift 2 8 | objs=$@ 9 | 10 | gcov -b -p -f -o "${objdir}" ${objs} 11 | 12 | # Move gcov outputs so that subsequent gcov invocations won't clobber results 13 | # for the same sources with different compilation flags. 14 | for f in `find . -maxdepth 1 -type f -name '*.gcov'` ; do 15 | mv "${f}" "${f}.${suffix}" 16 | done 17 | -------------------------------------------------------------------------------- /internal/jemalloc.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | includedir=@includedir@ 5 | install_suffix=@install_suffix@ 6 | 7 | Name: jemalloc 8 | Description: A general purpose malloc(3) implementation that emphasizes fragmentation avoidance and scalable concurrency support. 9 | URL: http://jemalloc.net/ 10 | Version: @jemalloc_version@ 11 | Cflags: -I${includedir} 12 | Libs: -L${libdir} -ljemalloc${install_suffix} 13 | -------------------------------------------------------------------------------- /internal/doc/stylesheet.xsl: -------------------------------------------------------------------------------- 1 | 2 | ansi 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /internal/include/msvc_compat/C99/stdbool.h: -------------------------------------------------------------------------------- 1 | #ifndef stdbool_h 2 | #define stdbool_h 3 | 4 | #include 5 | 6 | /* MSVC doesn't define _Bool or bool in C, but does have BOOL */ 7 | /* Note this doesn't pass autoconf's test because (bool) 0.5 != true */ 8 | /* Clang-cl uses MSVC headers, so needs msvc_compat, but has _Bool as 9 | * a built-in type. */ 10 | #ifndef __clang__ 11 | typedef BOOL _Bool; 12 | #endif 13 | 14 | #define bool _Bool 15 | #define true 1 16 | #define false 0 17 | 18 | #define __bool_true_false_are_defined 1 19 | 20 | #endif /* stdbool_h */ 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # jemalloc 2 | 3 | This is a go-gettable version of the jemalloc allocator for use in Go code that 4 | needs to link against jemalloc but wants to integrate with `go get` and 5 | `go build`. 6 | 7 | To use in your project you need to import the package and set appropriate cgo flag directives: 8 | 9 | ``` 10 | import _ "github.com/cockroachdb/c-jemalloc" 11 | 12 | // #cgo CPPFLAGS: -I /c-jemalloc/internal/include 13 | // #cgo darwin LDFLAGS: -Wl,-undefined -Wl,dynamic_lookup 14 | // #cgo !darwin LDFLAGS: -Wl,-unresolved-symbols=ignore-all 15 | import "C" 16 | ``` 17 | -------------------------------------------------------------------------------- /darwin_includes/internal/include/jemalloc/internal/public_unnamespace.h: -------------------------------------------------------------------------------- 1 | #undef je_malloc_conf 2 | #undef je_malloc_message 3 | #undef je_malloc 4 | #undef je_calloc 5 | #undef je_posix_memalign 6 | #undef je_aligned_alloc 7 | #undef je_realloc 8 | #undef je_free 9 | #undef je_mallocx 10 | #undef je_rallocx 11 | #undef je_xallocx 12 | #undef je_sallocx 13 | #undef je_dallocx 14 | #undef je_sdallocx 15 | #undef je_nallocx 16 | #undef je_mallctl 17 | #undef je_mallctlnametomib 18 | #undef je_mallctlbymib 19 | #undef je_malloc_stats_print 20 | #undef je_malloc_usable_size 21 | #undef je_valloc 22 | -------------------------------------------------------------------------------- /freebsd_includes/internal/include/jemalloc/internal/public_unnamespace.h: -------------------------------------------------------------------------------- 1 | #undef je_malloc_conf 2 | #undef je_malloc_message 3 | #undef je_malloc 4 | #undef je_calloc 5 | #undef je_posix_memalign 6 | #undef je_aligned_alloc 7 | #undef je_realloc 8 | #undef je_free 9 | #undef je_mallocx 10 | #undef je_rallocx 11 | #undef je_xallocx 12 | #undef je_sallocx 13 | #undef je_dallocx 14 | #undef je_sdallocx 15 | #undef je_nallocx 16 | #undef je_mallctl 17 | #undef je_mallctlnametomib 18 | #undef je_mallctlbymib 19 | #undef je_malloc_stats_print 20 | #undef je_malloc_usable_size 21 | #undef je_valloc 22 | -------------------------------------------------------------------------------- /internal/include/jemalloc/jemalloc_rename.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | public_symbols_txt=$1 4 | 5 | cat < 7 | 8 | void 9 | valgrind_make_mem_noaccess(void *ptr, size_t usize) 10 | { 11 | 12 | VALGRIND_MAKE_MEM_NOACCESS(ptr, usize); 13 | } 14 | 15 | void 16 | valgrind_make_mem_undefined(void *ptr, size_t usize) 17 | { 18 | 19 | VALGRIND_MAKE_MEM_UNDEFINED(ptr, usize); 20 | } 21 | 22 | void 23 | valgrind_make_mem_defined(void *ptr, size_t usize) 24 | { 25 | 26 | VALGRIND_MAKE_MEM_DEFINED(ptr, usize); 27 | } 28 | 29 | void 30 | valgrind_freelike_block(void *ptr, size_t usize) 31 | { 32 | 33 | VALGRIND_FREELIKE_BLOCK(ptr, usize); 34 | } 35 | -------------------------------------------------------------------------------- /cgo_flags.go: -------------------------------------------------------------------------------- 1 | // Package jemalloc uses the cgo compilation facilities to build the 2 | // jemalloc library. 3 | package jemalloc 4 | 5 | // #cgo CPPFLAGS: -Iinternal/include -std=gnu11 6 | // #cgo !musl CPPFLAGS: -DJEMALLOC_PROF -DJEMALLOC_PROF_LIBGCC 7 | // #cgo CPPFLAGS: -D_REENTRANT 8 | // #cgo !darwin LDFLAGS: -lm -lpthread 9 | // #cgo linux LDFLAGS: -lrt 10 | // #cgo linux CPPFLAGS: -D_GNU_SOURCE 11 | // #cgo darwin CPPFLAGS: -Idarwin_includes/internal/include -Idarwin_includes/internal/include/jemalloc/internal -fno-omit-frame-pointer 12 | // #cgo linux CPPFLAGS: -Ilinux_includes/internal/include -Ilinux_includes/internal/include/jemalloc/internal 13 | // #cgo freebsd CPPFLAGS: -Ifreebsd_includes/internal/include -Ifreebsd_includes/internal/include/jemalloc/internal 14 | import "C" 15 | -------------------------------------------------------------------------------- /internal/include/jemalloc/internal/chunk_mmap.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | #ifdef JEMALLOC_H_TYPES 3 | 4 | #endif /* JEMALLOC_H_TYPES */ 5 | /******************************************************************************/ 6 | #ifdef JEMALLOC_H_STRUCTS 7 | 8 | #endif /* JEMALLOC_H_STRUCTS */ 9 | /******************************************************************************/ 10 | #ifdef JEMALLOC_H_EXTERNS 11 | 12 | void *chunk_alloc_mmap(void *new_addr, size_t size, size_t alignment, 13 | bool *zero, bool *commit); 14 | bool chunk_dalloc_mmap(void *chunk, size_t size); 15 | 16 | #endif /* JEMALLOC_H_EXTERNS */ 17 | /******************************************************************************/ 18 | #ifdef JEMALLOC_H_INLINES 19 | 20 | #endif /* JEMALLOC_H_INLINES */ 21 | /******************************************************************************/ 22 | -------------------------------------------------------------------------------- /internal/test/src/thd.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | #ifdef _WIN32 4 | void 5 | thd_create(thd_t *thd, void *(*proc)(void *), void *arg) 6 | { 7 | LPTHREAD_START_ROUTINE routine = (LPTHREAD_START_ROUTINE)proc; 8 | *thd = CreateThread(NULL, 0, routine, arg, 0, NULL); 9 | if (*thd == NULL) 10 | test_fail("Error in CreateThread()\n"); 11 | } 12 | 13 | void 14 | thd_join(thd_t thd, void **ret) 15 | { 16 | 17 | if (WaitForSingleObject(thd, INFINITE) == WAIT_OBJECT_0 && ret) { 18 | DWORD exit_code; 19 | GetExitCodeThread(thd, (LPDWORD) &exit_code); 20 | *ret = (void *)(uintptr_t)exit_code; 21 | } 22 | } 23 | 24 | #else 25 | void 26 | thd_create(thd_t *thd, void *(*proc)(void *), void *arg) 27 | { 28 | 29 | if (pthread_create(thd, NULL, proc, arg) != 0) 30 | test_fail("Error in pthread_create()\n"); 31 | } 32 | 33 | void 34 | thd_join(thd_t thd, void **ret) 35 | { 36 | 37 | pthread_join(thd, ret); 38 | } 39 | #endif 40 | -------------------------------------------------------------------------------- /internal/test/include/test/btalloc.h: -------------------------------------------------------------------------------- 1 | /* btalloc() provides a mechanism for allocating via permuted backtraces. */ 2 | void *btalloc(size_t size, unsigned bits); 3 | 4 | #define btalloc_n_proto(n) \ 5 | void *btalloc_##n(size_t size, unsigned bits); 6 | btalloc_n_proto(0) 7 | btalloc_n_proto(1) 8 | 9 | #define btalloc_n_gen(n) \ 10 | void * \ 11 | btalloc_##n(size_t size, unsigned bits) \ 12 | { \ 13 | void *p; \ 14 | \ 15 | if (bits == 0) \ 16 | p = mallocx(size, 0); \ 17 | else { \ 18 | switch (bits & 0x1U) { \ 19 | case 0: \ 20 | p = (btalloc_0(size, bits >> 1)); \ 21 | break; \ 22 | case 1: \ 23 | p = (btalloc_1(size, bits >> 1)); \ 24 | break; \ 25 | default: not_reached(); \ 26 | } \ 27 | } \ 28 | /* Intentionally sabotage tail call optimization. */ \ 29 | assert_ptr_not_null(p, "Unexpected mallocx() failure"); \ 30 | return (p); \ 31 | } 32 | -------------------------------------------------------------------------------- /internal/include/jemalloc/internal/base.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | #ifdef JEMALLOC_H_TYPES 3 | 4 | #endif /* JEMALLOC_H_TYPES */ 5 | /******************************************************************************/ 6 | #ifdef JEMALLOC_H_STRUCTS 7 | 8 | #endif /* JEMALLOC_H_STRUCTS */ 9 | /******************************************************************************/ 10 | #ifdef JEMALLOC_H_EXTERNS 11 | 12 | void *base_alloc(tsdn_t *tsdn, size_t size); 13 | void base_stats_get(tsdn_t *tsdn, size_t *allocated, size_t *resident, 14 | size_t *mapped); 15 | bool base_boot(void); 16 | void base_prefork(tsdn_t *tsdn); 17 | void base_postfork_parent(tsdn_t *tsdn); 18 | void base_postfork_child(tsdn_t *tsdn); 19 | 20 | #endif /* JEMALLOC_H_EXTERNS */ 21 | /******************************************************************************/ 22 | #ifdef JEMALLOC_H_INLINES 23 | 24 | #endif /* JEMALLOC_H_INLINES */ 25 | /******************************************************************************/ 26 | -------------------------------------------------------------------------------- /internal/test/unit/prof_idump.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | static bool did_prof_dump_open; 4 | 5 | static int 6 | prof_dump_open_intercept(bool propagate_err, const char *filename) 7 | { 8 | int fd; 9 | 10 | did_prof_dump_open = true; 11 | 12 | fd = open("/dev/null", O_WRONLY); 13 | assert_d_ne(fd, -1, "Unexpected open() failure"); 14 | 15 | return (fd); 16 | } 17 | 18 | TEST_BEGIN(test_idump) 19 | { 20 | bool active; 21 | void *p; 22 | 23 | test_skip_if(!config_prof); 24 | 25 | active = true; 26 | assert_d_eq(mallctl("prof.active", NULL, NULL, (void *)&active, 27 | sizeof(active)), 0, 28 | "Unexpected mallctl failure while activating profiling"); 29 | 30 | prof_dump_open = prof_dump_open_intercept; 31 | 32 | did_prof_dump_open = false; 33 | p = mallocx(1, 0); 34 | assert_ptr_not_null(p, "Unexpected mallocx() failure"); 35 | dallocx(p, 0); 36 | assert_true(did_prof_dump_open, "Expected a profile dump"); 37 | } 38 | TEST_END 39 | 40 | int 41 | main(void) 42 | { 43 | 44 | return (test( 45 | test_idump)); 46 | } 47 | -------------------------------------------------------------------------------- /darwin_includes/internal/include/jemalloc/internal/public_namespace.h: -------------------------------------------------------------------------------- 1 | #define je_malloc_conf JEMALLOC_N(malloc_conf) 2 | #define je_malloc_message JEMALLOC_N(malloc_message) 3 | #define je_malloc JEMALLOC_N(malloc) 4 | #define je_calloc JEMALLOC_N(calloc) 5 | #define je_posix_memalign JEMALLOC_N(posix_memalign) 6 | #define je_aligned_alloc JEMALLOC_N(aligned_alloc) 7 | #define je_realloc JEMALLOC_N(realloc) 8 | #define je_free JEMALLOC_N(free) 9 | #define je_mallocx JEMALLOC_N(mallocx) 10 | #define je_rallocx JEMALLOC_N(rallocx) 11 | #define je_xallocx JEMALLOC_N(xallocx) 12 | #define je_sallocx JEMALLOC_N(sallocx) 13 | #define je_dallocx JEMALLOC_N(dallocx) 14 | #define je_sdallocx JEMALLOC_N(sdallocx) 15 | #define je_nallocx JEMALLOC_N(nallocx) 16 | #define je_mallctl JEMALLOC_N(mallctl) 17 | #define je_mallctlnametomib JEMALLOC_N(mallctlnametomib) 18 | #define je_mallctlbymib JEMALLOC_N(mallctlbymib) 19 | #define je_malloc_stats_print JEMALLOC_N(malloc_stats_print) 20 | #define je_malloc_usable_size JEMALLOC_N(malloc_usable_size) 21 | #define je_valloc JEMALLOC_N(valloc) 22 | -------------------------------------------------------------------------------- /freebsd_includes/internal/include/jemalloc/internal/public_namespace.h: -------------------------------------------------------------------------------- 1 | #define je_malloc_conf JEMALLOC_N(malloc_conf) 2 | #define je_malloc_message JEMALLOC_N(malloc_message) 3 | #define je_malloc JEMALLOC_N(malloc) 4 | #define je_calloc JEMALLOC_N(calloc) 5 | #define je_posix_memalign JEMALLOC_N(posix_memalign) 6 | #define je_aligned_alloc JEMALLOC_N(aligned_alloc) 7 | #define je_realloc JEMALLOC_N(realloc) 8 | #define je_free JEMALLOC_N(free) 9 | #define je_mallocx JEMALLOC_N(mallocx) 10 | #define je_rallocx JEMALLOC_N(rallocx) 11 | #define je_xallocx JEMALLOC_N(xallocx) 12 | #define je_sallocx JEMALLOC_N(sallocx) 13 | #define je_dallocx JEMALLOC_N(dallocx) 14 | #define je_sdallocx JEMALLOC_N(sdallocx) 15 | #define je_nallocx JEMALLOC_N(nallocx) 16 | #define je_mallctl JEMALLOC_N(mallctl) 17 | #define je_mallctlnametomib JEMALLOC_N(mallctlnametomib) 18 | #define je_mallctlbymib JEMALLOC_N(mallctlbymib) 19 | #define je_malloc_stats_print JEMALLOC_N(malloc_stats_print) 20 | #define je_malloc_usable_size JEMALLOC_N(malloc_usable_size) 21 | #define je_valloc JEMALLOC_N(valloc) 22 | -------------------------------------------------------------------------------- /internal/msvc/projects/vc2015/test_threads/test_threads.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | 14 | 15 | Source Files 16 | 17 | 18 | Source Files 19 | 20 | 21 | 22 | 23 | Header Files 24 | 25 | 26 | -------------------------------------------------------------------------------- /freebsd_includes/internal/include/jemalloc/jemalloc_rename.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Name mangling for public symbols is controlled by --with-mangling and 3 | * --with-jemalloc-prefix. With default settings the je_ prefix is stripped by 4 | * these macro definitions. 5 | */ 6 | #ifndef JEMALLOC_NO_RENAME 7 | # define je_malloc_conf malloc_conf 8 | # define je_malloc_message malloc_message 9 | # define je_malloc malloc 10 | # define je_calloc calloc 11 | # define je_posix_memalign posix_memalign 12 | # define je_aligned_alloc aligned_alloc 13 | # define je_realloc realloc 14 | # define je_free free 15 | # define je_mallocx mallocx 16 | # define je_rallocx rallocx 17 | # define je_xallocx xallocx 18 | # define je_sallocx sallocx 19 | # define je_dallocx dallocx 20 | # define je_sdallocx sdallocx 21 | # define je_nallocx nallocx 22 | # define je_mallctl mallctl 23 | # define je_mallctlnametomib mallctlnametomib 24 | # define je_mallctlbymib mallctlbymib 25 | # define je_malloc_stats_print malloc_stats_print 26 | # define je_malloc_usable_size malloc_usable_size 27 | # define je_valloc valloc 28 | #endif 29 | -------------------------------------------------------------------------------- /linux_includes/internal/include/jemalloc/internal/public_namespace.h: -------------------------------------------------------------------------------- 1 | #define je_malloc_conf JEMALLOC_N(malloc_conf) 2 | #define je_malloc_message JEMALLOC_N(malloc_message) 3 | #define je_malloc JEMALLOC_N(malloc) 4 | #define je_calloc JEMALLOC_N(calloc) 5 | #define je_posix_memalign JEMALLOC_N(posix_memalign) 6 | #define je_aligned_alloc JEMALLOC_N(aligned_alloc) 7 | #define je_realloc JEMALLOC_N(realloc) 8 | #define je_free JEMALLOC_N(free) 9 | #define je_mallocx JEMALLOC_N(mallocx) 10 | #define je_rallocx JEMALLOC_N(rallocx) 11 | #define je_xallocx JEMALLOC_N(xallocx) 12 | #define je_sallocx JEMALLOC_N(sallocx) 13 | #define je_dallocx JEMALLOC_N(dallocx) 14 | #define je_sdallocx JEMALLOC_N(sdallocx) 15 | #define je_nallocx JEMALLOC_N(nallocx) 16 | #define je_mallctl JEMALLOC_N(mallctl) 17 | #define je_mallctlnametomib JEMALLOC_N(mallctlnametomib) 18 | #define je_mallctlbymib JEMALLOC_N(mallctlbymib) 19 | #define je_malloc_stats_print JEMALLOC_N(malloc_stats_print) 20 | #define je_malloc_usable_size JEMALLOC_N(malloc_usable_size) 21 | #define je_memalign JEMALLOC_N(memalign) 22 | #define je_valloc JEMALLOC_N(valloc) 23 | -------------------------------------------------------------------------------- /linux_includes/internal/include/jemalloc/jemalloc_rename.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Name mangling for public symbols is controlled by --with-mangling and 3 | * --with-jemalloc-prefix. With default settings the je_ prefix is stripped by 4 | * these macro definitions. 5 | */ 6 | #ifndef JEMALLOC_NO_RENAME 7 | # define je_malloc_conf malloc_conf 8 | # define je_malloc_message malloc_message 9 | # define je_malloc malloc 10 | # define je_calloc calloc 11 | # define je_posix_memalign posix_memalign 12 | # define je_aligned_alloc aligned_alloc 13 | # define je_realloc realloc 14 | # define je_free free 15 | # define je_mallocx mallocx 16 | # define je_rallocx rallocx 17 | # define je_xallocx xallocx 18 | # define je_sallocx sallocx 19 | # define je_dallocx dallocx 20 | # define je_sdallocx sdallocx 21 | # define je_nallocx nallocx 22 | # define je_mallctl mallctl 23 | # define je_mallctlnametomib mallctlnametomib 24 | # define je_mallctlbymib mallctlbymib 25 | # define je_malloc_stats_print malloc_stats_print 26 | # define je_malloc_usable_size malloc_usable_size 27 | # define je_memalign memalign 28 | # define je_valloc valloc 29 | #endif 30 | -------------------------------------------------------------------------------- /internal/README: -------------------------------------------------------------------------------- 1 | jemalloc is a general purpose malloc(3) implementation that emphasizes 2 | fragmentation avoidance and scalable concurrency support. jemalloc first came 3 | into use as the FreeBSD libc allocator in 2005, and since then it has found its 4 | way into numerous applications that rely on its predictable behavior. In 2010 5 | jemalloc development efforts broadened to include developer support features 6 | such as heap profiling, Valgrind integration, and extensive monitoring/tuning 7 | hooks. Modern jemalloc releases continue to be integrated back into FreeBSD, 8 | and therefore versatility remains critical. Ongoing development efforts trend 9 | toward making jemalloc among the best allocators for a broad range of demanding 10 | applications, and eliminating/mitigating weaknesses that have practical 11 | repercussions for real world applications. 12 | 13 | The COPYING file contains copyright and licensing information. 14 | 15 | The INSTALL file contains information on how to configure, build, and install 16 | jemalloc. 17 | 18 | The ChangeLog file contains a brief summary of changes for each release. 19 | 20 | URL: http://jemalloc.net/ 21 | -------------------------------------------------------------------------------- /darwin_includes/internal/include/jemalloc/jemalloc_rename.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Name mangling for public symbols is controlled by --with-mangling and 3 | * --with-jemalloc-prefix. With default settings the je_ prefix is stripped by 4 | * these macro definitions. 5 | */ 6 | #ifndef JEMALLOC_NO_RENAME 7 | # define je_malloc_conf je_malloc_conf 8 | # define je_malloc_message je_malloc_message 9 | # define je_malloc je_malloc 10 | # define je_calloc je_calloc 11 | # define je_posix_memalign je_posix_memalign 12 | # define je_aligned_alloc je_aligned_alloc 13 | # define je_realloc je_realloc 14 | # define je_free je_free 15 | # define je_mallocx je_mallocx 16 | # define je_rallocx je_rallocx 17 | # define je_xallocx je_xallocx 18 | # define je_sallocx je_sallocx 19 | # define je_dallocx je_dallocx 20 | # define je_sdallocx je_sdallocx 21 | # define je_nallocx je_nallocx 22 | # define je_mallctl je_mallctl 23 | # define je_mallctlnametomib je_mallctlnametomib 24 | # define je_mallctlbymib je_mallctlbymib 25 | # define je_malloc_stats_print je_malloc_stats_print 26 | # define je_malloc_usable_size je_malloc_usable_size 27 | # define je_valloc je_valloc 28 | #endif 29 | -------------------------------------------------------------------------------- /internal/.appveyor.yml: -------------------------------------------------------------------------------- 1 | version: '{build}' 2 | 3 | environment: 4 | matrix: 5 | - MSYSTEM: MINGW64 6 | CPU: x86_64 7 | MSVC: amd64 8 | - MSYSTEM: MINGW32 9 | CPU: i686 10 | MSVC: x86 11 | - MSYSTEM: MINGW64 12 | CPU: x86_64 13 | - MSYSTEM: MINGW32 14 | CPU: i686 15 | - MSYSTEM: MINGW64 16 | CPU: x86_64 17 | MSVC: amd64 18 | CONFIG_FLAGS: --enable-debug 19 | - MSYSTEM: MINGW32 20 | CPU: i686 21 | MSVC: x86 22 | CONFIG_FLAGS: --enable-debug 23 | - MSYSTEM: MINGW64 24 | CPU: x86_64 25 | CONFIG_FLAGS: --enable-debug 26 | - MSYSTEM: MINGW32 27 | CPU: i686 28 | CONFIG_FLAGS: --enable-debug 29 | 30 | install: 31 | - set PATH=c:\msys64\%MSYSTEM%\bin;c:\msys64\usr\bin;%PATH% 32 | - if defined MSVC call "c:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" %MSVC% 33 | - if defined MSVC pacman --noconfirm -Rsc mingw-w64-%CPU%-gcc gcc 34 | - pacman --noconfirm -Suy mingw-w64-%CPU%-make 35 | 36 | build_script: 37 | - bash -c "autoconf" 38 | - bash -c "./configure $CONFIG_FLAGS" 39 | - mingw32-make -j3 40 | - file lib/jemalloc.dll 41 | - mingw32-make -j3 tests 42 | - mingw32-make -k check 43 | -------------------------------------------------------------------------------- /internal/include/jemalloc/internal/pages.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | #ifdef JEMALLOC_H_TYPES 3 | 4 | #endif /* JEMALLOC_H_TYPES */ 5 | /******************************************************************************/ 6 | #ifdef JEMALLOC_H_STRUCTS 7 | 8 | #endif /* JEMALLOC_H_STRUCTS */ 9 | /******************************************************************************/ 10 | #ifdef JEMALLOC_H_EXTERNS 11 | 12 | void *pages_map(void *addr, size_t size, bool *commit); 13 | void pages_unmap(void *addr, size_t size); 14 | void *pages_trim(void *addr, size_t alloc_size, size_t leadsize, 15 | size_t size, bool *commit); 16 | bool pages_commit(void *addr, size_t size); 17 | bool pages_decommit(void *addr, size_t size); 18 | bool pages_purge(void *addr, size_t size); 19 | bool pages_huge(void *addr, size_t size); 20 | bool pages_nohuge(void *addr, size_t size); 21 | void pages_boot(void); 22 | 23 | #endif /* JEMALLOC_H_EXTERNS */ 24 | /******************************************************************************/ 25 | #ifdef JEMALLOC_H_INLINES 26 | 27 | #endif /* JEMALLOC_H_INLINES */ 28 | /******************************************************************************/ 29 | 30 | -------------------------------------------------------------------------------- /internal/include/jemalloc/internal/assert.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Define a custom assert() in order to reduce the chances of deadlock during 3 | * assertion failure. 4 | */ 5 | #ifndef assert 6 | #define assert(e) do { \ 7 | if (unlikely(config_debug && !(e))) { \ 8 | malloc_printf( \ 9 | ": %s:%d: Failed assertion: \"%s\"\n", \ 10 | __FILE__, __LINE__, #e); \ 11 | abort(); \ 12 | } \ 13 | } while (0) 14 | #endif 15 | 16 | #ifndef not_reached 17 | #define not_reached() do { \ 18 | if (config_debug) { \ 19 | malloc_printf( \ 20 | ": %s:%d: Unreachable code reached\n", \ 21 | __FILE__, __LINE__); \ 22 | abort(); \ 23 | } \ 24 | unreachable(); \ 25 | } while (0) 26 | #endif 27 | 28 | #ifndef not_implemented 29 | #define not_implemented() do { \ 30 | if (config_debug) { \ 31 | malloc_printf(": %s:%d: Not implemented\n", \ 32 | __FILE__, __LINE__); \ 33 | abort(); \ 34 | } \ 35 | } while (0) 36 | #endif 37 | 38 | #ifndef assert_not_implemented 39 | #define assert_not_implemented(e) do { \ 40 | if (unlikely(config_debug && !(e))) \ 41 | not_implemented(); \ 42 | } while (0) 43 | #endif 44 | 45 | 46 | -------------------------------------------------------------------------------- /internal/test/unit/mtx.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | #define NTHREADS 2 4 | #define NINCRS 2000000 5 | 6 | TEST_BEGIN(test_mtx_basic) 7 | { 8 | mtx_t mtx; 9 | 10 | assert_false(mtx_init(&mtx), "Unexpected mtx_init() failure"); 11 | mtx_lock(&mtx); 12 | mtx_unlock(&mtx); 13 | mtx_fini(&mtx); 14 | } 15 | TEST_END 16 | 17 | typedef struct { 18 | mtx_t mtx; 19 | unsigned x; 20 | } thd_start_arg_t; 21 | 22 | static void * 23 | thd_start(void *varg) 24 | { 25 | thd_start_arg_t *arg = (thd_start_arg_t *)varg; 26 | unsigned i; 27 | 28 | for (i = 0; i < NINCRS; i++) { 29 | mtx_lock(&arg->mtx); 30 | arg->x++; 31 | mtx_unlock(&arg->mtx); 32 | } 33 | return (NULL); 34 | } 35 | 36 | TEST_BEGIN(test_mtx_race) 37 | { 38 | thd_start_arg_t arg; 39 | thd_t thds[NTHREADS]; 40 | unsigned i; 41 | 42 | assert_false(mtx_init(&arg.mtx), "Unexpected mtx_init() failure"); 43 | arg.x = 0; 44 | for (i = 0; i < NTHREADS; i++) 45 | thd_create(&thds[i], thd_start, (void *)&arg); 46 | for (i = 0; i < NTHREADS; i++) 47 | thd_join(thds[i], NULL); 48 | assert_u_eq(arg.x, NTHREADS * NINCRS, 49 | "Race-related counter corruption"); 50 | } 51 | TEST_END 52 | 53 | int 54 | main(void) 55 | { 56 | 57 | return (test( 58 | test_mtx_basic, 59 | test_mtx_race)); 60 | } 61 | -------------------------------------------------------------------------------- /internal/test/integration/sdallocx.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | #define MAXALIGN (((size_t)1) << 22) 4 | #define NITER 3 5 | 6 | TEST_BEGIN(test_basic) 7 | { 8 | void *ptr = mallocx(64, 0); 9 | sdallocx(ptr, 64, 0); 10 | } 11 | TEST_END 12 | 13 | TEST_BEGIN(test_alignment_and_size) 14 | { 15 | size_t nsz, sz, alignment, total; 16 | unsigned i; 17 | void *ps[NITER]; 18 | 19 | for (i = 0; i < NITER; i++) 20 | ps[i] = NULL; 21 | 22 | for (alignment = 8; 23 | alignment <= MAXALIGN; 24 | alignment <<= 1) { 25 | total = 0; 26 | for (sz = 1; 27 | sz < 3 * alignment && sz < (1U << 31); 28 | sz += (alignment >> (LG_SIZEOF_PTR-1)) - 1) { 29 | for (i = 0; i < NITER; i++) { 30 | nsz = nallocx(sz, MALLOCX_ALIGN(alignment) | 31 | MALLOCX_ZERO); 32 | ps[i] = mallocx(sz, MALLOCX_ALIGN(alignment) | 33 | MALLOCX_ZERO); 34 | total += nsz; 35 | if (total >= (MAXALIGN << 1)) 36 | break; 37 | } 38 | for (i = 0; i < NITER; i++) { 39 | if (ps[i] != NULL) { 40 | sdallocx(ps[i], sz, 41 | MALLOCX_ALIGN(alignment)); 42 | ps[i] = NULL; 43 | } 44 | } 45 | } 46 | } 47 | } 48 | TEST_END 49 | 50 | int 51 | main(void) 52 | { 53 | 54 | return (test( 55 | test_basic, 56 | test_alignment_and_size)); 57 | } 58 | -------------------------------------------------------------------------------- /internal/include/msvc_compat/strings.h: -------------------------------------------------------------------------------- 1 | #ifndef strings_h 2 | #define strings_h 3 | 4 | /* MSVC doesn't define ffs/ffsl. This dummy strings.h header is provided 5 | * for both */ 6 | #ifdef _MSC_VER 7 | # include 8 | # pragma intrinsic(_BitScanForward) 9 | static __forceinline int ffsl(long x) 10 | { 11 | unsigned long i; 12 | 13 | if (_BitScanForward(&i, x)) 14 | return (i + 1); 15 | return (0); 16 | } 17 | 18 | static __forceinline int ffs(int x) 19 | { 20 | 21 | return (ffsl(x)); 22 | } 23 | 24 | # ifdef _M_X64 25 | # pragma intrinsic(_BitScanForward64) 26 | # endif 27 | 28 | static __forceinline int ffsll(unsigned __int64 x) 29 | { 30 | unsigned long i; 31 | #ifdef _M_X64 32 | if (_BitScanForward64(&i, x)) 33 | return (i + 1); 34 | return (0); 35 | #else 36 | // Fallback for 32-bit build where 64-bit version not available 37 | // assuming little endian 38 | union { 39 | unsigned __int64 ll; 40 | unsigned long l[2]; 41 | } s; 42 | 43 | s.ll = x; 44 | 45 | if (_BitScanForward(&i, s.l[0])) 46 | return (i + 1); 47 | else if(_BitScanForward(&i, s.l[1])) 48 | return (i + 33); 49 | return (0); 50 | #endif 51 | } 52 | 53 | #else 54 | # define ffsll(x) __builtin_ffsll(x) 55 | # define ffsl(x) __builtin_ffsl(x) 56 | # define ffs(x) __builtin_ffs(x) 57 | #endif 58 | 59 | #endif /* strings_h */ 60 | -------------------------------------------------------------------------------- /internal/test/unit/fork.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | #ifndef _WIN32 4 | #include 5 | #endif 6 | 7 | TEST_BEGIN(test_fork) 8 | { 9 | #ifndef _WIN32 10 | void *p; 11 | pid_t pid; 12 | 13 | p = malloc(1); 14 | assert_ptr_not_null(p, "Unexpected malloc() failure"); 15 | 16 | pid = fork(); 17 | 18 | free(p); 19 | 20 | p = malloc(64); 21 | assert_ptr_not_null(p, "Unexpected malloc() failure"); 22 | free(p); 23 | 24 | if (pid == -1) { 25 | /* Error. */ 26 | test_fail("Unexpected fork() failure"); 27 | } else if (pid == 0) { 28 | /* Child. */ 29 | _exit(0); 30 | } else { 31 | int status; 32 | 33 | /* Parent. */ 34 | while (true) { 35 | if (waitpid(pid, &status, 0) == -1) 36 | test_fail("Unexpected waitpid() failure"); 37 | if (WIFSIGNALED(status)) { 38 | test_fail("Unexpected child termination due to " 39 | "signal %d", WTERMSIG(status)); 40 | break; 41 | } 42 | if (WIFEXITED(status)) { 43 | if (WEXITSTATUS(status) != 0) { 44 | test_fail( 45 | "Unexpected child exit value %d", 46 | WEXITSTATUS(status)); 47 | } 48 | break; 49 | } 50 | } 51 | } 52 | #else 53 | test_skip("fork(2) is irrelevant to Windows"); 54 | #endif 55 | } 56 | TEST_END 57 | 58 | int 59 | main(void) 60 | { 61 | 62 | return (test( 63 | test_fork)); 64 | } 65 | -------------------------------------------------------------------------------- /internal/include/jemalloc/jemalloc_defs.h.in: -------------------------------------------------------------------------------- 1 | /* Defined if __attribute__((...)) syntax is supported. */ 2 | #undef JEMALLOC_HAVE_ATTR 3 | 4 | /* Defined if alloc_size attribute is supported. */ 5 | #undef JEMALLOC_HAVE_ATTR_ALLOC_SIZE 6 | 7 | /* Defined if format(gnu_printf, ...) attribute is supported. */ 8 | #undef JEMALLOC_HAVE_ATTR_FORMAT_GNU_PRINTF 9 | 10 | /* Defined if format(printf, ...) attribute is supported. */ 11 | #undef JEMALLOC_HAVE_ATTR_FORMAT_PRINTF 12 | 13 | /* 14 | * Define overrides for non-standard allocator-related functions if they are 15 | * present on the system. 16 | */ 17 | #undef JEMALLOC_OVERRIDE_MEMALIGN 18 | #undef JEMALLOC_OVERRIDE_VALLOC 19 | 20 | /* 21 | * At least Linux omits the "const" in: 22 | * 23 | * size_t malloc_usable_size(const void *ptr); 24 | * 25 | * Match the operating system's prototype. 26 | */ 27 | #undef JEMALLOC_USABLE_SIZE_CONST 28 | 29 | /* 30 | * If defined, specify throw() for the public function prototypes when compiling 31 | * with C++. The only justification for this is to match the prototypes that 32 | * glibc defines. 33 | */ 34 | #undef JEMALLOC_USE_CXX_THROW 35 | 36 | #ifdef _MSC_VER 37 | # ifdef _WIN64 38 | # define LG_SIZEOF_PTR_WIN 3 39 | # else 40 | # define LG_SIZEOF_PTR_WIN 2 41 | # endif 42 | #endif 43 | 44 | /* sizeof(void *) == 2^LG_SIZEOF_PTR. */ 45 | #undef LG_SIZEOF_PTR 46 | -------------------------------------------------------------------------------- /internal/test/src/timer.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | void 4 | timer_start(timedelta_t *timer) 5 | { 6 | 7 | nstime_init(&timer->t0, 0); 8 | nstime_update(&timer->t0); 9 | } 10 | 11 | void 12 | timer_stop(timedelta_t *timer) 13 | { 14 | 15 | nstime_copy(&timer->t1, &timer->t0); 16 | nstime_update(&timer->t1); 17 | } 18 | 19 | uint64_t 20 | timer_usec(const timedelta_t *timer) 21 | { 22 | nstime_t delta; 23 | 24 | nstime_copy(&delta, &timer->t1); 25 | nstime_subtract(&delta, &timer->t0); 26 | return (nstime_ns(&delta) / 1000); 27 | } 28 | 29 | void 30 | timer_ratio(timedelta_t *a, timedelta_t *b, char *buf, size_t buflen) 31 | { 32 | uint64_t t0 = timer_usec(a); 33 | uint64_t t1 = timer_usec(b); 34 | uint64_t mult; 35 | size_t i = 0; 36 | size_t j, n; 37 | 38 | /* Whole. */ 39 | n = malloc_snprintf(&buf[i], buflen-i, "%"FMTu64, t0 / t1); 40 | i += n; 41 | if (i >= buflen) 42 | return; 43 | mult = 1; 44 | for (j = 0; j < n; j++) 45 | mult *= 10; 46 | 47 | /* Decimal. */ 48 | n = malloc_snprintf(&buf[i], buflen-i, "."); 49 | i += n; 50 | 51 | /* Fraction. */ 52 | while (i < buflen-1) { 53 | uint64_t round = (i+1 == buflen-1 && ((t0 * mult * 10 / t1) % 10 54 | >= 5)) ? 1 : 0; 55 | n = malloc_snprintf(&buf[i], buflen-i, 56 | "%"FMTu64, (t0 * mult / t1) % 10 + round); 57 | i += n; 58 | mult *= 10; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /internal/include/jemalloc/internal/chunk_dss.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | #ifdef JEMALLOC_H_TYPES 3 | 4 | typedef enum { 5 | dss_prec_disabled = 0, 6 | dss_prec_primary = 1, 7 | dss_prec_secondary = 2, 8 | 9 | dss_prec_limit = 3 10 | } dss_prec_t; 11 | #define DSS_PREC_DEFAULT dss_prec_secondary 12 | #define DSS_DEFAULT "secondary" 13 | 14 | #endif /* JEMALLOC_H_TYPES */ 15 | /******************************************************************************/ 16 | #ifdef JEMALLOC_H_STRUCTS 17 | 18 | extern const char *dss_prec_names[]; 19 | 20 | #endif /* JEMALLOC_H_STRUCTS */ 21 | /******************************************************************************/ 22 | #ifdef JEMALLOC_H_EXTERNS 23 | 24 | dss_prec_t chunk_dss_prec_get(void); 25 | bool chunk_dss_prec_set(dss_prec_t dss_prec); 26 | void *chunk_alloc_dss(tsdn_t *tsdn, arena_t *arena, void *new_addr, 27 | size_t size, size_t alignment, bool *zero, bool *commit); 28 | bool chunk_in_dss(void *chunk); 29 | bool chunk_dss_mergeable(void *chunk_a, void *chunk_b); 30 | void chunk_dss_boot(void); 31 | 32 | #endif /* JEMALLOC_H_EXTERNS */ 33 | /******************************************************************************/ 34 | #ifdef JEMALLOC_H_INLINES 35 | 36 | #endif /* JEMALLOC_H_INLINES */ 37 | /******************************************************************************/ 38 | -------------------------------------------------------------------------------- /internal/include/jemalloc/internal/spin.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | #ifdef JEMALLOC_H_TYPES 3 | 4 | typedef struct spin_s spin_t; 5 | 6 | #endif /* JEMALLOC_H_TYPES */ 7 | /******************************************************************************/ 8 | #ifdef JEMALLOC_H_STRUCTS 9 | 10 | struct spin_s { 11 | unsigned iteration; 12 | }; 13 | 14 | #endif /* JEMALLOC_H_STRUCTS */ 15 | /******************************************************************************/ 16 | #ifdef JEMALLOC_H_EXTERNS 17 | 18 | #endif /* JEMALLOC_H_EXTERNS */ 19 | /******************************************************************************/ 20 | #ifdef JEMALLOC_H_INLINES 21 | 22 | #ifndef JEMALLOC_ENABLE_INLINE 23 | void spin_init(spin_t *spin); 24 | void spin_adaptive(spin_t *spin); 25 | #endif 26 | 27 | #if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_SPIN_C_)) 28 | JEMALLOC_INLINE void 29 | spin_init(spin_t *spin) 30 | { 31 | 32 | spin->iteration = 0; 33 | } 34 | 35 | JEMALLOC_INLINE void 36 | spin_adaptive(spin_t *spin) 37 | { 38 | volatile uint64_t i; 39 | 40 | for (i = 0; i < (KQU(1) << spin->iteration); i++) 41 | CPU_SPINWAIT; 42 | 43 | if (spin->iteration < 63) 44 | spin->iteration++; 45 | } 46 | 47 | #endif 48 | 49 | #endif /* JEMALLOC_H_INLINES */ 50 | /******************************************************************************/ 51 | 52 | -------------------------------------------------------------------------------- /internal/include/jemalloc/jemalloc_mangle.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | public_symbols_txt=$1 4 | symbol_prefix=$2 5 | 6 | cat <lock, _CRT_SPINCOUNT)) 13 | return (true); 14 | #elif (defined(JEMALLOC_OS_UNFAIR_LOCK)) 15 | mtx->lock = OS_UNFAIR_LOCK_INIT; 16 | #elif (defined(JEMALLOC_OSSPIN)) 17 | mtx->lock = 0; 18 | #else 19 | pthread_mutexattr_t attr; 20 | 21 | if (pthread_mutexattr_init(&attr) != 0) 22 | return (true); 23 | pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_DEFAULT); 24 | if (pthread_mutex_init(&mtx->lock, &attr) != 0) { 25 | pthread_mutexattr_destroy(&attr); 26 | return (true); 27 | } 28 | pthread_mutexattr_destroy(&attr); 29 | #endif 30 | return (false); 31 | } 32 | 33 | void 34 | mtx_fini(mtx_t *mtx) 35 | { 36 | 37 | #ifdef _WIN32 38 | #elif (defined(JEMALLOC_OS_UNFAIR_LOCK)) 39 | #elif (defined(JEMALLOC_OSSPIN)) 40 | #else 41 | pthread_mutex_destroy(&mtx->lock); 42 | #endif 43 | } 44 | 45 | void 46 | mtx_lock(mtx_t *mtx) 47 | { 48 | 49 | #ifdef _WIN32 50 | EnterCriticalSection(&mtx->lock); 51 | #elif (defined(JEMALLOC_OS_UNFAIR_LOCK)) 52 | os_unfair_lock_lock(&mtx->lock); 53 | #elif (defined(JEMALLOC_OSSPIN)) 54 | OSSpinLockLock(&mtx->lock); 55 | #else 56 | pthread_mutex_lock(&mtx->lock); 57 | #endif 58 | } 59 | 60 | void 61 | mtx_unlock(mtx_t *mtx) 62 | { 63 | 64 | #ifdef _WIN32 65 | LeaveCriticalSection(&mtx->lock); 66 | #elif (defined(JEMALLOC_OS_UNFAIR_LOCK)) 67 | os_unfair_lock_unlock(&mtx->lock); 68 | #elif (defined(JEMALLOC_OSSPIN)) 69 | OSSpinLockUnlock(&mtx->lock); 70 | #else 71 | pthread_mutex_unlock(&mtx->lock); 72 | #endif 73 | } 74 | -------------------------------------------------------------------------------- /internal/test/unit/zero.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | static void 4 | test_zero(size_t sz_min, size_t sz_max) 5 | { 6 | uint8_t *s; 7 | size_t sz_prev, sz, i; 8 | #define MAGIC ((uint8_t)0x61) 9 | 10 | sz_prev = 0; 11 | s = (uint8_t *)mallocx(sz_min, 0); 12 | assert_ptr_not_null((void *)s, "Unexpected mallocx() failure"); 13 | 14 | for (sz = sallocx(s, 0); sz <= sz_max; 15 | sz_prev = sz, sz = sallocx(s, 0)) { 16 | if (sz_prev > 0) { 17 | assert_u_eq(s[0], MAGIC, 18 | "Previously allocated byte %zu/%zu is corrupted", 19 | ZU(0), sz_prev); 20 | assert_u_eq(s[sz_prev-1], MAGIC, 21 | "Previously allocated byte %zu/%zu is corrupted", 22 | sz_prev-1, sz_prev); 23 | } 24 | 25 | for (i = sz_prev; i < sz; i++) { 26 | assert_u_eq(s[i], 0x0, 27 | "Newly allocated byte %zu/%zu isn't zero-filled", 28 | i, sz); 29 | s[i] = MAGIC; 30 | } 31 | 32 | if (xallocx(s, sz+1, 0, 0) == sz) { 33 | s = (uint8_t *)rallocx(s, sz+1, 0); 34 | assert_ptr_not_null((void *)s, 35 | "Unexpected rallocx() failure"); 36 | } 37 | } 38 | 39 | dallocx(s, 0); 40 | #undef MAGIC 41 | } 42 | 43 | TEST_BEGIN(test_zero_small) 44 | { 45 | 46 | test_skip_if(!config_fill); 47 | test_zero(1, SMALL_MAXCLASS-1); 48 | } 49 | TEST_END 50 | 51 | TEST_BEGIN(test_zero_large) 52 | { 53 | 54 | test_skip_if(!config_fill); 55 | test_zero(SMALL_MAXCLASS+1, large_maxclass); 56 | } 57 | TEST_END 58 | 59 | TEST_BEGIN(test_zero_huge) 60 | { 61 | 62 | test_skip_if(!config_fill); 63 | test_zero(large_maxclass+1, chunksize*2); 64 | } 65 | TEST_END 66 | 67 | int 68 | main(void) 69 | { 70 | 71 | return (test( 72 | test_zero_small, 73 | test_zero_large, 74 | test_zero_huge)); 75 | } 76 | -------------------------------------------------------------------------------- /internal/test/integration/MALLOCX_ARENA.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | #define NTHREADS 10 4 | 5 | static bool have_dss = 6 | #ifdef JEMALLOC_DSS 7 | true 8 | #else 9 | false 10 | #endif 11 | ; 12 | 13 | void * 14 | thd_start(void *arg) 15 | { 16 | unsigned thread_ind = (unsigned)(uintptr_t)arg; 17 | unsigned arena_ind; 18 | void *p; 19 | size_t sz; 20 | 21 | sz = sizeof(arena_ind); 22 | assert_d_eq(mallctl("arenas.extend", (void *)&arena_ind, &sz, NULL, 0), 23 | 0, "Error in arenas.extend"); 24 | 25 | if (thread_ind % 4 != 3) { 26 | size_t mib[3]; 27 | size_t miblen = sizeof(mib) / sizeof(size_t); 28 | const char *dss_precs[] = {"disabled", "primary", "secondary"}; 29 | unsigned prec_ind = thread_ind % 30 | (sizeof(dss_precs)/sizeof(char*)); 31 | const char *dss = dss_precs[prec_ind]; 32 | int expected_err = (have_dss || prec_ind == 0) ? 0 : EFAULT; 33 | assert_d_eq(mallctlnametomib("arena.0.dss", mib, &miblen), 0, 34 | "Error in mallctlnametomib()"); 35 | mib[1] = arena_ind; 36 | assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, (void *)&dss, 37 | sizeof(const char *)), expected_err, 38 | "Error in mallctlbymib()"); 39 | } 40 | 41 | p = mallocx(1, MALLOCX_ARENA(arena_ind)); 42 | assert_ptr_not_null(p, "Unexpected mallocx() error"); 43 | dallocx(p, 0); 44 | 45 | return (NULL); 46 | } 47 | 48 | TEST_BEGIN(test_MALLOCX_ARENA) 49 | { 50 | thd_t thds[NTHREADS]; 51 | unsigned i; 52 | 53 | for (i = 0; i < NTHREADS; i++) { 54 | thd_create(&thds[i], thd_start, 55 | (void *)(uintptr_t)i); 56 | } 57 | 58 | for (i = 0; i < NTHREADS; i++) 59 | thd_join(thds[i], NULL); 60 | } 61 | TEST_END 62 | 63 | int 64 | main(void) 65 | { 66 | 67 | return (test( 68 | test_MALLOCX_ARENA)); 69 | } 70 | -------------------------------------------------------------------------------- /internal/COPYING: -------------------------------------------------------------------------------- 1 | Unless otherwise specified, files in the jemalloc source distribution are 2 | subject to the following license: 3 | -------------------------------------------------------------------------------- 4 | Copyright (C) 2002-2016 Jason Evans . 5 | All rights reserved. 6 | Copyright (C) 2007-2012 Mozilla Foundation. All rights reserved. 7 | Copyright (C) 2009-2016 Facebook, Inc. All rights reserved. 8 | 9 | Redistribution and use in source and binary forms, with or without 10 | modification, are permitted provided that the following conditions are met: 11 | 1. Redistributions of source code must retain the above copyright notice(s), 12 | this list of conditions and the following disclaimer. 13 | 2. Redistributions in binary form must reproduce the above copyright notice(s), 14 | this list of conditions and the following disclaimer in the documentation 15 | and/or other materials provided with the distribution. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY EXPRESS 18 | OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 20 | EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 23 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 | OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 26 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- 28 | -------------------------------------------------------------------------------- /internal/include/jemalloc/jemalloc_typedefs.h.in: -------------------------------------------------------------------------------- 1 | /* 2 | * void * 3 | * chunk_alloc(void *new_addr, size_t size, size_t alignment, bool *zero, 4 | * bool *commit, unsigned arena_ind); 5 | */ 6 | typedef void *(chunk_alloc_t)(void *, size_t, size_t, bool *, bool *, unsigned); 7 | 8 | /* 9 | * bool 10 | * chunk_dalloc(void *chunk, size_t size, bool committed, unsigned arena_ind); 11 | */ 12 | typedef bool (chunk_dalloc_t)(void *, size_t, bool, unsigned); 13 | 14 | /* 15 | * bool 16 | * chunk_commit(void *chunk, size_t size, size_t offset, size_t length, 17 | * unsigned arena_ind); 18 | */ 19 | typedef bool (chunk_commit_t)(void *, size_t, size_t, size_t, unsigned); 20 | 21 | /* 22 | * bool 23 | * chunk_decommit(void *chunk, size_t size, size_t offset, size_t length, 24 | * unsigned arena_ind); 25 | */ 26 | typedef bool (chunk_decommit_t)(void *, size_t, size_t, size_t, unsigned); 27 | 28 | /* 29 | * bool 30 | * chunk_purge(void *chunk, size_t size, size_t offset, size_t length, 31 | * unsigned arena_ind); 32 | */ 33 | typedef bool (chunk_purge_t)(void *, size_t, size_t, size_t, unsigned); 34 | 35 | /* 36 | * bool 37 | * chunk_split(void *chunk, size_t size, size_t size_a, size_t size_b, 38 | * bool committed, unsigned arena_ind); 39 | */ 40 | typedef bool (chunk_split_t)(void *, size_t, size_t, size_t, bool, unsigned); 41 | 42 | /* 43 | * bool 44 | * chunk_merge(void *chunk_a, size_t size_a, void *chunk_b, size_t size_b, 45 | * bool committed, unsigned arena_ind); 46 | */ 47 | typedef bool (chunk_merge_t)(void *, size_t, void *, size_t, bool, unsigned); 48 | 49 | typedef struct { 50 | chunk_alloc_t *alloc; 51 | chunk_dalloc_t *dalloc; 52 | chunk_commit_t *commit; 53 | chunk_decommit_t *decommit; 54 | chunk_purge_t *purge; 55 | chunk_split_t *split; 56 | chunk_merge_t *merge; 57 | } chunk_hooks_t; 58 | -------------------------------------------------------------------------------- /darwin_includes/internal/include/jemalloc/jemalloc_typedefs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * void * 3 | * chunk_alloc(void *new_addr, size_t size, size_t alignment, bool *zero, 4 | * bool *commit, unsigned arena_ind); 5 | */ 6 | typedef void *(chunk_alloc_t)(void *, size_t, size_t, bool *, bool *, unsigned); 7 | 8 | /* 9 | * bool 10 | * chunk_dalloc(void *chunk, size_t size, bool committed, unsigned arena_ind); 11 | */ 12 | typedef bool (chunk_dalloc_t)(void *, size_t, bool, unsigned); 13 | 14 | /* 15 | * bool 16 | * chunk_commit(void *chunk, size_t size, size_t offset, size_t length, 17 | * unsigned arena_ind); 18 | */ 19 | typedef bool (chunk_commit_t)(void *, size_t, size_t, size_t, unsigned); 20 | 21 | /* 22 | * bool 23 | * chunk_decommit(void *chunk, size_t size, size_t offset, size_t length, 24 | * unsigned arena_ind); 25 | */ 26 | typedef bool (chunk_decommit_t)(void *, size_t, size_t, size_t, unsigned); 27 | 28 | /* 29 | * bool 30 | * chunk_purge(void *chunk, size_t size, size_t offset, size_t length, 31 | * unsigned arena_ind); 32 | */ 33 | typedef bool (chunk_purge_t)(void *, size_t, size_t, size_t, unsigned); 34 | 35 | /* 36 | * bool 37 | * chunk_split(void *chunk, size_t size, size_t size_a, size_t size_b, 38 | * bool committed, unsigned arena_ind); 39 | */ 40 | typedef bool (chunk_split_t)(void *, size_t, size_t, size_t, bool, unsigned); 41 | 42 | /* 43 | * bool 44 | * chunk_merge(void *chunk_a, size_t size_a, void *chunk_b, size_t size_b, 45 | * bool committed, unsigned arena_ind); 46 | */ 47 | typedef bool (chunk_merge_t)(void *, size_t, void *, size_t, bool, unsigned); 48 | 49 | typedef struct { 50 | chunk_alloc_t *alloc; 51 | chunk_dalloc_t *dalloc; 52 | chunk_commit_t *commit; 53 | chunk_decommit_t *decommit; 54 | chunk_purge_t *purge; 55 | chunk_split_t *split; 56 | chunk_merge_t *merge; 57 | } chunk_hooks_t; 58 | -------------------------------------------------------------------------------- /freebsd_includes/internal/include/jemalloc/jemalloc_typedefs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * void * 3 | * chunk_alloc(void *new_addr, size_t size, size_t alignment, bool *zero, 4 | * bool *commit, unsigned arena_ind); 5 | */ 6 | typedef void *(chunk_alloc_t)(void *, size_t, size_t, bool *, bool *, unsigned); 7 | 8 | /* 9 | * bool 10 | * chunk_dalloc(void *chunk, size_t size, bool committed, unsigned arena_ind); 11 | */ 12 | typedef bool (chunk_dalloc_t)(void *, size_t, bool, unsigned); 13 | 14 | /* 15 | * bool 16 | * chunk_commit(void *chunk, size_t size, size_t offset, size_t length, 17 | * unsigned arena_ind); 18 | */ 19 | typedef bool (chunk_commit_t)(void *, size_t, size_t, size_t, unsigned); 20 | 21 | /* 22 | * bool 23 | * chunk_decommit(void *chunk, size_t size, size_t offset, size_t length, 24 | * unsigned arena_ind); 25 | */ 26 | typedef bool (chunk_decommit_t)(void *, size_t, size_t, size_t, unsigned); 27 | 28 | /* 29 | * bool 30 | * chunk_purge(void *chunk, size_t size, size_t offset, size_t length, 31 | * unsigned arena_ind); 32 | */ 33 | typedef bool (chunk_purge_t)(void *, size_t, size_t, size_t, unsigned); 34 | 35 | /* 36 | * bool 37 | * chunk_split(void *chunk, size_t size, size_t size_a, size_t size_b, 38 | * bool committed, unsigned arena_ind); 39 | */ 40 | typedef bool (chunk_split_t)(void *, size_t, size_t, size_t, bool, unsigned); 41 | 42 | /* 43 | * bool 44 | * chunk_merge(void *chunk_a, size_t size_a, void *chunk_b, size_t size_b, 45 | * bool committed, unsigned arena_ind); 46 | */ 47 | typedef bool (chunk_merge_t)(void *, size_t, void *, size_t, bool, unsigned); 48 | 49 | typedef struct { 50 | chunk_alloc_t *alloc; 51 | chunk_dalloc_t *dalloc; 52 | chunk_commit_t *commit; 53 | chunk_decommit_t *decommit; 54 | chunk_purge_t *purge; 55 | chunk_split_t *split; 56 | chunk_merge_t *merge; 57 | } chunk_hooks_t; 58 | -------------------------------------------------------------------------------- /linux_includes/internal/include/jemalloc/jemalloc_typedefs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * void * 3 | * chunk_alloc(void *new_addr, size_t size, size_t alignment, bool *zero, 4 | * bool *commit, unsigned arena_ind); 5 | */ 6 | typedef void *(chunk_alloc_t)(void *, size_t, size_t, bool *, bool *, unsigned); 7 | 8 | /* 9 | * bool 10 | * chunk_dalloc(void *chunk, size_t size, bool committed, unsigned arena_ind); 11 | */ 12 | typedef bool (chunk_dalloc_t)(void *, size_t, bool, unsigned); 13 | 14 | /* 15 | * bool 16 | * chunk_commit(void *chunk, size_t size, size_t offset, size_t length, 17 | * unsigned arena_ind); 18 | */ 19 | typedef bool (chunk_commit_t)(void *, size_t, size_t, size_t, unsigned); 20 | 21 | /* 22 | * bool 23 | * chunk_decommit(void *chunk, size_t size, size_t offset, size_t length, 24 | * unsigned arena_ind); 25 | */ 26 | typedef bool (chunk_decommit_t)(void *, size_t, size_t, size_t, unsigned); 27 | 28 | /* 29 | * bool 30 | * chunk_purge(void *chunk, size_t size, size_t offset, size_t length, 31 | * unsigned arena_ind); 32 | */ 33 | typedef bool (chunk_purge_t)(void *, size_t, size_t, size_t, unsigned); 34 | 35 | /* 36 | * bool 37 | * chunk_split(void *chunk, size_t size, size_t size_a, size_t size_b, 38 | * bool committed, unsigned arena_ind); 39 | */ 40 | typedef bool (chunk_split_t)(void *, size_t, size_t, size_t, bool, unsigned); 41 | 42 | /* 43 | * bool 44 | * chunk_merge(void *chunk_a, size_t size_a, void *chunk_b, size_t size_b, 45 | * bool committed, unsigned arena_ind); 46 | */ 47 | typedef bool (chunk_merge_t)(void *, size_t, void *, size_t, bool, unsigned); 48 | 49 | typedef struct { 50 | chunk_alloc_t *alloc; 51 | chunk_dalloc_t *dalloc; 52 | chunk_commit_t *commit; 53 | chunk_decommit_t *decommit; 54 | chunk_purge_t *purge; 55 | chunk_split_t *split; 56 | chunk_merge_t *merge; 57 | } chunk_hooks_t; 58 | -------------------------------------------------------------------------------- /internal/bin/jemalloc-config.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | usage() { 4 | cat < 7 | Options: 8 | --help | -h : Print usage. 9 | --version : Print jemalloc version. 10 | --revision : Print shared library revision number. 11 | --config : Print configure options used to build jemalloc. 12 | --prefix : Print installation directory prefix. 13 | --bindir : Print binary installation directory. 14 | --datadir : Print data installation directory. 15 | --includedir : Print include installation directory. 16 | --libdir : Print library installation directory. 17 | --mandir : Print manual page installation directory. 18 | --cc : Print compiler used to build jemalloc. 19 | --cflags : Print compiler flags used to build jemalloc. 20 | --cppflags : Print preprocessor flags used to build jemalloc. 21 | --ldflags : Print library flags used to build jemalloc. 22 | --libs : Print libraries jemalloc was linked against. 23 | EOF 24 | } 25 | 26 | prefix="@prefix@" 27 | exec_prefix="@exec_prefix@" 28 | 29 | case "$1" in 30 | --help | -h) 31 | usage 32 | exit 0 33 | ;; 34 | --version) 35 | echo "@jemalloc_version@" 36 | ;; 37 | --revision) 38 | echo "@rev@" 39 | ;; 40 | --config) 41 | echo "@CONFIG@" 42 | ;; 43 | --prefix) 44 | echo "@PREFIX@" 45 | ;; 46 | --bindir) 47 | echo "@BINDIR@" 48 | ;; 49 | --datadir) 50 | echo "@DATADIR@" 51 | ;; 52 | --includedir) 53 | echo "@INCLUDEDIR@" 54 | ;; 55 | --libdir) 56 | echo "@LIBDIR@" 57 | ;; 58 | --mandir) 59 | echo "@MANDIR@" 60 | ;; 61 | --cc) 62 | echo "@CC@" 63 | ;; 64 | --cflags) 65 | echo "@CFLAGS@" 66 | ;; 67 | --cppflags) 68 | echo "@CPPFLAGS@" 69 | ;; 70 | --ldflags) 71 | echo "@LDFLAGS@ @EXTRA_LDFLAGS@" 72 | ;; 73 | --libs) 74 | echo "@LIBS@" 75 | ;; 76 | *) 77 | usage 78 | exit 1 79 | esac 80 | -------------------------------------------------------------------------------- /internal/include/jemalloc/internal/quarantine.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | #ifdef JEMALLOC_H_TYPES 3 | 4 | typedef struct quarantine_obj_s quarantine_obj_t; 5 | typedef struct quarantine_s quarantine_t; 6 | 7 | /* Default per thread quarantine size if valgrind is enabled. */ 8 | #define JEMALLOC_VALGRIND_QUARANTINE_DEFAULT (ZU(1) << 24) 9 | 10 | #endif /* JEMALLOC_H_TYPES */ 11 | /******************************************************************************/ 12 | #ifdef JEMALLOC_H_STRUCTS 13 | 14 | struct quarantine_obj_s { 15 | void *ptr; 16 | size_t usize; 17 | }; 18 | 19 | struct quarantine_s { 20 | size_t curbytes; 21 | size_t curobjs; 22 | size_t first; 23 | #define LG_MAXOBJS_INIT 10 24 | size_t lg_maxobjs; 25 | quarantine_obj_t objs[1]; /* Dynamically sized ring buffer. */ 26 | }; 27 | 28 | #endif /* JEMALLOC_H_STRUCTS */ 29 | /******************************************************************************/ 30 | #ifdef JEMALLOC_H_EXTERNS 31 | 32 | void quarantine_alloc_hook_work(tsd_t *tsd); 33 | void quarantine(tsd_t *tsd, void *ptr); 34 | void quarantine_cleanup(tsd_t *tsd); 35 | 36 | #endif /* JEMALLOC_H_EXTERNS */ 37 | /******************************************************************************/ 38 | #ifdef JEMALLOC_H_INLINES 39 | 40 | #ifndef JEMALLOC_ENABLE_INLINE 41 | void quarantine_alloc_hook(void); 42 | #endif 43 | 44 | #if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_QUARANTINE_C_)) 45 | JEMALLOC_ALWAYS_INLINE void 46 | quarantine_alloc_hook(void) 47 | { 48 | tsd_t *tsd; 49 | 50 | assert(config_fill && opt_quarantine); 51 | 52 | tsd = tsd_fetch(); 53 | if (tsd_quarantine_get(tsd) == NULL) 54 | quarantine_alloc_hook_work(tsd); 55 | } 56 | #endif 57 | 58 | #endif /* JEMALLOC_H_INLINES */ 59 | /******************************************************************************/ 60 | 61 | -------------------------------------------------------------------------------- /internal/include/jemalloc/internal/jemalloc_internal_macros.h: -------------------------------------------------------------------------------- 1 | /* 2 | * JEMALLOC_ALWAYS_INLINE and JEMALLOC_INLINE are used within header files for 3 | * functions that are static inline functions if inlining is enabled, and 4 | * single-definition library-private functions if inlining is disabled. 5 | * 6 | * JEMALLOC_ALWAYS_INLINE_C and JEMALLOC_INLINE_C are for use in .c files, in 7 | * which case the denoted functions are always static, regardless of whether 8 | * inlining is enabled. 9 | */ 10 | #if defined(JEMALLOC_DEBUG) || defined(JEMALLOC_CODE_COVERAGE) 11 | /* Disable inlining to make debugging/profiling easier. */ 12 | # define JEMALLOC_ALWAYS_INLINE 13 | # define JEMALLOC_ALWAYS_INLINE_C static 14 | # define JEMALLOC_INLINE 15 | # define JEMALLOC_INLINE_C static 16 | # define inline 17 | #else 18 | # define JEMALLOC_ENABLE_INLINE 19 | # ifdef JEMALLOC_HAVE_ATTR 20 | # define JEMALLOC_ALWAYS_INLINE \ 21 | static inline JEMALLOC_ATTR(unused) JEMALLOC_ATTR(always_inline) 22 | # define JEMALLOC_ALWAYS_INLINE_C \ 23 | static inline JEMALLOC_ATTR(always_inline) 24 | # else 25 | # define JEMALLOC_ALWAYS_INLINE static inline 26 | # define JEMALLOC_ALWAYS_INLINE_C static inline 27 | # endif 28 | # define JEMALLOC_INLINE static inline 29 | # define JEMALLOC_INLINE_C static inline 30 | # ifdef _MSC_VER 31 | # define inline _inline 32 | # endif 33 | #endif 34 | 35 | #ifdef JEMALLOC_CC_SILENCE 36 | # define UNUSED JEMALLOC_ATTR(unused) 37 | #else 38 | # define UNUSED 39 | #endif 40 | 41 | #define ZU(z) ((size_t)z) 42 | #define ZI(z) ((ssize_t)z) 43 | #define QU(q) ((uint64_t)q) 44 | #define QI(q) ((int64_t)q) 45 | 46 | #define KZU(z) ZU(z##ULL) 47 | #define KZI(z) ZI(z##LL) 48 | #define KQU(q) QU(q##ULL) 49 | #define KQI(q) QI(q##LL) 50 | 51 | #ifndef __DECONST 52 | # define __DECONST(type, var) ((type)(uintptr_t)(const void *)(var)) 53 | #endif 54 | 55 | #ifndef JEMALLOC_HAS_RESTRICT 56 | # define restrict 57 | #endif 58 | -------------------------------------------------------------------------------- /internal/include/jemalloc/internal/nstime.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | #ifdef JEMALLOC_H_TYPES 3 | 4 | typedef struct nstime_s nstime_t; 5 | 6 | /* Maximum supported number of seconds (~584 years). */ 7 | #define NSTIME_SEC_MAX KQU(18446744072) 8 | 9 | #endif /* JEMALLOC_H_TYPES */ 10 | /******************************************************************************/ 11 | #ifdef JEMALLOC_H_STRUCTS 12 | 13 | struct nstime_s { 14 | uint64_t ns; 15 | }; 16 | 17 | #endif /* JEMALLOC_H_STRUCTS */ 18 | /******************************************************************************/ 19 | #ifdef JEMALLOC_H_EXTERNS 20 | 21 | void nstime_init(nstime_t *time, uint64_t ns); 22 | void nstime_init2(nstime_t *time, uint64_t sec, uint64_t nsec); 23 | uint64_t nstime_ns(const nstime_t *time); 24 | uint64_t nstime_sec(const nstime_t *time); 25 | uint64_t nstime_nsec(const nstime_t *time); 26 | void nstime_copy(nstime_t *time, const nstime_t *source); 27 | int nstime_compare(const nstime_t *a, const nstime_t *b); 28 | void nstime_add(nstime_t *time, const nstime_t *addend); 29 | void nstime_subtract(nstime_t *time, const nstime_t *subtrahend); 30 | void nstime_imultiply(nstime_t *time, uint64_t multiplier); 31 | void nstime_idivide(nstime_t *time, uint64_t divisor); 32 | uint64_t nstime_divide(const nstime_t *time, const nstime_t *divisor); 33 | #ifdef JEMALLOC_JET 34 | typedef bool (nstime_monotonic_t)(void); 35 | extern nstime_monotonic_t *nstime_monotonic; 36 | typedef bool (nstime_update_t)(nstime_t *); 37 | extern nstime_update_t *nstime_update; 38 | #else 39 | bool nstime_monotonic(void); 40 | bool nstime_update(nstime_t *time); 41 | #endif 42 | 43 | #endif /* JEMALLOC_H_EXTERNS */ 44 | /******************************************************************************/ 45 | #ifdef JEMALLOC_H_INLINES 46 | 47 | #endif /* JEMALLOC_H_INLINES */ 48 | /******************************************************************************/ 49 | -------------------------------------------------------------------------------- /internal/test/integration/thread_arena.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | #define NTHREADS 10 4 | 5 | void * 6 | thd_start(void *arg) 7 | { 8 | unsigned main_arena_ind = *(unsigned *)arg; 9 | void *p; 10 | unsigned arena_ind; 11 | size_t size; 12 | int err; 13 | 14 | p = malloc(1); 15 | assert_ptr_not_null(p, "Error in malloc()"); 16 | free(p); 17 | 18 | size = sizeof(arena_ind); 19 | if ((err = mallctl("thread.arena", (void *)&arena_ind, &size, 20 | (void *)&main_arena_ind, sizeof(main_arena_ind)))) { 21 | char buf[BUFERROR_BUF]; 22 | 23 | buferror(err, buf, sizeof(buf)); 24 | test_fail("Error in mallctl(): %s", buf); 25 | } 26 | 27 | size = sizeof(arena_ind); 28 | if ((err = mallctl("thread.arena", (void *)&arena_ind, &size, NULL, 29 | 0))) { 30 | char buf[BUFERROR_BUF]; 31 | 32 | buferror(err, buf, sizeof(buf)); 33 | test_fail("Error in mallctl(): %s", buf); 34 | } 35 | assert_u_eq(arena_ind, main_arena_ind, 36 | "Arena index should be same as for main thread"); 37 | 38 | return (NULL); 39 | } 40 | 41 | TEST_BEGIN(test_thread_arena) 42 | { 43 | void *p; 44 | unsigned arena_ind; 45 | size_t size; 46 | int err; 47 | thd_t thds[NTHREADS]; 48 | unsigned i; 49 | 50 | p = malloc(1); 51 | assert_ptr_not_null(p, "Error in malloc()"); 52 | 53 | size = sizeof(arena_ind); 54 | if ((err = mallctl("thread.arena", (void *)&arena_ind, &size, NULL, 55 | 0))) { 56 | char buf[BUFERROR_BUF]; 57 | 58 | buferror(err, buf, sizeof(buf)); 59 | test_fail("Error in mallctl(): %s", buf); 60 | } 61 | 62 | for (i = 0; i < NTHREADS; i++) { 63 | thd_create(&thds[i], thd_start, 64 | (void *)&arena_ind); 65 | } 66 | 67 | for (i = 0; i < NTHREADS; i++) { 68 | intptr_t join_ret; 69 | thd_join(thds[i], (void *)&join_ret); 70 | assert_zd_eq(join_ret, 0, "Unexpected thread join error"); 71 | } 72 | } 73 | TEST_END 74 | 75 | int 76 | main(void) 77 | { 78 | 79 | return (test( 80 | test_thread_arena)); 81 | } 82 | -------------------------------------------------------------------------------- /internal/include/jemalloc/internal/jemalloc_internal_decls.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_DECLS_H 2 | #define JEMALLOC_INTERNAL_DECLS_H 3 | 4 | #include 5 | #ifdef _WIN32 6 | # include 7 | # include "msvc_compat/windows_extra.h" 8 | 9 | #else 10 | # include 11 | # include 12 | # if !defined(__pnacl__) && !defined(__native_client__) 13 | # include 14 | # if !defined(SYS_write) && defined(__NR_write) 15 | # define SYS_write __NR_write 16 | # endif 17 | # include 18 | # endif 19 | # include 20 | # ifdef JEMALLOC_OS_UNFAIR_LOCK 21 | # include 22 | # endif 23 | # ifdef JEMALLOC_GLIBC_MALLOC_HOOK 24 | # include 25 | # endif 26 | # include 27 | # include 28 | # include 29 | # ifdef JEMALLOC_HAVE_MACH_ABSOLUTE_TIME 30 | # include 31 | # endif 32 | #endif 33 | #include 34 | 35 | #include 36 | #ifndef SIZE_T_MAX 37 | # define SIZE_T_MAX SIZE_MAX 38 | #endif 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #ifndef offsetof 46 | # define offsetof(type, member) ((size_t)&(((type *)NULL)->member)) 47 | #endif 48 | #include 49 | #include 50 | #include 51 | #ifdef _MSC_VER 52 | # include 53 | typedef intptr_t ssize_t; 54 | # define PATH_MAX 1024 55 | # define STDERR_FILENO 2 56 | # define __func__ __FUNCTION__ 57 | # ifdef JEMALLOC_HAS_RESTRICT 58 | # define restrict __restrict 59 | # endif 60 | /* Disable warnings about deprecated system functions. */ 61 | # pragma warning(disable: 4996) 62 | #if _MSC_VER < 1800 63 | static int 64 | isblank(int c) 65 | { 66 | 67 | return (c == '\t' || c == ' '); 68 | } 69 | #endif 70 | #else 71 | # include 72 | #endif 73 | #include 74 | 75 | #endif /* JEMALLOC_INTERNAL_H */ 76 | -------------------------------------------------------------------------------- /internal/include/jemalloc/internal/ticker.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | #ifdef JEMALLOC_H_TYPES 3 | 4 | typedef struct ticker_s ticker_t; 5 | 6 | #endif /* JEMALLOC_H_TYPES */ 7 | /******************************************************************************/ 8 | #ifdef JEMALLOC_H_STRUCTS 9 | 10 | struct ticker_s { 11 | int32_t tick; 12 | int32_t nticks; 13 | }; 14 | 15 | #endif /* JEMALLOC_H_STRUCTS */ 16 | /******************************************************************************/ 17 | #ifdef JEMALLOC_H_EXTERNS 18 | 19 | #endif /* JEMALLOC_H_EXTERNS */ 20 | /******************************************************************************/ 21 | #ifdef JEMALLOC_H_INLINES 22 | 23 | #ifndef JEMALLOC_ENABLE_INLINE 24 | void ticker_init(ticker_t *ticker, int32_t nticks); 25 | void ticker_copy(ticker_t *ticker, const ticker_t *other); 26 | int32_t ticker_read(const ticker_t *ticker); 27 | bool ticker_ticks(ticker_t *ticker, int32_t nticks); 28 | bool ticker_tick(ticker_t *ticker); 29 | #endif 30 | 31 | #if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_TICKER_C_)) 32 | JEMALLOC_INLINE void 33 | ticker_init(ticker_t *ticker, int32_t nticks) 34 | { 35 | 36 | ticker->tick = nticks; 37 | ticker->nticks = nticks; 38 | } 39 | 40 | JEMALLOC_INLINE void 41 | ticker_copy(ticker_t *ticker, const ticker_t *other) 42 | { 43 | 44 | *ticker = *other; 45 | } 46 | 47 | JEMALLOC_INLINE int32_t 48 | ticker_read(const ticker_t *ticker) 49 | { 50 | 51 | return (ticker->tick); 52 | } 53 | 54 | JEMALLOC_INLINE bool 55 | ticker_ticks(ticker_t *ticker, int32_t nticks) 56 | { 57 | 58 | if (unlikely(ticker->tick < nticks)) { 59 | ticker->tick = ticker->nticks; 60 | return (true); 61 | } 62 | ticker->tick -= nticks; 63 | return(false); 64 | } 65 | 66 | JEMALLOC_INLINE bool 67 | ticker_tick(ticker_t *ticker) 68 | { 69 | 70 | return (ticker_ticks(ticker, 1)); 71 | } 72 | #endif 73 | 74 | #endif /* JEMALLOC_H_INLINES */ 75 | /******************************************************************************/ 76 | -------------------------------------------------------------------------------- /internal/.gitignore: -------------------------------------------------------------------------------- 1 | /*.gcov.* 2 | 3 | /bin/jemalloc-config 4 | /bin/jemalloc.sh 5 | /bin/jeprof 6 | 7 | /config.stamp 8 | /config.log 9 | /config.status 10 | /configure 11 | 12 | /doc/html.xsl 13 | /doc/manpages.xsl 14 | /doc/jemalloc.xml 15 | /doc/jemalloc.html 16 | /doc/jemalloc.3 17 | 18 | /jemalloc.pc 19 | 20 | /lib/ 21 | 22 | /Makefile 23 | 24 | /include/jemalloc/internal/jemalloc_internal.h 25 | /include/jemalloc/internal/jemalloc_internal_defs.h 26 | /include/jemalloc/internal/private_namespace.h 27 | /include/jemalloc/internal/private_unnamespace.h 28 | /include/jemalloc/internal/public_namespace.h 29 | /include/jemalloc/internal/public_symbols.txt 30 | /include/jemalloc/internal/public_unnamespace.h 31 | /include/jemalloc/internal/size_classes.h 32 | /include/jemalloc/jemalloc.h 33 | /include/jemalloc/jemalloc_defs.h 34 | /include/jemalloc/jemalloc_macros.h 35 | /include/jemalloc/jemalloc_mangle.h 36 | /include/jemalloc/jemalloc_mangle_jet.h 37 | /include/jemalloc/jemalloc_protos.h 38 | /include/jemalloc/jemalloc_protos_jet.h 39 | /include/jemalloc/jemalloc_rename.h 40 | /include/jemalloc/jemalloc_typedefs.h 41 | 42 | /src/*.[od] 43 | /src/*.gcda 44 | /src/*.gcno 45 | 46 | /test/test.sh 47 | test/include/test/jemalloc_test.h 48 | test/include/test/jemalloc_test_defs.h 49 | 50 | /test/integration/[A-Za-z]* 51 | !/test/integration/[A-Za-z]*.* 52 | /test/integration/*.[od] 53 | /test/integration/*.gcda 54 | /test/integration/*.gcno 55 | /test/integration/*.out 56 | 57 | /test/src/*.[od] 58 | /test/src/*.gcda 59 | /test/src/*.gcno 60 | 61 | /test/stress/[A-Za-z]* 62 | !/test/stress/[A-Za-z]*.* 63 | /test/stress/*.[od] 64 | /test/stress/*.gcda 65 | /test/stress/*.gcno 66 | /test/stress/*.out 67 | 68 | /test/unit/[A-Za-z]* 69 | !/test/unit/[A-Za-z]*.* 70 | /test/unit/*.[od] 71 | /test/unit/*.gcda 72 | /test/unit/*.gcno 73 | /test/unit/*.out 74 | 75 | /VERSION 76 | 77 | *.pdb 78 | *.sdf 79 | *.opendb 80 | *.opensdf 81 | *.cachefile 82 | *.suo 83 | *.user 84 | *.sln.docstates 85 | *.tmp 86 | /msvc/Win32/ 87 | /msvc/x64/ 88 | /msvc/projects/*/*/Debug*/ 89 | /msvc/projects/*/*/Release*/ 90 | /msvc/projects/*/*/Win32/ 91 | /msvc/projects/*/*/x64/ 92 | -------------------------------------------------------------------------------- /internal/test/unit/prof_accum.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | #define NTHREADS 4 4 | #define NALLOCS_PER_THREAD 50 5 | #define DUMP_INTERVAL 1 6 | #define BT_COUNT_CHECK_INTERVAL 5 7 | 8 | static int 9 | prof_dump_open_intercept(bool propagate_err, const char *filename) 10 | { 11 | int fd; 12 | 13 | fd = open("/dev/null", O_WRONLY); 14 | assert_d_ne(fd, -1, "Unexpected open() failure"); 15 | 16 | return (fd); 17 | } 18 | 19 | static void * 20 | alloc_from_permuted_backtrace(unsigned thd_ind, unsigned iteration) 21 | { 22 | 23 | return (btalloc(1, thd_ind*NALLOCS_PER_THREAD + iteration)); 24 | } 25 | 26 | static void * 27 | thd_start(void *varg) 28 | { 29 | unsigned thd_ind = *(unsigned *)varg; 30 | size_t bt_count_prev, bt_count; 31 | unsigned i_prev, i; 32 | 33 | i_prev = 0; 34 | bt_count_prev = 0; 35 | for (i = 0; i < NALLOCS_PER_THREAD; i++) { 36 | void *p = alloc_from_permuted_backtrace(thd_ind, i); 37 | dallocx(p, 0); 38 | if (i % DUMP_INTERVAL == 0) { 39 | assert_d_eq(mallctl("prof.dump", NULL, NULL, NULL, 0), 40 | 0, "Unexpected error while dumping heap profile"); 41 | } 42 | 43 | if (i % BT_COUNT_CHECK_INTERVAL == 0 || 44 | i+1 == NALLOCS_PER_THREAD) { 45 | bt_count = prof_bt_count(); 46 | assert_zu_le(bt_count_prev+(i-i_prev), bt_count, 47 | "Expected larger backtrace count increase"); 48 | i_prev = i; 49 | bt_count_prev = bt_count; 50 | } 51 | } 52 | 53 | return (NULL); 54 | } 55 | 56 | TEST_BEGIN(test_idump) 57 | { 58 | bool active; 59 | thd_t thds[NTHREADS]; 60 | unsigned thd_args[NTHREADS]; 61 | unsigned i; 62 | 63 | test_skip_if(!config_prof); 64 | 65 | active = true; 66 | assert_d_eq(mallctl("prof.active", NULL, NULL, (void *)&active, 67 | sizeof(active)), 0, 68 | "Unexpected mallctl failure while activating profiling"); 69 | 70 | prof_dump_open = prof_dump_open_intercept; 71 | 72 | for (i = 0; i < NTHREADS; i++) { 73 | thd_args[i] = i; 74 | thd_create(&thds[i], thd_start, (void *)&thd_args[i]); 75 | } 76 | for (i = 0; i < NTHREADS; i++) 77 | thd_join(thds[i], NULL); 78 | } 79 | TEST_END 80 | 81 | int 82 | main(void) 83 | { 84 | 85 | return (test( 86 | test_idump)); 87 | } 88 | -------------------------------------------------------------------------------- /internal/test/unit/mq.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | #define NSENDERS 3 4 | #define NMSGS 100000 5 | 6 | typedef struct mq_msg_s mq_msg_t; 7 | struct mq_msg_s { 8 | mq_msg(mq_msg_t) link; 9 | }; 10 | mq_gen(static, mq_, mq_t, mq_msg_t, link) 11 | 12 | TEST_BEGIN(test_mq_basic) 13 | { 14 | mq_t mq; 15 | mq_msg_t msg; 16 | 17 | assert_false(mq_init(&mq), "Unexpected mq_init() failure"); 18 | assert_u_eq(mq_count(&mq), 0, "mq should be empty"); 19 | assert_ptr_null(mq_tryget(&mq), 20 | "mq_tryget() should fail when the queue is empty"); 21 | 22 | mq_put(&mq, &msg); 23 | assert_u_eq(mq_count(&mq), 1, "mq should contain one message"); 24 | assert_ptr_eq(mq_tryget(&mq), &msg, "mq_tryget() should return msg"); 25 | 26 | mq_put(&mq, &msg); 27 | assert_ptr_eq(mq_get(&mq), &msg, "mq_get() should return msg"); 28 | 29 | mq_fini(&mq); 30 | } 31 | TEST_END 32 | 33 | static void * 34 | thd_receiver_start(void *arg) 35 | { 36 | mq_t *mq = (mq_t *)arg; 37 | unsigned i; 38 | 39 | for (i = 0; i < (NSENDERS * NMSGS); i++) { 40 | mq_msg_t *msg = mq_get(mq); 41 | assert_ptr_not_null(msg, "mq_get() should never return NULL"); 42 | dallocx(msg, 0); 43 | } 44 | return (NULL); 45 | } 46 | 47 | static void * 48 | thd_sender_start(void *arg) 49 | { 50 | mq_t *mq = (mq_t *)arg; 51 | unsigned i; 52 | 53 | for (i = 0; i < NMSGS; i++) { 54 | mq_msg_t *msg; 55 | void *p; 56 | p = mallocx(sizeof(mq_msg_t), 0); 57 | assert_ptr_not_null(p, "Unexpected mallocx() failure"); 58 | msg = (mq_msg_t *)p; 59 | mq_put(mq, msg); 60 | } 61 | return (NULL); 62 | } 63 | 64 | TEST_BEGIN(test_mq_threaded) 65 | { 66 | mq_t mq; 67 | thd_t receiver; 68 | thd_t senders[NSENDERS]; 69 | unsigned i; 70 | 71 | assert_false(mq_init(&mq), "Unexpected mq_init() failure"); 72 | 73 | thd_create(&receiver, thd_receiver_start, (void *)&mq); 74 | for (i = 0; i < NSENDERS; i++) 75 | thd_create(&senders[i], thd_sender_start, (void *)&mq); 76 | 77 | thd_join(receiver, NULL); 78 | for (i = 0; i < NSENDERS; i++) 79 | thd_join(senders[i], NULL); 80 | 81 | mq_fini(&mq); 82 | } 83 | TEST_END 84 | 85 | int 86 | main(void) 87 | { 88 | 89 | return (test( 90 | test_mq_basic, 91 | test_mq_threaded)); 92 | } 93 | 94 | -------------------------------------------------------------------------------- /import.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | MAKE=${MAKE:-make} 4 | set -eu 5 | 6 | rm -rf internal/* 7 | find . -type l -not -path './.git/*' -exec rm {} \; 8 | curl -sfSL https://github.com/jemalloc/jemalloc/releases/download/4.5.0/jemalloc-4.5.0.tar.bz2 | tar jxf - -C internal --strip-components=1 9 | 10 | # symlink source files so cgo compiles them. Link the license to make 11 | # it more discoverable in this repo. 12 | for source_file in $($MAKE sources) internal/COPYING; do 13 | ln -sf "$source_file" . 14 | done 15 | 16 | # TODO(tamird): restore --enable-prof on all ./configure lines below when 17 | # https://github.com/jemalloc/jemalloc/issues/585 is resolved. 18 | 19 | # You need to manually run the following code. 20 | # on OSX: 21 | # (cd internal && MACOSX_DEPLOYMENT_TARGET=10.9 ./configure) 22 | # and adjust the latter. 23 | # rm -r darwin_includes 24 | # git clean -Xn -- internal/include/jemalloc | sed 's/.* //' | xargs -I % rsync -R % darwin_includes/ 25 | # 26 | # on Linux: 27 | # cd internal 28 | # echo 'ac_cv_func_issetugid=no' >> config.cache 29 | # echo 'ac_cv_func_secure_getenv=no' >> config.cache 30 | # echo 'je_cv_glibc_malloc_hook=no' >> config.cache 31 | # echo 'je_cv_glibc_memalign_hook=no' >> config.cache 32 | # echo 'je_cv_madv_free=no' >> config.cache 33 | # echo 'je_cv_pthread_mutex_adaptive_np=no' >> config.cache 34 | # echo 'je_cv_thp=no' >> config.cache 35 | # ./configure -C 36 | # rm config.cache 37 | # cd - 38 | # and adjust the latter. 39 | # rm -r linux_includes 40 | # git clean -Xn -- internal/include/jemalloc | sed 's/.* //' | xargs -I % rsync -R % linux_includes/ 41 | # 42 | # on FreeBSD: 43 | # (cd internal && ./configure) 44 | # and adjust the latter. 45 | # rm -r freebsd_includes 46 | # git clean -Xn -- internal/include/jemalloc | sed 's/.* //' | xargs -I % rsync -R % freebsd_includes/ 47 | # 48 | # After committing locally you should run the command below to ensure your repo 49 | # is in a clean state and then build/test cockroachdb with the new version: 50 | # git clean -dXf 51 | -------------------------------------------------------------------------------- /internal/test/unit/prof_gdump.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | static bool did_prof_dump_open; 4 | 5 | static int 6 | prof_dump_open_intercept(bool propagate_err, const char *filename) 7 | { 8 | int fd; 9 | 10 | did_prof_dump_open = true; 11 | 12 | fd = open("/dev/null", O_WRONLY); 13 | assert_d_ne(fd, -1, "Unexpected open() failure"); 14 | 15 | return (fd); 16 | } 17 | 18 | TEST_BEGIN(test_gdump) 19 | { 20 | bool active, gdump, gdump_old; 21 | void *p, *q, *r, *s; 22 | size_t sz; 23 | 24 | test_skip_if(!config_prof); 25 | 26 | active = true; 27 | assert_d_eq(mallctl("prof.active", NULL, NULL, (void *)&active, 28 | sizeof(active)), 0, 29 | "Unexpected mallctl failure while activating profiling"); 30 | 31 | prof_dump_open = prof_dump_open_intercept; 32 | 33 | did_prof_dump_open = false; 34 | p = mallocx(chunksize, 0); 35 | assert_ptr_not_null(p, "Unexpected mallocx() failure"); 36 | assert_true(did_prof_dump_open, "Expected a profile dump"); 37 | 38 | did_prof_dump_open = false; 39 | q = mallocx(chunksize, 0); 40 | assert_ptr_not_null(q, "Unexpected mallocx() failure"); 41 | assert_true(did_prof_dump_open, "Expected a profile dump"); 42 | 43 | gdump = false; 44 | sz = sizeof(gdump_old); 45 | assert_d_eq(mallctl("prof.gdump", (void *)&gdump_old, &sz, 46 | (void *)&gdump, sizeof(gdump)), 0, 47 | "Unexpected mallctl failure while disabling prof.gdump"); 48 | assert(gdump_old); 49 | did_prof_dump_open = false; 50 | r = mallocx(chunksize, 0); 51 | assert_ptr_not_null(q, "Unexpected mallocx() failure"); 52 | assert_false(did_prof_dump_open, "Unexpected profile dump"); 53 | 54 | gdump = true; 55 | sz = sizeof(gdump_old); 56 | assert_d_eq(mallctl("prof.gdump", (void *)&gdump_old, &sz, 57 | (void *)&gdump, sizeof(gdump)), 0, 58 | "Unexpected mallctl failure while enabling prof.gdump"); 59 | assert(!gdump_old); 60 | did_prof_dump_open = false; 61 | s = mallocx(chunksize, 0); 62 | assert_ptr_not_null(q, "Unexpected mallocx() failure"); 63 | assert_true(did_prof_dump_open, "Expected a profile dump"); 64 | 65 | dallocx(p, 0); 66 | dallocx(q, 0); 67 | dallocx(r, 0); 68 | dallocx(s, 0); 69 | } 70 | TEST_END 71 | 72 | int 73 | main(void) 74 | { 75 | 76 | return (test( 77 | test_gdump)); 78 | } 79 | -------------------------------------------------------------------------------- /internal/src/chunk_mmap.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_CHUNK_MMAP_C_ 2 | #include "jemalloc/internal/jemalloc_internal.h" 3 | 4 | /******************************************************************************/ 5 | 6 | static void * 7 | chunk_alloc_mmap_slow(size_t size, size_t alignment, bool *zero, bool *commit) 8 | { 9 | void *ret; 10 | size_t alloc_size; 11 | 12 | alloc_size = size + alignment - PAGE; 13 | /* Beware size_t wrap-around. */ 14 | if (alloc_size < size) 15 | return (NULL); 16 | do { 17 | void *pages; 18 | size_t leadsize; 19 | pages = pages_map(NULL, alloc_size, commit); 20 | if (pages == NULL) 21 | return (NULL); 22 | leadsize = ALIGNMENT_CEILING((uintptr_t)pages, alignment) - 23 | (uintptr_t)pages; 24 | ret = pages_trim(pages, alloc_size, leadsize, size, commit); 25 | } while (ret == NULL); 26 | 27 | assert(ret != NULL); 28 | *zero = true; 29 | return (ret); 30 | } 31 | 32 | void * 33 | chunk_alloc_mmap(void *new_addr, size_t size, size_t alignment, bool *zero, 34 | bool *commit) 35 | { 36 | void *ret; 37 | size_t offset; 38 | 39 | /* 40 | * Ideally, there would be a way to specify alignment to mmap() (like 41 | * NetBSD has), but in the absence of such a feature, we have to work 42 | * hard to efficiently create aligned mappings. The reliable, but 43 | * slow method is to create a mapping that is over-sized, then trim the 44 | * excess. However, that always results in one or two calls to 45 | * pages_unmap(). 46 | * 47 | * Optimistically try mapping precisely the right amount before falling 48 | * back to the slow method, with the expectation that the optimistic 49 | * approach works most of the time. 50 | */ 51 | 52 | assert(alignment != 0); 53 | assert((alignment & chunksize_mask) == 0); 54 | 55 | ret = pages_map(new_addr, size, commit); 56 | if (ret == NULL || ret == new_addr) 57 | return (ret); 58 | assert(new_addr == NULL); 59 | offset = ALIGNMENT_ADDR2OFFSET(ret, alignment); 60 | if (offset != 0) { 61 | pages_unmap(ret, size); 62 | return (chunk_alloc_mmap_slow(size, alignment, zero, commit)); 63 | } 64 | 65 | assert(ret != NULL); 66 | *zero = true; 67 | return (ret); 68 | } 69 | 70 | bool 71 | chunk_dalloc_mmap(void *chunk, size_t size) 72 | { 73 | 74 | if (config_munmap) 75 | pages_unmap(chunk, size); 76 | 77 | return (!config_munmap); 78 | } 79 | -------------------------------------------------------------------------------- /internal/test/unit/ticker.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | TEST_BEGIN(test_ticker_tick) 4 | { 5 | #define NREPS 2 6 | #define NTICKS 3 7 | ticker_t ticker; 8 | int32_t i, j; 9 | 10 | ticker_init(&ticker, NTICKS); 11 | for (i = 0; i < NREPS; i++) { 12 | for (j = 0; j < NTICKS; j++) { 13 | assert_u_eq(ticker_read(&ticker), NTICKS - j, 14 | "Unexpected ticker value (i=%d, j=%d)", i, j); 15 | assert_false(ticker_tick(&ticker), 16 | "Unexpected ticker fire (i=%d, j=%d)", i, j); 17 | } 18 | assert_u32_eq(ticker_read(&ticker), 0, 19 | "Expected ticker depletion"); 20 | assert_true(ticker_tick(&ticker), 21 | "Expected ticker fire (i=%d)", i); 22 | assert_u32_eq(ticker_read(&ticker), NTICKS, 23 | "Expected ticker reset"); 24 | } 25 | #undef NTICKS 26 | } 27 | TEST_END 28 | 29 | TEST_BEGIN(test_ticker_ticks) 30 | { 31 | #define NTICKS 3 32 | ticker_t ticker; 33 | 34 | ticker_init(&ticker, NTICKS); 35 | 36 | assert_u_eq(ticker_read(&ticker), NTICKS, "Unexpected ticker value"); 37 | assert_false(ticker_ticks(&ticker, NTICKS), "Unexpected ticker fire"); 38 | assert_u_eq(ticker_read(&ticker), 0, "Unexpected ticker value"); 39 | assert_true(ticker_ticks(&ticker, NTICKS), "Expected ticker fire"); 40 | assert_u_eq(ticker_read(&ticker), NTICKS, "Unexpected ticker value"); 41 | 42 | assert_true(ticker_ticks(&ticker, NTICKS + 1), "Expected ticker fire"); 43 | assert_u_eq(ticker_read(&ticker), NTICKS, "Unexpected ticker value"); 44 | #undef NTICKS 45 | } 46 | TEST_END 47 | 48 | TEST_BEGIN(test_ticker_copy) 49 | { 50 | #define NTICKS 3 51 | ticker_t ta, tb; 52 | 53 | ticker_init(&ta, NTICKS); 54 | ticker_copy(&tb, &ta); 55 | assert_u_eq(ticker_read(&tb), NTICKS, "Unexpected ticker value"); 56 | assert_true(ticker_ticks(&tb, NTICKS + 1), "Expected ticker fire"); 57 | assert_u_eq(ticker_read(&tb), NTICKS, "Unexpected ticker value"); 58 | 59 | ticker_tick(&ta); 60 | ticker_copy(&tb, &ta); 61 | assert_u_eq(ticker_read(&tb), NTICKS - 1, "Unexpected ticker value"); 62 | assert_true(ticker_ticks(&tb, NTICKS), "Expected ticker fire"); 63 | assert_u_eq(ticker_read(&tb), NTICKS, "Unexpected ticker value"); 64 | #undef NTICKS 65 | } 66 | TEST_END 67 | 68 | int 69 | main(void) 70 | { 71 | 72 | return (test( 73 | test_ticker_tick, 74 | test_ticker_ticks, 75 | test_ticker_copy)); 76 | } 77 | -------------------------------------------------------------------------------- /darwin_includes/internal/include/jemalloc/jemalloc_mangle.h: -------------------------------------------------------------------------------- 1 | /* 2 | * By default application code must explicitly refer to mangled symbol names, 3 | * so that it is possible to use jemalloc in conjunction with another allocator 4 | * in the same application. Define JEMALLOC_MANGLE in order to cause automatic 5 | * name mangling that matches the API prefixing that happened as a result of 6 | * --with-mangling and/or --with-jemalloc-prefix configuration settings. 7 | */ 8 | #ifdef JEMALLOC_MANGLE 9 | # ifndef JEMALLOC_NO_DEMANGLE 10 | # define JEMALLOC_NO_DEMANGLE 11 | # endif 12 | # define malloc_conf je_malloc_conf 13 | # define malloc_message je_malloc_message 14 | # define malloc je_malloc 15 | # define calloc je_calloc 16 | # define posix_memalign je_posix_memalign 17 | # define aligned_alloc je_aligned_alloc 18 | # define realloc je_realloc 19 | # define free je_free 20 | # define mallocx je_mallocx 21 | # define rallocx je_rallocx 22 | # define xallocx je_xallocx 23 | # define sallocx je_sallocx 24 | # define dallocx je_dallocx 25 | # define sdallocx je_sdallocx 26 | # define nallocx je_nallocx 27 | # define mallctl je_mallctl 28 | # define mallctlnametomib je_mallctlnametomib 29 | # define mallctlbymib je_mallctlbymib 30 | # define malloc_stats_print je_malloc_stats_print 31 | # define malloc_usable_size je_malloc_usable_size 32 | # define valloc je_valloc 33 | #endif 34 | 35 | /* 36 | * The je_* macros can be used as stable alternative names for the 37 | * public jemalloc API if JEMALLOC_NO_DEMANGLE is defined. This is primarily 38 | * meant for use in jemalloc itself, but it can be used by application code to 39 | * provide isolation from the name mangling specified via --with-mangling 40 | * and/or --with-jemalloc-prefix. 41 | */ 42 | #ifndef JEMALLOC_NO_DEMANGLE 43 | # undef je_malloc_conf 44 | # undef je_malloc_message 45 | # undef je_malloc 46 | # undef je_calloc 47 | # undef je_posix_memalign 48 | # undef je_aligned_alloc 49 | # undef je_realloc 50 | # undef je_free 51 | # undef je_mallocx 52 | # undef je_rallocx 53 | # undef je_xallocx 54 | # undef je_sallocx 55 | # undef je_dallocx 56 | # undef je_sdallocx 57 | # undef je_nallocx 58 | # undef je_mallctl 59 | # undef je_mallctlnametomib 60 | # undef je_mallctlbymib 61 | # undef je_malloc_stats_print 62 | # undef je_malloc_usable_size 63 | # undef je_valloc 64 | #endif 65 | -------------------------------------------------------------------------------- /freebsd_includes/internal/include/jemalloc/jemalloc_mangle.h: -------------------------------------------------------------------------------- 1 | /* 2 | * By default application code must explicitly refer to mangled symbol names, 3 | * so that it is possible to use jemalloc in conjunction with another allocator 4 | * in the same application. Define JEMALLOC_MANGLE in order to cause automatic 5 | * name mangling that matches the API prefixing that happened as a result of 6 | * --with-mangling and/or --with-jemalloc-prefix configuration settings. 7 | */ 8 | #ifdef JEMALLOC_MANGLE 9 | # ifndef JEMALLOC_NO_DEMANGLE 10 | # define JEMALLOC_NO_DEMANGLE 11 | # endif 12 | # define malloc_conf je_malloc_conf 13 | # define malloc_message je_malloc_message 14 | # define malloc je_malloc 15 | # define calloc je_calloc 16 | # define posix_memalign je_posix_memalign 17 | # define aligned_alloc je_aligned_alloc 18 | # define realloc je_realloc 19 | # define free je_free 20 | # define mallocx je_mallocx 21 | # define rallocx je_rallocx 22 | # define xallocx je_xallocx 23 | # define sallocx je_sallocx 24 | # define dallocx je_dallocx 25 | # define sdallocx je_sdallocx 26 | # define nallocx je_nallocx 27 | # define mallctl je_mallctl 28 | # define mallctlnametomib je_mallctlnametomib 29 | # define mallctlbymib je_mallctlbymib 30 | # define malloc_stats_print je_malloc_stats_print 31 | # define malloc_usable_size je_malloc_usable_size 32 | # define valloc je_valloc 33 | #endif 34 | 35 | /* 36 | * The je_* macros can be used as stable alternative names for the 37 | * public jemalloc API if JEMALLOC_NO_DEMANGLE is defined. This is primarily 38 | * meant for use in jemalloc itself, but it can be used by application code to 39 | * provide isolation from the name mangling specified via --with-mangling 40 | * and/or --with-jemalloc-prefix. 41 | */ 42 | #ifndef JEMALLOC_NO_DEMANGLE 43 | # undef je_malloc_conf 44 | # undef je_malloc_message 45 | # undef je_malloc 46 | # undef je_calloc 47 | # undef je_posix_memalign 48 | # undef je_aligned_alloc 49 | # undef je_realloc 50 | # undef je_free 51 | # undef je_mallocx 52 | # undef je_rallocx 53 | # undef je_xallocx 54 | # undef je_sallocx 55 | # undef je_dallocx 56 | # undef je_sdallocx 57 | # undef je_nallocx 58 | # undef je_mallctl 59 | # undef je_mallctlnametomib 60 | # undef je_mallctlbymib 61 | # undef je_malloc_stats_print 62 | # undef je_malloc_usable_size 63 | # undef je_valloc 64 | #endif 65 | -------------------------------------------------------------------------------- /darwin_includes/internal/include/jemalloc/jemalloc_mangle_jet.h: -------------------------------------------------------------------------------- 1 | /* 2 | * By default application code must explicitly refer to mangled symbol names, 3 | * so that it is possible to use jemalloc in conjunction with another allocator 4 | * in the same application. Define JEMALLOC_MANGLE in order to cause automatic 5 | * name mangling that matches the API prefixing that happened as a result of 6 | * --with-mangling and/or --with-jemalloc-prefix configuration settings. 7 | */ 8 | #ifdef JEMALLOC_MANGLE 9 | # ifndef JEMALLOC_NO_DEMANGLE 10 | # define JEMALLOC_NO_DEMANGLE 11 | # endif 12 | # define malloc_conf jet_malloc_conf 13 | # define malloc_message jet_malloc_message 14 | # define malloc jet_malloc 15 | # define calloc jet_calloc 16 | # define posix_memalign jet_posix_memalign 17 | # define aligned_alloc jet_aligned_alloc 18 | # define realloc jet_realloc 19 | # define free jet_free 20 | # define mallocx jet_mallocx 21 | # define rallocx jet_rallocx 22 | # define xallocx jet_xallocx 23 | # define sallocx jet_sallocx 24 | # define dallocx jet_dallocx 25 | # define sdallocx jet_sdallocx 26 | # define nallocx jet_nallocx 27 | # define mallctl jet_mallctl 28 | # define mallctlnametomib jet_mallctlnametomib 29 | # define mallctlbymib jet_mallctlbymib 30 | # define malloc_stats_print jet_malloc_stats_print 31 | # define malloc_usable_size jet_malloc_usable_size 32 | # define valloc jet_valloc 33 | #endif 34 | 35 | /* 36 | * The jet_* macros can be used as stable alternative names for the 37 | * public jemalloc API if JEMALLOC_NO_DEMANGLE is defined. This is primarily 38 | * meant for use in jemalloc itself, but it can be used by application code to 39 | * provide isolation from the name mangling specified via --with-mangling 40 | * and/or --with-jemalloc-prefix. 41 | */ 42 | #ifndef JEMALLOC_NO_DEMANGLE 43 | # undef jet_malloc_conf 44 | # undef jet_malloc_message 45 | # undef jet_malloc 46 | # undef jet_calloc 47 | # undef jet_posix_memalign 48 | # undef jet_aligned_alloc 49 | # undef jet_realloc 50 | # undef jet_free 51 | # undef jet_mallocx 52 | # undef jet_rallocx 53 | # undef jet_xallocx 54 | # undef jet_sallocx 55 | # undef jet_dallocx 56 | # undef jet_sdallocx 57 | # undef jet_nallocx 58 | # undef jet_mallctl 59 | # undef jet_mallctlnametomib 60 | # undef jet_mallctlbymib 61 | # undef jet_malloc_stats_print 62 | # undef jet_malloc_usable_size 63 | # undef jet_valloc 64 | #endif 65 | -------------------------------------------------------------------------------- /freebsd_includes/internal/include/jemalloc/jemalloc_mangle_jet.h: -------------------------------------------------------------------------------- 1 | /* 2 | * By default application code must explicitly refer to mangled symbol names, 3 | * so that it is possible to use jemalloc in conjunction with another allocator 4 | * in the same application. Define JEMALLOC_MANGLE in order to cause automatic 5 | * name mangling that matches the API prefixing that happened as a result of 6 | * --with-mangling and/or --with-jemalloc-prefix configuration settings. 7 | */ 8 | #ifdef JEMALLOC_MANGLE 9 | # ifndef JEMALLOC_NO_DEMANGLE 10 | # define JEMALLOC_NO_DEMANGLE 11 | # endif 12 | # define malloc_conf jet_malloc_conf 13 | # define malloc_message jet_malloc_message 14 | # define malloc jet_malloc 15 | # define calloc jet_calloc 16 | # define posix_memalign jet_posix_memalign 17 | # define aligned_alloc jet_aligned_alloc 18 | # define realloc jet_realloc 19 | # define free jet_free 20 | # define mallocx jet_mallocx 21 | # define rallocx jet_rallocx 22 | # define xallocx jet_xallocx 23 | # define sallocx jet_sallocx 24 | # define dallocx jet_dallocx 25 | # define sdallocx jet_sdallocx 26 | # define nallocx jet_nallocx 27 | # define mallctl jet_mallctl 28 | # define mallctlnametomib jet_mallctlnametomib 29 | # define mallctlbymib jet_mallctlbymib 30 | # define malloc_stats_print jet_malloc_stats_print 31 | # define malloc_usable_size jet_malloc_usable_size 32 | # define valloc jet_valloc 33 | #endif 34 | 35 | /* 36 | * The jet_* macros can be used as stable alternative names for the 37 | * public jemalloc API if JEMALLOC_NO_DEMANGLE is defined. This is primarily 38 | * meant for use in jemalloc itself, but it can be used by application code to 39 | * provide isolation from the name mangling specified via --with-mangling 40 | * and/or --with-jemalloc-prefix. 41 | */ 42 | #ifndef JEMALLOC_NO_DEMANGLE 43 | # undef jet_malloc_conf 44 | # undef jet_malloc_message 45 | # undef jet_malloc 46 | # undef jet_calloc 47 | # undef jet_posix_memalign 48 | # undef jet_aligned_alloc 49 | # undef jet_realloc 50 | # undef jet_free 51 | # undef jet_mallocx 52 | # undef jet_rallocx 53 | # undef jet_xallocx 54 | # undef jet_sallocx 55 | # undef jet_dallocx 56 | # undef jet_sdallocx 57 | # undef jet_nallocx 58 | # undef jet_mallctl 59 | # undef jet_mallctlnametomib 60 | # undef jet_mallctlbymib 61 | # undef jet_malloc_stats_print 62 | # undef jet_malloc_usable_size 63 | # undef jet_valloc 64 | #endif 65 | -------------------------------------------------------------------------------- /linux_includes/internal/include/jemalloc/jemalloc_mangle.h: -------------------------------------------------------------------------------- 1 | /* 2 | * By default application code must explicitly refer to mangled symbol names, 3 | * so that it is possible to use jemalloc in conjunction with another allocator 4 | * in the same application. Define JEMALLOC_MANGLE in order to cause automatic 5 | * name mangling that matches the API prefixing that happened as a result of 6 | * --with-mangling and/or --with-jemalloc-prefix configuration settings. 7 | */ 8 | #ifdef JEMALLOC_MANGLE 9 | # ifndef JEMALLOC_NO_DEMANGLE 10 | # define JEMALLOC_NO_DEMANGLE 11 | # endif 12 | # define malloc_conf je_malloc_conf 13 | # define malloc_message je_malloc_message 14 | # define malloc je_malloc 15 | # define calloc je_calloc 16 | # define posix_memalign je_posix_memalign 17 | # define aligned_alloc je_aligned_alloc 18 | # define realloc je_realloc 19 | # define free je_free 20 | # define mallocx je_mallocx 21 | # define rallocx je_rallocx 22 | # define xallocx je_xallocx 23 | # define sallocx je_sallocx 24 | # define dallocx je_dallocx 25 | # define sdallocx je_sdallocx 26 | # define nallocx je_nallocx 27 | # define mallctl je_mallctl 28 | # define mallctlnametomib je_mallctlnametomib 29 | # define mallctlbymib je_mallctlbymib 30 | # define malloc_stats_print je_malloc_stats_print 31 | # define malloc_usable_size je_malloc_usable_size 32 | # define memalign je_memalign 33 | # define valloc je_valloc 34 | #endif 35 | 36 | /* 37 | * The je_* macros can be used as stable alternative names for the 38 | * public jemalloc API if JEMALLOC_NO_DEMANGLE is defined. This is primarily 39 | * meant for use in jemalloc itself, but it can be used by application code to 40 | * provide isolation from the name mangling specified via --with-mangling 41 | * and/or --with-jemalloc-prefix. 42 | */ 43 | #ifndef JEMALLOC_NO_DEMANGLE 44 | # undef je_malloc_conf 45 | # undef je_malloc_message 46 | # undef je_malloc 47 | # undef je_calloc 48 | # undef je_posix_memalign 49 | # undef je_aligned_alloc 50 | # undef je_realloc 51 | # undef je_free 52 | # undef je_mallocx 53 | # undef je_rallocx 54 | # undef je_xallocx 55 | # undef je_sallocx 56 | # undef je_dallocx 57 | # undef je_sdallocx 58 | # undef je_nallocx 59 | # undef je_mallctl 60 | # undef je_mallctlnametomib 61 | # undef je_mallctlbymib 62 | # undef je_malloc_stats_print 63 | # undef je_malloc_usable_size 64 | # undef je_memalign 65 | # undef je_valloc 66 | #endif 67 | -------------------------------------------------------------------------------- /linux_includes/internal/include/jemalloc/jemalloc_mangle_jet.h: -------------------------------------------------------------------------------- 1 | /* 2 | * By default application code must explicitly refer to mangled symbol names, 3 | * so that it is possible to use jemalloc in conjunction with another allocator 4 | * in the same application. Define JEMALLOC_MANGLE in order to cause automatic 5 | * name mangling that matches the API prefixing that happened as a result of 6 | * --with-mangling and/or --with-jemalloc-prefix configuration settings. 7 | */ 8 | #ifdef JEMALLOC_MANGLE 9 | # ifndef JEMALLOC_NO_DEMANGLE 10 | # define JEMALLOC_NO_DEMANGLE 11 | # endif 12 | # define malloc_conf jet_malloc_conf 13 | # define malloc_message jet_malloc_message 14 | # define malloc jet_malloc 15 | # define calloc jet_calloc 16 | # define posix_memalign jet_posix_memalign 17 | # define aligned_alloc jet_aligned_alloc 18 | # define realloc jet_realloc 19 | # define free jet_free 20 | # define mallocx jet_mallocx 21 | # define rallocx jet_rallocx 22 | # define xallocx jet_xallocx 23 | # define sallocx jet_sallocx 24 | # define dallocx jet_dallocx 25 | # define sdallocx jet_sdallocx 26 | # define nallocx jet_nallocx 27 | # define mallctl jet_mallctl 28 | # define mallctlnametomib jet_mallctlnametomib 29 | # define mallctlbymib jet_mallctlbymib 30 | # define malloc_stats_print jet_malloc_stats_print 31 | # define malloc_usable_size jet_malloc_usable_size 32 | # define memalign jet_memalign 33 | # define valloc jet_valloc 34 | #endif 35 | 36 | /* 37 | * The jet_* macros can be used as stable alternative names for the 38 | * public jemalloc API if JEMALLOC_NO_DEMANGLE is defined. This is primarily 39 | * meant for use in jemalloc itself, but it can be used by application code to 40 | * provide isolation from the name mangling specified via --with-mangling 41 | * and/or --with-jemalloc-prefix. 42 | */ 43 | #ifndef JEMALLOC_NO_DEMANGLE 44 | # undef jet_malloc_conf 45 | # undef jet_malloc_message 46 | # undef jet_malloc 47 | # undef jet_calloc 48 | # undef jet_posix_memalign 49 | # undef jet_aligned_alloc 50 | # undef jet_realloc 51 | # undef jet_free 52 | # undef jet_mallocx 53 | # undef jet_rallocx 54 | # undef jet_xallocx 55 | # undef jet_sallocx 56 | # undef jet_dallocx 57 | # undef jet_sdallocx 58 | # undef jet_nallocx 59 | # undef jet_mallctl 60 | # undef jet_mallctlnametomib 61 | # undef jet_mallctlbymib 62 | # undef jet_malloc_stats_print 63 | # undef jet_malloc_usable_size 64 | # undef jet_memalign 65 | # undef jet_valloc 66 | #endif 67 | -------------------------------------------------------------------------------- /internal/test/test.sh.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | case @abi@ in 4 | macho) 5 | export DYLD_FALLBACK_LIBRARY_PATH="@objroot@lib" 6 | ;; 7 | pecoff) 8 | export PATH="${PATH}:@objroot@lib" 9 | ;; 10 | *) 11 | ;; 12 | esac 13 | 14 | # Make a copy of the @JEMALLOC_CPREFIX@MALLOC_CONF passed in to this script, so 15 | # it can be repeatedly concatenated with per test settings. 16 | export MALLOC_CONF_ALL=${@JEMALLOC_CPREFIX@MALLOC_CONF} 17 | # Concatenate the individual test's MALLOC_CONF and MALLOC_CONF_ALL. 18 | export_malloc_conf() { 19 | if [ "x${MALLOC_CONF}" != "x" -a "x${MALLOC_CONF_ALL}" != "x" ] ; then 20 | export @JEMALLOC_CPREFIX@MALLOC_CONF="${MALLOC_CONF},${MALLOC_CONF_ALL}" 21 | else 22 | export @JEMALLOC_CPREFIX@MALLOC_CONF="${MALLOC_CONF}${MALLOC_CONF_ALL}" 23 | fi 24 | } 25 | 26 | # Corresponds to test_status_t. 27 | pass_code=0 28 | skip_code=1 29 | fail_code=2 30 | 31 | pass_count=0 32 | skip_count=0 33 | fail_count=0 34 | for t in $@; do 35 | if [ $pass_count -ne 0 -o $skip_count -ne 0 -o $fail_count != 0 ] ; then 36 | echo 37 | fi 38 | echo "=== ${t} ===" 39 | if [ -e "@srcroot@${t}.sh" ] ; then 40 | # Source the shell script corresponding to the test in a subshell and 41 | # execute the test. This allows the shell script to set MALLOC_CONF, which 42 | # is then used to set @JEMALLOC_CPREFIX@MALLOC_CONF (thus allowing the 43 | # per test shell script to ignore the @JEMALLOC_CPREFIX@ detail). 44 | $(enable_fill=@enable_fill@ \ 45 | enable_prof=@enable_prof@ \ 46 | enable_tcache=@enable_tcache@ \ 47 | . @srcroot@${t}.sh && \ 48 | export_malloc_conf && \ 49 | ${t}@exe@ @abs_srcroot@ @abs_objroot@) 50 | else 51 | $(export MALLOC_CONF= && \ 52 | export_malloc_conf && 53 | ${t}@exe@ @abs_srcroot@ @abs_objroot@) 54 | fi 55 | result_code=$? 56 | case ${result_code} in 57 | ${pass_code}) 58 | pass_count=$((pass_count+1)) 59 | ;; 60 | ${skip_code}) 61 | skip_count=$((skip_count+1)) 62 | ;; 63 | ${fail_code}) 64 | fail_count=$((fail_count+1)) 65 | ;; 66 | *) 67 | echo "Test harness error" 1>&2 68 | exit 1 69 | esac 70 | done 71 | 72 | total_count=`expr ${pass_count} + ${skip_count} + ${fail_count}` 73 | echo 74 | echo "Test suite summary: pass: ${pass_count}/${total_count}, skip: ${skip_count}/${total_count}, fail: ${fail_count}/${total_count}" 75 | 76 | if [ ${fail_count} -eq 0 ] ; then 77 | exit 0 78 | else 79 | exit 1 80 | fi 81 | -------------------------------------------------------------------------------- /internal/include/jemalloc/internal/qr.h: -------------------------------------------------------------------------------- 1 | /* Ring definitions. */ 2 | #define qr(a_type) \ 3 | struct { \ 4 | a_type *qre_next; \ 5 | a_type *qre_prev; \ 6 | } 7 | 8 | /* Ring functions. */ 9 | #define qr_new(a_qr, a_field) do { \ 10 | (a_qr)->a_field.qre_next = (a_qr); \ 11 | (a_qr)->a_field.qre_prev = (a_qr); \ 12 | } while (0) 13 | 14 | #define qr_next(a_qr, a_field) ((a_qr)->a_field.qre_next) 15 | 16 | #define qr_prev(a_qr, a_field) ((a_qr)->a_field.qre_prev) 17 | 18 | #define qr_before_insert(a_qrelm, a_qr, a_field) do { \ 19 | (a_qr)->a_field.qre_prev = (a_qrelm)->a_field.qre_prev; \ 20 | (a_qr)->a_field.qre_next = (a_qrelm); \ 21 | (a_qr)->a_field.qre_prev->a_field.qre_next = (a_qr); \ 22 | (a_qrelm)->a_field.qre_prev = (a_qr); \ 23 | } while (0) 24 | 25 | #define qr_after_insert(a_qrelm, a_qr, a_field) \ 26 | do \ 27 | { \ 28 | (a_qr)->a_field.qre_next = (a_qrelm)->a_field.qre_next; \ 29 | (a_qr)->a_field.qre_prev = (a_qrelm); \ 30 | (a_qr)->a_field.qre_next->a_field.qre_prev = (a_qr); \ 31 | (a_qrelm)->a_field.qre_next = (a_qr); \ 32 | } while (0) 33 | 34 | #define qr_meld(a_qr_a, a_qr_b, a_field) do { \ 35 | void *t; \ 36 | (a_qr_a)->a_field.qre_prev->a_field.qre_next = (a_qr_b); \ 37 | (a_qr_b)->a_field.qre_prev->a_field.qre_next = (a_qr_a); \ 38 | t = (a_qr_a)->a_field.qre_prev; \ 39 | (a_qr_a)->a_field.qre_prev = (a_qr_b)->a_field.qre_prev; \ 40 | (a_qr_b)->a_field.qre_prev = t; \ 41 | } while (0) 42 | 43 | /* 44 | * qr_meld() and qr_split() are functionally equivalent, so there's no need to 45 | * have two copies of the code. 46 | */ 47 | #define qr_split(a_qr_a, a_qr_b, a_field) \ 48 | qr_meld((a_qr_a), (a_qr_b), a_field) 49 | 50 | #define qr_remove(a_qr, a_field) do { \ 51 | (a_qr)->a_field.qre_prev->a_field.qre_next \ 52 | = (a_qr)->a_field.qre_next; \ 53 | (a_qr)->a_field.qre_next->a_field.qre_prev \ 54 | = (a_qr)->a_field.qre_prev; \ 55 | (a_qr)->a_field.qre_next = (a_qr); \ 56 | (a_qr)->a_field.qre_prev = (a_qr); \ 57 | } while (0) 58 | 59 | #define qr_foreach(var, a_qr, a_field) \ 60 | for ((var) = (a_qr); \ 61 | (var) != NULL; \ 62 | (var) = (((var)->a_field.qre_next != (a_qr)) \ 63 | ? (var)->a_field.qre_next : NULL)) 64 | 65 | #define qr_reverse_foreach(var, a_qr, a_field) \ 66 | for ((var) = ((a_qr) != NULL) ? qr_prev(a_qr, a_field) : NULL; \ 67 | (var) != NULL; \ 68 | (var) = (((var) != (a_qr)) \ 69 | ? (var)->a_field.qre_prev : NULL)) 70 | -------------------------------------------------------------------------------- /internal/src/extent.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_EXTENT_C_ 2 | #include "jemalloc/internal/jemalloc_internal.h" 3 | 4 | /******************************************************************************/ 5 | 6 | #ifndef JEMALLOC_JET 7 | static 8 | #endif 9 | size_t 10 | extent_size_quantize_floor(size_t size) { 11 | size_t ret; 12 | szind_t ind; 13 | 14 | assert(size > 0); 15 | 16 | ind = size2index(size + 1); 17 | if (ind == 0) { 18 | /* Avoid underflow. */ 19 | return (index2size(0)); 20 | } 21 | ret = index2size(ind - 1); 22 | assert(ret <= size); 23 | return (ret); 24 | } 25 | 26 | size_t 27 | extent_size_quantize_ceil(size_t size) { 28 | size_t ret; 29 | 30 | assert(size > 0); 31 | 32 | ret = extent_size_quantize_floor(size); 33 | if (ret < size) { 34 | /* 35 | * Skip a quantization that may have an adequately large extent, 36 | * because under-sized extents may be mixed in. This only 37 | * happens when an unusual size is requested, i.e. for aligned 38 | * allocation, and is just one of several places where linear 39 | * search would potentially find sufficiently aligned available 40 | * memory somewhere lower. 41 | */ 42 | ret = index2size(size2index(ret + 1)); 43 | } 44 | return ret; 45 | } 46 | 47 | JEMALLOC_INLINE_C int 48 | extent_sz_comp(const extent_node_t *a, const extent_node_t *b) 49 | { 50 | size_t a_qsize = extent_size_quantize_floor(extent_node_size_get(a)); 51 | size_t b_qsize = extent_size_quantize_floor(extent_node_size_get(b)); 52 | 53 | return ((a_qsize > b_qsize) - (a_qsize < b_qsize)); 54 | } 55 | 56 | JEMALLOC_INLINE_C int 57 | extent_sn_comp(const extent_node_t *a, const extent_node_t *b) 58 | { 59 | size_t a_sn = extent_node_sn_get(a); 60 | size_t b_sn = extent_node_sn_get(b); 61 | 62 | return ((a_sn > b_sn) - (a_sn < b_sn)); 63 | } 64 | 65 | JEMALLOC_INLINE_C int 66 | extent_ad_comp(const extent_node_t *a, const extent_node_t *b) 67 | { 68 | uintptr_t a_addr = (uintptr_t)extent_node_addr_get(a); 69 | uintptr_t b_addr = (uintptr_t)extent_node_addr_get(b); 70 | 71 | return ((a_addr > b_addr) - (a_addr < b_addr)); 72 | } 73 | 74 | JEMALLOC_INLINE_C int 75 | extent_szsnad_comp(const extent_node_t *a, const extent_node_t *b) 76 | { 77 | int ret; 78 | 79 | ret = extent_sz_comp(a, b); 80 | if (ret != 0) 81 | return (ret); 82 | 83 | ret = extent_sn_comp(a, b); 84 | if (ret != 0) 85 | return (ret); 86 | 87 | ret = extent_ad_comp(a, b); 88 | return (ret); 89 | } 90 | 91 | /* Generate red-black tree functions. */ 92 | rb_gen(, extent_tree_szsnad_, extent_tree_t, extent_node_t, szsnad_link, 93 | extent_szsnad_comp) 94 | 95 | /* Generate red-black tree functions. */ 96 | rb_gen(, extent_tree_ad_, extent_tree_t, extent_node_t, ad_link, extent_ad_comp) 97 | -------------------------------------------------------------------------------- /internal/include/jemalloc/internal/ql.h: -------------------------------------------------------------------------------- 1 | /* List definitions. */ 2 | #define ql_head(a_type) \ 3 | struct { \ 4 | a_type *qlh_first; \ 5 | } 6 | 7 | #define ql_head_initializer(a_head) {NULL} 8 | 9 | #define ql_elm(a_type) qr(a_type) 10 | 11 | /* List functions. */ 12 | #define ql_new(a_head) do { \ 13 | (a_head)->qlh_first = NULL; \ 14 | } while (0) 15 | 16 | #define ql_elm_new(a_elm, a_field) qr_new((a_elm), a_field) 17 | 18 | #define ql_first(a_head) ((a_head)->qlh_first) 19 | 20 | #define ql_last(a_head, a_field) \ 21 | ((ql_first(a_head) != NULL) \ 22 | ? qr_prev(ql_first(a_head), a_field) : NULL) 23 | 24 | #define ql_next(a_head, a_elm, a_field) \ 25 | ((ql_last(a_head, a_field) != (a_elm)) \ 26 | ? qr_next((a_elm), a_field) : NULL) 27 | 28 | #define ql_prev(a_head, a_elm, a_field) \ 29 | ((ql_first(a_head) != (a_elm)) ? qr_prev((a_elm), a_field) \ 30 | : NULL) 31 | 32 | #define ql_before_insert(a_head, a_qlelm, a_elm, a_field) do { \ 33 | qr_before_insert((a_qlelm), (a_elm), a_field); \ 34 | if (ql_first(a_head) == (a_qlelm)) { \ 35 | ql_first(a_head) = (a_elm); \ 36 | } \ 37 | } while (0) 38 | 39 | #define ql_after_insert(a_qlelm, a_elm, a_field) \ 40 | qr_after_insert((a_qlelm), (a_elm), a_field) 41 | 42 | #define ql_head_insert(a_head, a_elm, a_field) do { \ 43 | if (ql_first(a_head) != NULL) { \ 44 | qr_before_insert(ql_first(a_head), (a_elm), a_field); \ 45 | } \ 46 | ql_first(a_head) = (a_elm); \ 47 | } while (0) 48 | 49 | #define ql_tail_insert(a_head, a_elm, a_field) do { \ 50 | if (ql_first(a_head) != NULL) { \ 51 | qr_before_insert(ql_first(a_head), (a_elm), a_field); \ 52 | } \ 53 | ql_first(a_head) = qr_next((a_elm), a_field); \ 54 | } while (0) 55 | 56 | #define ql_remove(a_head, a_elm, a_field) do { \ 57 | if (ql_first(a_head) == (a_elm)) { \ 58 | ql_first(a_head) = qr_next(ql_first(a_head), a_field); \ 59 | } \ 60 | if (ql_first(a_head) != (a_elm)) { \ 61 | qr_remove((a_elm), a_field); \ 62 | } else { \ 63 | ql_first(a_head) = NULL; \ 64 | } \ 65 | } while (0) 66 | 67 | #define ql_head_remove(a_head, a_type, a_field) do { \ 68 | a_type *t = ql_first(a_head); \ 69 | ql_remove((a_head), t, a_field); \ 70 | } while (0) 71 | 72 | #define ql_tail_remove(a_head, a_type, a_field) do { \ 73 | a_type *t = ql_last(a_head, a_field); \ 74 | ql_remove((a_head), t, a_field); \ 75 | } while (0) 76 | 77 | #define ql_foreach(a_var, a_head, a_field) \ 78 | qr_foreach((a_var), ql_first(a_head), a_field) 79 | 80 | #define ql_reverse_foreach(a_var, a_head, a_field) \ 81 | qr_reverse_foreach((a_var), ql_first(a_head), a_field) 82 | -------------------------------------------------------------------------------- /internal/test/unit/tsd.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | #define THREAD_DATA 0x72b65c10 4 | 5 | typedef unsigned int data_t; 6 | 7 | static bool data_cleanup_executed; 8 | 9 | malloc_tsd_types(data_, data_t) 10 | malloc_tsd_protos(, data_, data_t) 11 | 12 | void 13 | data_cleanup(void *arg) 14 | { 15 | data_t *data = (data_t *)arg; 16 | 17 | if (!data_cleanup_executed) { 18 | assert_x_eq(*data, THREAD_DATA, 19 | "Argument passed into cleanup function should match tsd " 20 | "value"); 21 | } 22 | data_cleanup_executed = true; 23 | 24 | /* 25 | * Allocate during cleanup for two rounds, in order to assure that 26 | * jemalloc's internal tsd reinitialization happens. 27 | */ 28 | switch (*data) { 29 | case THREAD_DATA: 30 | *data = 1; 31 | data_tsd_set(data); 32 | break; 33 | case 1: 34 | *data = 2; 35 | data_tsd_set(data); 36 | break; 37 | case 2: 38 | return; 39 | default: 40 | not_reached(); 41 | } 42 | 43 | { 44 | void *p = mallocx(1, 0); 45 | assert_ptr_not_null(p, "Unexpeced mallocx() failure"); 46 | dallocx(p, 0); 47 | } 48 | } 49 | 50 | malloc_tsd_externs(data_, data_t) 51 | #define DATA_INIT 0x12345678 52 | malloc_tsd_data(, data_, data_t, DATA_INIT) 53 | malloc_tsd_funcs(, data_, data_t, DATA_INIT, data_cleanup) 54 | 55 | static void * 56 | thd_start(void *arg) 57 | { 58 | data_t d = (data_t)(uintptr_t)arg; 59 | void *p; 60 | 61 | assert_x_eq(*data_tsd_get(true), DATA_INIT, 62 | "Initial tsd get should return initialization value"); 63 | 64 | p = malloc(1); 65 | assert_ptr_not_null(p, "Unexpected malloc() failure"); 66 | 67 | data_tsd_set(&d); 68 | assert_x_eq(*data_tsd_get(true), d, 69 | "After tsd set, tsd get should return value that was set"); 70 | 71 | d = 0; 72 | assert_x_eq(*data_tsd_get(true), (data_t)(uintptr_t)arg, 73 | "Resetting local data should have no effect on tsd"); 74 | 75 | free(p); 76 | return (NULL); 77 | } 78 | 79 | TEST_BEGIN(test_tsd_main_thread) 80 | { 81 | 82 | thd_start((void *)(uintptr_t)0xa5f3e329); 83 | } 84 | TEST_END 85 | 86 | TEST_BEGIN(test_tsd_sub_thread) 87 | { 88 | thd_t thd; 89 | 90 | data_cleanup_executed = false; 91 | thd_create(&thd, thd_start, (void *)THREAD_DATA); 92 | thd_join(thd, NULL); 93 | assert_true(data_cleanup_executed, 94 | "Cleanup function should have executed"); 95 | } 96 | TEST_END 97 | 98 | int 99 | main(void) 100 | { 101 | 102 | /* Core tsd bootstrapping must happen prior to data_tsd_boot(). */ 103 | if (nallocx(1, 0) == 0) { 104 | malloc_printf("Initialization error"); 105 | return (test_status_fail); 106 | } 107 | data_tsd_boot(); 108 | 109 | return (test( 110 | test_tsd_main_thread, 111 | test_tsd_sub_thread)); 112 | } 113 | -------------------------------------------------------------------------------- /internal/scripts/gen_travis.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from itertools import combinations 4 | 5 | travis_template = """\ 6 | language: generic 7 | 8 | matrix: 9 | include: 10 | %s 11 | 12 | before_script: 13 | - autoconf 14 | - ./configure ${COMPILER_FLAGS:+ \ 15 | CC="$CC $COMPILER_FLAGS" } \ 16 | $CONFIGURE_FLAGS 17 | - make -j3 18 | - make -j3 tests 19 | 20 | script: 21 | - make check 22 | """ 23 | 24 | # The 'default' configuration is gcc, on linux, with no compiler or configure 25 | # flags. We also test with clang, -m32, --enable-debug, --enable-prof, 26 | # --disable-stats, and --disable-tcache. To avoid abusing travis though, we 27 | # don't test all 2**7 = 128 possible combinations of these; instead, we only 28 | # test combinations of up to 2 'unusual' settings, under the hope that bugs 29 | # involving interactions of such settings are rare. 30 | # things at once, for C(7, 0) + C(7, 1) + C(7, 2) = 29 31 | MAX_UNUSUAL_OPTIONS = 2 32 | 33 | os_default = 'linux' 34 | os_unusual = 'osx' 35 | 36 | compilers_default = 'CC=gcc' 37 | compilers_unusual = 'CC=clang' 38 | 39 | compiler_flag_unusuals = ['-m32'] 40 | 41 | configure_flag_unusuals = [ 42 | '--enable-debug', '--enable-prof', '--disable-stats', '--disable-tcache', 43 | ] 44 | 45 | all_unusuals = ( 46 | [os_unusual] + [compilers_unusual] + compiler_flag_unusuals 47 | + configure_flag_unusuals 48 | ) 49 | 50 | unusual_combinations_to_test = [] 51 | for i in xrange(MAX_UNUSUAL_OPTIONS + 1): 52 | unusual_combinations_to_test += combinations(all_unusuals, i) 53 | 54 | include_rows = "" 55 | for unusual_combination in unusual_combinations_to_test: 56 | os = os_default 57 | if os_unusual in unusual_combination: 58 | os = os_unusual 59 | 60 | compilers = compilers_default 61 | if compilers_unusual in unusual_combination: 62 | compilers = compilers_unusual 63 | 64 | compiler_flags = [ 65 | x for x in unusual_combination if x in compiler_flag_unusuals] 66 | 67 | configure_flags = [ 68 | x for x in unusual_combination if x in configure_flag_unusuals] 69 | 70 | # Filter out an unsupported configuration - heap profiling on OS X. 71 | if os == 'osx' and '--enable-prof' in configure_flags: 72 | continue 73 | 74 | env_string = '{} COMPILER_FLAGS="{}" CONFIGURE_FLAGS="{}"'.format( 75 | compilers, " ".join(compiler_flags), " ".join(configure_flags)) 76 | 77 | include_rows += ' - os: %s\n' % os 78 | include_rows += ' env: %s\n' % env_string 79 | if '-m32' in unusual_combination and os == 'linux': 80 | include_rows += ' addons:\n' 81 | include_rows += ' apt:\n' 82 | include_rows += ' packages:\n' 83 | include_rows += ' - gcc-multilib\n' 84 | 85 | print travis_template % include_rows 86 | -------------------------------------------------------------------------------- /internal/test/unit/quarantine.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | /* Keep in sync with definition in quarantine.sh. */ 4 | #define QUARANTINE_SIZE 8192 5 | 6 | void 7 | quarantine_clear(void) 8 | { 9 | void *p; 10 | 11 | p = mallocx(QUARANTINE_SIZE*2, 0); 12 | assert_ptr_not_null(p, "Unexpected mallocx() failure"); 13 | dallocx(p, 0); 14 | } 15 | 16 | TEST_BEGIN(test_quarantine) 17 | { 18 | #define SZ ZU(256) 19 | #define NQUARANTINED (QUARANTINE_SIZE/SZ) 20 | void *quarantined[NQUARANTINED+1]; 21 | size_t i, j; 22 | 23 | test_skip_if(!config_fill); 24 | 25 | assert_zu_eq(nallocx(SZ, 0), SZ, 26 | "SZ=%zu does not precisely equal a size class", SZ); 27 | 28 | quarantine_clear(); 29 | 30 | /* 31 | * Allocate enough regions to completely fill the quarantine, plus one 32 | * more. The last iteration occurs with a completely full quarantine, 33 | * but no regions should be drained from the quarantine until the last 34 | * deallocation occurs. Therefore no region recycling should occur 35 | * until after this loop completes. 36 | */ 37 | for (i = 0; i < NQUARANTINED+1; i++) { 38 | void *p = mallocx(SZ, 0); 39 | assert_ptr_not_null(p, "Unexpected mallocx() failure"); 40 | quarantined[i] = p; 41 | dallocx(p, 0); 42 | for (j = 0; j < i; j++) { 43 | assert_ptr_ne(p, quarantined[j], 44 | "Quarantined region recycled too early; " 45 | "i=%zu, j=%zu", i, j); 46 | } 47 | } 48 | #undef NQUARANTINED 49 | #undef SZ 50 | } 51 | TEST_END 52 | 53 | static bool detected_redzone_corruption; 54 | 55 | static void 56 | arena_redzone_corruption_replacement(void *ptr, size_t usize, bool after, 57 | size_t offset, uint8_t byte) 58 | { 59 | 60 | detected_redzone_corruption = true; 61 | } 62 | 63 | TEST_BEGIN(test_quarantine_redzone) 64 | { 65 | char *s; 66 | arena_redzone_corruption_t *arena_redzone_corruption_orig; 67 | 68 | test_skip_if(!config_fill); 69 | 70 | arena_redzone_corruption_orig = arena_redzone_corruption; 71 | arena_redzone_corruption = arena_redzone_corruption_replacement; 72 | 73 | /* Test underflow. */ 74 | detected_redzone_corruption = false; 75 | s = (char *)mallocx(1, 0); 76 | assert_ptr_not_null((void *)s, "Unexpected mallocx() failure"); 77 | s[-1] = 0xbb; 78 | dallocx(s, 0); 79 | assert_true(detected_redzone_corruption, 80 | "Did not detect redzone corruption"); 81 | 82 | /* Test overflow. */ 83 | detected_redzone_corruption = false; 84 | s = (char *)mallocx(1, 0); 85 | assert_ptr_not_null((void *)s, "Unexpected mallocx() failure"); 86 | s[sallocx(s, 0)] = 0xbb; 87 | dallocx(s, 0); 88 | assert_true(detected_redzone_corruption, 89 | "Did not detect redzone corruption"); 90 | 91 | arena_redzone_corruption = arena_redzone_corruption_orig; 92 | } 93 | TEST_END 94 | 95 | int 96 | main(void) 97 | { 98 | 99 | return (test( 100 | test_quarantine, 101 | test_quarantine_redzone)); 102 | } 103 | -------------------------------------------------------------------------------- /internal/include/jemalloc/internal/ckh.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | #ifdef JEMALLOC_H_TYPES 3 | 4 | typedef struct ckh_s ckh_t; 5 | typedef struct ckhc_s ckhc_t; 6 | 7 | /* Typedefs to allow easy function pointer passing. */ 8 | typedef void ckh_hash_t (const void *, size_t[2]); 9 | typedef bool ckh_keycomp_t (const void *, const void *); 10 | 11 | /* Maintain counters used to get an idea of performance. */ 12 | /* #define CKH_COUNT */ 13 | /* Print counter values in ckh_delete() (requires CKH_COUNT). */ 14 | /* #define CKH_VERBOSE */ 15 | 16 | /* 17 | * There are 2^LG_CKH_BUCKET_CELLS cells in each hash table bucket. Try to fit 18 | * one bucket per L1 cache line. 19 | */ 20 | #define LG_CKH_BUCKET_CELLS (LG_CACHELINE - LG_SIZEOF_PTR - 1) 21 | 22 | #endif /* JEMALLOC_H_TYPES */ 23 | /******************************************************************************/ 24 | #ifdef JEMALLOC_H_STRUCTS 25 | 26 | /* Hash table cell. */ 27 | struct ckhc_s { 28 | const void *key; 29 | const void *data; 30 | }; 31 | 32 | struct ckh_s { 33 | #ifdef CKH_COUNT 34 | /* Counters used to get an idea of performance. */ 35 | uint64_t ngrows; 36 | uint64_t nshrinks; 37 | uint64_t nshrinkfails; 38 | uint64_t ninserts; 39 | uint64_t nrelocs; 40 | #endif 41 | 42 | /* Used for pseudo-random number generation. */ 43 | uint64_t prng_state; 44 | 45 | /* Total number of items. */ 46 | size_t count; 47 | 48 | /* 49 | * Minimum and current number of hash table buckets. There are 50 | * 2^LG_CKH_BUCKET_CELLS cells per bucket. 51 | */ 52 | unsigned lg_minbuckets; 53 | unsigned lg_curbuckets; 54 | 55 | /* Hash and comparison functions. */ 56 | ckh_hash_t *hash; 57 | ckh_keycomp_t *keycomp; 58 | 59 | /* Hash table with 2^lg_curbuckets buckets. */ 60 | ckhc_t *tab; 61 | }; 62 | 63 | #endif /* JEMALLOC_H_STRUCTS */ 64 | /******************************************************************************/ 65 | #ifdef JEMALLOC_H_EXTERNS 66 | 67 | bool ckh_new(tsd_t *tsd, ckh_t *ckh, size_t minitems, ckh_hash_t *hash, 68 | ckh_keycomp_t *keycomp); 69 | void ckh_delete(tsd_t *tsd, ckh_t *ckh); 70 | size_t ckh_count(ckh_t *ckh); 71 | bool ckh_iter(ckh_t *ckh, size_t *tabind, void **key, void **data); 72 | bool ckh_insert(tsd_t *tsd, ckh_t *ckh, const void *key, const void *data); 73 | bool ckh_remove(tsd_t *tsd, ckh_t *ckh, const void *searchkey, void **key, 74 | void **data); 75 | bool ckh_search(ckh_t *ckh, const void *searchkey, void **key, void **data); 76 | void ckh_string_hash(const void *key, size_t r_hash[2]); 77 | bool ckh_string_keycomp(const void *k1, const void *k2); 78 | void ckh_pointer_hash(const void *key, size_t r_hash[2]); 79 | bool ckh_pointer_keycomp(const void *k1, const void *k2); 80 | 81 | #endif /* JEMALLOC_H_EXTERNS */ 82 | /******************************************************************************/ 83 | #ifdef JEMALLOC_H_INLINES 84 | 85 | #endif /* JEMALLOC_H_INLINES */ 86 | /******************************************************************************/ 87 | -------------------------------------------------------------------------------- /internal/test/unit/extent_quantize.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | TEST_BEGIN(test_huge_extent_size) { 4 | unsigned nhchunks, i; 5 | size_t sz, extent_size_prev, ceil_prev; 6 | size_t mib[4]; 7 | size_t miblen = sizeof(mib) / sizeof(size_t); 8 | 9 | /* 10 | * Iterate over all huge size classes, get their extent sizes, and 11 | * verify that the quantized size is the same as the extent size. 12 | */ 13 | 14 | sz = sizeof(unsigned); 15 | assert_d_eq(mallctl("arenas.nhchunks", (void *)&nhchunks, &sz, NULL, 16 | 0), 0, "Unexpected mallctl failure"); 17 | 18 | assert_d_eq(mallctlnametomib("arenas.hchunk.0.size", mib, &miblen), 0, 19 | "Unexpected mallctlnametomib failure"); 20 | for (i = 0; i < nhchunks; i++) { 21 | size_t extent_size, floor, ceil; 22 | 23 | 24 | mib[2] = i; 25 | sz = sizeof(size_t); 26 | assert_d_eq(mallctlbymib(mib, miblen, (void *)&extent_size, 27 | &sz, NULL, 0), 0, "Unexpected mallctlbymib failure"); 28 | floor = extent_size_quantize_floor(extent_size); 29 | ceil = extent_size_quantize_ceil(extent_size); 30 | 31 | assert_zu_eq(extent_size, floor, 32 | "Extent quantization should be a no-op for precise size " 33 | "(extent_size=%zu)", extent_size); 34 | assert_zu_eq(extent_size, ceil, 35 | "Extent quantization should be a no-op for precise size " 36 | "(extent_size=%zu)", extent_size); 37 | 38 | if (i > 0) { 39 | assert_zu_eq(extent_size_prev, 40 | extent_size_quantize_floor(extent_size - PAGE), 41 | "Floor should be a precise size"); 42 | if (extent_size_prev < ceil_prev) { 43 | assert_zu_eq(ceil_prev, extent_size, 44 | "Ceiling should be a precise size " 45 | "(extent_size_prev=%zu, ceil_prev=%zu, " 46 | "extent_size=%zu)", extent_size_prev, 47 | ceil_prev, extent_size); 48 | } 49 | } 50 | if (i + 1 < nhchunks) { 51 | extent_size_prev = floor; 52 | ceil_prev = extent_size_quantize_ceil(extent_size + 53 | PAGE); 54 | } 55 | } 56 | } 57 | TEST_END 58 | 59 | TEST_BEGIN(test_monotonic) { 60 | #define SZ_MAX ZU(4 * 1024 * 1024) 61 | unsigned i; 62 | size_t floor_prev, ceil_prev; 63 | 64 | floor_prev = 0; 65 | ceil_prev = 0; 66 | for (i = 1; i <= SZ_MAX >> LG_PAGE; i++) { 67 | size_t extent_size, floor, ceil; 68 | 69 | extent_size = i << LG_PAGE; 70 | floor = extent_size_quantize_floor(extent_size); 71 | ceil = extent_size_quantize_ceil(extent_size); 72 | 73 | assert_zu_le(floor, extent_size, 74 | "Floor should be <= (floor=%zu, extent_size=%zu, ceil=%zu)", 75 | floor, extent_size, ceil); 76 | assert_zu_ge(ceil, extent_size, 77 | "Ceiling should be >= (floor=%zu, extent_size=%zu, " 78 | "ceil=%zu)", floor, extent_size, ceil); 79 | 80 | assert_zu_le(floor_prev, floor, "Floor should be monotonic " 81 | "(floor_prev=%zu, floor=%zu, extent_size=%zu, ceil=%zu)", 82 | floor_prev, floor, extent_size, ceil); 83 | assert_zu_le(ceil_prev, ceil, "Ceiling should be monotonic " 84 | "(floor=%zu, extent_size=%zu, ceil_prev=%zu, ceil=%zu)", 85 | floor, extent_size, ceil_prev, ceil); 86 | 87 | floor_prev = floor; 88 | ceil_prev = ceil; 89 | } 90 | } 91 | TEST_END 92 | 93 | int 94 | main(void) { 95 | return test( 96 | test_huge_extent_size, 97 | test_monotonic); 98 | } 99 | -------------------------------------------------------------------------------- /internal/test/unit/smoothstep.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | static const uint64_t smoothstep_tab[] = { 4 | #define STEP(step, h, x, y) \ 5 | h, 6 | SMOOTHSTEP 7 | #undef STEP 8 | }; 9 | 10 | TEST_BEGIN(test_smoothstep_integral) 11 | { 12 | uint64_t sum, min, max; 13 | unsigned i; 14 | 15 | /* 16 | * The integral of smoothstep in the [0..1] range equals 1/2. Verify 17 | * that the fixed point representation's integral is no more than 18 | * rounding error distant from 1/2. Regarding rounding, each table 19 | * element is rounded down to the nearest fixed point value, so the 20 | * integral may be off by as much as SMOOTHSTEP_NSTEPS ulps. 21 | */ 22 | sum = 0; 23 | for (i = 0; i < SMOOTHSTEP_NSTEPS; i++) 24 | sum += smoothstep_tab[i]; 25 | 26 | max = (KQU(1) << (SMOOTHSTEP_BFP-1)) * (SMOOTHSTEP_NSTEPS+1); 27 | min = max - SMOOTHSTEP_NSTEPS; 28 | 29 | assert_u64_ge(sum, min, 30 | "Integral too small, even accounting for truncation"); 31 | assert_u64_le(sum, max, "Integral exceeds 1/2"); 32 | if (false) { 33 | malloc_printf("%"FMTu64" ulps under 1/2 (limit %d)\n", 34 | max - sum, SMOOTHSTEP_NSTEPS); 35 | } 36 | } 37 | TEST_END 38 | 39 | TEST_BEGIN(test_smoothstep_monotonic) 40 | { 41 | uint64_t prev_h; 42 | unsigned i; 43 | 44 | /* 45 | * The smoothstep function is monotonic in [0..1], i.e. its slope is 46 | * non-negative. In practice we want to parametrize table generation 47 | * such that piecewise slope is greater than zero, but do not require 48 | * that here. 49 | */ 50 | prev_h = 0; 51 | for (i = 0; i < SMOOTHSTEP_NSTEPS; i++) { 52 | uint64_t h = smoothstep_tab[i]; 53 | assert_u64_ge(h, prev_h, "Piecewise non-monotonic, i=%u", i); 54 | prev_h = h; 55 | } 56 | assert_u64_eq(smoothstep_tab[SMOOTHSTEP_NSTEPS-1], 57 | (KQU(1) << SMOOTHSTEP_BFP), "Last step must equal 1"); 58 | } 59 | TEST_END 60 | 61 | TEST_BEGIN(test_smoothstep_slope) 62 | { 63 | uint64_t prev_h, prev_delta; 64 | unsigned i; 65 | 66 | /* 67 | * The smoothstep slope strictly increases until x=0.5, and then 68 | * strictly decreases until x=1.0. Verify the slightly weaker 69 | * requirement of monotonicity, so that inadequate table precision does 70 | * not cause false test failures. 71 | */ 72 | prev_h = 0; 73 | prev_delta = 0; 74 | for (i = 0; i < SMOOTHSTEP_NSTEPS / 2 + SMOOTHSTEP_NSTEPS % 2; i++) { 75 | uint64_t h = smoothstep_tab[i]; 76 | uint64_t delta = h - prev_h; 77 | assert_u64_ge(delta, prev_delta, 78 | "Slope must monotonically increase in 0.0 <= x <= 0.5, " 79 | "i=%u", i); 80 | prev_h = h; 81 | prev_delta = delta; 82 | } 83 | 84 | prev_h = KQU(1) << SMOOTHSTEP_BFP; 85 | prev_delta = 0; 86 | for (i = SMOOTHSTEP_NSTEPS-1; i >= SMOOTHSTEP_NSTEPS / 2; i--) { 87 | uint64_t h = smoothstep_tab[i]; 88 | uint64_t delta = prev_h - h; 89 | assert_u64_ge(delta, prev_delta, 90 | "Slope must monotonically decrease in 0.5 <= x <= 1.0, " 91 | "i=%u", i); 92 | prev_h = h; 93 | prev_delta = delta; 94 | } 95 | } 96 | TEST_END 97 | 98 | int 99 | main(void) 100 | { 101 | 102 | return (test( 103 | test_smoothstep_integral, 104 | test_smoothstep_monotonic, 105 | test_smoothstep_slope)); 106 | } 107 | -------------------------------------------------------------------------------- /internal/test/integration/thread_tcache_enabled.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | static const bool config_tcache = 4 | #ifdef JEMALLOC_TCACHE 5 | true 6 | #else 7 | false 8 | #endif 9 | ; 10 | 11 | void * 12 | thd_start(void *arg) 13 | { 14 | int err; 15 | size_t sz; 16 | bool e0, e1; 17 | 18 | sz = sizeof(bool); 19 | if ((err = mallctl("thread.tcache.enabled", (void *)&e0, &sz, NULL, 20 | 0))) { 21 | if (err == ENOENT) { 22 | assert_false(config_tcache, 23 | "ENOENT should only be returned if tcache is " 24 | "disabled"); 25 | } 26 | goto label_ENOENT; 27 | } 28 | 29 | if (e0) { 30 | e1 = false; 31 | assert_d_eq(mallctl("thread.tcache.enabled", (void *)&e0, &sz, 32 | (void *)&e1, sz), 0, "Unexpected mallctl() error"); 33 | assert_true(e0, "tcache should be enabled"); 34 | } 35 | 36 | e1 = true; 37 | assert_d_eq(mallctl("thread.tcache.enabled", (void *)&e0, &sz, 38 | (void *)&e1, sz), 0, "Unexpected mallctl() error"); 39 | assert_false(e0, "tcache should be disabled"); 40 | 41 | e1 = true; 42 | assert_d_eq(mallctl("thread.tcache.enabled", (void *)&e0, &sz, 43 | (void *)&e1, sz), 0, "Unexpected mallctl() error"); 44 | assert_true(e0, "tcache should be enabled"); 45 | 46 | e1 = false; 47 | assert_d_eq(mallctl("thread.tcache.enabled", (void *)&e0, &sz, 48 | (void *)&e1, sz), 0, "Unexpected mallctl() error"); 49 | assert_true(e0, "tcache should be enabled"); 50 | 51 | e1 = false; 52 | assert_d_eq(mallctl("thread.tcache.enabled", (void *)&e0, &sz, 53 | (void *)&e1, sz), 0, "Unexpected mallctl() error"); 54 | assert_false(e0, "tcache should be disabled"); 55 | 56 | free(malloc(1)); 57 | e1 = true; 58 | assert_d_eq(mallctl("thread.tcache.enabled", (void *)&e0, &sz, 59 | (void *)&e1, sz), 0, "Unexpected mallctl() error"); 60 | assert_false(e0, "tcache should be disabled"); 61 | 62 | free(malloc(1)); 63 | e1 = true; 64 | assert_d_eq(mallctl("thread.tcache.enabled", (void *)&e0, &sz, 65 | (void *)&e1, sz), 0, "Unexpected mallctl() error"); 66 | assert_true(e0, "tcache should be enabled"); 67 | 68 | free(malloc(1)); 69 | e1 = false; 70 | assert_d_eq(mallctl("thread.tcache.enabled", (void *)&e0, &sz, 71 | (void *)&e1, sz), 0, "Unexpected mallctl() error"); 72 | assert_true(e0, "tcache should be enabled"); 73 | 74 | free(malloc(1)); 75 | e1 = false; 76 | assert_d_eq(mallctl("thread.tcache.enabled", (void *)&e0, &sz, 77 | (void *)&e1, sz), 0, "Unexpected mallctl() error"); 78 | assert_false(e0, "tcache should be disabled"); 79 | 80 | free(malloc(1)); 81 | return (NULL); 82 | label_ENOENT: 83 | test_skip("\"thread.tcache.enabled\" mallctl not available"); 84 | return (NULL); 85 | } 86 | 87 | TEST_BEGIN(test_main_thread) 88 | { 89 | 90 | thd_start(NULL); 91 | } 92 | TEST_END 93 | 94 | TEST_BEGIN(test_subthread) 95 | { 96 | thd_t thd; 97 | 98 | thd_create(&thd, thd_start, NULL); 99 | thd_join(thd, NULL); 100 | } 101 | TEST_END 102 | 103 | int 104 | main(void) 105 | { 106 | 107 | /* Run tests multiple times to check for bad interactions. */ 108 | return (test( 109 | test_main_thread, 110 | test_subthread, 111 | test_main_thread, 112 | test_subthread, 113 | test_main_thread)); 114 | } 115 | -------------------------------------------------------------------------------- /internal/test/src/test.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | static unsigned test_count = 0; 4 | static test_status_t test_counts[test_status_count] = {0, 0, 0}; 5 | static test_status_t test_status = test_status_pass; 6 | static const char * test_name = ""; 7 | 8 | JEMALLOC_FORMAT_PRINTF(1, 2) 9 | void 10 | test_skip(const char *format, ...) 11 | { 12 | va_list ap; 13 | 14 | va_start(ap, format); 15 | malloc_vcprintf(NULL, NULL, format, ap); 16 | va_end(ap); 17 | malloc_printf("\n"); 18 | test_status = test_status_skip; 19 | } 20 | 21 | JEMALLOC_FORMAT_PRINTF(1, 2) 22 | void 23 | test_fail(const char *format, ...) 24 | { 25 | va_list ap; 26 | 27 | va_start(ap, format); 28 | malloc_vcprintf(NULL, NULL, format, ap); 29 | va_end(ap); 30 | malloc_printf("\n"); 31 | test_status = test_status_fail; 32 | } 33 | 34 | static const char * 35 | test_status_string(test_status_t test_status) 36 | { 37 | 38 | switch (test_status) { 39 | case test_status_pass: return "pass"; 40 | case test_status_skip: return "skip"; 41 | case test_status_fail: return "fail"; 42 | default: not_reached(); 43 | } 44 | } 45 | 46 | void 47 | p_test_init(const char *name) 48 | { 49 | 50 | test_count++; 51 | test_status = test_status_pass; 52 | test_name = name; 53 | } 54 | 55 | void 56 | p_test_fini(void) 57 | { 58 | 59 | test_counts[test_status]++; 60 | malloc_printf("%s: %s\n", test_name, test_status_string(test_status)); 61 | } 62 | 63 | static test_status_t 64 | p_test_impl(bool do_malloc_init, test_t *t, va_list ap) 65 | { 66 | test_status_t ret; 67 | 68 | if (do_malloc_init) { 69 | /* 70 | * Make sure initialization occurs prior to running tests. 71 | * Tests are special because they may use internal facilities 72 | * prior to triggering initialization as a side effect of 73 | * calling into the public API. 74 | */ 75 | if (nallocx(1, 0) == 0) { 76 | malloc_printf("Initialization error"); 77 | return (test_status_fail); 78 | } 79 | } 80 | 81 | ret = test_status_pass; 82 | for (; t != NULL; t = va_arg(ap, test_t *)) { 83 | t(); 84 | if (test_status > ret) 85 | ret = test_status; 86 | } 87 | 88 | malloc_printf("--- %s: %u/%u, %s: %u/%u, %s: %u/%u ---\n", 89 | test_status_string(test_status_pass), 90 | test_counts[test_status_pass], test_count, 91 | test_status_string(test_status_skip), 92 | test_counts[test_status_skip], test_count, 93 | test_status_string(test_status_fail), 94 | test_counts[test_status_fail], test_count); 95 | 96 | return (ret); 97 | } 98 | 99 | test_status_t 100 | p_test(test_t *t, ...) 101 | { 102 | test_status_t ret; 103 | va_list ap; 104 | 105 | ret = test_status_pass; 106 | va_start(ap, t); 107 | ret = p_test_impl(true, t, ap); 108 | va_end(ap); 109 | 110 | return (ret); 111 | } 112 | 113 | test_status_t 114 | p_test_no_malloc_init(test_t *t, ...) 115 | { 116 | test_status_t ret; 117 | va_list ap; 118 | 119 | ret = test_status_pass; 120 | va_start(ap, t); 121 | ret = p_test_impl(false, t, ap); 122 | va_end(ap); 123 | 124 | return (ret); 125 | } 126 | 127 | void 128 | p_test_fail(const char *prefix, const char *message) 129 | { 130 | 131 | malloc_cprintf(NULL, NULL, "%s%s\n", prefix, message); 132 | test_status = test_status_fail; 133 | } 134 | -------------------------------------------------------------------------------- /internal/include/jemalloc/internal/mb.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | #ifdef JEMALLOC_H_TYPES 3 | 4 | #endif /* JEMALLOC_H_TYPES */ 5 | /******************************************************************************/ 6 | #ifdef JEMALLOC_H_STRUCTS 7 | 8 | #endif /* JEMALLOC_H_STRUCTS */ 9 | /******************************************************************************/ 10 | #ifdef JEMALLOC_H_EXTERNS 11 | 12 | #endif /* JEMALLOC_H_EXTERNS */ 13 | /******************************************************************************/ 14 | #ifdef JEMALLOC_H_INLINES 15 | 16 | #ifndef JEMALLOC_ENABLE_INLINE 17 | void mb_write(void); 18 | #endif 19 | 20 | #if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_MB_C_)) 21 | #ifdef __i386__ 22 | /* 23 | * According to the Intel Architecture Software Developer's Manual, current 24 | * processors execute instructions in order from the perspective of other 25 | * processors in a multiprocessor system, but 1) Intel reserves the right to 26 | * change that, and 2) the compiler's optimizer could re-order instructions if 27 | * there weren't some form of barrier. Therefore, even if running on an 28 | * architecture that does not need memory barriers (everything through at least 29 | * i686), an "optimizer barrier" is necessary. 30 | */ 31 | JEMALLOC_INLINE void 32 | mb_write(void) 33 | { 34 | 35 | # if 0 36 | /* This is a true memory barrier. */ 37 | asm volatile ("pusha;" 38 | "xor %%eax,%%eax;" 39 | "cpuid;" 40 | "popa;" 41 | : /* Outputs. */ 42 | : /* Inputs. */ 43 | : "memory" /* Clobbers. */ 44 | ); 45 | # else 46 | /* 47 | * This is hopefully enough to keep the compiler from reordering 48 | * instructions around this one. 49 | */ 50 | asm volatile ("nop;" 51 | : /* Outputs. */ 52 | : /* Inputs. */ 53 | : "memory" /* Clobbers. */ 54 | ); 55 | # endif 56 | } 57 | #elif (defined(__amd64__) || defined(__x86_64__)) 58 | JEMALLOC_INLINE void 59 | mb_write(void) 60 | { 61 | 62 | asm volatile ("sfence" 63 | : /* Outputs. */ 64 | : /* Inputs. */ 65 | : "memory" /* Clobbers. */ 66 | ); 67 | } 68 | #elif defined(__powerpc__) 69 | JEMALLOC_INLINE void 70 | mb_write(void) 71 | { 72 | 73 | asm volatile ("eieio" 74 | : /* Outputs. */ 75 | : /* Inputs. */ 76 | : "memory" /* Clobbers. */ 77 | ); 78 | } 79 | #elif defined(__sparc__) && defined(__arch64__) 80 | JEMALLOC_INLINE void 81 | mb_write(void) 82 | { 83 | 84 | asm volatile ("membar #StoreStore" 85 | : /* Outputs. */ 86 | : /* Inputs. */ 87 | : "memory" /* Clobbers. */ 88 | ); 89 | } 90 | #elif defined(__tile__) 91 | JEMALLOC_INLINE void 92 | mb_write(void) 93 | { 94 | 95 | __sync_synchronize(); 96 | } 97 | #else 98 | /* 99 | * This is much slower than a simple memory barrier, but the semantics of mutex 100 | * unlock make this work. 101 | */ 102 | JEMALLOC_INLINE void 103 | mb_write(void) 104 | { 105 | malloc_mutex_t mtx; 106 | 107 | malloc_mutex_init(&mtx, "mb", WITNESS_RANK_OMIT); 108 | malloc_mutex_lock(TSDN_NULL, &mtx); 109 | malloc_mutex_unlock(TSDN_NULL, &mtx); 110 | } 111 | #endif 112 | #endif 113 | 114 | #endif /* JEMALLOC_H_INLINES */ 115 | /******************************************************************************/ 116 | -------------------------------------------------------------------------------- /internal/src/bitmap.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_BITMAP_C_ 2 | #include "jemalloc/internal/jemalloc_internal.h" 3 | 4 | /******************************************************************************/ 5 | 6 | #ifdef USE_TREE 7 | 8 | void 9 | bitmap_info_init(bitmap_info_t *binfo, size_t nbits) 10 | { 11 | unsigned i; 12 | size_t group_count; 13 | 14 | assert(nbits > 0); 15 | assert(nbits <= (ZU(1) << LG_BITMAP_MAXBITS)); 16 | 17 | /* 18 | * Compute the number of groups necessary to store nbits bits, and 19 | * progressively work upward through the levels until reaching a level 20 | * that requires only one group. 21 | */ 22 | binfo->levels[0].group_offset = 0; 23 | group_count = BITMAP_BITS2GROUPS(nbits); 24 | for (i = 1; group_count > 1; i++) { 25 | assert(i < BITMAP_MAX_LEVELS); 26 | binfo->levels[i].group_offset = binfo->levels[i-1].group_offset 27 | + group_count; 28 | group_count = BITMAP_BITS2GROUPS(group_count); 29 | } 30 | binfo->levels[i].group_offset = binfo->levels[i-1].group_offset 31 | + group_count; 32 | assert(binfo->levels[i].group_offset <= BITMAP_GROUPS_MAX); 33 | binfo->nlevels = i; 34 | binfo->nbits = nbits; 35 | } 36 | 37 | static size_t 38 | bitmap_info_ngroups(const bitmap_info_t *binfo) 39 | { 40 | 41 | return (binfo->levels[binfo->nlevels].group_offset); 42 | } 43 | 44 | void 45 | bitmap_init(bitmap_t *bitmap, const bitmap_info_t *binfo) 46 | { 47 | size_t extra; 48 | unsigned i; 49 | 50 | /* 51 | * Bits are actually inverted with regard to the external bitmap 52 | * interface, so the bitmap starts out with all 1 bits, except for 53 | * trailing unused bits (if any). Note that each group uses bit 0 to 54 | * correspond to the first logical bit in the group, so extra bits 55 | * are the most significant bits of the last group. 56 | */ 57 | memset(bitmap, 0xffU, bitmap_size(binfo)); 58 | extra = (BITMAP_GROUP_NBITS - (binfo->nbits & BITMAP_GROUP_NBITS_MASK)) 59 | & BITMAP_GROUP_NBITS_MASK; 60 | if (extra != 0) 61 | bitmap[binfo->levels[1].group_offset - 1] >>= extra; 62 | for (i = 1; i < binfo->nlevels; i++) { 63 | size_t group_count = binfo->levels[i].group_offset - 64 | binfo->levels[i-1].group_offset; 65 | extra = (BITMAP_GROUP_NBITS - (group_count & 66 | BITMAP_GROUP_NBITS_MASK)) & BITMAP_GROUP_NBITS_MASK; 67 | if (extra != 0) 68 | bitmap[binfo->levels[i+1].group_offset - 1] >>= extra; 69 | } 70 | } 71 | 72 | #else /* USE_TREE */ 73 | 74 | void 75 | bitmap_info_init(bitmap_info_t *binfo, size_t nbits) 76 | { 77 | 78 | assert(nbits > 0); 79 | assert(nbits <= (ZU(1) << LG_BITMAP_MAXBITS)); 80 | 81 | binfo->ngroups = BITMAP_BITS2GROUPS(nbits); 82 | binfo->nbits = nbits; 83 | } 84 | 85 | static size_t 86 | bitmap_info_ngroups(const bitmap_info_t *binfo) 87 | { 88 | 89 | return (binfo->ngroups); 90 | } 91 | 92 | void 93 | bitmap_init(bitmap_t *bitmap, const bitmap_info_t *binfo) 94 | { 95 | size_t extra; 96 | 97 | memset(bitmap, 0xffU, bitmap_size(binfo)); 98 | extra = (BITMAP_GROUP_NBITS - (binfo->nbits & BITMAP_GROUP_NBITS_MASK)) 99 | & BITMAP_GROUP_NBITS_MASK; 100 | if (extra != 0) 101 | bitmap[binfo->ngroups - 1] >>= extra; 102 | } 103 | 104 | #endif /* USE_TREE */ 105 | 106 | size_t 107 | bitmap_size(const bitmap_info_t *binfo) 108 | { 109 | 110 | return (bitmap_info_ngroups(binfo) << LG_SIZEOF_BITMAP); 111 | } 112 | -------------------------------------------------------------------------------- /internal/.travis.yml: -------------------------------------------------------------------------------- 1 | language: generic 2 | 3 | matrix: 4 | include: 5 | - os: linux 6 | env: CC=gcc COMPILER_FLAGS="" CONFIGURE_FLAGS="" 7 | - os: osx 8 | env: CC=gcc COMPILER_FLAGS="" CONFIGURE_FLAGS="" 9 | - os: linux 10 | env: CC=clang COMPILER_FLAGS="" CONFIGURE_FLAGS="" 11 | - os: linux 12 | env: CC=gcc COMPILER_FLAGS="-m32" CONFIGURE_FLAGS="" 13 | addons: 14 | apt: 15 | packages: 16 | - gcc-multilib 17 | - os: linux 18 | env: CC=gcc COMPILER_FLAGS="" CONFIGURE_FLAGS="--enable-debug" 19 | - os: linux 20 | env: CC=gcc COMPILER_FLAGS="" CONFIGURE_FLAGS="--enable-prof" 21 | - os: linux 22 | env: CC=gcc COMPILER_FLAGS="" CONFIGURE_FLAGS="--disable-stats" 23 | - os: linux 24 | env: CC=gcc COMPILER_FLAGS="" CONFIGURE_FLAGS="--disable-tcache" 25 | - os: osx 26 | env: CC=clang COMPILER_FLAGS="" CONFIGURE_FLAGS="" 27 | - os: osx 28 | env: CC=gcc COMPILER_FLAGS="-m32" CONFIGURE_FLAGS="" 29 | - os: osx 30 | env: CC=gcc COMPILER_FLAGS="" CONFIGURE_FLAGS="--enable-debug" 31 | - os: osx 32 | env: CC=gcc COMPILER_FLAGS="" CONFIGURE_FLAGS="--disable-stats" 33 | - os: osx 34 | env: CC=gcc COMPILER_FLAGS="" CONFIGURE_FLAGS="--disable-tcache" 35 | - os: linux 36 | env: CC=clang COMPILER_FLAGS="-m32" CONFIGURE_FLAGS="" 37 | addons: 38 | apt: 39 | packages: 40 | - gcc-multilib 41 | - os: linux 42 | env: CC=clang COMPILER_FLAGS="" CONFIGURE_FLAGS="--enable-debug" 43 | - os: linux 44 | env: CC=clang COMPILER_FLAGS="" CONFIGURE_FLAGS="--enable-prof" 45 | - os: linux 46 | env: CC=clang COMPILER_FLAGS="" CONFIGURE_FLAGS="--disable-stats" 47 | - os: linux 48 | env: CC=clang COMPILER_FLAGS="" CONFIGURE_FLAGS="--disable-tcache" 49 | - os: linux 50 | env: CC=gcc COMPILER_FLAGS="-m32" CONFIGURE_FLAGS="--enable-debug" 51 | addons: 52 | apt: 53 | packages: 54 | - gcc-multilib 55 | - os: linux 56 | env: CC=gcc COMPILER_FLAGS="-m32" CONFIGURE_FLAGS="--enable-prof" 57 | addons: 58 | apt: 59 | packages: 60 | - gcc-multilib 61 | - os: linux 62 | env: CC=gcc COMPILER_FLAGS="-m32" CONFIGURE_FLAGS="--disable-stats" 63 | addons: 64 | apt: 65 | packages: 66 | - gcc-multilib 67 | - os: linux 68 | env: CC=gcc COMPILER_FLAGS="-m32" CONFIGURE_FLAGS="--disable-tcache" 69 | addons: 70 | apt: 71 | packages: 72 | - gcc-multilib 73 | - os: linux 74 | env: CC=gcc COMPILER_FLAGS="" CONFIGURE_FLAGS="--enable-debug --enable-prof" 75 | - os: linux 76 | env: CC=gcc COMPILER_FLAGS="" CONFIGURE_FLAGS="--enable-debug --disable-stats" 77 | - os: linux 78 | env: CC=gcc COMPILER_FLAGS="" CONFIGURE_FLAGS="--enable-debug --disable-tcache" 79 | - os: linux 80 | env: CC=gcc COMPILER_FLAGS="" CONFIGURE_FLAGS="--enable-prof --disable-stats" 81 | - os: linux 82 | env: CC=gcc COMPILER_FLAGS="" CONFIGURE_FLAGS="--enable-prof --disable-tcache" 83 | - os: linux 84 | env: CC=gcc COMPILER_FLAGS="" CONFIGURE_FLAGS="--disable-stats --disable-tcache" 85 | 86 | 87 | before_script: 88 | - autoconf 89 | - ./configure ${COMPILER_FLAGS:+ CC="$CC $COMPILER_FLAGS" } $CONFIGURE_FLAGS 90 | - make -j3 91 | - make -j3 tests 92 | 93 | script: 94 | - make check 95 | 96 | -------------------------------------------------------------------------------- /internal/test/include/test/mq.h: -------------------------------------------------------------------------------- 1 | void mq_nanosleep(unsigned ns); 2 | 3 | /* 4 | * Simple templated message queue implementation that relies on only mutexes for 5 | * synchronization (which reduces portability issues). Given the following 6 | * setup: 7 | * 8 | * typedef struct mq_msg_s mq_msg_t; 9 | * struct mq_msg_s { 10 | * mq_msg(mq_msg_t) link; 11 | * [message data] 12 | * }; 13 | * mq_gen(, mq_, mq_t, mq_msg_t, link) 14 | * 15 | * The API is as follows: 16 | * 17 | * bool mq_init(mq_t *mq); 18 | * void mq_fini(mq_t *mq); 19 | * unsigned mq_count(mq_t *mq); 20 | * mq_msg_t *mq_tryget(mq_t *mq); 21 | * mq_msg_t *mq_get(mq_t *mq); 22 | * void mq_put(mq_t *mq, mq_msg_t *msg); 23 | * 24 | * The message queue linkage embedded in each message is to be treated as 25 | * externally opaque (no need to initialize or clean up externally). mq_fini() 26 | * does not perform any cleanup of messages, since it knows nothing of their 27 | * payloads. 28 | */ 29 | #define mq_msg(a_mq_msg_type) ql_elm(a_mq_msg_type) 30 | 31 | #define mq_gen(a_attr, a_prefix, a_mq_type, a_mq_msg_type, a_field) \ 32 | typedef struct { \ 33 | mtx_t lock; \ 34 | ql_head(a_mq_msg_type) msgs; \ 35 | unsigned count; \ 36 | } a_mq_type; \ 37 | a_attr bool \ 38 | a_prefix##init(a_mq_type *mq) { \ 39 | \ 40 | if (mtx_init(&mq->lock)) \ 41 | return (true); \ 42 | ql_new(&mq->msgs); \ 43 | mq->count = 0; \ 44 | return (false); \ 45 | } \ 46 | a_attr void \ 47 | a_prefix##fini(a_mq_type *mq) \ 48 | { \ 49 | \ 50 | mtx_fini(&mq->lock); \ 51 | } \ 52 | a_attr unsigned \ 53 | a_prefix##count(a_mq_type *mq) \ 54 | { \ 55 | unsigned count; \ 56 | \ 57 | mtx_lock(&mq->lock); \ 58 | count = mq->count; \ 59 | mtx_unlock(&mq->lock); \ 60 | return (count); \ 61 | } \ 62 | a_attr a_mq_msg_type * \ 63 | a_prefix##tryget(a_mq_type *mq) \ 64 | { \ 65 | a_mq_msg_type *msg; \ 66 | \ 67 | mtx_lock(&mq->lock); \ 68 | msg = ql_first(&mq->msgs); \ 69 | if (msg != NULL) { \ 70 | ql_head_remove(&mq->msgs, a_mq_msg_type, a_field); \ 71 | mq->count--; \ 72 | } \ 73 | mtx_unlock(&mq->lock); \ 74 | return (msg); \ 75 | } \ 76 | a_attr a_mq_msg_type * \ 77 | a_prefix##get(a_mq_type *mq) \ 78 | { \ 79 | a_mq_msg_type *msg; \ 80 | unsigned ns; \ 81 | \ 82 | msg = a_prefix##tryget(mq); \ 83 | if (msg != NULL) \ 84 | return (msg); \ 85 | \ 86 | ns = 1; \ 87 | while (true) { \ 88 | mq_nanosleep(ns); \ 89 | msg = a_prefix##tryget(mq); \ 90 | if (msg != NULL) \ 91 | return (msg); \ 92 | if (ns < 1000*1000*1000) { \ 93 | /* Double sleep time, up to max 1 second. */ \ 94 | ns <<= 1; \ 95 | if (ns > 1000*1000*1000) \ 96 | ns = 1000*1000*1000; \ 97 | } \ 98 | } \ 99 | } \ 100 | a_attr void \ 101 | a_prefix##put(a_mq_type *mq, a_mq_msg_type *msg) \ 102 | { \ 103 | \ 104 | mtx_lock(&mq->lock); \ 105 | ql_elm_new(msg, a_field); \ 106 | ql_tail_insert(&mq->msgs, msg, a_field); \ 107 | mq->count++; \ 108 | mtx_unlock(&mq->lock); \ 109 | } 110 | -------------------------------------------------------------------------------- /darwin_includes/internal/include/jemalloc/jemalloc_protos.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The je_ prefix on the following public symbol declarations is an artifact 3 | * of namespace management, and should be omitted in application code unless 4 | * JEMALLOC_NO_DEMANGLE is defined (see jemalloc_mangle.h). 5 | */ 6 | extern JEMALLOC_EXPORT const char *je_malloc_conf; 7 | extern JEMALLOC_EXPORT void (*je_malloc_message)(void *cbopaque, 8 | const char *s); 9 | 10 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 11 | void JEMALLOC_NOTHROW *je_malloc(size_t size) 12 | JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE(1); 13 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 14 | void JEMALLOC_NOTHROW *je_calloc(size_t num, size_t size) 15 | JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE2(1, 2); 16 | JEMALLOC_EXPORT int JEMALLOC_NOTHROW je_posix_memalign(void **memptr, 17 | size_t alignment, size_t size) JEMALLOC_CXX_THROW JEMALLOC_ATTR(nonnull(1)); 18 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 19 | void JEMALLOC_NOTHROW *je_aligned_alloc(size_t alignment, 20 | size_t size) JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc) 21 | JEMALLOC_ALLOC_SIZE(2); 22 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 23 | void JEMALLOC_NOTHROW *je_realloc(void *ptr, size_t size) 24 | JEMALLOC_CXX_THROW JEMALLOC_ALLOC_SIZE(2); 25 | JEMALLOC_EXPORT void JEMALLOC_NOTHROW je_free(void *ptr) 26 | JEMALLOC_CXX_THROW; 27 | 28 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 29 | void JEMALLOC_NOTHROW *je_mallocx(size_t size, int flags) 30 | JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE(1); 31 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 32 | void JEMALLOC_NOTHROW *je_rallocx(void *ptr, size_t size, 33 | int flags) JEMALLOC_ALLOC_SIZE(2); 34 | JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW je_xallocx(void *ptr, size_t size, 35 | size_t extra, int flags); 36 | JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW je_sallocx(const void *ptr, 37 | int flags) JEMALLOC_ATTR(pure); 38 | JEMALLOC_EXPORT void JEMALLOC_NOTHROW je_dallocx(void *ptr, int flags); 39 | JEMALLOC_EXPORT void JEMALLOC_NOTHROW je_sdallocx(void *ptr, size_t size, 40 | int flags); 41 | JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW je_nallocx(size_t size, int flags) 42 | JEMALLOC_ATTR(pure); 43 | 44 | JEMALLOC_EXPORT int JEMALLOC_NOTHROW je_mallctl(const char *name, 45 | void *oldp, size_t *oldlenp, void *newp, size_t newlen); 46 | JEMALLOC_EXPORT int JEMALLOC_NOTHROW je_mallctlnametomib(const char *name, 47 | size_t *mibp, size_t *miblenp); 48 | JEMALLOC_EXPORT int JEMALLOC_NOTHROW je_mallctlbymib(const size_t *mib, 49 | size_t miblen, void *oldp, size_t *oldlenp, void *newp, size_t newlen); 50 | JEMALLOC_EXPORT void JEMALLOC_NOTHROW je_malloc_stats_print( 51 | void (*write_cb)(void *, const char *), void *je_cbopaque, 52 | const char *opts); 53 | JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW je_malloc_usable_size( 54 | JEMALLOC_USABLE_SIZE_CONST void *ptr) JEMALLOC_CXX_THROW; 55 | 56 | #ifdef JEMALLOC_OVERRIDE_MEMALIGN 57 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 58 | void JEMALLOC_NOTHROW *je_memalign(size_t alignment, size_t size) 59 | JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc); 60 | #endif 61 | 62 | #ifdef JEMALLOC_OVERRIDE_VALLOC 63 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 64 | void JEMALLOC_NOTHROW *je_valloc(size_t size) JEMALLOC_CXX_THROW 65 | JEMALLOC_ATTR(malloc); 66 | #endif 67 | -------------------------------------------------------------------------------- /freebsd_includes/internal/include/jemalloc/jemalloc_protos.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The je_ prefix on the following public symbol declarations is an artifact 3 | * of namespace management, and should be omitted in application code unless 4 | * JEMALLOC_NO_DEMANGLE is defined (see jemalloc_mangle.h). 5 | */ 6 | extern JEMALLOC_EXPORT const char *je_malloc_conf; 7 | extern JEMALLOC_EXPORT void (*je_malloc_message)(void *cbopaque, 8 | const char *s); 9 | 10 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 11 | void JEMALLOC_NOTHROW *je_malloc(size_t size) 12 | JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE(1); 13 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 14 | void JEMALLOC_NOTHROW *je_calloc(size_t num, size_t size) 15 | JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE2(1, 2); 16 | JEMALLOC_EXPORT int JEMALLOC_NOTHROW je_posix_memalign(void **memptr, 17 | size_t alignment, size_t size) JEMALLOC_CXX_THROW JEMALLOC_ATTR(nonnull(1)); 18 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 19 | void JEMALLOC_NOTHROW *je_aligned_alloc(size_t alignment, 20 | size_t size) JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc) 21 | JEMALLOC_ALLOC_SIZE(2); 22 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 23 | void JEMALLOC_NOTHROW *je_realloc(void *ptr, size_t size) 24 | JEMALLOC_CXX_THROW JEMALLOC_ALLOC_SIZE(2); 25 | JEMALLOC_EXPORT void JEMALLOC_NOTHROW je_free(void *ptr) 26 | JEMALLOC_CXX_THROW; 27 | 28 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 29 | void JEMALLOC_NOTHROW *je_mallocx(size_t size, int flags) 30 | JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE(1); 31 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 32 | void JEMALLOC_NOTHROW *je_rallocx(void *ptr, size_t size, 33 | int flags) JEMALLOC_ALLOC_SIZE(2); 34 | JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW je_xallocx(void *ptr, size_t size, 35 | size_t extra, int flags); 36 | JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW je_sallocx(const void *ptr, 37 | int flags) JEMALLOC_ATTR(pure); 38 | JEMALLOC_EXPORT void JEMALLOC_NOTHROW je_dallocx(void *ptr, int flags); 39 | JEMALLOC_EXPORT void JEMALLOC_NOTHROW je_sdallocx(void *ptr, size_t size, 40 | int flags); 41 | JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW je_nallocx(size_t size, int flags) 42 | JEMALLOC_ATTR(pure); 43 | 44 | JEMALLOC_EXPORT int JEMALLOC_NOTHROW je_mallctl(const char *name, 45 | void *oldp, size_t *oldlenp, void *newp, size_t newlen); 46 | JEMALLOC_EXPORT int JEMALLOC_NOTHROW je_mallctlnametomib(const char *name, 47 | size_t *mibp, size_t *miblenp); 48 | JEMALLOC_EXPORT int JEMALLOC_NOTHROW je_mallctlbymib(const size_t *mib, 49 | size_t miblen, void *oldp, size_t *oldlenp, void *newp, size_t newlen); 50 | JEMALLOC_EXPORT void JEMALLOC_NOTHROW je_malloc_stats_print( 51 | void (*write_cb)(void *, const char *), void *je_cbopaque, 52 | const char *opts); 53 | JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW je_malloc_usable_size( 54 | JEMALLOC_USABLE_SIZE_CONST void *ptr) JEMALLOC_CXX_THROW; 55 | 56 | #ifdef JEMALLOC_OVERRIDE_MEMALIGN 57 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 58 | void JEMALLOC_NOTHROW *je_memalign(size_t alignment, size_t size) 59 | JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc); 60 | #endif 61 | 62 | #ifdef JEMALLOC_OVERRIDE_VALLOC 63 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 64 | void JEMALLOC_NOTHROW *je_valloc(size_t size) JEMALLOC_CXX_THROW 65 | JEMALLOC_ATTR(malloc); 66 | #endif 67 | -------------------------------------------------------------------------------- /linux_includes/internal/include/jemalloc/jemalloc_protos.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The je_ prefix on the following public symbol declarations is an artifact 3 | * of namespace management, and should be omitted in application code unless 4 | * JEMALLOC_NO_DEMANGLE is defined (see jemalloc_mangle.h). 5 | */ 6 | extern JEMALLOC_EXPORT const char *je_malloc_conf; 7 | extern JEMALLOC_EXPORT void (*je_malloc_message)(void *cbopaque, 8 | const char *s); 9 | 10 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 11 | void JEMALLOC_NOTHROW *je_malloc(size_t size) 12 | JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE(1); 13 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 14 | void JEMALLOC_NOTHROW *je_calloc(size_t num, size_t size) 15 | JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE2(1, 2); 16 | JEMALLOC_EXPORT int JEMALLOC_NOTHROW je_posix_memalign(void **memptr, 17 | size_t alignment, size_t size) JEMALLOC_CXX_THROW JEMALLOC_ATTR(nonnull(1)); 18 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 19 | void JEMALLOC_NOTHROW *je_aligned_alloc(size_t alignment, 20 | size_t size) JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc) 21 | JEMALLOC_ALLOC_SIZE(2); 22 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 23 | void JEMALLOC_NOTHROW *je_realloc(void *ptr, size_t size) 24 | JEMALLOC_CXX_THROW JEMALLOC_ALLOC_SIZE(2); 25 | JEMALLOC_EXPORT void JEMALLOC_NOTHROW je_free(void *ptr) 26 | JEMALLOC_CXX_THROW; 27 | 28 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 29 | void JEMALLOC_NOTHROW *je_mallocx(size_t size, int flags) 30 | JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE(1); 31 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 32 | void JEMALLOC_NOTHROW *je_rallocx(void *ptr, size_t size, 33 | int flags) JEMALLOC_ALLOC_SIZE(2); 34 | JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW je_xallocx(void *ptr, size_t size, 35 | size_t extra, int flags); 36 | JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW je_sallocx(const void *ptr, 37 | int flags) JEMALLOC_ATTR(pure); 38 | JEMALLOC_EXPORT void JEMALLOC_NOTHROW je_dallocx(void *ptr, int flags); 39 | JEMALLOC_EXPORT void JEMALLOC_NOTHROW je_sdallocx(void *ptr, size_t size, 40 | int flags); 41 | JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW je_nallocx(size_t size, int flags) 42 | JEMALLOC_ATTR(pure); 43 | 44 | JEMALLOC_EXPORT int JEMALLOC_NOTHROW je_mallctl(const char *name, 45 | void *oldp, size_t *oldlenp, void *newp, size_t newlen); 46 | JEMALLOC_EXPORT int JEMALLOC_NOTHROW je_mallctlnametomib(const char *name, 47 | size_t *mibp, size_t *miblenp); 48 | JEMALLOC_EXPORT int JEMALLOC_NOTHROW je_mallctlbymib(const size_t *mib, 49 | size_t miblen, void *oldp, size_t *oldlenp, void *newp, size_t newlen); 50 | JEMALLOC_EXPORT void JEMALLOC_NOTHROW je_malloc_stats_print( 51 | void (*write_cb)(void *, const char *), void *je_cbopaque, 52 | const char *opts); 53 | JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW je_malloc_usable_size( 54 | JEMALLOC_USABLE_SIZE_CONST void *ptr) JEMALLOC_CXX_THROW; 55 | 56 | #ifdef JEMALLOC_OVERRIDE_MEMALIGN 57 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 58 | void JEMALLOC_NOTHROW *je_memalign(size_t alignment, size_t size) 59 | JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc); 60 | #endif 61 | 62 | #ifdef JEMALLOC_OVERRIDE_VALLOC 63 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 64 | void JEMALLOC_NOTHROW *je_valloc(size_t size) JEMALLOC_CXX_THROW 65 | JEMALLOC_ATTR(malloc); 66 | #endif 67 | -------------------------------------------------------------------------------- /linux_includes/internal/include/jemalloc/jemalloc_protos_jet.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The jet_ prefix on the following public symbol declarations is an artifact 3 | * of namespace management, and should be omitted in application code unless 4 | * JEMALLOC_NO_DEMANGLE is defined (see jemalloc_mangle@install_suffix@.h). 5 | */ 6 | extern JEMALLOC_EXPORT const char *jet_malloc_conf; 7 | extern JEMALLOC_EXPORT void (*jet_malloc_message)(void *cbopaque, 8 | const char *s); 9 | 10 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 11 | void JEMALLOC_NOTHROW *jet_malloc(size_t size) 12 | JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE(1); 13 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 14 | void JEMALLOC_NOTHROW *jet_calloc(size_t num, size_t size) 15 | JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE2(1, 2); 16 | JEMALLOC_EXPORT int JEMALLOC_NOTHROW jet_posix_memalign(void **memptr, 17 | size_t alignment, size_t size) JEMALLOC_CXX_THROW JEMALLOC_ATTR(nonnull(1)); 18 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 19 | void JEMALLOC_NOTHROW *jet_aligned_alloc(size_t alignment, 20 | size_t size) JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc) 21 | JEMALLOC_ALLOC_SIZE(2); 22 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 23 | void JEMALLOC_NOTHROW *jet_realloc(void *ptr, size_t size) 24 | JEMALLOC_CXX_THROW JEMALLOC_ALLOC_SIZE(2); 25 | JEMALLOC_EXPORT void JEMALLOC_NOTHROW jet_free(void *ptr) 26 | JEMALLOC_CXX_THROW; 27 | 28 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 29 | void JEMALLOC_NOTHROW *jet_mallocx(size_t size, int flags) 30 | JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE(1); 31 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 32 | void JEMALLOC_NOTHROW *jet_rallocx(void *ptr, size_t size, 33 | int flags) JEMALLOC_ALLOC_SIZE(2); 34 | JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW jet_xallocx(void *ptr, size_t size, 35 | size_t extra, int flags); 36 | JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW jet_sallocx(const void *ptr, 37 | int flags) JEMALLOC_ATTR(pure); 38 | JEMALLOC_EXPORT void JEMALLOC_NOTHROW jet_dallocx(void *ptr, int flags); 39 | JEMALLOC_EXPORT void JEMALLOC_NOTHROW jet_sdallocx(void *ptr, size_t size, 40 | int flags); 41 | JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW jet_nallocx(size_t size, int flags) 42 | JEMALLOC_ATTR(pure); 43 | 44 | JEMALLOC_EXPORT int JEMALLOC_NOTHROW jet_mallctl(const char *name, 45 | void *oldp, size_t *oldlenp, void *newp, size_t newlen); 46 | JEMALLOC_EXPORT int JEMALLOC_NOTHROW jet_mallctlnametomib(const char *name, 47 | size_t *mibp, size_t *miblenp); 48 | JEMALLOC_EXPORT int JEMALLOC_NOTHROW jet_mallctlbymib(const size_t *mib, 49 | size_t miblen, void *oldp, size_t *oldlenp, void *newp, size_t newlen); 50 | JEMALLOC_EXPORT void JEMALLOC_NOTHROW jet_malloc_stats_print( 51 | void (*write_cb)(void *, const char *), void *jet_cbopaque, 52 | const char *opts); 53 | JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW jet_malloc_usable_size( 54 | JEMALLOC_USABLE_SIZE_CONST void *ptr) JEMALLOC_CXX_THROW; 55 | 56 | #ifdef JEMALLOC_OVERRIDE_MEMALIGN 57 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 58 | void JEMALLOC_NOTHROW *jet_memalign(size_t alignment, size_t size) 59 | JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc); 60 | #endif 61 | 62 | #ifdef JEMALLOC_OVERRIDE_VALLOC 63 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 64 | void JEMALLOC_NOTHROW *jet_valloc(size_t size) JEMALLOC_CXX_THROW 65 | JEMALLOC_ATTR(malloc); 66 | #endif 67 | -------------------------------------------------------------------------------- /darwin_includes/internal/include/jemalloc/jemalloc_protos_jet.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The jet_ prefix on the following public symbol declarations is an artifact 3 | * of namespace management, and should be omitted in application code unless 4 | * JEMALLOC_NO_DEMANGLE is defined (see jemalloc_mangle@install_suffix@.h). 5 | */ 6 | extern JEMALLOC_EXPORT const char *jet_malloc_conf; 7 | extern JEMALLOC_EXPORT void (*jet_malloc_message)(void *cbopaque, 8 | const char *s); 9 | 10 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 11 | void JEMALLOC_NOTHROW *jet_malloc(size_t size) 12 | JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE(1); 13 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 14 | void JEMALLOC_NOTHROW *jet_calloc(size_t num, size_t size) 15 | JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE2(1, 2); 16 | JEMALLOC_EXPORT int JEMALLOC_NOTHROW jet_posix_memalign(void **memptr, 17 | size_t alignment, size_t size) JEMALLOC_CXX_THROW JEMALLOC_ATTR(nonnull(1)); 18 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 19 | void JEMALLOC_NOTHROW *jet_aligned_alloc(size_t alignment, 20 | size_t size) JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc) 21 | JEMALLOC_ALLOC_SIZE(2); 22 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 23 | void JEMALLOC_NOTHROW *jet_realloc(void *ptr, size_t size) 24 | JEMALLOC_CXX_THROW JEMALLOC_ALLOC_SIZE(2); 25 | JEMALLOC_EXPORT void JEMALLOC_NOTHROW jet_free(void *ptr) 26 | JEMALLOC_CXX_THROW; 27 | 28 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 29 | void JEMALLOC_NOTHROW *jet_mallocx(size_t size, int flags) 30 | JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE(1); 31 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 32 | void JEMALLOC_NOTHROW *jet_rallocx(void *ptr, size_t size, 33 | int flags) JEMALLOC_ALLOC_SIZE(2); 34 | JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW jet_xallocx(void *ptr, size_t size, 35 | size_t extra, int flags); 36 | JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW jet_sallocx(const void *ptr, 37 | int flags) JEMALLOC_ATTR(pure); 38 | JEMALLOC_EXPORT void JEMALLOC_NOTHROW jet_dallocx(void *ptr, int flags); 39 | JEMALLOC_EXPORT void JEMALLOC_NOTHROW jet_sdallocx(void *ptr, size_t size, 40 | int flags); 41 | JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW jet_nallocx(size_t size, int flags) 42 | JEMALLOC_ATTR(pure); 43 | 44 | JEMALLOC_EXPORT int JEMALLOC_NOTHROW jet_mallctl(const char *name, 45 | void *oldp, size_t *oldlenp, void *newp, size_t newlen); 46 | JEMALLOC_EXPORT int JEMALLOC_NOTHROW jet_mallctlnametomib(const char *name, 47 | size_t *mibp, size_t *miblenp); 48 | JEMALLOC_EXPORT int JEMALLOC_NOTHROW jet_mallctlbymib(const size_t *mib, 49 | size_t miblen, void *oldp, size_t *oldlenp, void *newp, size_t newlen); 50 | JEMALLOC_EXPORT void JEMALLOC_NOTHROW jet_malloc_stats_print( 51 | void (*write_cb)(void *, const char *), void *jet_cbopaque, 52 | const char *opts); 53 | JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW jet_malloc_usable_size( 54 | JEMALLOC_USABLE_SIZE_CONST void *ptr) JEMALLOC_CXX_THROW; 55 | 56 | #ifdef JEMALLOC_OVERRIDE_MEMALIGN 57 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 58 | void JEMALLOC_NOTHROW *jet_memalign(size_t alignment, size_t size) 59 | JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc); 60 | #endif 61 | 62 | #ifdef JEMALLOC_OVERRIDE_VALLOC 63 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 64 | void JEMALLOC_NOTHROW *jet_valloc(size_t size) JEMALLOC_CXX_THROW 65 | JEMALLOC_ATTR(malloc); 66 | #endif 67 | -------------------------------------------------------------------------------- /freebsd_includes/internal/include/jemalloc/jemalloc_protos_jet.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The jet_ prefix on the following public symbol declarations is an artifact 3 | * of namespace management, and should be omitted in application code unless 4 | * JEMALLOC_NO_DEMANGLE is defined (see jemalloc_mangle@install_suffix@.h). 5 | */ 6 | extern JEMALLOC_EXPORT const char *jet_malloc_conf; 7 | extern JEMALLOC_EXPORT void (*jet_malloc_message)(void *cbopaque, 8 | const char *s); 9 | 10 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 11 | void JEMALLOC_NOTHROW *jet_malloc(size_t size) 12 | JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE(1); 13 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 14 | void JEMALLOC_NOTHROW *jet_calloc(size_t num, size_t size) 15 | JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE2(1, 2); 16 | JEMALLOC_EXPORT int JEMALLOC_NOTHROW jet_posix_memalign(void **memptr, 17 | size_t alignment, size_t size) JEMALLOC_CXX_THROW JEMALLOC_ATTR(nonnull(1)); 18 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 19 | void JEMALLOC_NOTHROW *jet_aligned_alloc(size_t alignment, 20 | size_t size) JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc) 21 | JEMALLOC_ALLOC_SIZE(2); 22 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 23 | void JEMALLOC_NOTHROW *jet_realloc(void *ptr, size_t size) 24 | JEMALLOC_CXX_THROW JEMALLOC_ALLOC_SIZE(2); 25 | JEMALLOC_EXPORT void JEMALLOC_NOTHROW jet_free(void *ptr) 26 | JEMALLOC_CXX_THROW; 27 | 28 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 29 | void JEMALLOC_NOTHROW *jet_mallocx(size_t size, int flags) 30 | JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE(1); 31 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 32 | void JEMALLOC_NOTHROW *jet_rallocx(void *ptr, size_t size, 33 | int flags) JEMALLOC_ALLOC_SIZE(2); 34 | JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW jet_xallocx(void *ptr, size_t size, 35 | size_t extra, int flags); 36 | JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW jet_sallocx(const void *ptr, 37 | int flags) JEMALLOC_ATTR(pure); 38 | JEMALLOC_EXPORT void JEMALLOC_NOTHROW jet_dallocx(void *ptr, int flags); 39 | JEMALLOC_EXPORT void JEMALLOC_NOTHROW jet_sdallocx(void *ptr, size_t size, 40 | int flags); 41 | JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW jet_nallocx(size_t size, int flags) 42 | JEMALLOC_ATTR(pure); 43 | 44 | JEMALLOC_EXPORT int JEMALLOC_NOTHROW jet_mallctl(const char *name, 45 | void *oldp, size_t *oldlenp, void *newp, size_t newlen); 46 | JEMALLOC_EXPORT int JEMALLOC_NOTHROW jet_mallctlnametomib(const char *name, 47 | size_t *mibp, size_t *miblenp); 48 | JEMALLOC_EXPORT int JEMALLOC_NOTHROW jet_mallctlbymib(const size_t *mib, 49 | size_t miblen, void *oldp, size_t *oldlenp, void *newp, size_t newlen); 50 | JEMALLOC_EXPORT void JEMALLOC_NOTHROW jet_malloc_stats_print( 51 | void (*write_cb)(void *, const char *), void *jet_cbopaque, 52 | const char *opts); 53 | JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW jet_malloc_usable_size( 54 | JEMALLOC_USABLE_SIZE_CONST void *ptr) JEMALLOC_CXX_THROW; 55 | 56 | #ifdef JEMALLOC_OVERRIDE_MEMALIGN 57 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 58 | void JEMALLOC_NOTHROW *jet_memalign(size_t alignment, size_t size) 59 | JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc); 60 | #endif 61 | 62 | #ifdef JEMALLOC_OVERRIDE_VALLOC 63 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 64 | void JEMALLOC_NOTHROW *jet_valloc(size_t size) JEMALLOC_CXX_THROW 65 | JEMALLOC_ATTR(malloc); 66 | #endif 67 | -------------------------------------------------------------------------------- /internal/include/jemalloc/jemalloc_protos.h.in: -------------------------------------------------------------------------------- 1 | /* 2 | * The @je_@ prefix on the following public symbol declarations is an artifact 3 | * of namespace management, and should be omitted in application code unless 4 | * JEMALLOC_NO_DEMANGLE is defined (see jemalloc_mangle@install_suffix@.h). 5 | */ 6 | extern JEMALLOC_EXPORT const char *@je_@malloc_conf; 7 | extern JEMALLOC_EXPORT void (*@je_@malloc_message)(void *cbopaque, 8 | const char *s); 9 | 10 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 11 | void JEMALLOC_NOTHROW *@je_@malloc(size_t size) 12 | JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE(1); 13 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 14 | void JEMALLOC_NOTHROW *@je_@calloc(size_t num, size_t size) 15 | JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE2(1, 2); 16 | JEMALLOC_EXPORT int JEMALLOC_NOTHROW @je_@posix_memalign(void **memptr, 17 | size_t alignment, size_t size) JEMALLOC_CXX_THROW JEMALLOC_ATTR(nonnull(1)); 18 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 19 | void JEMALLOC_NOTHROW *@je_@aligned_alloc(size_t alignment, 20 | size_t size) JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc) 21 | JEMALLOC_ALLOC_SIZE(2); 22 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 23 | void JEMALLOC_NOTHROW *@je_@realloc(void *ptr, size_t size) 24 | JEMALLOC_CXX_THROW JEMALLOC_ALLOC_SIZE(2); 25 | JEMALLOC_EXPORT void JEMALLOC_NOTHROW @je_@free(void *ptr) 26 | JEMALLOC_CXX_THROW; 27 | 28 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 29 | void JEMALLOC_NOTHROW *@je_@mallocx(size_t size, int flags) 30 | JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE(1); 31 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 32 | void JEMALLOC_NOTHROW *@je_@rallocx(void *ptr, size_t size, 33 | int flags) JEMALLOC_ALLOC_SIZE(2); 34 | JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW @je_@xallocx(void *ptr, size_t size, 35 | size_t extra, int flags); 36 | JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW @je_@sallocx(const void *ptr, 37 | int flags) JEMALLOC_ATTR(pure); 38 | JEMALLOC_EXPORT void JEMALLOC_NOTHROW @je_@dallocx(void *ptr, int flags); 39 | JEMALLOC_EXPORT void JEMALLOC_NOTHROW @je_@sdallocx(void *ptr, size_t size, 40 | int flags); 41 | JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW @je_@nallocx(size_t size, int flags) 42 | JEMALLOC_ATTR(pure); 43 | 44 | JEMALLOC_EXPORT int JEMALLOC_NOTHROW @je_@mallctl(const char *name, 45 | void *oldp, size_t *oldlenp, void *newp, size_t newlen); 46 | JEMALLOC_EXPORT int JEMALLOC_NOTHROW @je_@mallctlnametomib(const char *name, 47 | size_t *mibp, size_t *miblenp); 48 | JEMALLOC_EXPORT int JEMALLOC_NOTHROW @je_@mallctlbymib(const size_t *mib, 49 | size_t miblen, void *oldp, size_t *oldlenp, void *newp, size_t newlen); 50 | JEMALLOC_EXPORT void JEMALLOC_NOTHROW @je_@malloc_stats_print( 51 | void (*write_cb)(void *, const char *), void *@je_@cbopaque, 52 | const char *opts); 53 | JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW @je_@malloc_usable_size( 54 | JEMALLOC_USABLE_SIZE_CONST void *ptr) JEMALLOC_CXX_THROW; 55 | 56 | #ifdef JEMALLOC_OVERRIDE_MEMALIGN 57 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 58 | void JEMALLOC_NOTHROW *@je_@memalign(size_t alignment, size_t size) 59 | JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc); 60 | #endif 61 | 62 | #ifdef JEMALLOC_OVERRIDE_VALLOC 63 | JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN 64 | void JEMALLOC_NOTHROW *@je_@valloc(size_t size) JEMALLOC_CXX_THROW 65 | JEMALLOC_ATTR(malloc); 66 | #endif 67 | -------------------------------------------------------------------------------- /internal/msvc/projects/vc2015/test_threads/test_threads.cpp: -------------------------------------------------------------------------------- 1 | // jemalloc C++ threaded test 2 | // Author: Rustam Abdullaev 3 | // Public Domain 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | using std::vector; 15 | using std::thread; 16 | using std::uniform_int_distribution; 17 | using std::minstd_rand; 18 | 19 | int test_threads() 20 | { 21 | je_malloc_conf = "narenas:3"; 22 | int narenas = 0; 23 | size_t sz = sizeof(narenas); 24 | je_mallctl("opt.narenas", (void *)&narenas, &sz, NULL, 0); 25 | if (narenas != 3) { 26 | printf("Error: unexpected number of arenas: %d\n", narenas); 27 | return 1; 28 | } 29 | static const int sizes[] = { 7, 16, 32, 60, 91, 100, 120, 144, 169, 199, 255, 400, 670, 900, 917, 1025, 3333, 5190, 13131, 49192, 99999, 123123, 255265, 2333111 }; 30 | static const int numSizes = (int)(sizeof(sizes) / sizeof(sizes[0])); 31 | vector workers; 32 | static const int numThreads = narenas + 1, numAllocsMax = 25, numIter1 = 50, numIter2 = 50; 33 | je_malloc_stats_print(NULL, NULL, NULL); 34 | size_t allocated1; 35 | size_t sz1 = sizeof(allocated1); 36 | je_mallctl("stats.active", (void *)&allocated1, &sz1, NULL, 0); 37 | printf("\nPress Enter to start threads...\n"); 38 | getchar(); 39 | printf("Starting %d threads x %d x %d iterations...\n", numThreads, numIter1, numIter2); 40 | for (int i = 0; i < numThreads; i++) { 41 | workers.emplace_back([tid=i]() { 42 | uniform_int_distribution sizeDist(0, numSizes - 1); 43 | minstd_rand rnd(tid * 17); 44 | uint8_t* ptrs[numAllocsMax]; 45 | int ptrsz[numAllocsMax]; 46 | for (int i = 0; i < numIter1; ++i) { 47 | thread t([&]() { 48 | for (int i = 0; i < numIter2; ++i) { 49 | const int numAllocs = numAllocsMax - sizeDist(rnd); 50 | for (int j = 0; j < numAllocs; j += 64) { 51 | const int x = sizeDist(rnd); 52 | const int sz = sizes[x]; 53 | ptrsz[j] = sz; 54 | ptrs[j] = (uint8_t*)je_malloc(sz); 55 | if (!ptrs[j]) { 56 | printf("Unable to allocate %d bytes in thread %d, iter %d, alloc %d. %d\n", sz, tid, i, j, x); 57 | exit(1); 58 | } 59 | for (int k = 0; k < sz; k++) 60 | ptrs[j][k] = tid + k; 61 | } 62 | for (int j = 0; j < numAllocs; j += 64) { 63 | for (int k = 0, sz = ptrsz[j]; k < sz; k++) 64 | if (ptrs[j][k] != (uint8_t)(tid + k)) { 65 | printf("Memory error in thread %d, iter %d, alloc %d @ %d : %02X!=%02X\n", tid, i, j, k, ptrs[j][k], (uint8_t)(tid + k)); 66 | exit(1); 67 | } 68 | je_free(ptrs[j]); 69 | } 70 | } 71 | }); 72 | t.join(); 73 | } 74 | }); 75 | } 76 | for (thread& t : workers) { 77 | t.join(); 78 | } 79 | je_malloc_stats_print(NULL, NULL, NULL); 80 | size_t allocated2; 81 | je_mallctl("stats.active", (void *)&allocated2, &sz1, NULL, 0); 82 | size_t leaked = allocated2 - allocated1; 83 | printf("\nDone. Leaked: %zd bytes\n", leaked); 84 | bool failed = leaked > 65536; // in case C++ runtime allocated something (e.g. iostream locale or facet) 85 | printf("\nTest %s!\n", (failed ? "FAILED" : "successful")); 86 | printf("\nPress Enter to continue...\n"); 87 | getchar(); 88 | return failed ? 1 : 0; 89 | } 90 | -------------------------------------------------------------------------------- /internal/include/jemalloc/internal/chunk.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | #ifdef JEMALLOC_H_TYPES 3 | 4 | /* 5 | * Size and alignment of memory chunks that are allocated by the OS's virtual 6 | * memory system. 7 | */ 8 | #define LG_CHUNK_DEFAULT 21 9 | 10 | /* Return the chunk address for allocation address a. */ 11 | #define CHUNK_ADDR2BASE(a) \ 12 | ((void *)((uintptr_t)(a) & ~chunksize_mask)) 13 | 14 | /* Return the chunk offset of address a. */ 15 | #define CHUNK_ADDR2OFFSET(a) \ 16 | ((size_t)((uintptr_t)(a) & chunksize_mask)) 17 | 18 | /* Return the smallest chunk multiple that is >= s. */ 19 | #define CHUNK_CEILING(s) \ 20 | (((s) + chunksize_mask) & ~chunksize_mask) 21 | 22 | #define CHUNK_HOOKS_INITIALIZER { \ 23 | NULL, \ 24 | NULL, \ 25 | NULL, \ 26 | NULL, \ 27 | NULL, \ 28 | NULL, \ 29 | NULL \ 30 | } 31 | 32 | #endif /* JEMALLOC_H_TYPES */ 33 | /******************************************************************************/ 34 | #ifdef JEMALLOC_H_STRUCTS 35 | 36 | #endif /* JEMALLOC_H_STRUCTS */ 37 | /******************************************************************************/ 38 | #ifdef JEMALLOC_H_EXTERNS 39 | 40 | extern size_t opt_lg_chunk; 41 | extern const char *opt_dss; 42 | 43 | extern rtree_t chunks_rtree; 44 | 45 | extern size_t chunksize; 46 | extern size_t chunksize_mask; /* (chunksize - 1). */ 47 | extern size_t chunk_npages; 48 | 49 | extern const chunk_hooks_t chunk_hooks_default; 50 | 51 | chunk_hooks_t chunk_hooks_get(tsdn_t *tsdn, arena_t *arena); 52 | chunk_hooks_t chunk_hooks_set(tsdn_t *tsdn, arena_t *arena, 53 | const chunk_hooks_t *chunk_hooks); 54 | 55 | bool chunk_register(const void *chunk, const extent_node_t *node, 56 | bool *gdump); 57 | void chunk_deregister(const void *chunk, const extent_node_t *node); 58 | void *chunk_alloc_base(size_t size); 59 | void *chunk_alloc_cache(tsdn_t *tsdn, arena_t *arena, 60 | chunk_hooks_t *chunk_hooks, void *new_addr, size_t size, size_t alignment, 61 | size_t *sn, bool *zero, bool *commit, bool dalloc_node); 62 | void *chunk_alloc_wrapper(tsdn_t *tsdn, arena_t *arena, 63 | chunk_hooks_t *chunk_hooks, void *new_addr, size_t size, size_t alignment, 64 | size_t *sn, bool *zero, bool *commit); 65 | void chunk_dalloc_cache(tsdn_t *tsdn, arena_t *arena, 66 | chunk_hooks_t *chunk_hooks, void *chunk, size_t size, size_t sn, 67 | bool committed); 68 | void chunk_dalloc_wrapper(tsdn_t *tsdn, arena_t *arena, 69 | chunk_hooks_t *chunk_hooks, void *chunk, size_t size, size_t sn, 70 | bool zeroed, bool committed); 71 | bool chunk_purge_wrapper(tsdn_t *tsdn, arena_t *arena, 72 | chunk_hooks_t *chunk_hooks, void *chunk, size_t size, size_t offset, 73 | size_t length); 74 | bool chunk_boot(void); 75 | 76 | #endif /* JEMALLOC_H_EXTERNS */ 77 | /******************************************************************************/ 78 | #ifdef JEMALLOC_H_INLINES 79 | 80 | #ifndef JEMALLOC_ENABLE_INLINE 81 | extent_node_t *chunk_lookup(const void *chunk, bool dependent); 82 | #endif 83 | 84 | #if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_CHUNK_C_)) 85 | JEMALLOC_INLINE extent_node_t * 86 | chunk_lookup(const void *ptr, bool dependent) 87 | { 88 | 89 | return (rtree_get(&chunks_rtree, (uintptr_t)ptr, dependent)); 90 | } 91 | #endif 92 | 93 | #endif /* JEMALLOC_H_INLINES */ 94 | /******************************************************************************/ 95 | 96 | #include "jemalloc/internal/chunk_dss.h" 97 | #include "jemalloc/internal/chunk_mmap.h" 98 | -------------------------------------------------------------------------------- /internal/test/integration/posix_memalign.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | #define CHUNK 0x400000 4 | #define MAXALIGN (((size_t)1) << 23) 5 | 6 | /* 7 | * On systems which can't merge extents, tests that call this function generate 8 | * a lot of dirty memory very quickly. Purging between cycles mitigates 9 | * potential OOM on e.g. 32-bit Windows. 10 | */ 11 | static void 12 | purge(void) 13 | { 14 | 15 | assert_d_eq(mallctl("arena.0.purge", NULL, NULL, NULL, 0), 0, 16 | "Unexpected mallctl error"); 17 | } 18 | 19 | TEST_BEGIN(test_alignment_errors) 20 | { 21 | size_t alignment; 22 | void *p; 23 | 24 | for (alignment = 0; alignment < sizeof(void *); alignment++) { 25 | assert_d_eq(posix_memalign(&p, alignment, 1), EINVAL, 26 | "Expected error for invalid alignment %zu", 27 | alignment); 28 | } 29 | 30 | for (alignment = sizeof(size_t); alignment < MAXALIGN; 31 | alignment <<= 1) { 32 | assert_d_ne(posix_memalign(&p, alignment + 1, 1), 0, 33 | "Expected error for invalid alignment %zu", 34 | alignment + 1); 35 | } 36 | } 37 | TEST_END 38 | 39 | TEST_BEGIN(test_oom_errors) 40 | { 41 | size_t alignment, size; 42 | void *p; 43 | 44 | #if LG_SIZEOF_PTR == 3 45 | alignment = UINT64_C(0x8000000000000000); 46 | size = UINT64_C(0x8000000000000000); 47 | #else 48 | alignment = 0x80000000LU; 49 | size = 0x80000000LU; 50 | #endif 51 | assert_d_ne(posix_memalign(&p, alignment, size), 0, 52 | "Expected error for posix_memalign(&p, %zu, %zu)", 53 | alignment, size); 54 | 55 | #if LG_SIZEOF_PTR == 3 56 | alignment = UINT64_C(0x4000000000000000); 57 | size = UINT64_C(0xc000000000000001); 58 | #else 59 | alignment = 0x40000000LU; 60 | size = 0xc0000001LU; 61 | #endif 62 | assert_d_ne(posix_memalign(&p, alignment, size), 0, 63 | "Expected error for posix_memalign(&p, %zu, %zu)", 64 | alignment, size); 65 | 66 | alignment = 0x10LU; 67 | #if LG_SIZEOF_PTR == 3 68 | size = UINT64_C(0xfffffffffffffff0); 69 | #else 70 | size = 0xfffffff0LU; 71 | #endif 72 | assert_d_ne(posix_memalign(&p, alignment, size), 0, 73 | "Expected error for posix_memalign(&p, %zu, %zu)", 74 | alignment, size); 75 | } 76 | TEST_END 77 | 78 | TEST_BEGIN(test_alignment_and_size) 79 | { 80 | #define NITER 4 81 | size_t alignment, size, total; 82 | unsigned i; 83 | int err; 84 | void *ps[NITER]; 85 | 86 | for (i = 0; i < NITER; i++) 87 | ps[i] = NULL; 88 | 89 | for (alignment = 8; 90 | alignment <= MAXALIGN; 91 | alignment <<= 1) { 92 | total = 0; 93 | for (size = 1; 94 | size < 3 * alignment && size < (1U << 31); 95 | size += (alignment >> (LG_SIZEOF_PTR-1)) - 1) { 96 | for (i = 0; i < NITER; i++) { 97 | err = posix_memalign(&ps[i], 98 | alignment, size); 99 | if (err) { 100 | char buf[BUFERROR_BUF]; 101 | 102 | buferror(get_errno(), buf, sizeof(buf)); 103 | test_fail( 104 | "Error for alignment=%zu, " 105 | "size=%zu (%#zx): %s", 106 | alignment, size, size, buf); 107 | } 108 | total += malloc_usable_size(ps[i]); 109 | if (total >= (MAXALIGN << 1)) 110 | break; 111 | } 112 | for (i = 0; i < NITER; i++) { 113 | if (ps[i] != NULL) { 114 | free(ps[i]); 115 | ps[i] = NULL; 116 | } 117 | } 118 | } 119 | purge(); 120 | } 121 | #undef NITER 122 | } 123 | TEST_END 124 | 125 | int 126 | main(void) 127 | { 128 | 129 | return (test( 130 | test_alignment_errors, 131 | test_oom_errors, 132 | test_alignment_and_size)); 133 | } 134 | -------------------------------------------------------------------------------- /internal/test/unit/atomic.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | #define TEST_STRUCT(p, t) \ 4 | struct p##_test_s { \ 5 | t accum0; \ 6 | t x; \ 7 | t s; \ 8 | }; \ 9 | typedef struct p##_test_s p##_test_t; 10 | 11 | #define TEST_BODY(p, t, tc, ta, FMT) do { \ 12 | const p##_test_t tests[] = { \ 13 | {(t)-1, (t)-1, (t)-2}, \ 14 | {(t)-1, (t) 0, (t)-2}, \ 15 | {(t)-1, (t) 1, (t)-2}, \ 16 | \ 17 | {(t) 0, (t)-1, (t)-2}, \ 18 | {(t) 0, (t) 0, (t)-2}, \ 19 | {(t) 0, (t) 1, (t)-2}, \ 20 | \ 21 | {(t) 1, (t)-1, (t)-2}, \ 22 | {(t) 1, (t) 0, (t)-2}, \ 23 | {(t) 1, (t) 1, (t)-2}, \ 24 | \ 25 | {(t)0, (t)-(1 << 22), (t)-2}, \ 26 | {(t)0, (t)(1 << 22), (t)-2}, \ 27 | {(t)(1 << 22), (t)-(1 << 22), (t)-2}, \ 28 | {(t)(1 << 22), (t)(1 << 22), (t)-2} \ 29 | }; \ 30 | unsigned i; \ 31 | \ 32 | for (i = 0; i < sizeof(tests)/sizeof(p##_test_t); i++) { \ 33 | bool err; \ 34 | t accum = tests[i].accum0; \ 35 | assert_##ta##_eq(atomic_read_##p(&accum), \ 36 | tests[i].accum0, \ 37 | "Erroneous read, i=%u", i); \ 38 | \ 39 | assert_##ta##_eq(atomic_add_##p(&accum, tests[i].x), \ 40 | (t)((tc)tests[i].accum0 + (tc)tests[i].x), \ 41 | "i=%u, accum=%"FMT", x=%"FMT, \ 42 | i, tests[i].accum0, tests[i].x); \ 43 | assert_##ta##_eq(atomic_read_##p(&accum), accum, \ 44 | "Erroneous add, i=%u", i); \ 45 | \ 46 | accum = tests[i].accum0; \ 47 | assert_##ta##_eq(atomic_sub_##p(&accum, tests[i].x), \ 48 | (t)((tc)tests[i].accum0 - (tc)tests[i].x), \ 49 | "i=%u, accum=%"FMT", x=%"FMT, \ 50 | i, tests[i].accum0, tests[i].x); \ 51 | assert_##ta##_eq(atomic_read_##p(&accum), accum, \ 52 | "Erroneous sub, i=%u", i); \ 53 | \ 54 | accum = tests[i].accum0; \ 55 | err = atomic_cas_##p(&accum, tests[i].x, tests[i].s); \ 56 | assert_b_eq(err, tests[i].accum0 != tests[i].x, \ 57 | "Erroneous cas success/failure result"); \ 58 | assert_##ta##_eq(accum, err ? tests[i].accum0 : \ 59 | tests[i].s, "Erroneous cas effect, i=%u", i); \ 60 | \ 61 | accum = tests[i].accum0; \ 62 | atomic_write_##p(&accum, tests[i].s); \ 63 | assert_##ta##_eq(accum, tests[i].s, \ 64 | "Erroneous write, i=%u", i); \ 65 | } \ 66 | } while (0) 67 | 68 | TEST_STRUCT(uint64, uint64_t) 69 | TEST_BEGIN(test_atomic_uint64) 70 | { 71 | 72 | #if !(LG_SIZEOF_PTR == 3 || LG_SIZEOF_INT == 3) 73 | test_skip("64-bit atomic operations not supported"); 74 | #else 75 | TEST_BODY(uint64, uint64_t, uint64_t, u64, FMTx64); 76 | #endif 77 | } 78 | TEST_END 79 | 80 | TEST_STRUCT(uint32, uint32_t) 81 | TEST_BEGIN(test_atomic_uint32) 82 | { 83 | 84 | TEST_BODY(uint32, uint32_t, uint32_t, u32, "#"FMTx32); 85 | } 86 | TEST_END 87 | 88 | TEST_STRUCT(p, void *) 89 | TEST_BEGIN(test_atomic_p) 90 | { 91 | 92 | TEST_BODY(p, void *, uintptr_t, ptr, "p"); 93 | } 94 | TEST_END 95 | 96 | TEST_STRUCT(z, size_t) 97 | TEST_BEGIN(test_atomic_z) 98 | { 99 | 100 | TEST_BODY(z, size_t, size_t, zu, "#zx"); 101 | } 102 | TEST_END 103 | 104 | TEST_STRUCT(u, unsigned) 105 | TEST_BEGIN(test_atomic_u) 106 | { 107 | 108 | TEST_BODY(u, unsigned, unsigned, u, "#x"); 109 | } 110 | TEST_END 111 | 112 | int 113 | main(void) 114 | { 115 | 116 | return (test( 117 | test_atomic_uint64, 118 | test_atomic_uint32, 119 | test_atomic_p, 120 | test_atomic_z, 121 | test_atomic_u)); 122 | } 123 | -------------------------------------------------------------------------------- /internal/test/integration/allocated.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | static const bool config_stats = 4 | #ifdef JEMALLOC_STATS 5 | true 6 | #else 7 | false 8 | #endif 9 | ; 10 | 11 | void * 12 | thd_start(void *arg) 13 | { 14 | int err; 15 | void *p; 16 | uint64_t a0, a1, d0, d1; 17 | uint64_t *ap0, *ap1, *dp0, *dp1; 18 | size_t sz, usize; 19 | 20 | sz = sizeof(a0); 21 | if ((err = mallctl("thread.allocated", (void *)&a0, &sz, NULL, 0))) { 22 | if (err == ENOENT) 23 | goto label_ENOENT; 24 | test_fail("%s(): Error in mallctl(): %s", __func__, 25 | strerror(err)); 26 | } 27 | sz = sizeof(ap0); 28 | if ((err = mallctl("thread.allocatedp", (void *)&ap0, &sz, NULL, 0))) { 29 | if (err == ENOENT) 30 | goto label_ENOENT; 31 | test_fail("%s(): Error in mallctl(): %s", __func__, 32 | strerror(err)); 33 | } 34 | assert_u64_eq(*ap0, a0, 35 | "\"thread.allocatedp\" should provide a pointer to internal " 36 | "storage"); 37 | 38 | sz = sizeof(d0); 39 | if ((err = mallctl("thread.deallocated", (void *)&d0, &sz, NULL, 0))) { 40 | if (err == ENOENT) 41 | goto label_ENOENT; 42 | test_fail("%s(): Error in mallctl(): %s", __func__, 43 | strerror(err)); 44 | } 45 | sz = sizeof(dp0); 46 | if ((err = mallctl("thread.deallocatedp", (void *)&dp0, &sz, NULL, 47 | 0))) { 48 | if (err == ENOENT) 49 | goto label_ENOENT; 50 | test_fail("%s(): Error in mallctl(): %s", __func__, 51 | strerror(err)); 52 | } 53 | assert_u64_eq(*dp0, d0, 54 | "\"thread.deallocatedp\" should provide a pointer to internal " 55 | "storage"); 56 | 57 | p = malloc(1); 58 | assert_ptr_not_null(p, "Unexpected malloc() error"); 59 | 60 | sz = sizeof(a1); 61 | mallctl("thread.allocated", (void *)&a1, &sz, NULL, 0); 62 | sz = sizeof(ap1); 63 | mallctl("thread.allocatedp", (void *)&ap1, &sz, NULL, 0); 64 | assert_u64_eq(*ap1, a1, 65 | "Dereferenced \"thread.allocatedp\" value should equal " 66 | "\"thread.allocated\" value"); 67 | assert_ptr_eq(ap0, ap1, 68 | "Pointer returned by \"thread.allocatedp\" should not change"); 69 | 70 | usize = malloc_usable_size(p); 71 | assert_u64_le(a0 + usize, a1, 72 | "Allocated memory counter should increase by at least the amount " 73 | "explicitly allocated"); 74 | 75 | free(p); 76 | 77 | sz = sizeof(d1); 78 | mallctl("thread.deallocated", (void *)&d1, &sz, NULL, 0); 79 | sz = sizeof(dp1); 80 | mallctl("thread.deallocatedp", (void *)&dp1, &sz, NULL, 0); 81 | assert_u64_eq(*dp1, d1, 82 | "Dereferenced \"thread.deallocatedp\" value should equal " 83 | "\"thread.deallocated\" value"); 84 | assert_ptr_eq(dp0, dp1, 85 | "Pointer returned by \"thread.deallocatedp\" should not change"); 86 | 87 | assert_u64_le(d0 + usize, d1, 88 | "Deallocated memory counter should increase by at least the amount " 89 | "explicitly deallocated"); 90 | 91 | return (NULL); 92 | label_ENOENT: 93 | assert_false(config_stats, 94 | "ENOENT should only be returned if stats are disabled"); 95 | test_skip("\"thread.allocated\" mallctl not available"); 96 | return (NULL); 97 | } 98 | 99 | TEST_BEGIN(test_main_thread) 100 | { 101 | 102 | thd_start(NULL); 103 | } 104 | TEST_END 105 | 106 | TEST_BEGIN(test_subthread) 107 | { 108 | thd_t thd; 109 | 110 | thd_create(&thd, thd_start, NULL); 111 | thd_join(thd, NULL); 112 | } 113 | TEST_END 114 | 115 | int 116 | main(void) 117 | { 118 | 119 | /* Run tests multiple times to check for bad interactions. */ 120 | return (test( 121 | test_main_thread, 122 | test_subthread, 123 | test_main_thread, 124 | test_subthread, 125 | test_main_thread)); 126 | } 127 | --------------------------------------------------------------------------------