From 4b63c6ba6bb78f0709779daf8b71339a97724fc5 Mon Sep 17 00:00:00 2001 From: wf9a5m75 Date: Tue, 13 Feb 2018 16:23:39 -0800 Subject: [PATCH] redis-android v1.0.4 (redis 4.0.8) --- CHANGELOGS.md | 6 + README.md | 50 +- redis-android/build.gradle | 2 +- .../java/io/wf9a5m75/redis/RedisAndroid.java | 2 +- redis-android/src/main/jni/Application.mk | 3 +- .../src/main/jni/redis-4.0.6/src/version.h | 1 - .../{redis-4.0.6 => redis-4.0.8}/.gitignore | 0 .../00-RELEASENOTES | 249 + .../{redis-4.0.6 => redis-4.0.8}/Android.mk | 57 +- .../jni/{redis-4.0.6 => redis-4.0.8}/BUGS | 0 .../{redis-4.0.6 => redis-4.0.8}/CONTRIBUTING | 0 .../jni/{redis-4.0.6 => redis-4.0.8}/COPYING | 0 .../jni/{redis-4.0.6 => redis-4.0.8}/INSTALL | 0 .../{redis-4.0.6 => redis-4.0.8}/MANIFESTO | 0 .../jni/{redis-4.0.6 => redis-4.0.8}/Makefile | 0 .../{redis-4.0.6 => redis-4.0.8}/README.md | 0 .../main/jni/redis-4.0.8/android-elf-cleaner | Bin 0 -> 13500 bytes .../deps/Android.mk | 0 .../deps/Makefile | 0 .../deps/README.md | 0 .../deps/hiredis/.gitignore | 0 .../deps/hiredis/.travis.yml | 0 .../deps/hiredis/Android.mk | 0 .../deps/hiredis/CHANGELOG.md | 0 .../deps/hiredis/COPYING | 0 .../deps/hiredis/Makefile | 0 .../deps/hiredis/README.md | 0 .../deps/hiredis/adapters/ae.h | 0 .../deps/hiredis/adapters/glib.h | 0 .../deps/hiredis/adapters/ivykis.h | 0 .../deps/hiredis/adapters/libev.h | 0 .../deps/hiredis/adapters/libevent.h | 0 .../deps/hiredis/adapters/libuv.h | 0 .../deps/hiredis/adapters/macosx.h | 0 .../deps/hiredis/adapters/qt.h | 0 .../deps/hiredis/appveyor.yml | 0 .../deps/hiredis/async.c | 0 .../deps/hiredis/async.h | 0 .../deps/hiredis/dict.c | 0 .../deps/hiredis/dict.h | 0 .../deps/hiredis/examples/example-ae.c | 0 .../deps/hiredis/examples/example-glib.c | 0 .../deps/hiredis/examples/example-ivykis.c | 0 .../deps/hiredis/examples/example-libev.c | 0 .../deps/hiredis/examples/example-libevent.c | 0 .../deps/hiredis/examples/example-libuv.c | 0 .../deps/hiredis/examples/example-macosx.c | 0 .../deps/hiredis/examples/example-qt.cpp | 0 .../deps/hiredis/examples/example-qt.h | 0 .../deps/hiredis/examples/example.c | 0 .../deps/hiredis/fmacros.h | 0 .../deps/hiredis/hiredis.c | 0 .../deps/hiredis/hiredis.h | 0 .../deps/hiredis/net.c | 0 .../deps/hiredis/net.h | 0 .../deps/hiredis/read.c | 0 .../deps/hiredis/read.h | 0 .../deps/hiredis/sds.c | 0 .../deps/hiredis/sds.h | 0 .../deps/hiredis/sdsalloc.h | 0 .../deps/hiredis/test.c | 0 .../deps/hiredis/win32.h | 0 .../redis-4.0.8/deps/jemalloc/.autom4te.cfg | 3 + .../redis-4.0.8/deps/jemalloc/.gitattributes | 1 + .../jni/redis-4.0.8/deps/jemalloc/.gitignore | 75 + .../jni/redis-4.0.8/deps/jemalloc/COPYING | 27 + .../jni/redis-4.0.8/deps/jemalloc/ChangeLog | 788 +++ .../jni/redis-4.0.8/deps/jemalloc/INSTALL | 402 ++ .../jni/redis-4.0.8/deps/jemalloc/Makefile.in | 458 ++ .../main/jni/redis-4.0.8/deps/jemalloc/README | 20 + .../jni/redis-4.0.8/deps/jemalloc/autogen.sh | 17 + .../deps/jemalloc/bin/jemalloc-config.in | 79 + .../deps/jemalloc/bin/jemalloc.sh.in | 9 + .../redis-4.0.8/deps/jemalloc/bin/jeprof.in | 5510 +++++++++++++++++ .../redis-4.0.8/deps/jemalloc/config.guess | 1420 +++++ .../deps/jemalloc/config.stamp.in} | 0 .../jni/redis-4.0.8/deps/jemalloc/config.sub | 1797 ++++++ .../redis-4.0.8/deps/jemalloc/configure.ac | 1745 ++++++ .../jni/redis-4.0.8/deps/jemalloc/coverage.sh | 16 + .../redis-4.0.8/deps/jemalloc/doc/html.xsl.in | 4 + .../deps/jemalloc/doc/jemalloc.xml.in | 2762 +++++++++ .../deps/jemalloc/doc/manpages.xsl.in | 4 + .../deps/jemalloc/doc/stylesheet.xsl | 7 + .../include/jemalloc/internal/arena.h | 1347 ++++ .../include/jemalloc/internal/atomic.h | 651 ++ .../jemalloc/include/jemalloc/internal/base.h | 24 + .../include/jemalloc/internal/bitmap.h | 230 + .../include/jemalloc/internal/chunk.h | 99 + .../include/jemalloc/internal/chunk_dss.h | 39 + .../include/jemalloc/internal/chunk_mmap.h | 21 + .../jemalloc/include/jemalloc/internal/ckh.h | 88 + .../jemalloc/include/jemalloc/internal/ctl.h | 111 + .../include/jemalloc/internal/extent.h | 239 + .../jemalloc/include/jemalloc/internal/hash.h | 336 + .../jemalloc/include/jemalloc/internal/huge.h | 36 + .../jemalloc/internal/jemalloc_internal.h.in | 1134 ++++ .../internal/jemalloc_internal_decls.h | 64 + .../internal/jemalloc_internal_defs.h.in | 262 + .../internal/jemalloc_internal_macros.h | 57 + .../jemalloc/include/jemalloc/internal/mb.h | 115 + .../include/jemalloc/internal/mutex.h | 111 + .../include/jemalloc/internal/pages.h | 26 + .../jemalloc/internal/private_namespace.sh | 5 + .../jemalloc/internal/private_symbols.txt | 499 ++ .../jemalloc/internal/private_unnamespace.sh | 5 + .../jemalloc/include/jemalloc/internal/prng.h | 60 + .../jemalloc/include/jemalloc/internal/prof.h | 545 ++ .../jemalloc/internal/public_namespace.sh | 6 + .../jemalloc/internal/public_unnamespace.sh | 6 + .../jemalloc/include/jemalloc/internal/ql.h | 81 + .../jemalloc/include/jemalloc/internal/qr.h | 69 + .../include/jemalloc/internal/quarantine.h | 60 + .../jemalloc/include/jemalloc/internal/rb.h | 981 +++ .../include/jemalloc/internal/rtree.h | 294 + .../include/jemalloc/internal/size_classes.sh | 286 + .../include/jemalloc/internal/stats.h | 183 + .../include/jemalloc/internal/tcache.h | 426 ++ .../jemalloc/include/jemalloc/internal/tsd.h | 665 ++ .../jemalloc/include/jemalloc/internal/util.h | 314 + .../include/jemalloc/internal/valgrind.h | 112 + .../jemalloc/include/jemalloc/jemalloc.sh | 28 + .../include/jemalloc/jemalloc_defs.h.in | 37 + .../include/jemalloc/jemalloc_macros.h.in | 106 + .../include/jemalloc/jemalloc_mangle.sh | 45 + .../include/jemalloc/jemalloc_protos.h.in | 66 + .../include/jemalloc/jemalloc_rename.sh | 22 + .../include/jemalloc/jemalloc_typedefs.h.in | 57 + .../include/msvc_compat/C99/stdbool.h | 20 + .../jemalloc/include/msvc_compat/C99/stdint.h | 247 + .../jemalloc/include/msvc_compat/strings.h | 29 + .../include/msvc_compat/windows_extra.h | 26 + .../jni/redis-4.0.8/deps/jemalloc/install-sh | 250 + .../redis-4.0.8/deps/jemalloc/jemalloc.pc.in | 12 + .../jni/redis-4.0.8/deps/jemalloc/src/arena.c | 3318 ++++++++++ .../redis-4.0.8/deps/jemalloc/src/atomic.c | 2 + .../jni/redis-4.0.8/deps/jemalloc/src/base.c | 174 + .../redis-4.0.8/deps/jemalloc/src/bitmap.c | 78 + .../jni/redis-4.0.8/deps/jemalloc/src/chunk.c | 761 +++ .../redis-4.0.8/deps/jemalloc/src/chunk_dss.c | 214 + .../deps/jemalloc/src/chunk_mmap.c | 80 + .../jni/redis-4.0.8/deps/jemalloc/src/ckh.c | 568 ++ .../jni/redis-4.0.8/deps/jemalloc/src/ctl.c | 2123 +++++++ .../redis-4.0.8/deps/jemalloc/src/extent.c | 53 + .../jni/redis-4.0.8/deps/jemalloc/src/hash.c | 2 + .../jni/redis-4.0.8/deps/jemalloc/src/huge.c | 435 ++ .../redis-4.0.8/deps/jemalloc/src/jemalloc.c | 2625 ++++++++ .../jni/redis-4.0.8/deps/jemalloc/src/mb.c | 2 + .../jni/redis-4.0.8/deps/jemalloc/src/mutex.c | 153 + .../jni/redis-4.0.8/deps/jemalloc/src/pages.c | 173 + .../jni/redis-4.0.8/deps/jemalloc/src/prof.c | 2237 +++++++ .../deps/jemalloc/src/quarantine.c | 183 + .../jni/redis-4.0.8/deps/jemalloc/src/rtree.c | 127 + .../jni/redis-4.0.8/deps/jemalloc/src/stats.c | 640 ++ .../redis-4.0.8/deps/jemalloc/src/tcache.c | 537 ++ .../jni/redis-4.0.8/deps/jemalloc/src/tsd.c | 193 + .../jni/redis-4.0.8/deps/jemalloc/src/util.c | 650 ++ .../redis-4.0.8/deps/jemalloc/src/valgrind.c | 34 + .../jni/redis-4.0.8/deps/jemalloc/src/zone.c | 274 + .../jemalloc/test/include/test/SFMT-alti.h | 186 + .../jemalloc/test/include/test/SFMT-params.h | 132 + .../test/include/test/SFMT-params11213.h | 81 + .../test/include/test/SFMT-params1279.h | 81 + .../test/include/test/SFMT-params132049.h | 81 + .../test/include/test/SFMT-params19937.h | 81 + .../test/include/test/SFMT-params216091.h | 81 + .../test/include/test/SFMT-params2281.h | 81 + .../test/include/test/SFMT-params4253.h | 81 + .../test/include/test/SFMT-params44497.h | 81 + .../test/include/test/SFMT-params607.h | 81 + .../test/include/test/SFMT-params86243.h | 81 + .../jemalloc/test/include/test/SFMT-sse2.h | 157 + .../deps/jemalloc/test/include/test/SFMT.h | 171 + .../deps/jemalloc/test/include/test/btalloc.h | 31 + .../test/include/test/jemalloc_test.h.in | 151 + .../test/include/test/jemalloc_test_defs.h.in | 9 + .../deps/jemalloc/test/include/test/math.h | 311 + .../deps/jemalloc/test/include/test/mq.h | 109 + .../deps/jemalloc/test/include/test/mtx.h | 21 + .../deps/jemalloc/test/include/test/test.h | 329 + .../deps/jemalloc/test/include/test/thd.h | 9 + .../deps/jemalloc/test/include/test/timer.h | 26 + .../jemalloc/test/integration/MALLOCX_ARENA.c | 69 + .../jemalloc/test/integration/aligned_alloc.c | 125 + .../jemalloc/test/integration/allocated.c | 125 + .../deps/jemalloc/test/integration/chunk.c | 276 + .../deps/jemalloc/test/integration/mallocx.c | 182 + .../deps/jemalloc/test/integration/overflow.c | 49 + .../test/integration/posix_memalign.c | 119 + .../deps/jemalloc/test/integration/rallocx.c | 185 + .../deps/jemalloc/test/integration/sdallocx.c | 57 + .../jemalloc/test/integration/thread_arena.c | 79 + .../test/integration/thread_tcache_enabled.c | 113 + .../deps/jemalloc/test/integration/xallocx.c | 471 ++ .../redis-4.0.8/deps/jemalloc/test/src/SFMT.c | 719 +++ .../deps/jemalloc/test/src/btalloc.c | 8 + .../deps/jemalloc/test/src/btalloc_0.c | 3 + .../deps/jemalloc/test/src/btalloc_1.c | 3 + .../redis-4.0.8/deps/jemalloc/test/src/math.c | 2 + .../redis-4.0.8/deps/jemalloc/test/src/mq.c | 29 + .../redis-4.0.8/deps/jemalloc/test/src/mtx.c | 66 + .../redis-4.0.8/deps/jemalloc/test/src/test.c | 107 + .../redis-4.0.8/deps/jemalloc/test/src/thd.c | 39 + .../deps/jemalloc/test/src/timer.c | 85 + .../deps/jemalloc/test/stress/microbench.c | 181 + .../redis-4.0.8/deps/jemalloc/test/test.sh.in | 53 + .../deps/jemalloc/test/unit/SFMT.c | 1605 +++++ .../deps/jemalloc/test/unit/atomic.c | 122 + .../deps/jemalloc/test/unit/bitmap.c | 159 + .../redis-4.0.8/deps/jemalloc/test/unit/ckh.c | 214 + .../deps/jemalloc/test/unit/hash.c | 171 + .../deps/jemalloc/test/unit/junk.c | 254 + .../deps/jemalloc/test/unit/junk_alloc.c | 3 + .../deps/jemalloc/test/unit/junk_free.c | 3 + .../deps/jemalloc/test/unit/lg_chunk.c | 26 + .../deps/jemalloc/test/unit/mallctl.c | 633 ++ .../deps/jemalloc/test/unit/math.c | 394 ++ .../redis-4.0.8/deps/jemalloc/test/unit/mq.c | 93 + .../redis-4.0.8/deps/jemalloc/test/unit/mtx.c | 60 + .../deps/jemalloc/test/unit/prof_accum.c | 91 + .../deps/jemalloc/test/unit/prof_active.c | 136 + .../deps/jemalloc/test/unit/prof_gdump.c | 81 + .../deps/jemalloc/test/unit/prof_idump.c | 51 + .../deps/jemalloc/test/unit/prof_reset.c | 302 + .../jemalloc/test/unit/prof_thread_name.c | 129 + .../redis-4.0.8/deps/jemalloc/test/unit/ql.c | 209 + .../redis-4.0.8/deps/jemalloc/test/unit/qr.c | 248 + .../deps/jemalloc/test/unit/quarantine.c | 108 + .../redis-4.0.8/deps/jemalloc/test/unit/rb.c | 336 + .../deps/jemalloc/test/unit/rtree.c | 151 + .../deps/jemalloc/test/unit/size_classes.c | 89 + .../deps/jemalloc/test/unit/stats.c | 447 ++ .../redis-4.0.8/deps/jemalloc/test/unit/tsd.c | 107 + .../deps/jemalloc/test/unit/util.c | 294 + .../deps/jemalloc/test/unit/zero.c | 78 + .../deps/lua/Android.mk | 0 .../deps/lua/COPYRIGHT | 0 .../deps/lua/HISTORY | 0 .../deps/lua/INSTALL | 0 .../deps/lua/Makefile | 0 .../deps/lua/README | 0 .../deps/lua/doc/contents.html | 0 .../deps/lua/doc/cover.png | Bin .../deps/lua/doc/logo.gif | Bin .../deps/lua/doc/lua.1 | 0 .../deps/lua/doc/lua.css | 0 .../deps/lua/doc/lua.html | 0 .../deps/lua/doc/luac.1 | 0 .../deps/lua/doc/luac.html | 0 .../deps/lua/doc/manual.css | 0 .../deps/lua/doc/manual.html | 0 .../deps/lua/doc/readme.html | 0 .../deps/lua/etc/Makefile | 0 .../deps/lua/etc/README | 0 .../deps/lua/etc/all.c | 0 .../deps/lua/etc/lua.hpp | 0 .../deps/lua/etc/lua.ico | Bin .../deps/lua/etc/lua.pc | 0 .../deps/lua/etc/luavs.bat | 0 .../deps/lua/etc/min.c | 0 .../deps/lua/etc/noparser.c | 0 .../deps/lua/etc/strict.lua | 0 .../deps/lua/src/Makefile | 0 .../deps/lua/src/fpconv.c | 0 .../deps/lua/src/fpconv.h | 0 .../deps/lua/src/lapi.c | 0 .../deps/lua/src/lapi.h | 0 .../deps/lua/src/lauxlib.c | 0 .../deps/lua/src/lauxlib.h | 0 .../deps/lua/src/lbaselib.c | 0 .../deps/lua/src/lcode.c | 0 .../deps/lua/src/lcode.h | 0 .../deps/lua/src/ldblib.c | 0 .../deps/lua/src/ldebug.c | 0 .../deps/lua/src/ldebug.h | 0 .../deps/lua/src/ldo.c | 0 .../deps/lua/src/ldo.h | 0 .../deps/lua/src/ldump.c | 0 .../deps/lua/src/lfunc.c | 0 .../deps/lua/src/lfunc.h | 0 .../deps/lua/src/lgc.c | 0 .../deps/lua/src/lgc.h | 0 .../deps/lua/src/linit.c | 0 .../deps/lua/src/liolib.c | 0 .../deps/lua/src/llex.c | 0 .../deps/lua/src/llex.h | 0 .../deps/lua/src/llimits.h | 0 .../deps/lua/src/lmathlib.c | 0 .../deps/lua/src/lmem.c | 0 .../deps/lua/src/lmem.h | 0 .../deps/lua/src/loadlib.c | 0 .../deps/lua/src/lobject.c | 0 .../deps/lua/src/lobject.h | 0 .../deps/lua/src/lopcodes.c | 0 .../deps/lua/src/lopcodes.h | 0 .../deps/lua/src/loslib.c | 0 .../deps/lua/src/lparser.c | 0 .../deps/lua/src/lparser.h | 0 .../deps/lua/src/lstate.c | 0 .../deps/lua/src/lstate.h | 0 .../deps/lua/src/lstring.c | 0 .../deps/lua/src/lstring.h | 0 .../deps/lua/src/lstrlib.c | 0 .../deps/lua/src/ltable.c | 0 .../deps/lua/src/ltable.h | 0 .../deps/lua/src/ltablib.c | 0 .../deps/lua/src/ltm.c | 0 .../deps/lua/src/ltm.h | 0 .../deps/lua/src/lua.c | 5 +- .../deps/lua/src/lua.h | 0 .../deps/lua/src/lua_bit.c | 0 .../deps/lua/src/lua_cjson.c | 0 .../deps/lua/src/lua_cmsgpack.c | 0 .../deps/lua/src/lua_struct.c | 0 .../deps/lua/src/luac.c | 0 .../deps/lua/src/luaconf.h | 0 .../deps/lua/src/lualib.h | 0 .../deps/lua/src/lundump.c | 0 .../deps/lua/src/lundump.h | 0 .../deps/lua/src/lvm.c | 0 .../deps/lua/src/lvm.h | 0 .../deps/lua/src/lzio.c | 0 .../deps/lua/src/lzio.h | 0 .../deps/lua/src/print.c | 0 .../deps/lua/src/strbuf.c | 0 .../deps/lua/src/strbuf.h | 0 .../deps/lua/test/README | 0 .../deps/lua/test/bisect.lua | 0 .../deps/lua/test/cf.lua | 0 .../deps/lua/test/echo.lua | 0 .../deps/lua/test/env.lua | 0 .../deps/lua/test/factorial.lua | 0 .../deps/lua/test/fib.lua | 0 .../deps/lua/test/fibfor.lua | 0 .../deps/lua/test/globals.lua | 0 .../deps/lua/test/hello.lua | 0 .../deps/lua/test/life.lua | 0 .../deps/lua/test/luac.lua | 0 .../deps/lua/test/printf.lua | 0 .../deps/lua/test/readonly.lua | 0 .../deps/lua/test/sieve.lua | 0 .../deps/lua/test/sort.lua | 0 .../deps/lua/test/table.lua | 0 .../deps/lua/test/trace-calls.lua | 0 .../deps/lua/test/trace-globals.lua | 0 .../deps/lua/test/xd.lua | 0 .../deps/update-jemalloc.sh | 0 .../{redis-4.0.6 => redis-4.0.8}/redis.conf | 14 + .../src/main/{ => jni/redis-4.0.8}/release.c | 0 .../jni/{redis-4.0.6 => redis-4.0.8}/runtest | 0 .../runtest-cluster | 0 .../runtest-sentinel | 0 .../sentinel.conf | 0 .../src/.gitignore | 0 .../{redis-4.0.6 => redis-4.0.8}/src/Makefile | 16 +- .../{redis-4.0.6 => redis-4.0.8}/src/adlist.c | 0 .../{redis-4.0.6 => redis-4.0.8}/src/adlist.h | 0 .../jni/{redis-4.0.6 => redis-4.0.8}/src/ae.c | 6 +- .../jni/{redis-4.0.6 => redis-4.0.8}/src/ae.h | 0 .../src/ae_epoll.c | 0 .../src/ae_evport.c | 0 .../src/ae_kqueue.c | 0 .../src/ae_select.c | 0 .../{redis-4.0.6 => redis-4.0.8}/src/anet.c | 2 +- .../{redis-4.0.6 => redis-4.0.8}/src/anet.h | 0 .../{redis-4.0.6 => redis-4.0.8}/src/aof.c | 52 +- .../src/asciilogo.h | 0 .../src/atomicvar.h | 0 .../{redis-4.0.6 => redis-4.0.8}/src/bio.c | 9 +- .../{redis-4.0.6 => redis-4.0.8}/src/bio.h | 0 .../{redis-4.0.6 => redis-4.0.8}/src/bitops.c | 0 .../src/blocked.c | 0 .../src/childinfo.c | 0 .../src/cluster.c | 56 +- .../src/cluster.h | 0 .../{redis-4.0.6 => redis-4.0.8}/src/config.c | 21 +- .../{redis-4.0.6 => redis-4.0.8}/src/config.h | 8 +- .../{redis-4.0.6 => redis-4.0.8}/src/crc16.c | 0 .../{redis-4.0.6 => redis-4.0.8}/src/crc64.c | 0 .../{redis-4.0.6 => redis-4.0.8}/src/crc64.h | 0 .../jni/{redis-4.0.6 => redis-4.0.8}/src/db.c | 12 +- .../{redis-4.0.6 => redis-4.0.8}/src/debug.c | 2 +- .../src/debugmacro.h | 0 .../{redis-4.0.6 => redis-4.0.8}/src/defrag.c | 2 +- .../{redis-4.0.6 => redis-4.0.8}/src/dict.c | 22 +- .../{redis-4.0.6 => redis-4.0.8}/src/dict.h | 4 +- .../src/endianconv.c | 0 .../src/endianconv.h | 0 .../{redis-4.0.6 => redis-4.0.8}/src/evict.c | 0 .../{redis-4.0.6 => redis-4.0.8}/src/expire.c | 0 .../src/fmacros.h | 0 .../{redis-4.0.6 => redis-4.0.8}/src/geo.c | 0 .../{redis-4.0.6 => redis-4.0.8}/src/geo.h | 0 .../src/geohash.c | 0 .../src/geohash.h | 0 .../src/geohash_helper.c | 0 .../src/geohash_helper.h | 0 .../{redis-4.0.6 => redis-4.0.8}/src/help.h | 0 .../src/hyperloglog.c | 79 +- .../{redis-4.0.6 => redis-4.0.8}/src/intset.c | 0 .../{redis-4.0.6 => redis-4.0.8}/src/intset.h | 0 .../src/latency.c | 0 .../src/latency.h | 0 .../src/lazyfree.c | 12 +- .../{redis-4.0.6 => redis-4.0.8}/src/lzf.h | 0 .../{redis-4.0.6 => redis-4.0.8}/src/lzfP.h | 0 .../{redis-4.0.6 => redis-4.0.8}/src/lzf_c.c | 0 .../{redis-4.0.6 => redis-4.0.8}/src/lzf_d.c | 0 .../src/memtest.c | 0 .../src/mkreleasehdr.sh | 0 .../{redis-4.0.6 => redis-4.0.8}/src/module.c | 19 +- .../src/modules/.gitignore | 0 .../src/modules/Makefile | 0 .../src/modules/gendoc.rb | 0 .../src/modules/helloblock.c | 0 .../src/modules/hellotype.c | 0 .../src/modules/helloworld.c | 0 .../src/modules/testmodule.c | 39 + .../{redis-4.0.6 => redis-4.0.8}/src/multi.c | 0 .../src/networking.c | 25 +- .../{redis-4.0.6 => redis-4.0.8}/src/notify.c | 0 .../{redis-4.0.6 => redis-4.0.8}/src/object.c | 2 +- .../{redis-4.0.6 => redis-4.0.8}/src/pqsort.c | 0 .../{redis-4.0.6 => redis-4.0.8}/src/pqsort.h | 0 .../{redis-4.0.6 => redis-4.0.8}/src/pubsub.c | 0 .../src/quicklist.c | 0 .../src/quicklist.h | 0 .../{redis-4.0.6 => redis-4.0.8}/src/rand.c | 0 .../{redis-4.0.6 => redis-4.0.8}/src/rand.h | 0 .../{redis-4.0.6 => redis-4.0.8}/src/rax.c | 74 +- .../{redis-4.0.6 => redis-4.0.8}/src/rax.h | 3 + .../src/rax_malloc.h | 0 .../{redis-4.0.6 => redis-4.0.8}/src/rdb.c | 20 +- .../{redis-4.0.6 => redis-4.0.8}/src/rdb.h | 2 +- .../src/redis-benchmark.c | 2 +- .../src/redis-check-aof.c | 0 .../src/redis-check-rdb.c | 0 .../src/redis-cli.c | 3 +- .../src/redis-trib.rb | 132 +- .../src/redisassert.h | 0 .../src/redismodule.h | 4 +- .../src/release.c | 0 .../src/replication.c | 14 +- .../{redis-4.0.6 => redis-4.0.8}/src/rio.c | 2 +- .../{redis-4.0.6 => redis-4.0.8}/src/rio.h | 2 +- .../src/scripting.c | 0 .../{redis-4.0.6 => redis-4.0.8}/src/sds.c | 23 +- .../{redis-4.0.6 => redis-4.0.8}/src/sds.h | 6 +- .../src/sdsalloc.h | 0 .../src/sentinel.c | 0 .../{redis-4.0.6 => redis-4.0.8}/src/server.c | 28 +- .../{redis-4.0.6 => redis-4.0.8}/src/server.h | 8 +- .../src/setproctitle.c | 0 .../{redis-4.0.6 => redis-4.0.8}/src/sha1.c | 0 .../{redis-4.0.6 => redis-4.0.8}/src/sha1.h | 0 .../src/siphash.c | 0 .../src/slowlog.c | 0 .../src/slowlog.h | 0 .../src/solarisfixes.h | 0 .../{redis-4.0.6 => redis-4.0.8}/src/sort.c | 0 .../src/sparkline.c | 0 .../src/sparkline.h | 0 .../src/sync_file_range_flags.h | 0 .../{redis-4.0.6 => redis-4.0.8}/src/syncio.c | 0 .../{redis-4.0.6 => redis-4.0.8}/src/t_hash.c | 0 .../{redis-4.0.6 => redis-4.0.8}/src/t_list.c | 0 .../{redis-4.0.6 => redis-4.0.8}/src/t_set.c | 14 +- .../src/t_string.c | 0 .../{redis-4.0.6 => redis-4.0.8}/src/t_zset.c | 0 .../src/testhelp.h | 0 .../{redis-4.0.6 => redis-4.0.8}/src/util.c | 2 +- .../{redis-4.0.6 => redis-4.0.8}/src/util.h | 0 .../src/valgrind.sup | 0 .../src/main/jni/redis-4.0.8/src/version.h | 1 + .../{redis-4.0.6 => redis-4.0.8}/src/wait3.c | 0 .../{redis-4.0.6 => redis-4.0.8}/src/wait3.h | 0 .../src/ziplist.c | 2 +- .../src/ziplist.h | 0 .../{redis-4.0.6 => redis-4.0.8}/src/zipmap.c | 0 .../{redis-4.0.6 => redis-4.0.8}/src/zipmap.h | 0 .../src/zmalloc.c | 0 .../src/zmalloc.h | 0 .../tests/assets/default.conf | 0 .../tests/assets/encodings.rdb | Bin .../tests/assets/hash-zipmap.rdb | Bin .../tests/cluster/cluster.tcl | 0 .../tests/cluster/run.tcl | 0 .../tests/cluster/tests/00-base.tcl | 0 .../tests/cluster/tests/01-faildet.tcl | 0 .../tests/cluster/tests/02-failover.tcl | 0 .../tests/cluster/tests/03-failover-loop.tcl | 0 .../tests/cluster/tests/04-resharding.tcl | 0 .../cluster/tests/05-slave-selection.tcl | 0 .../cluster/tests/06-slave-stop-cond.tcl | 0 .../cluster/tests/07-replica-migration.tcl | 0 .../tests/cluster/tests/08-update-msg.tcl | 0 .../tests/cluster/tests/09-pubsub.tcl | 0 .../cluster/tests/10-manual-failover.tcl | 0 .../cluster/tests/11-manual-takeover.tcl | 0 .../cluster/tests/12-replica-migration-2.tcl | 0 .../tests/cluster/tests/helpers/onlydots.tcl | 0 .../cluster/tests/includes/init-tests.tcl | 0 .../tests/cluster/tmp/.gitignore | 0 .../tests/helpers/bg_complex_data.tcl | 0 .../tests/helpers/gen_write_load.tcl | 0 .../tests/instances.tcl | 0 .../tests/integration/aof-race.tcl | 0 .../tests/integration/aof.tcl | 0 .../convert-zipmap-hash-on-load.tcl | 0 .../tests/integration/logging.tcl | 0 .../tests/integration/psync2-reg.tcl | 0 .../tests/integration/psync2.tcl | 0 .../tests/integration/rdb.tcl | 0 .../tests/integration/redis-cli.tcl | 0 .../tests/integration/replication-2.tcl | 9 +- .../tests/integration/replication-3.tcl | 0 .../tests/integration/replication-4.tcl | 0 .../tests/integration/replication-psync.tcl | 0 .../tests/integration/replication.tcl | 0 .../tests/sentinel/run.tcl | 0 .../tests/sentinel/tests/00-base.tcl | 0 .../tests/sentinel/tests/01-conf-update.tcl | 0 .../tests/sentinel/tests/02-slaves-reconf.tcl | 0 .../sentinel/tests/03-runtime-reconf.tcl | 0 .../sentinel/tests/04-slave-selection.tcl | 0 .../tests/sentinel/tests/05-manual.tcl | 0 .../tests/sentinel/tests/06-ckquorum.tcl | 0 .../sentinel/tests/07-down-conditions.tcl | 0 .../sentinel/tests/includes/init-tests.tcl | 0 .../tests/sentinel/tmp/.gitignore | 0 .../tests/support/cluster.tcl | 0 .../tests/support/redis.tcl | 0 .../tests/support/server.tcl | 0 .../tests/support/test.tcl | 0 .../tests/support/tmpfile.tcl | 0 .../tests/support/util.tcl | 0 .../tests/test_helper.tcl | 0 .../tests/unit/aofrw.tcl | 0 .../tests/unit/auth.tcl | 0 .../tests/unit/bitfield.tcl | 0 .../tests/unit/bitops.tcl | 0 .../tests/unit/dump.tcl | 24 + .../tests/unit/expire.tcl | 0 .../tests/unit/geo.tcl | 0 .../tests/unit/hyperloglog.tcl | 0 .../tests/unit/introspection-2.tcl | 0 .../tests/unit/introspection.tcl | 0 .../tests/unit/keyspace.tcl | 0 .../tests/unit/latency-monitor.tcl | 0 .../tests/unit/lazyfree.tcl | 0 .../tests/unit/limits.tcl | 0 .../tests/unit/maxmemory.tcl | 0 .../tests/unit/memefficiency.tcl | 0 .../tests/unit/multi.tcl | 0 .../tests/unit/obuf-limits.tcl | 0 .../tests/unit/other.tcl | 0 .../tests/unit/printver.tcl | 0 .../tests/unit/protocol.tcl | 0 .../tests/unit/pubsub.tcl | 0 .../tests/unit/quit.tcl | 0 .../tests/unit/scan.tcl | 0 .../tests/unit/scripting.tcl | 0 .../tests/unit/slowlog.tcl | 0 .../tests/unit/sort.tcl | 0 .../tests/unit/type/hash.tcl | 0 .../tests/unit/type/incr.tcl | 0 .../tests/unit/type/list-2.tcl | 0 .../tests/unit/type/list-3.tcl | 0 .../tests/unit/type/list-common.tcl | 0 .../tests/unit/type/list.tcl | 0 .../tests/unit/type/set.tcl | 0 .../tests/unit/type/string.tcl | 0 .../tests/unit/type/zset.tcl | 0 .../tests/unit/wait.tcl | 0 .../utils/build-static-symbols.tcl | 0 .../utils/cluster_fail_time.tcl | 0 .../utils/corrupt_rdb.c | 0 .../utils/create-cluster/.gitignore | 0 .../utils/create-cluster/README | 0 .../utils/create-cluster/create-cluster | 0 .../utils/generate-command-help.rb | 0 .../utils/graphs/commits-over-time/README.md | 0 .../graphs/commits-over-time/genhtml.tcl | 0 .../utils/hashtable/README | 0 .../utils/hashtable/rehashing.c | 0 .../utils/hyperloglog/.gitignore | 0 .../utils/hyperloglog/hll-err.rb | 0 .../utils/hyperloglog/hll-gnuplot-graph.rb | 0 .../utils/install_server.sh | 0 .../utils/lru/README | 0 .../utils/lru/lfu-simulation.c | 0 .../utils/lru/test-lru.rb | 0 .../utils/redis-copy.rb | 0 .../utils/redis-sha1.rb | 0 .../utils/redis_init_script | 0 .../utils/redis_init_script.tpl | 0 .../utils/releasetools/01_create_tarball.sh | 0 .../utils/releasetools/02_upload_tarball.sh | 0 .../utils/releasetools/03_test_release.sh | 0 .../utils/releasetools/04_release_hash.sh | 0 .../utils/releasetools/changelog.tcl | 0 .../utils/speed-regression.tcl | 0 .../utils/whatisdoing.sh | 0 redis-android/src/main/jni/redis-android.c | 2 +- redis-android/src/main/jni/redis-android.h | 2 +- redis-android/src/main/jni/release.h | 6 +- .../src/main/libs/arm64-v8a/libredis.so | Bin 1211144 -> 1215240 bytes .../src/main/libs/arm64-v8a/redis-cli | Bin 132976 -> 132976 bytes .../src/main/libs/armeabi-v7a/libredis.so | Bin 906292 -> 906292 bytes .../src/main/libs/armeabi-v7a/redis-cli | Bin 99928 -> 108120 bytes redis-android/src/main/libs/x86/libredis.so | Bin 1241276 -> 1245372 bytes redis-android/src/main/libs/x86/redis-cli | Bin 124424 -> 128520 bytes .../src/main/libs/x86_64/libredis.so | Bin 1248312 -> 1248312 bytes redis-android/src/main/libs/x86_64/redis-cli | Bin 141360 -> 141360 bytes redis-android/src/main/release.h | 3 - .../1.0.4/redis-android-1.0.4.aar | Bin 0 -> 2096719 bytes .../1.0.4/redis-android-1.0.4.aar.md5 | 1 + .../1.0.4/redis-android-1.0.4.aar.sha1 | 1 + .../1.0.4/redis-android-1.0.4.pom | 9 + .../1.0.4/redis-android-1.0.4.pom.md5 | 1 + .../1.0.4/redis-android-1.0.4.pom.sha1 | 1 + .../wf9a5m75/redis-android/maven-metadata.xml | 5 +- .../redis-android/maven-metadata.xml.md5 | 2 +- .../redis-android/maven-metadata.xml.sha1 | 2 +- 623 files changed, 54462 insertions(+), 228 deletions(-) delete mode 100644 redis-android/src/main/jni/redis-4.0.6/src/version.h rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/.gitignore (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/00-RELEASENOTES (94%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/Android.mk (72%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/BUGS (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/CONTRIBUTING (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/COPYING (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/INSTALL (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/MANIFESTO (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/Makefile (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/README.md (100%) create mode 100755 redis-android/src/main/jni/redis-4.0.8/android-elf-cleaner rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/Android.mk (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/Makefile (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/README.md (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/hiredis/.gitignore (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/hiredis/.travis.yml (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/hiredis/Android.mk (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/hiredis/CHANGELOG.md (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/hiredis/COPYING (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/hiredis/Makefile (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/hiredis/README.md (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/hiredis/adapters/ae.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/hiredis/adapters/glib.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/hiredis/adapters/ivykis.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/hiredis/adapters/libev.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/hiredis/adapters/libevent.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/hiredis/adapters/libuv.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/hiredis/adapters/macosx.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/hiredis/adapters/qt.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/hiredis/appveyor.yml (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/hiredis/async.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/hiredis/async.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/hiredis/dict.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/hiredis/dict.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/hiredis/examples/example-ae.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/hiredis/examples/example-glib.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/hiredis/examples/example-ivykis.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/hiredis/examples/example-libev.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/hiredis/examples/example-libevent.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/hiredis/examples/example-libuv.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/hiredis/examples/example-macosx.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/hiredis/examples/example-qt.cpp (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/hiredis/examples/example-qt.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/hiredis/examples/example.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/hiredis/fmacros.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/hiredis/hiredis.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/hiredis/hiredis.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/hiredis/net.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/hiredis/net.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/hiredis/read.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/hiredis/read.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/hiredis/sds.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/hiredis/sds.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/hiredis/sdsalloc.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/hiredis/test.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/hiredis/win32.h (100%) create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/.autom4te.cfg create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/.gitattributes create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/.gitignore create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/COPYING create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/ChangeLog create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/INSTALL create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/Makefile.in create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/README create mode 100755 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/autogen.sh create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/bin/jemalloc-config.in create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/bin/jemalloc.sh.in create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/bin/jeprof.in create mode 100755 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/config.guess rename redis-android/src/main/jni/{redis-4.0.6/release.c => redis-4.0.8/deps/jemalloc/config.stamp.in} (100%) create mode 100755 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/config.sub create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/configure.ac create mode 100755 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/coverage.sh create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/doc/html.xsl.in create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/doc/jemalloc.xml.in create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/doc/manpages.xsl.in create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/doc/stylesheet.xsl create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/arena.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/atomic.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/base.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/bitmap.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/chunk.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/chunk_dss.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/chunk_mmap.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/ckh.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/ctl.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/extent.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/hash.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/huge.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/jemalloc_internal.h.in create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/jemalloc_internal_decls.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/jemalloc_internal_defs.h.in create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/jemalloc_internal_macros.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/mb.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/mutex.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/pages.h create mode 100755 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/private_namespace.sh create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/private_symbols.txt create mode 100755 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/private_unnamespace.sh create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/prng.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/prof.h create mode 100755 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/public_namespace.sh create mode 100755 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/public_unnamespace.sh create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/ql.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/qr.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/quarantine.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/rb.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/rtree.h create mode 100755 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/size_classes.sh create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/stats.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/tcache.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/tsd.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/util.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/valgrind.h create mode 100755 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/jemalloc.sh create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/jemalloc_defs.h.in create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/jemalloc_macros.h.in create mode 100755 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/jemalloc_mangle.sh create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/jemalloc_protos.h.in create mode 100755 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/jemalloc_rename.sh create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/jemalloc_typedefs.h.in create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/msvc_compat/C99/stdbool.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/msvc_compat/C99/stdint.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/msvc_compat/strings.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/msvc_compat/windows_extra.h create mode 100755 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/install-sh create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/jemalloc.pc.in create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/arena.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/atomic.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/base.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/bitmap.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/chunk.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/chunk_dss.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/chunk_mmap.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/ckh.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/ctl.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/extent.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/hash.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/huge.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/jemalloc.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/mb.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/mutex.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/pages.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/prof.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/quarantine.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/rtree.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/stats.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/tcache.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/tsd.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/util.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/valgrind.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/zone.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-alti.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params11213.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params1279.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params132049.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params19937.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params216091.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params2281.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params4253.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params44497.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params607.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params86243.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-sse2.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/btalloc.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/jemalloc_test.h.in create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/jemalloc_test_defs.h.in create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/math.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/mq.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/mtx.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/test.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/thd.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/timer.h create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/MALLOCX_ARENA.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/aligned_alloc.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/allocated.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/chunk.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/mallocx.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/overflow.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/posix_memalign.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/rallocx.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/sdallocx.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/thread_arena.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/thread_tcache_enabled.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/xallocx.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/src/SFMT.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/src/btalloc.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/src/btalloc_0.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/src/btalloc_1.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/src/math.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/src/mq.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/src/mtx.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/src/test.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/src/thd.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/src/timer.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/stress/microbench.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/test.sh.in create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/SFMT.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/atomic.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/bitmap.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/ckh.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/hash.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/junk.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/junk_alloc.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/junk_free.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/lg_chunk.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/mallctl.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/math.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/mq.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/mtx.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/prof_accum.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/prof_active.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/prof_gdump.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/prof_idump.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/prof_reset.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/prof_thread_name.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/ql.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/qr.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/quarantine.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/rb.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/rtree.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/size_classes.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/stats.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/tsd.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/util.c create mode 100644 redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/zero.c rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/Android.mk (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/COPYRIGHT (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/HISTORY (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/INSTALL (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/Makefile (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/README (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/doc/contents.html (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/doc/cover.png (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/doc/logo.gif (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/doc/lua.1 (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/doc/lua.css (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/doc/lua.html (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/doc/luac.1 (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/doc/luac.html (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/doc/manual.css (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/doc/manual.html (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/doc/readme.html (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/etc/Makefile (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/etc/README (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/etc/all.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/etc/lua.hpp (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/etc/lua.ico (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/etc/lua.pc (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/etc/luavs.bat (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/etc/min.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/etc/noparser.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/etc/strict.lua (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/Makefile (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/fpconv.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/fpconv.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/lapi.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/lapi.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/lauxlib.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/lauxlib.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/lbaselib.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/lcode.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/lcode.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/ldblib.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/ldebug.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/ldebug.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/ldo.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/ldo.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/ldump.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/lfunc.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/lfunc.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/lgc.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/lgc.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/linit.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/liolib.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/llex.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/llex.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/llimits.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/lmathlib.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/lmem.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/lmem.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/loadlib.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/lobject.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/lobject.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/lopcodes.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/lopcodes.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/loslib.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/lparser.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/lparser.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/lstate.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/lstate.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/lstring.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/lstring.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/lstrlib.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/ltable.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/ltable.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/ltablib.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/ltm.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/ltm.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/lua.c (99%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/lua.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/lua_bit.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/lua_cjson.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/lua_cmsgpack.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/lua_struct.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/luac.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/luaconf.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/lualib.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/lundump.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/lundump.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/lvm.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/lvm.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/lzio.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/lzio.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/print.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/strbuf.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/src/strbuf.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/test/README (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/test/bisect.lua (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/test/cf.lua (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/test/echo.lua (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/test/env.lua (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/test/factorial.lua (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/test/fib.lua (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/test/fibfor.lua (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/test/globals.lua (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/test/hello.lua (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/test/life.lua (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/test/luac.lua (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/test/printf.lua (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/test/readonly.lua (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/test/sieve.lua (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/test/sort.lua (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/test/table.lua (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/test/trace-calls.lua (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/test/trace-globals.lua (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/lua/test/xd.lua (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/deps/update-jemalloc.sh (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/redis.conf (98%) rename redis-android/src/main/{ => jni/redis-4.0.8}/release.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/runtest (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/runtest-cluster (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/runtest-sentinel (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/sentinel.conf (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/.gitignore (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/Makefile (95%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/adlist.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/adlist.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/ae.c (99%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/ae.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/ae_epoll.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/ae_evport.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/ae_kqueue.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/ae_select.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/anet.c (99%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/anet.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/aof.c (97%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/asciilogo.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/atomicvar.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/bio.c (99%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/bio.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/bitops.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/blocked.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/childinfo.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/cluster.c (99%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/cluster.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/config.c (98%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/config.h (98%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/crc16.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/crc64.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/crc64.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/db.c (99%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/debug.c (99%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/debugmacro.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/defrag.c (99%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/dict.c (98%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/dict.h (98%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/endianconv.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/endianconv.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/evict.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/expire.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/fmacros.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/geo.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/geo.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/geohash.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/geohash.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/geohash_helper.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/geohash_helper.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/help.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/hyperloglog.c (96%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/intset.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/intset.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/latency.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/latency.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/lazyfree.c (88%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/lzf.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/lzfP.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/lzf_c.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/lzf_d.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/memtest.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/mkreleasehdr.sh (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/module.c (99%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/modules/.gitignore (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/modules/Makefile (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/modules/gendoc.rb (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/modules/helloblock.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/modules/hellotype.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/modules/helloworld.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/modules/testmodule.c (88%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/multi.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/networking.c (99%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/notify.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/object.c (99%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/pqsort.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/pqsort.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/pubsub.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/quicklist.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/quicklist.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/rand.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/rand.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/rax.c (97%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/rax.h (98%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/rax_malloc.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/rdb.c (99%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/rdb.h (99%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/redis-benchmark.c (99%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/redis-check-aof.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/redis-check-rdb.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/redis-cli.c (99%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/redis-trib.rb (92%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/redisassert.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/redismodule.h (99%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/release.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/replication.c (99%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/rio.c (99%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/rio.h (98%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/scripting.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/sds.c (98%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/sds.h (98%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/sdsalloc.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/sentinel.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/server.c (99%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/server.h (99%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/setproctitle.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/sha1.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/sha1.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/siphash.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/slowlog.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/slowlog.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/solarisfixes.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/sort.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/sparkline.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/sparkline.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/sync_file_range_flags.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/syncio.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/t_hash.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/t_list.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/t_set.c (98%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/t_string.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/t_zset.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/testhelp.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/util.c (99%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/util.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/valgrind.sup (100%) create mode 100644 redis-android/src/main/jni/redis-4.0.8/src/version.h rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/wait3.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/wait3.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/ziplist.c (99%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/ziplist.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/zipmap.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/zipmap.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/zmalloc.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/src/zmalloc.h (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/assets/default.conf (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/assets/encodings.rdb (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/assets/hash-zipmap.rdb (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/cluster/cluster.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/cluster/run.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/cluster/tests/00-base.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/cluster/tests/01-faildet.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/cluster/tests/02-failover.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/cluster/tests/03-failover-loop.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/cluster/tests/04-resharding.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/cluster/tests/05-slave-selection.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/cluster/tests/06-slave-stop-cond.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/cluster/tests/07-replica-migration.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/cluster/tests/08-update-msg.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/cluster/tests/09-pubsub.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/cluster/tests/10-manual-failover.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/cluster/tests/11-manual-takeover.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/cluster/tests/12-replica-migration-2.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/cluster/tests/helpers/onlydots.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/cluster/tests/includes/init-tests.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/cluster/tmp/.gitignore (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/helpers/bg_complex_data.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/helpers/gen_write_load.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/instances.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/integration/aof-race.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/integration/aof.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/integration/convert-zipmap-hash-on-load.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/integration/logging.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/integration/psync2-reg.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/integration/psync2.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/integration/rdb.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/integration/redis-cli.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/integration/replication-2.tcl (94%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/integration/replication-3.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/integration/replication-4.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/integration/replication-psync.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/integration/replication.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/sentinel/run.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/sentinel/tests/00-base.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/sentinel/tests/01-conf-update.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/sentinel/tests/02-slaves-reconf.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/sentinel/tests/03-runtime-reconf.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/sentinel/tests/04-slave-selection.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/sentinel/tests/05-manual.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/sentinel/tests/06-ckquorum.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/sentinel/tests/07-down-conditions.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/sentinel/tests/includes/init-tests.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/sentinel/tmp/.gitignore (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/support/cluster.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/support/redis.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/support/server.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/support/test.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/support/tmpfile.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/support/util.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/test_helper.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/unit/aofrw.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/unit/auth.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/unit/bitfield.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/unit/bitops.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/unit/dump.tcl (92%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/unit/expire.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/unit/geo.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/unit/hyperloglog.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/unit/introspection-2.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/unit/introspection.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/unit/keyspace.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/unit/latency-monitor.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/unit/lazyfree.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/unit/limits.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/unit/maxmemory.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/unit/memefficiency.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/unit/multi.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/unit/obuf-limits.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/unit/other.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/unit/printver.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/unit/protocol.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/unit/pubsub.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/unit/quit.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/unit/scan.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/unit/scripting.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/unit/slowlog.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/unit/sort.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/unit/type/hash.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/unit/type/incr.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/unit/type/list-2.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/unit/type/list-3.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/unit/type/list-common.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/unit/type/list.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/unit/type/set.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/unit/type/string.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/unit/type/zset.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/tests/unit/wait.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/utils/build-static-symbols.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/utils/cluster_fail_time.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/utils/corrupt_rdb.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/utils/create-cluster/.gitignore (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/utils/create-cluster/README (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/utils/create-cluster/create-cluster (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/utils/generate-command-help.rb (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/utils/graphs/commits-over-time/README.md (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/utils/graphs/commits-over-time/genhtml.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/utils/hashtable/README (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/utils/hashtable/rehashing.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/utils/hyperloglog/.gitignore (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/utils/hyperloglog/hll-err.rb (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/utils/hyperloglog/hll-gnuplot-graph.rb (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/utils/install_server.sh (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/utils/lru/README (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/utils/lru/lfu-simulation.c (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/utils/lru/test-lru.rb (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/utils/redis-copy.rb (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/utils/redis-sha1.rb (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/utils/redis_init_script (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/utils/redis_init_script.tpl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/utils/releasetools/01_create_tarball.sh (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/utils/releasetools/02_upload_tarball.sh (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/utils/releasetools/03_test_release.sh (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/utils/releasetools/04_release_hash.sh (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/utils/releasetools/changelog.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/utils/speed-regression.tcl (100%) rename redis-android/src/main/jni/{redis-4.0.6 => redis-4.0.8}/utils/whatisdoing.sh (100%) delete mode 100644 redis-android/src/main/release.h create mode 100644 repository/io/wf9a5m75/redis-android/1.0.4/redis-android-1.0.4.aar create mode 100644 repository/io/wf9a5m75/redis-android/1.0.4/redis-android-1.0.4.aar.md5 create mode 100644 repository/io/wf9a5m75/redis-android/1.0.4/redis-android-1.0.4.aar.sha1 create mode 100644 repository/io/wf9a5m75/redis-android/1.0.4/redis-android-1.0.4.pom create mode 100644 repository/io/wf9a5m75/redis-android/1.0.4/redis-android-1.0.4.pom.md5 create mode 100644 repository/io/wf9a5m75/redis-android/1.0.4/redis-android-1.0.4.pom.sha1 diff --git a/CHANGELOGS.md b/CHANGELOGS.md index 273cfe1..e4de7a5 100644 --- a/CHANGELOGS.md +++ b/CHANGELOGS.md @@ -1,6 +1,12 @@ Redis on Android 1.0 release notes ==================================== +================================================================================ +Redis on Android 1.0.4 Released Feb/13/2018 15:32 PST +================================================================================ + +Upgrade the redis 4.0.8 + ================================================================================ Redis on Android 1.0.3 Released Jan/03/2018 17:10 PST ================================================================================ diff --git a/README.md b/README.md index 6cf086b..e98124e 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,48 @@ -# Redis on Android (server) +# RedisDB on Android (v1.0.4) -This library allows you to run a Redis DB on Android devices. -You can store data, get it, pubsub, ... etc, you can manipulate the DB like normal Redis. +## Redis version -This repository is forked from [rikiji/redis-android](https://github.com/rikiji/redis-android), because the original author [Riccardo](http://rikiji.it/2012/08/21/Redis-Android-NDK-port.html) does not work on this anymore. -But thank you for your hard work, @rikiji +Feb/13/2018 Redis 4.0.8 -## Redis version +## Description + +Redis is known for NoSQL database. You can run Redis database on your server. + +**_This library helps you to run Redis database on Android device_**. + +This library is just cross-compiled the [original redis database](https://redis.io/) for Android architectures such as ARM cpu. + +You can run Redis database in background thread in your application. + + + +## Benefit of running Redis DB on Android + +There are some benefits for running Redis DB on Android. + + - NoSQL database in memory + + The most remarkable feature of the Redis DB is `NoSQL`. + It means you can easily store data with key, and retrieve it (just like JSON object). + + - No Internet is required + + `MongoDB` or `Google Firebase` are known for NoSQL hosted on their cloud servers. However they need to connect to their server through the Internet. + It is depends on your purpose, but I wanted own hosted database on Android. + + - `TTL` for key + + One of my favorite points of Redis DB is you are able to set `TTL (time to live)`. You can save the key-value pairs that is available only in TTL time. + + - `Publish/Subscriber` + + One of the reason I created this library is Redis DB has `publisher/subscriber` mechanism, like a chat room. + You can notify your message from one application, and receive the data on another applications, even on multiple devices. + + - No dependencies -Jan/03/2018 Redis 4.0.6 + One of the reason I gave up to use `Google Firebase` is that the library requires `Google Play Services`. But my Android does not have it (AOSP rom). + You can run Redis DB with **only this library.** ## Install @@ -21,7 +55,7 @@ repositories { } dependencies { - compile 'io.wf9a5m75:redis-android:1.0.3' + compile 'io.wf9a5m75:redis-android:1.0.4' } ``` diff --git a/redis-android/build.gradle b/redis-android/build.gradle index e733359..3506dbb 100644 --- a/redis-android/build.gradle +++ b/redis-android/build.gradle @@ -35,7 +35,7 @@ uploadArchives { repositories { mavenDeployer { repository url: "file://${repo.absolutePath}" - pom.version = "1.0.3" + pom.version = "1.0.4" pom.groupId = "io.wf9a5m75" pom.artifactId = "redis-android" } diff --git a/redis-android/src/main/java/io/wf9a5m75/redis/RedisAndroid.java b/redis-android/src/main/java/io/wf9a5m75/redis/RedisAndroid.java index f574df0..3c95a67 100644 --- a/redis-android/src/main/java/io/wf9a5m75/redis/RedisAndroid.java +++ b/redis-android/src/main/java/io/wf9a5m75/redis/RedisAndroid.java @@ -120,7 +120,7 @@ public static void start(Context context, Bundle options) { configs.putString("appendfsync", "everysec"); configs.putString("no-appendfsync-on-rewrite", "no"); configs.putString("auto-aof-rewrite-percentage", "100"); - configs.putString("auto-aof-rewrite-min-size", "64mb"); + configs.putString("auto-aof-rewrite-min-size", "5mb"); configs.putString("aof-load-truncated", "yes"); configs.putString("aof-use-rdb-preamble", "no"); diff --git a/redis-android/src/main/jni/Application.mk b/redis-android/src/main/jni/Application.mk index 16789c4..708f933 100644 --- a/redis-android/src/main/jni/Application.mk +++ b/redis-android/src/main/jni/Application.mk @@ -1,4 +1,5 @@ #NDK_TOOLCHAIN_VERSION := 4.9 #APP_CFLAGS := -fexceptions -std=c11 -APP_PLATFORM := android-15 +APP_PLATFORM := android-16 +APP_PIE := true #APP_ABI := armeabi-v7a \ No newline at end of file diff --git a/redis-android/src/main/jni/redis-4.0.6/src/version.h b/redis-android/src/main/jni/redis-4.0.6/src/version.h deleted file mode 100644 index 1ec63fc..0000000 --- a/redis-android/src/main/jni/redis-4.0.6/src/version.h +++ /dev/null @@ -1 +0,0 @@ -#define REDIS_VERSION "4.0.6" diff --git a/redis-android/src/main/jni/redis-4.0.6/.gitignore b/redis-android/src/main/jni/redis-4.0.8/.gitignore similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/.gitignore rename to redis-android/src/main/jni/redis-4.0.8/.gitignore diff --git a/redis-android/src/main/jni/redis-4.0.6/00-RELEASENOTES b/redis-android/src/main/jni/redis-4.0.8/00-RELEASENOTES similarity index 94% rename from redis-android/src/main/jni/redis-4.0.6/00-RELEASENOTES rename to redis-android/src/main/jni/redis-4.0.8/00-RELEASENOTES index a2d875c..1fc1902 100644 --- a/redis-android/src/main/jni/redis-4.0.6/00-RELEASENOTES +++ b/redis-android/src/main/jni/redis-4.0.8/00-RELEASENOTES @@ -10,6 +10,255 @@ HIGH: There is a critical bug that may affect a subset of users. Upgrade! CRITICAL: There is a critical bug affecting MOST USERS. Upgrade ASAP. -------------------------------------------------------------------------------- +================================================================================ +Redis 4.0.8 Released Fri Feb 2 11:17:40 CET 2018 +================================================================================ + +Upgrade urgency CRITICAL ONLY for Redis Cluster users. Otherwise no reason +to upgrade at all. + +Redis 4.0.8 fixes a single critical bug in the radix tree data structure +used for Redis Cluster keys slot tracking. The problem was actually fixed +10 months ago into unstable, but it was fixed in a commit related to Streams +so it was never backported (for error) into the 4.0 branch. + +The problem will crash Redis Cluster instances during deletions, but it is +very hard to trigger: only when the node removed is in the edge of a memory +mapped area there are the conditions to create an issue, because otherwise +the code just accesses an out of range word in read-only way in an allocated +structure: this is almost always harmless. + +The single commit in this release: + +f603940f Rax updated to latest antirez/rax commit. (Salvatore Sanfilippo) + +Cheers, +Salvatore + +================================================================================ +Redis 4.0.7 Released Wed Jan 24 11:01:40 CET 2018 +================================================================================ + +Upgrade urgency MODERATE: Several bugs fixed, but none of critical level. + +Dear Redis Users, + +Redis 4.0.7 addresses a number of problems and adds a few things that are +very useful to have and was worth to backport into a patchlevel release. +Here is a list of the most important things, but you can find the full list +of commits below as usually: + +* Many 32 bit overflows were addressed in order to allow to use Redis with + a very significant amount of data, memory size permitting. (zhaozhao.zz, + Oran Agra) + +* MEMORY USAGE fixed for the list type. (gnuhpc) + +* Allow read-only scripts in Redis Cluster. (Salvatore Sanfilippo) + +* Fix AOF pipes setup in edge case. (heqin) + +* AUTH option for MIGRATE. (AlexStocks, Salvatore Sanfilippo, Fabio Nicotra) + +* HyperLogLogs are no longer converted from sparse to dense in order + to be merged. (Salvatore Sanfilippo) + +* Fix AOF rewrite dead loop under edge cases. (heqin) + +* Fix processing of large bulk strings (>= 2GB). (Oran Agra) + +* Added RM_UnlinkKey in modules API. (Dvir Volk) + +* Fix Redis Cluster crashes when certain commands with a variable number + of arguments are called in an improper way. (Salvatore Sanfilippo) + +* Fix memory leak in lazyfree engine. (zhaozhao.zz) + +* Fix many potentially successful partial synchronizations that end + doing a full SYNC, because of a bug destroying the replication + backlog on the slave. So after a failover the slave was often not able + to PSYNC with masters, and a full SYNC was triggered. The bug only + happened after 1 hour of uptime so escaped the unit tests. (Oran Agra) + +* Improve anti-affinity in master/slave allocation for Redis Cluster + when the cluster is created. (Salvatore Sanfilippo) + +* Improve output buffer handling for slaves, by not limiting the amount + of writes a slave could receive. (Guy Benoish) + +The full list of commits follow. + +Enjoy, +Salvatore + +jianqingdu in commit 2b99d77a: + fix not call va_end when syncWrite() failed + 1 file changed, 2 insertions(+), 2 deletions(-) + +Yusaku Kaneta in commit 5f9b9e11: + Fix the firstkey, lastkey, and keystep of moduleCommand + 1 file changed, 1 insertion(+), 1 deletion(-) + +Mark Nunberg in commit ba2d3e8e: + redismodule.h: Check ModuleNameBusy before calling it + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit 05c1f18d: + Fix integration test NOREPLICAS error time dependent false positive. + 1 file changed, 6 insertions(+), 3 deletions(-) + +antirez in commit 4acd6973: + Fix migrateCommand() access of not initialized byte. + 1 file changed, 5 insertions(+), 2 deletions(-) + +Guy Benoish in commit 548e4fe0: + Replication buffer fills up on high rate traffic. + 1 file changed, 7 insertions(+), 2 deletions(-) + +antirez in commit efa7063c: + Cluster: improve anti-affinity algo in redis-trib.rb. + 1 file changed, 131 insertions(+), 1 deletion(-) + +antirez in commit 48568ab6: + Remove useless comment from serverCron(). + 1 file changed, 2 insertions(+), 3 deletions(-) + +heqin in commit 0201dea5: + fixbug for #4545 dead loop aof rewrite + 1 file changed, 1 insertion(+), 1 deletion(-) + +antirez in commit 926beaa3: + Hopefully more clear comment to explain the change in #4607. + 1 file changed, 4 insertions(+), 3 deletions(-) + +qinchao in commit 019ad3e2: + fix assert problem in ZIP_DECODE_PREVLENSIZE , see issue: https://github.com/antirez/redis/issues/4587 + 1 file changed, 1 insertion(+), 1 deletion(-) + +Oran Agra in commit 8d9dff84: + PSYNC2 fix - promoted slave should hold on to it's backlog + 1 file changed, 5 insertions(+) + +zhaozhao.zz in commit fba2e169: + aof: format code and comment + 1 file changed, 5 insertions(+), 5 deletions(-) + +antirez in commit 7777be7b: + Put more details in the comment introduced by #4601. + 1 file changed, 8 insertions(+), 3 deletions(-) + +zhaozhao.zz in commit 91c1568b: + lazyfree: fix memory leak for lazyfree-lazy-server-del + 1 file changed, 4 insertions(+), 3 deletions(-) + +antirez in commit f9c2c1ac: + Fix getKeysUsingCommandTable() in the case of nagative arity. + 1 file changed, 7 insertions(+), 5 deletions(-) + +antirez in commit 61135f18: + Document new protocol options in #4568 into redis.conf. + 1 file changed, 14 insertions(+) + +antirez in commit e77fba4d: + proto-max-querybuf-len -> client-query-buffer-limit. + 1 file changed, 4 insertions(+), 4 deletions(-) + +antirez in commit 87fe813b: + New config options about protocol prefixed with "proto". + 4 files changed, 13 insertions(+), 13 deletions(-) + +gnuhpc in commit 2e0d2414: + Fix a typo(maybe instruction?) in crash log + 1 file changed, 1 insertion(+), 1 deletion(-) + +Dvir Volk in commit 9f7e214e: + Added RM_UnlinkKey - a low level analog to UNLINK command + 3 files changed, 56 insertions(+) + +zhaozhao.zz in commit 947077bb: + redis-benchmark: bugfix - handle zero liveclients in right way + 1 file changed, 1 insertion(+), 1 deletion(-) + +Oran Agra in commit ff2e628f: + Add config options for max-bulk-len and max-querybuf-len mainly to support RESTORE of large keys + 4 files changed, 16 insertions(+), 1 deletion(-) + +Oran Agra in commit aefa9caa: + fix processing of large bulks (above 2GB) + 8 files changed, 39 insertions(+), 33 deletions(-) + +heqin in commit 896cf1a9: + fixbug for #4545 dead loop aof rewrite + 1 file changed, 3 insertions(+), 1 deletion(-) + +antirez in commit 5abb12e0: + Hyperloglog: refresh hdr variable correctly. + 1 file changed, 3 insertions(+), 1 deletion(-) + +antirez in commit c39a0f7c: + Hyperloglog: Support for PFMERGE sparse encoding as target. + 1 file changed, 14 insertions(+), 3 deletions(-) + +antirez in commit 8a012df9: + Hyperloglog: refactoring of sparse/dense add function. + 1 file changed, 38 insertions(+), 20 deletions(-) + +antirez in commit 549409ff: + Test: MIGRATE AUTH test added. + 1 file changed, 24 insertions(+) + +antirez in commit 47717222: + Rewrite MIGRATE AUTH option. + 1 file changed, 38 insertions(+), 12 deletions(-) + +heqin in commit d8da89ea: + fixbug for #4538 Error opening /setting AOF rewrite IPC pipes: No such file or directory + 1 file changed, 6 insertions(+), 4 deletions(-) + +antirez in commit 4fcc564a: + safe_write -> aofWrite. Function commented. + 1 file changed, 9 insertions(+), 2 deletions(-) + +zhaozhao.zz in commit 27d9c729: + aof: cast sdslen to ssize_t + 1 file changed, 1 insertion(+), 1 deletion(-) + +zhaozhao.zz in commit de4fb877: + aof: fix the short write + 1 file changed, 22 insertions(+), 1 deletion(-) + +Tomasz Poradowski in commit 1fade3d3: + always enable command history in redis-cli + 1 file changed, 2 insertions(+), 1 deletion(-) + +antirez in commit 9f4d4eef: + Cluster: allow read-only EVAL/EVALSHA in slaves. + 1 file changed, 2 insertions(+), 1 deletion(-) + +nashe in commit 8eeceabd: + Prevent off-by-one read in stringmatchlen() (fixes #4527) + 1 file changed, 1 insertion(+), 1 deletion(-) + +gnuhpc in commit 733af148: + Fix memory usage list bug + 1 file changed, 1 insertion(+), 1 deletion(-) + +zhaozhao.zz in commit c9cb699b: + dict: fix the int problem for defrag + 3 files changed, 5 insertions(+), 5 deletions(-) + +zhaozhao.zz in commit b37099a1: + dict: fix the int problem + 1 file changed, 9 insertions(+), 9 deletions(-) + +zhaozhao.zz in commit 8fe586d3: + set: fix the int problem for qsort + 1 file changed, 8 insertions(+), 2 deletions(-) + +zhaozhao.zz in commit 219e29af: + set: fix the int problem for SPOP & SRANDMEMBER + 1 file changed, 2 insertions(+), 2 deletions(-) + ================================================================================ Redis 4.0.6 Released Thu Dec 4 17:54:10 CET 2017 ================================================================================ diff --git a/redis-android/src/main/jni/redis-4.0.6/Android.mk b/redis-android/src/main/jni/redis-4.0.8/Android.mk similarity index 72% rename from redis-android/src/main/jni/redis-4.0.6/Android.mk rename to redis-android/src/main/jni/redis-4.0.8/Android.mk index a399cb0..ac72156 100644 --- a/redis-android/src/main/jni/redis-4.0.6/Android.mk +++ b/redis-android/src/main/jni/redis-4.0.8/Android.mk @@ -19,7 +19,7 @@ RELEASE_HDR := $(shell sh -c '$(SRC)/mkreleasehdr.sh') LOCAL_MODULE := redis REDIS_ANDROID := redis-android -REDIS_DIR := redis-4.0.6 +REDIS_DIR := redis-4.0.8 LOCAL_LDLIBS := -llog LOCAL_CFLAGS := -O3 -D__ANDROID__ @@ -51,7 +51,7 @@ LOCAL_STATIC_LIBRARIES += lua LOCAL_STATIC_LIBRARIES += linenoise -ifeq ($(REDIS_DIR),redis-4.0.6) +ifeq ($(REDIS_DIR),redis-4.0.8) LOCAL_SRC_FILES += \ $(SRC)/adlist.c $(SRC)/ae.c \ @@ -81,14 +81,61 @@ endif include $(BUILD_SHARED_LIBRARY) +#------------------ +# redis-check-rdb +#------------------ +include $(CLEAR_VARS) +LOCAL_MODULE := redis-check-rdb + +REDIS_ANDROID_DIR := redis-4.0.8 +REDIS_DIR := redis-4.0.8 + +# Includes lua library +LOCAL_STATIC_LIBRARIES += lua + +LOCAL_LDLIBS := -llog +LOCAL_CFLAGS := -O3 -D__ANDROID__ + +ifeq ($(REDIS_DIR),redis-4.0.8) + LOCAL_SRC_FILES += \ + $(SRC)/redis-check-rdb.c + +endif + +#include $(BUILD_EXECUTABLE) + +#------------------ +# redis-check-aof +#------------------ +include $(CLEAR_VARS) +LOCAL_MODULE := redis-check-aof + +REDIS_ANDROID_DIR := redis-4.0.8 +REDIS_DIR := redis-4.0.8 + +# Includes lua library +LOCAL_STATIC_LIBRARIES += lua + +LOCAL_LDLIBS := -llog +LOCAL_CFLAGS := -O3 -D__ANDROID__ + +ifeq ($(REDIS_DIR),redis-4.0.8) + LOCAL_SRC_FILES += \ + $(SRC)/redis-check-aof.c $(SRC)/zmalloc.c $(SRC)/server.c \ + $(SRC)/util.c $(SRC)/ae.c $(SRC)/sds.c $(SRC)/SHA1.c + +endif + +#include $(BUILD_EXECUTABLE) + #------------------ # redis-cli #------------------ include $(CLEAR_VARS) LOCAL_MODULE := redis-cli -REDIS_ANDROID_DIR := redis-3.2.5 -REDIS_DIR := redis-3.2.5 +REDIS_ANDROID_DIR := redis-4.0.8 +REDIS_DIR := redis-4.0.8 # Includes linenoise library @@ -106,7 +153,7 @@ LOCAL_SRC_FILES += \ $(SRC)/release.c $(SRC)/crc64.c \ $(SRC)/ae.c -PROJECT_PATH := $(abspath $(SOURCE_PATH)/../../) +#### PROJECT_PATH := $(abspath $(SOURCE_PATH)/../../) #### TARGET_OUT := $(PROJECT_PATH)/res/raw/ #### $(warning $(TARGET_OUT)) diff --git a/redis-android/src/main/jni/redis-4.0.6/BUGS b/redis-android/src/main/jni/redis-4.0.8/BUGS similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/BUGS rename to redis-android/src/main/jni/redis-4.0.8/BUGS diff --git a/redis-android/src/main/jni/redis-4.0.6/CONTRIBUTING b/redis-android/src/main/jni/redis-4.0.8/CONTRIBUTING similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/CONTRIBUTING rename to redis-android/src/main/jni/redis-4.0.8/CONTRIBUTING diff --git a/redis-android/src/main/jni/redis-4.0.6/COPYING b/redis-android/src/main/jni/redis-4.0.8/COPYING similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/COPYING rename to redis-android/src/main/jni/redis-4.0.8/COPYING diff --git a/redis-android/src/main/jni/redis-4.0.6/INSTALL b/redis-android/src/main/jni/redis-4.0.8/INSTALL similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/INSTALL rename to redis-android/src/main/jni/redis-4.0.8/INSTALL diff --git a/redis-android/src/main/jni/redis-4.0.6/MANIFESTO b/redis-android/src/main/jni/redis-4.0.8/MANIFESTO similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/MANIFESTO rename to redis-android/src/main/jni/redis-4.0.8/MANIFESTO diff --git a/redis-android/src/main/jni/redis-4.0.6/Makefile b/redis-android/src/main/jni/redis-4.0.8/Makefile similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/Makefile rename to redis-android/src/main/jni/redis-4.0.8/Makefile diff --git a/redis-android/src/main/jni/redis-4.0.6/README.md b/redis-android/src/main/jni/redis-4.0.8/README.md similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/README.md rename to redis-android/src/main/jni/redis-4.0.8/README.md diff --git a/redis-android/src/main/jni/redis-4.0.8/android-elf-cleaner b/redis-android/src/main/jni/redis-4.0.8/android-elf-cleaner new file mode 100755 index 0000000000000000000000000000000000000000..2f1111e52a0059df827ad5c095bc3eb0487c6416 GIT binary patch literal 13500 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 literal 0 HcmV?d00001 diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/Android.mk b/redis-android/src/main/jni/redis-4.0.8/deps/Android.mk similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/Android.mk rename to redis-android/src/main/jni/redis-4.0.8/deps/Android.mk diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/Makefile b/redis-android/src/main/jni/redis-4.0.8/deps/Makefile similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/Makefile rename to redis-android/src/main/jni/redis-4.0.8/deps/Makefile diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/README.md b/redis-android/src/main/jni/redis-4.0.8/deps/README.md similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/README.md rename to redis-android/src/main/jni/redis-4.0.8/deps/README.md diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/hiredis/.gitignore b/redis-android/src/main/jni/redis-4.0.8/deps/hiredis/.gitignore similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/hiredis/.gitignore rename to redis-android/src/main/jni/redis-4.0.8/deps/hiredis/.gitignore diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/hiredis/.travis.yml b/redis-android/src/main/jni/redis-4.0.8/deps/hiredis/.travis.yml similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/hiredis/.travis.yml rename to redis-android/src/main/jni/redis-4.0.8/deps/hiredis/.travis.yml diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/hiredis/Android.mk b/redis-android/src/main/jni/redis-4.0.8/deps/hiredis/Android.mk similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/hiredis/Android.mk rename to redis-android/src/main/jni/redis-4.0.8/deps/hiredis/Android.mk diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/hiredis/CHANGELOG.md b/redis-android/src/main/jni/redis-4.0.8/deps/hiredis/CHANGELOG.md similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/hiredis/CHANGELOG.md rename to redis-android/src/main/jni/redis-4.0.8/deps/hiredis/CHANGELOG.md diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/hiredis/COPYING b/redis-android/src/main/jni/redis-4.0.8/deps/hiredis/COPYING similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/hiredis/COPYING rename to redis-android/src/main/jni/redis-4.0.8/deps/hiredis/COPYING diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/hiredis/Makefile b/redis-android/src/main/jni/redis-4.0.8/deps/hiredis/Makefile similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/hiredis/Makefile rename to redis-android/src/main/jni/redis-4.0.8/deps/hiredis/Makefile diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/hiredis/README.md b/redis-android/src/main/jni/redis-4.0.8/deps/hiredis/README.md similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/hiredis/README.md rename to redis-android/src/main/jni/redis-4.0.8/deps/hiredis/README.md diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/hiredis/adapters/ae.h b/redis-android/src/main/jni/redis-4.0.8/deps/hiredis/adapters/ae.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/hiredis/adapters/ae.h rename to redis-android/src/main/jni/redis-4.0.8/deps/hiredis/adapters/ae.h diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/hiredis/adapters/glib.h b/redis-android/src/main/jni/redis-4.0.8/deps/hiredis/adapters/glib.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/hiredis/adapters/glib.h rename to redis-android/src/main/jni/redis-4.0.8/deps/hiredis/adapters/glib.h diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/hiredis/adapters/ivykis.h b/redis-android/src/main/jni/redis-4.0.8/deps/hiredis/adapters/ivykis.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/hiredis/adapters/ivykis.h rename to redis-android/src/main/jni/redis-4.0.8/deps/hiredis/adapters/ivykis.h diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/hiredis/adapters/libev.h b/redis-android/src/main/jni/redis-4.0.8/deps/hiredis/adapters/libev.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/hiredis/adapters/libev.h rename to redis-android/src/main/jni/redis-4.0.8/deps/hiredis/adapters/libev.h diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/hiredis/adapters/libevent.h b/redis-android/src/main/jni/redis-4.0.8/deps/hiredis/adapters/libevent.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/hiredis/adapters/libevent.h rename to redis-android/src/main/jni/redis-4.0.8/deps/hiredis/adapters/libevent.h diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/hiredis/adapters/libuv.h b/redis-android/src/main/jni/redis-4.0.8/deps/hiredis/adapters/libuv.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/hiredis/adapters/libuv.h rename to redis-android/src/main/jni/redis-4.0.8/deps/hiredis/adapters/libuv.h diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/hiredis/adapters/macosx.h b/redis-android/src/main/jni/redis-4.0.8/deps/hiredis/adapters/macosx.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/hiredis/adapters/macosx.h rename to redis-android/src/main/jni/redis-4.0.8/deps/hiredis/adapters/macosx.h diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/hiredis/adapters/qt.h b/redis-android/src/main/jni/redis-4.0.8/deps/hiredis/adapters/qt.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/hiredis/adapters/qt.h rename to redis-android/src/main/jni/redis-4.0.8/deps/hiredis/adapters/qt.h diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/hiredis/appveyor.yml b/redis-android/src/main/jni/redis-4.0.8/deps/hiredis/appveyor.yml similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/hiredis/appveyor.yml rename to redis-android/src/main/jni/redis-4.0.8/deps/hiredis/appveyor.yml diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/hiredis/async.c b/redis-android/src/main/jni/redis-4.0.8/deps/hiredis/async.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/hiredis/async.c rename to redis-android/src/main/jni/redis-4.0.8/deps/hiredis/async.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/hiredis/async.h b/redis-android/src/main/jni/redis-4.0.8/deps/hiredis/async.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/hiredis/async.h rename to redis-android/src/main/jni/redis-4.0.8/deps/hiredis/async.h diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/hiredis/dict.c b/redis-android/src/main/jni/redis-4.0.8/deps/hiredis/dict.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/hiredis/dict.c rename to redis-android/src/main/jni/redis-4.0.8/deps/hiredis/dict.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/hiredis/dict.h b/redis-android/src/main/jni/redis-4.0.8/deps/hiredis/dict.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/hiredis/dict.h rename to redis-android/src/main/jni/redis-4.0.8/deps/hiredis/dict.h diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/hiredis/examples/example-ae.c b/redis-android/src/main/jni/redis-4.0.8/deps/hiredis/examples/example-ae.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/hiredis/examples/example-ae.c rename to redis-android/src/main/jni/redis-4.0.8/deps/hiredis/examples/example-ae.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/hiredis/examples/example-glib.c b/redis-android/src/main/jni/redis-4.0.8/deps/hiredis/examples/example-glib.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/hiredis/examples/example-glib.c rename to redis-android/src/main/jni/redis-4.0.8/deps/hiredis/examples/example-glib.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/hiredis/examples/example-ivykis.c b/redis-android/src/main/jni/redis-4.0.8/deps/hiredis/examples/example-ivykis.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/hiredis/examples/example-ivykis.c rename to redis-android/src/main/jni/redis-4.0.8/deps/hiredis/examples/example-ivykis.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/hiredis/examples/example-libev.c b/redis-android/src/main/jni/redis-4.0.8/deps/hiredis/examples/example-libev.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/hiredis/examples/example-libev.c rename to redis-android/src/main/jni/redis-4.0.8/deps/hiredis/examples/example-libev.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/hiredis/examples/example-libevent.c b/redis-android/src/main/jni/redis-4.0.8/deps/hiredis/examples/example-libevent.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/hiredis/examples/example-libevent.c rename to redis-android/src/main/jni/redis-4.0.8/deps/hiredis/examples/example-libevent.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/hiredis/examples/example-libuv.c b/redis-android/src/main/jni/redis-4.0.8/deps/hiredis/examples/example-libuv.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/hiredis/examples/example-libuv.c rename to redis-android/src/main/jni/redis-4.0.8/deps/hiredis/examples/example-libuv.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/hiredis/examples/example-macosx.c b/redis-android/src/main/jni/redis-4.0.8/deps/hiredis/examples/example-macosx.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/hiredis/examples/example-macosx.c rename to redis-android/src/main/jni/redis-4.0.8/deps/hiredis/examples/example-macosx.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/hiredis/examples/example-qt.cpp b/redis-android/src/main/jni/redis-4.0.8/deps/hiredis/examples/example-qt.cpp similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/hiredis/examples/example-qt.cpp rename to redis-android/src/main/jni/redis-4.0.8/deps/hiredis/examples/example-qt.cpp diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/hiredis/examples/example-qt.h b/redis-android/src/main/jni/redis-4.0.8/deps/hiredis/examples/example-qt.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/hiredis/examples/example-qt.h rename to redis-android/src/main/jni/redis-4.0.8/deps/hiredis/examples/example-qt.h diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/hiredis/examples/example.c b/redis-android/src/main/jni/redis-4.0.8/deps/hiredis/examples/example.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/hiredis/examples/example.c rename to redis-android/src/main/jni/redis-4.0.8/deps/hiredis/examples/example.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/hiredis/fmacros.h b/redis-android/src/main/jni/redis-4.0.8/deps/hiredis/fmacros.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/hiredis/fmacros.h rename to redis-android/src/main/jni/redis-4.0.8/deps/hiredis/fmacros.h diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/hiredis/hiredis.c b/redis-android/src/main/jni/redis-4.0.8/deps/hiredis/hiredis.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/hiredis/hiredis.c rename to redis-android/src/main/jni/redis-4.0.8/deps/hiredis/hiredis.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/hiredis/hiredis.h b/redis-android/src/main/jni/redis-4.0.8/deps/hiredis/hiredis.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/hiredis/hiredis.h rename to redis-android/src/main/jni/redis-4.0.8/deps/hiredis/hiredis.h diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/hiredis/net.c b/redis-android/src/main/jni/redis-4.0.8/deps/hiredis/net.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/hiredis/net.c rename to redis-android/src/main/jni/redis-4.0.8/deps/hiredis/net.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/hiredis/net.h b/redis-android/src/main/jni/redis-4.0.8/deps/hiredis/net.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/hiredis/net.h rename to redis-android/src/main/jni/redis-4.0.8/deps/hiredis/net.h diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/hiredis/read.c b/redis-android/src/main/jni/redis-4.0.8/deps/hiredis/read.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/hiredis/read.c rename to redis-android/src/main/jni/redis-4.0.8/deps/hiredis/read.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/hiredis/read.h b/redis-android/src/main/jni/redis-4.0.8/deps/hiredis/read.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/hiredis/read.h rename to redis-android/src/main/jni/redis-4.0.8/deps/hiredis/read.h diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/hiredis/sds.c b/redis-android/src/main/jni/redis-4.0.8/deps/hiredis/sds.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/hiredis/sds.c rename to redis-android/src/main/jni/redis-4.0.8/deps/hiredis/sds.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/hiredis/sds.h b/redis-android/src/main/jni/redis-4.0.8/deps/hiredis/sds.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/hiredis/sds.h rename to redis-android/src/main/jni/redis-4.0.8/deps/hiredis/sds.h diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/hiredis/sdsalloc.h b/redis-android/src/main/jni/redis-4.0.8/deps/hiredis/sdsalloc.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/hiredis/sdsalloc.h rename to redis-android/src/main/jni/redis-4.0.8/deps/hiredis/sdsalloc.h diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/hiredis/test.c b/redis-android/src/main/jni/redis-4.0.8/deps/hiredis/test.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/hiredis/test.c rename to redis-android/src/main/jni/redis-4.0.8/deps/hiredis/test.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/hiredis/win32.h b/redis-android/src/main/jni/redis-4.0.8/deps/hiredis/win32.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/hiredis/win32.h rename to redis-android/src/main/jni/redis-4.0.8/deps/hiredis/win32.h diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/.autom4te.cfg b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/.autom4te.cfg new file mode 100644 index 0000000..fe2424d --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/.autom4te.cfg @@ -0,0 +1,3 @@ +begin-language: "Autoconf-without-aclocal-m4" +args: --no-cache +end-language: "Autoconf-without-aclocal-m4" diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/.gitattributes b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/.gitattributes new file mode 100644 index 0000000..6313b56 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/.gitattributes @@ -0,0 +1 @@ +* text=auto eol=lf diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/.gitignore b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/.gitignore new file mode 100644 index 0000000..d0e3936 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/.gitignore @@ -0,0 +1,75 @@ +/*.gcov.* + +/bin/jemalloc-config +/bin/jemalloc.sh +/bin/jeprof + +/config.stamp +/config.log +/config.status +/configure + +/doc/html.xsl +/doc/manpages.xsl +/doc/jemalloc.xml +/doc/jemalloc.html +/doc/jemalloc.3 + +/jemalloc.pc + +/lib/ + +/Makefile + +/include/jemalloc/internal/jemalloc_internal.h +/include/jemalloc/internal/jemalloc_internal_defs.h +/include/jemalloc/internal/private_namespace.h +/include/jemalloc/internal/private_unnamespace.h +/include/jemalloc/internal/public_namespace.h +/include/jemalloc/internal/public_symbols.txt +/include/jemalloc/internal/public_unnamespace.h +/include/jemalloc/internal/size_classes.h +/include/jemalloc/jemalloc.h +/include/jemalloc/jemalloc_defs.h +/include/jemalloc/jemalloc_macros.h +/include/jemalloc/jemalloc_mangle.h +/include/jemalloc/jemalloc_mangle_jet.h +/include/jemalloc/jemalloc_protos.h +/include/jemalloc/jemalloc_protos_jet.h +/include/jemalloc/jemalloc_rename.h +/include/jemalloc/jemalloc_typedefs.h + +/src/*.[od] +/src/*.gcda +/src/*.gcno + +/test/test.sh +test/include/test/jemalloc_test.h +test/include/test/jemalloc_test_defs.h + +/test/integration/[A-Za-z]* +!/test/integration/[A-Za-z]*.* +/test/integration/*.[od] +/test/integration/*.gcda +/test/integration/*.gcno +/test/integration/*.out + +/test/src/*.[od] +/test/src/*.gcda +/test/src/*.gcno + +/test/stress/[A-Za-z]* +!/test/stress/[A-Za-z]*.* +/test/stress/*.[od] +/test/stress/*.gcda +/test/stress/*.gcno +/test/stress/*.out + +/test/unit/[A-Za-z]* +!/test/unit/[A-Za-z]*.* +/test/unit/*.[od] +/test/unit/*.gcda +/test/unit/*.gcno +/test/unit/*.out + +/VERSION diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/COPYING b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/COPYING new file mode 100644 index 0000000..611968c --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/COPYING @@ -0,0 +1,27 @@ +Unless otherwise specified, files in the jemalloc source distribution are +subject to the following license: +-------------------------------------------------------------------------------- +Copyright (C) 2002-2015 Jason Evans . +All rights reserved. +Copyright (C) 2007-2012 Mozilla Foundation. All rights reserved. +Copyright (C) 2009-2015 Facebook, Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: +1. Redistributions of source code must retain the above copyright notice(s), + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice(s), + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY EXPRESS +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +-------------------------------------------------------------------------------- diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/ChangeLog b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/ChangeLog new file mode 100644 index 0000000..e3b0a51 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/ChangeLog @@ -0,0 +1,788 @@ +Following are change highlights associated with official releases. Important +bug fixes are all mentioned, but some internal enhancements are omitted here for +brevity. Much more detail can be found in the git revision history: + + https://github.com/jemalloc/jemalloc + +* 4.0.3 (September 24, 2015) + + This bugfix release continues the trend of xallocx() and heap profiling fixes. + + Bug fixes: + - Fix xallocx(..., MALLOCX_ZERO) to zero all trailing bytes of large + allocations when --enable-cache-oblivious configure option is enabled. + - Fix xallocx(..., MALLOCX_ZERO) to zero trailing bytes of huge allocations + when resizing from/to a size class that is not a multiple of the chunk size. + - Fix prof_tctx_dump_iter() to filter out nodes that were created after heap + profile dumping started. + - Work around a potentially bad thread-specific data initialization + interaction with NPTL (glibc's pthreads implementation). + +* 4.0.2 (September 21, 2015) + + This bugfix release addresses a few bugs specific to heap profiling. + + Bug fixes: + - Fix ixallocx_prof_sample() to never modify nor create sampled small + allocations. xallocx() is in general incapable of moving small allocations, + so this fix removes buggy code without loss of generality. + - Fix irallocx_prof_sample() to always allocate large regions, even when + alignment is non-zero. + - Fix prof_alloc_rollback() to read tdata from thread-specific data rather + than dereferencing a potentially invalid tctx. + +* 4.0.1 (September 15, 2015) + + This is a bugfix release that is somewhat high risk due to the amount of + refactoring required to address deep xallocx() problems. As a side effect of + these fixes, xallocx() now tries harder to partially fulfill requests for + optional extra space. Note that a couple of minor heap profiling + optimizations are included, but these are better thought of as performance + fixes that were integral to disovering most of the other bugs. + + Optimizations: + - Avoid a chunk metadata read in arena_prof_tctx_set(), since it is in the + fast path when heap profiling is enabled. Additionally, split a special + case out into arena_prof_tctx_reset(), which also avoids chunk metadata + reads. + - Optimize irallocx_prof() to optimistically update the sampler state. The + prior implementation appears to have been a holdover from when + rallocx()/xallocx() functionality was combined as rallocm(). + + Bug fixes: + - Fix TLS configuration such that it is enabled by default for platforms on + which it works correctly. + - Fix arenas_cache_cleanup() and arena_get_hard() to handle + allocation/deallocation within the application's thread-specific data + cleanup functions even after arenas_cache is torn down. + - Fix xallocx() bugs related to size+extra exceeding HUGE_MAXCLASS. + - Fix chunk purge hook calls for in-place huge shrinking reallocation to + specify the old chunk size rather than the new chunk size. This bug caused + no correctness issues for the default chunk purge function, but was + visible to custom functions set via the "arena..chunk_hooks" mallctl. + - Fix heap profiling bugs: + + Fix heap profiling to distinguish among otherwise identical sample sites + with interposed resets (triggered via the "prof.reset" mallctl). This bug + could cause data structure corruption that would most likely result in a + segfault. + + Fix irealloc_prof() to prof_alloc_rollback() on OOM. + + Make one call to prof_active_get_unlocked() per allocation event, and use + the result throughout the relevant functions that handle an allocation + event. Also add a missing check in prof_realloc(). These fixes protect + allocation events against concurrent prof_active changes. + + Fix ixallocx_prof() to pass usize_max and zero to ixallocx_prof_sample() + in the correct order. + + Fix prof_realloc() to call prof_free_sampled_object() after calling + prof_malloc_sample_object(). Prior to this fix, if tctx and old_tctx were + the same, the tctx could have been prematurely destroyed. + - Fix portability bugs: + + Don't bitshift by negative amounts when encoding/decoding run sizes in + chunk header maps. This affected systems with page sizes greater than 8 + KiB. + + Rename index_t to szind_t to avoid an existing type on Solaris. + + Add JEMALLOC_CXX_THROW to the memalign() function prototype, in order to + match glibc and avoid compilation errors when including both + jemalloc/jemalloc.h and malloc.h in C++ code. + + Don't assume that /bin/sh is appropriate when running size_classes.sh + during configuration. + + Consider __sparcv9 a synonym for __sparc64__ when defining LG_QUANTUM. + + Link tests to librt if it contains clock_gettime(2). + +* 4.0.0 (August 17, 2015) + + This version contains many speed and space optimizations, both minor and + major. The major themes are generalization, unification, and simplification. + Although many of these optimizations cause no visible behavior change, their + cumulative effect is substantial. + + New features: + - Normalize size class spacing to be consistent across the complete size + range. By default there are four size classes per size doubling, but this + is now configurable via the --with-lg-size-class-group option. Also add the + --with-lg-page, --with-lg-page-sizes, --with-lg-quantum, and + --with-lg-tiny-min options, which can be used to tweak page and size class + settings. Impacts: + + Worst case performance for incrementally growing/shrinking reallocation + is improved because there are far fewer size classes, and therefore + copying happens less often. + + Internal fragmentation is limited to 20% for all but the smallest size + classes (those less than four times the quantum). (1B + 4 KiB) + and (1B + 4 MiB) previously suffered nearly 50% internal fragmentation. + + Chunk fragmentation tends to be lower because there are fewer distinct run + sizes to pack. + - Add support for explicit tcaches. The "tcache.create", "tcache.flush", and + "tcache.destroy" mallctls control tcache lifetime and flushing, and the + MALLOCX_TCACHE(tc) and MALLOCX_TCACHE_NONE flags to the *allocx() API + control which tcache is used for each operation. + - Implement per thread heap profiling, as well as the ability to + enable/disable heap profiling on a per thread basis. Add the "prof.reset", + "prof.lg_sample", "thread.prof.name", "thread.prof.active", + "opt.prof_thread_active_init", "prof.thread_active_init", and + "thread.prof.active" mallctls. + - Add support for per arena application-specified chunk allocators, configured + via the "arena..chunk_hooks" mallctl. + - Refactor huge allocation to be managed by arenas, so that arenas now + function as general purpose independent allocators. This is important in + the context of user-specified chunk allocators, aside from the scalability + benefits. Related new statistics: + + The "stats.arenas..huge.allocated", "stats.arenas..huge.nmalloc", + "stats.arenas..huge.ndalloc", and "stats.arenas..huge.nrequests" + mallctls provide high level per arena huge allocation statistics. + + The "arenas.nhchunks", "arenas.hchunk..size", + "stats.arenas..hchunks..nmalloc", + "stats.arenas..hchunks..ndalloc", + "stats.arenas..hchunks..nrequests", and + "stats.arenas..hchunks..curhchunks" mallctls provide per size class + statistics. + - Add the 'util' column to malloc_stats_print() output, which reports the + proportion of available regions that are currently in use for each small + size class. + - Add "alloc" and "free" modes for for junk filling (see the "opt.junk" + mallctl), so that it is possible to separately enable junk filling for + allocation versus deallocation. + - Add the jemalloc-config script, which provides information about how + jemalloc was configured, and how to integrate it into application builds. + - Add metadata statistics, which are accessible via the "stats.metadata", + "stats.arenas..metadata.mapped", and + "stats.arenas..metadata.allocated" mallctls. + - Add the "stats.resident" mallctl, which reports the upper limit of + physically resident memory mapped by the allocator. + - Add per arena control over unused dirty page purging, via the + "arenas.lg_dirty_mult", "arena..lg_dirty_mult", and + "stats.arenas..lg_dirty_mult" mallctls. + - Add the "prof.gdump" mallctl, which makes it possible to toggle the gdump + feature on/off during program execution. + - Add sdallocx(), which implements sized deallocation. The primary + optimization over dallocx() is the removal of a metadata read, which often + suffers an L1 cache miss. + - Add missing header includes in jemalloc/jemalloc.h, so that applications + only have to #include . + - Add support for additional platforms: + + Bitrig + + Cygwin + + DragonFlyBSD + + iOS + + OpenBSD + + OpenRISC/or1k + + Optimizations: + - Maintain dirty runs in per arena LRUs rather than in per arena trees of + dirty-run-containing chunks. In practice this change significantly reduces + dirty page purging volume. + - Integrate whole chunks into the unused dirty page purging machinery. This + reduces the cost of repeated huge allocation/deallocation, because it + effectively introduces a cache of chunks. + - Split the arena chunk map into two separate arrays, in order to increase + cache locality for the frequently accessed bits. + - Move small run metadata out of runs, into arena chunk headers. This reduces + run fragmentation, smaller runs reduce external fragmentation for small size + classes, and packed (less uniformly aligned) metadata layout improves CPU + cache set distribution. + - Randomly distribute large allocation base pointer alignment relative to page + boundaries in order to more uniformly utilize CPU cache sets. This can be + disabled via the --disable-cache-oblivious configure option, and queried via + the "config.cache_oblivious" mallctl. + - Micro-optimize the fast paths for the public API functions. + - Refactor thread-specific data to reside in a single structure. This assures + that only a single TLS read is necessary per call into the public API. + - Implement in-place huge allocation growing and shrinking. + - Refactor rtree (radix tree for chunk lookups) to be lock-free, and make + additional optimizations that reduce maximum lookup depth to one or two + levels. This resolves what was a concurrency bottleneck for per arena huge + allocation, because a global data structure is critical for determining + which arenas own which huge allocations. + + Incompatible changes: + - Replace --enable-cc-silence with --disable-cc-silence to suppress spurious + warnings by default. + - Assure that the constness of malloc_usable_size()'s return type matches that + of the system implementation. + - Change the heap profile dump format to support per thread heap profiling, + rename pprof to jeprof, and enhance it with the --thread= option. As a + result, the bundled jeprof must now be used rather than the upstream + (gperftools) pprof. + - Disable "opt.prof_final" by default, in order to avoid atexit(3), which can + internally deadlock on some platforms. + - Change the "arenas.nlruns" mallctl type from size_t to unsigned. + - Replace the "stats.arenas..bins..allocated" mallctl with + "stats.arenas..bins..curregs". + - Ignore MALLOC_CONF in set{uid,gid,cap} binaries. + - Ignore MALLOCX_ARENA(a) in dallocx(), in favor of using the + MALLOCX_TCACHE(tc) and MALLOCX_TCACHE_NONE flags to control tcache usage. + + Removed features: + - Remove the *allocm() API, which is superseded by the *allocx() API. + - Remove the --enable-dss options, and make dss non-optional on all platforms + which support sbrk(2). + - Remove the "arenas.purge" mallctl, which was obsoleted by the + "arena..purge" mallctl in 3.1.0. + - Remove the unnecessary "opt.valgrind" mallctl; jemalloc automatically + detects whether it is running inside Valgrind. + - Remove the "stats.huge.allocated", "stats.huge.nmalloc", and + "stats.huge.ndalloc" mallctls. + - Remove the --enable-mremap option. + - Remove the "stats.chunks.current", "stats.chunks.total", and + "stats.chunks.high" mallctls. + + Bug fixes: + - Fix the cactive statistic to decrease (rather than increase) when active + memory decreases. This regression was first released in 3.5.0. + - Fix OOM handling in memalign() and valloc(). A variant of this bug existed + in all releases since 2.0.0, which introduced these functions. + - Fix an OOM-related regression in arena_tcache_fill_small(), which could + cause cache corruption on OOM. This regression was present in all releases + from 2.2.0 through 3.6.0. + - Fix size class overflow handling for malloc(), posix_memalign(), memalign(), + calloc(), and realloc() when profiling is enabled. + - Fix the "arena..dss" mallctl to return an error if "primary" or + "secondary" precedence is specified, but sbrk(2) is not supported. + - Fix fallback lg_floor() implementations to handle extremely large inputs. + - Ensure the default purgeable zone is after the default zone on OS X. + - Fix latent bugs in atomic_*(). + - Fix the "arena..dss" mallctl to handle read-only calls. + - Fix tls_model configuration to enable the initial-exec model when possible. + - Mark malloc_conf as a weak symbol so that the application can override it. + - Correctly detect glibc's adaptive pthread mutexes. + - Fix the --without-export configure option. + +* 3.6.0 (March 31, 2014) + + This version contains a critical bug fix for a regression present in 3.5.0 and + 3.5.1. + + Bug fixes: + - Fix a regression in arena_chunk_alloc() that caused crashes during + small/large allocation if chunk allocation failed. In the absence of this + bug, chunk allocation failure would result in allocation failure, e.g. NULL + return from malloc(). This regression was introduced in 3.5.0. + - Fix backtracing for gcc intrinsics-based backtracing by specifying + -fno-omit-frame-pointer to gcc. Note that the application (and all the + libraries it links to) must also be compiled with this option for + backtracing to be reliable. + - Use dss allocation precedence for huge allocations as well as small/large + allocations. + - Fix test assertion failure message formatting. This bug did not manifest on + x86_64 systems because of implementation subtleties in va_list. + - Fix inconsequential test failures for hash and SFMT code. + + New features: + - Support heap profiling on FreeBSD. This feature depends on the proc + filesystem being mounted during heap profile dumping. + +* 3.5.1 (February 25, 2014) + + This version primarily addresses minor bugs in test code. + + Bug fixes: + - Configure Solaris/Illumos to use MADV_FREE. + - Fix junk filling for mremap(2)-based huge reallocation. This is only + relevant if configuring with the --enable-mremap option specified. + - Avoid compilation failure if 'restrict' C99 keyword is not supported by the + compiler. + - Add a configure test for SSE2 rather than assuming it is usable on i686 + systems. This fixes test compilation errors, especially on 32-bit Linux + systems. + - Fix mallctl argument size mismatches (size_t vs. uint64_t) in the stats unit + test. + - Fix/remove flawed alignment-related overflow tests. + - Prevent compiler optimizations that could change backtraces in the + prof_accum unit test. + +* 3.5.0 (January 22, 2014) + + This version focuses on refactoring and automated testing, though it also + includes some non-trivial heap profiling optimizations not mentioned below. + + New features: + - Add the *allocx() API, which is a successor to the experimental *allocm() + API. The *allocx() functions are slightly simpler to use because they have + fewer parameters, they directly return the results of primary interest, and + mallocx()/rallocx() avoid the strict aliasing pitfall that + allocm()/rallocm() share with posix_memalign(). Note that *allocm() is + slated for removal in the next non-bugfix release. + - Add support for LinuxThreads. + + Bug fixes: + - Unless heap profiling is enabled, disable floating point code and don't link + with libm. This, in combination with e.g. EXTRA_CFLAGS=-mno-sse on x64 + systems, makes it possible to completely disable floating point register + use. Some versions of glibc neglect to save/restore caller-saved floating + point registers during dynamic lazy symbol loading, and the symbol loading + code uses whatever malloc the application happens to have linked/loaded + with, the result being potential floating point register corruption. + - Report ENOMEM rather than EINVAL if an OOM occurs during heap profiling + backtrace creation in imemalign(). This bug impacted posix_memalign() and + aligned_alloc(). + - Fix a file descriptor leak in a prof_dump_maps() error path. + - Fix prof_dump() to close the dump file descriptor for all relevant error + paths. + - Fix rallocm() to use the arena specified by the ALLOCM_ARENA(s) flag for + allocation, not just deallocation. + - Fix a data race for large allocation stats counters. + - Fix a potential infinite loop during thread exit. This bug occurred on + Solaris, and could affect other platforms with similar pthreads TSD + implementations. + - Don't junk-fill reallocations unless usable size changes. This fixes a + violation of the *allocx()/*allocm() semantics. + - Fix growing large reallocation to junk fill new space. + - Fix huge deallocation to junk fill when munmap is disabled. + - Change the default private namespace prefix from empty to je_, and change + --with-private-namespace-prefix so that it prepends an additional prefix + rather than replacing je_. This reduces the likelihood of applications + which statically link jemalloc experiencing symbol name collisions. + - Add missing private namespace mangling (relevant when + --with-private-namespace is specified). + - Add and use JEMALLOC_INLINE_C so that static inline functions are marked as + static even for debug builds. + - Add a missing mutex unlock in a malloc_init_hard() error path. In practice + this error path is never executed. + - Fix numerous bugs in malloc_strotumax() error handling/reporting. These + bugs had no impact except for malformed inputs. + - Fix numerous bugs in malloc_snprintf(). These bugs were not exercised by + existing calls, so they had no impact. + +* 3.4.1 (October 20, 2013) + + Bug fixes: + - Fix a race in the "arenas.extend" mallctl that could cause memory corruption + of internal data structures and subsequent crashes. + - Fix Valgrind integration flaws that caused Valgrind warnings about reads of + uninitialized memory in: + + arena chunk headers + + internal zero-initialized data structures (relevant to tcache and prof + code) + - Preserve errno during the first allocation. A readlink(2) call during + initialization fails unless /etc/malloc.conf exists, so errno was typically + set during the first allocation prior to this fix. + - Fix compilation warnings reported by gcc 4.8.1. + +* 3.4.0 (June 2, 2013) + + This version is essentially a small bugfix release, but the addition of + aarch64 support requires that the minor version be incremented. + + Bug fixes: + - Fix race-triggered deadlocks in chunk_record(). These deadlocks were + typically triggered by multiple threads concurrently deallocating huge + objects. + + New features: + - Add support for the aarch64 architecture. + +* 3.3.1 (March 6, 2013) + + This version fixes bugs that are typically encountered only when utilizing + custom run-time options. + + Bug fixes: + - Fix a locking order bug that could cause deadlock during fork if heap + profiling were enabled. + - Fix a chunk recycling bug that could cause the allocator to lose track of + whether a chunk was zeroed. On FreeBSD, NetBSD, and OS X, it could cause + corruption if allocating via sbrk(2) (unlikely unless running with the + "dss:primary" option specified). This was completely harmless on Linux + unless using mlockall(2) (and unlikely even then, unless the + --disable-munmap configure option or the "dss:primary" option was + specified). This regression was introduced in 3.1.0 by the + mlockall(2)/madvise(2) interaction fix. + - Fix TLS-related memory corruption that could occur during thread exit if the + thread never allocated memory. Only the quarantine and prof facilities were + susceptible. + - Fix two quarantine bugs: + + Internal reallocation of the quarantined object array leaked the old + array. + + Reallocation failure for internal reallocation of the quarantined object + array (very unlikely) resulted in memory corruption. + - Fix Valgrind integration to annotate all internally allocated memory in a + way that keeps Valgrind happy about internal data structure access. + - Fix building for s390 systems. + +* 3.3.0 (January 23, 2013) + + This version includes a few minor performance improvements in addition to the + listed new features and bug fixes. + + New features: + - Add clipping support to lg_chunk option processing. + - Add the --enable-ivsalloc option. + - Add the --without-export option. + - Add the --disable-zone-allocator option. + + Bug fixes: + - Fix "arenas.extend" mallctl to output the number of arenas. + - Fix chunk_recycle() to unconditionally inform Valgrind that returned memory + is undefined. + - Fix build break on FreeBSD related to alloca.h. + +* 3.2.0 (November 9, 2012) + + In addition to a couple of bug fixes, this version modifies page run + allocation and dirty page purging algorithms in order to better control + page-level virtual memory fragmentation. + + Incompatible changes: + - Change the "opt.lg_dirty_mult" default from 5 to 3 (32:1 to 8:1). + + Bug fixes: + - Fix dss/mmap allocation precedence code to use recyclable mmap memory only + after primary dss allocation fails. + - Fix deadlock in the "arenas.purge" mallctl. This regression was introduced + in 3.1.0 by the addition of the "arena..purge" mallctl. + +* 3.1.0 (October 16, 2012) + + New features: + - Auto-detect whether running inside Valgrind, thus removing the need to + manually specify MALLOC_CONF=valgrind:true. + - Add the "arenas.extend" mallctl, which allows applications to create + manually managed arenas. + - Add the ALLOCM_ARENA() flag for {,r,d}allocm(). + - Add the "opt.dss", "arena..dss", and "stats.arenas..dss" mallctls, + which provide control over dss/mmap precedence. + - Add the "arena..purge" mallctl, which obsoletes "arenas.purge". + - Define LG_QUANTUM for hppa. + + Incompatible changes: + - Disable tcache by default if running inside Valgrind, in order to avoid + making unallocated objects appear reachable to Valgrind. + - Drop const from malloc_usable_size() argument on Linux. + + Bug fixes: + - Fix heap profiling crash if sampled object is freed via realloc(p, 0). + - Remove const from __*_hook variable declarations, so that glibc can modify + them during process forking. + - Fix mlockall(2)/madvise(2) interaction. + - Fix fork(2)-related deadlocks. + - Fix error return value for "thread.tcache.enabled" mallctl. + +* 3.0.0 (May 11, 2012) + + Although this version adds some major new features, the primary focus is on + internal code cleanup that facilitates maintainability and portability, most + of which is not reflected in the ChangeLog. This is the first release to + incorporate substantial contributions from numerous other developers, and the + result is a more broadly useful allocator (see the git revision history for + contribution details). Note that the license has been unified, thanks to + Facebook granting a license under the same terms as the other copyright + holders (see COPYING). + + New features: + - Implement Valgrind support, redzones, and quarantine. + - Add support for additional platforms: + + FreeBSD + + Mac OS X Lion + + MinGW + + Windows (no support yet for replacing the system malloc) + - Add support for additional architectures: + + MIPS + + SH4 + + Tilera + - Add support for cross compiling. + - Add nallocm(), which rounds a request size up to the nearest size class + without actually allocating. + - Implement aligned_alloc() (blame C11). + - Add the "thread.tcache.enabled" mallctl. + - Add the "opt.prof_final" mallctl. + - Update pprof (from gperftools 2.0). + - Add the --with-mangling option. + - Add the --disable-experimental option. + - Add the --disable-munmap option, and make it the default on Linux. + - Add the --enable-mremap option, which disables use of mremap(2) by default. + + Incompatible changes: + - Enable stats by default. + - Enable fill by default. + - Disable lazy locking by default. + - Rename the "tcache.flush" mallctl to "thread.tcache.flush". + - Rename the "arenas.pagesize" mallctl to "arenas.page". + - Change the "opt.lg_prof_sample" default from 0 to 19 (1 B to 512 KiB). + - Change the "opt.prof_accum" default from true to false. + + Removed features: + - Remove the swap feature, including the "config.swap", "swap.avail", + "swap.prezeroed", "swap.nfds", and "swap.fds" mallctls. + - Remove highruns statistics, including the + "stats.arenas..bins..highruns" and + "stats.arenas..lruns..highruns" mallctls. + - As part of small size class refactoring, remove the "opt.lg_[qc]space_max", + "arenas.cacheline", "arenas.subpage", "arenas.[tqcs]space_{min,max}", and + "arenas.[tqcs]bins" mallctls. + - Remove the "arenas.chunksize" mallctl. + - Remove the "opt.lg_prof_tcmax" option. + - Remove the "opt.lg_prof_bt_max" option. + - Remove the "opt.lg_tcache_gc_sweep" option. + - Remove the --disable-tiny option, including the "config.tiny" mallctl. + - Remove the --enable-dynamic-page-shift configure option. + - Remove the --enable-sysv configure option. + + Bug fixes: + - Fix a statistics-related bug in the "thread.arena" mallctl that could cause + invalid statistics and crashes. + - Work around TLS deallocation via free() on Linux. This bug could cause + write-after-free memory corruption. + - Fix a potential deadlock that could occur during interval- and + growth-triggered heap profile dumps. + - Fix large calloc() zeroing bugs due to dropping chunk map unzeroed flags. + - Fix chunk_alloc_dss() to stop claiming memory is zeroed. This bug could + cause memory corruption and crashes with --enable-dss specified. + - Fix fork-related bugs that could cause deadlock in children between fork + and exec. + - Fix malloc_stats_print() to honor 'b' and 'l' in the opts parameter. + - Fix realloc(p, 0) to act like free(p). + - Do not enforce minimum alignment in memalign(). + - Check for NULL pointer in malloc_usable_size(). + - Fix an off-by-one heap profile statistics bug that could be observed in + interval- and growth-triggered heap profiles. + - Fix the "epoch" mallctl to update cached stats even if the passed in epoch + is 0. + - Fix bin->runcur management to fix a layout policy bug. This bug did not + affect correctness. + - Fix a bug in choose_arena_hard() that potentially caused more arenas to be + initialized than necessary. + - Add missing "opt.lg_tcache_max" mallctl implementation. + - Use glibc allocator hooks to make mixed allocator usage less likely. + - Fix build issues for --disable-tcache. + - Don't mangle pthread_create() when --with-private-namespace is specified. + +* 2.2.5 (November 14, 2011) + + Bug fixes: + - Fix huge_ralloc() race when using mremap(2). This is a serious bug that + could cause memory corruption and/or crashes. + - Fix huge_ralloc() to maintain chunk statistics. + - Fix malloc_stats_print(..., "a") output. + +* 2.2.4 (November 5, 2011) + + Bug fixes: + - Initialize arenas_tsd before using it. This bug existed for 2.2.[0-3], as + well as for --disable-tls builds in earlier releases. + - Do not assume a 4 KiB page size in test/rallocm.c. + +* 2.2.3 (August 31, 2011) + + This version fixes numerous bugs related to heap profiling. + + Bug fixes: + - Fix a prof-related race condition. This bug could cause memory corruption, + but only occurred in non-default configurations (prof_accum:false). + - Fix off-by-one backtracing issues (make sure that prof_alloc_prep() is + excluded from backtraces). + - Fix a prof-related bug in realloc() (only triggered by OOM errors). + - Fix prof-related bugs in allocm() and rallocm(). + - Fix prof_tdata_cleanup() for --disable-tls builds. + - Fix a relative include path, to fix objdir builds. + +* 2.2.2 (July 30, 2011) + + Bug fixes: + - Fix a build error for --disable-tcache. + - Fix assertions in arena_purge() (for real this time). + - Add the --with-private-namespace option. This is a workaround for symbol + conflicts that can inadvertently arise when using static libraries. + +* 2.2.1 (March 30, 2011) + + Bug fixes: + - Implement atomic operations for x86/x64. This fixes compilation failures + for versions of gcc that are still in wide use. + - Fix an assertion in arena_purge(). + +* 2.2.0 (March 22, 2011) + + This version incorporates several improvements to algorithms and data + structures that tend to reduce fragmentation and increase speed. + + New features: + - Add the "stats.cactive" mallctl. + - Update pprof (from google-perftools 1.7). + - Improve backtracing-related configuration logic, and add the + --disable-prof-libgcc option. + + Bug fixes: + - Change default symbol visibility from "internal", to "hidden", which + decreases the overhead of library-internal function calls. + - Fix symbol visibility so that it is also set on OS X. + - Fix a build dependency regression caused by the introduction of the .pic.o + suffix for PIC object files. + - Add missing checks for mutex initialization failures. + - Don't use libgcc-based backtracing except on x64, where it is known to work. + - Fix deadlocks on OS X that were due to memory allocation in + pthread_mutex_lock(). + - Heap profiling-specific fixes: + + Fix memory corruption due to integer overflow in small region index + computation, when using a small enough sample interval that profiling + context pointers are stored in small run headers. + + Fix a bootstrap ordering bug that only occurred with TLS disabled. + + Fix a rallocm() rsize bug. + + Fix error detection bugs for aligned memory allocation. + +* 2.1.3 (March 14, 2011) + + Bug fixes: + - Fix a cpp logic regression (due to the "thread.{de,}allocatedp" mallctl fix + for OS X in 2.1.2). + - Fix a "thread.arena" mallctl bug. + - Fix a thread cache stats merging bug. + +* 2.1.2 (March 2, 2011) + + Bug fixes: + - Fix "thread.{de,}allocatedp" mallctl for OS X. + - Add missing jemalloc.a to build system. + +* 2.1.1 (January 31, 2011) + + Bug fixes: + - Fix aligned huge reallocation (affected allocm()). + - Fix the ALLOCM_LG_ALIGN macro definition. + - Fix a heap dumping deadlock. + - Fix a "thread.arena" mallctl bug. + +* 2.1.0 (December 3, 2010) + + This version incorporates some optimizations that can't quite be considered + bug fixes. + + New features: + - Use Linux's mremap(2) for huge object reallocation when possible. + - Avoid locking in mallctl*() when possible. + - Add the "thread.[de]allocatedp" mallctl's. + - Convert the manual page source from roff to DocBook, and generate both roff + and HTML manuals. + + Bug fixes: + - Fix a crash due to incorrect bootstrap ordering. This only impacted + --enable-debug --enable-dss configurations. + - Fix a minor statistics bug for mallctl("swap.avail", ...). + +* 2.0.1 (October 29, 2010) + + Bug fixes: + - Fix a race condition in heap profiling that could cause undefined behavior + if "opt.prof_accum" were disabled. + - Add missing mutex unlocks for some OOM error paths in the heap profiling + code. + - Fix a compilation error for non-C99 builds. + +* 2.0.0 (October 24, 2010) + + This version focuses on the experimental *allocm() API, and on improved + run-time configuration/introspection. Nonetheless, numerous performance + improvements are also included. + + New features: + - Implement the experimental {,r,s,d}allocm() API, which provides a superset + of the functionality available via malloc(), calloc(), posix_memalign(), + realloc(), malloc_usable_size(), and free(). These functions can be used to + allocate/reallocate aligned zeroed memory, ask for optional extra memory + during reallocation, prevent object movement during reallocation, etc. + - Replace JEMALLOC_OPTIONS/JEMALLOC_PROF_PREFIX with MALLOC_CONF, which is + more human-readable, and more flexible. For example: + JEMALLOC_OPTIONS=AJP + is now: + MALLOC_CONF=abort:true,fill:true,stats_print:true + - Port to Apple OS X. Sponsored by Mozilla. + - Make it possible for the application to control thread-->arena mappings via + the "thread.arena" mallctl. + - Add compile-time support for all TLS-related functionality via pthreads TSD. + This is mainly of interest for OS X, which does not support TLS, but has a + TSD implementation with similar performance. + - Override memalign() and valloc() if they are provided by the system. + - Add the "arenas.purge" mallctl, which can be used to synchronously purge all + dirty unused pages. + - Make cumulative heap profiling data optional, so that it is possible to + limit the amount of memory consumed by heap profiling data structures. + - Add per thread allocation counters that can be accessed via the + "thread.allocated" and "thread.deallocated" mallctls. + + Incompatible changes: + - Remove JEMALLOC_OPTIONS and malloc_options (see MALLOC_CONF above). + - Increase default backtrace depth from 4 to 128 for heap profiling. + - Disable interval-based profile dumps by default. + + Bug fixes: + - Remove bad assertions in fork handler functions. These assertions could + cause aborts for some combinations of configure settings. + - Fix strerror_r() usage to deal with non-standard semantics in GNU libc. + - Fix leak context reporting. This bug tended to cause the number of contexts + to be underreported (though the reported number of objects and bytes were + correct). + - Fix a realloc() bug for large in-place growing reallocation. This bug could + cause memory corruption, but it was hard to trigger. + - Fix an allocation bug for small allocations that could be triggered if + multiple threads raced to create a new run of backing pages. + - Enhance the heap profiler to trigger samples based on usable size, rather + than request size. + - Fix a heap profiling bug due to sometimes losing track of requested object + size for sampled objects. + +* 1.0.3 (August 12, 2010) + + Bug fixes: + - Fix the libunwind-based implementation of stack backtracing (used for heap + profiling). This bug could cause zero-length backtraces to be reported. + - Add a missing mutex unlock in library initialization code. If multiple + threads raced to initialize malloc, some of them could end up permanently + blocked. + +* 1.0.2 (May 11, 2010) + + Bug fixes: + - Fix junk filling of large objects, which could cause memory corruption. + - Add MAP_NORESERVE support for chunk mapping, because otherwise virtual + memory limits could cause swap file configuration to fail. Contributed by + Jordan DeLong. + +* 1.0.1 (April 14, 2010) + + Bug fixes: + - Fix compilation when --enable-fill is specified. + - Fix threads-related profiling bugs that affected accuracy and caused memory + to be leaked during thread exit. + - Fix dirty page purging race conditions that could cause crashes. + - Fix crash in tcache flushing code during thread destruction. + +* 1.0.0 (April 11, 2010) + + This release focuses on speed and run-time introspection. Numerous + algorithmic improvements make this release substantially faster than its + predecessors. + + New features: + - Implement autoconf-based configuration system. + - Add mallctl*(), for the purposes of introspection and run-time + configuration. + - Make it possible for the application to manually flush a thread's cache, via + the "tcache.flush" mallctl. + - Base maximum dirty page count on proportion of active memory. + - Compute various additional run-time statistics, including per size class + statistics for large objects. + - Expose malloc_stats_print(), which can be called repeatedly by the + application. + - Simplify the malloc_message() signature to only take one string argument, + and incorporate an opaque data pointer argument for use by the application + in combination with malloc_stats_print(). + - Add support for allocation backed by one or more swap files, and allow the + application to disable over-commit if swap files are in use. + - Implement allocation profiling and leak checking. + + Removed features: + - Remove the dynamic arena rebalancing code, since thread-specific caching + reduces its utility. + + Bug fixes: + - Modify chunk allocation to work when address space layout randomization + (ASLR) is in use. + - Fix thread cleanup bugs related to TLS destruction. + - Handle 0-size allocation requests in posix_memalign(). + - Fix a chunk leak. The leaked chunks were never touched, so this impacted + virtual memory usage, but not physical memory usage. + +* linux_2008082[78]a (August 27/28, 2008) + + These snapshot releases are the simple result of incorporating Linux-specific + support into the FreeBSD malloc sources. + +-------------------------------------------------------------------------------- +vim:filetype=text:textwidth=80 diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/INSTALL b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/INSTALL new file mode 100644 index 0000000..8d39687 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/INSTALL @@ -0,0 +1,402 @@ +Building and installing a packaged release of jemalloc can be as simple as +typing the following while in the root directory of the source tree: + + ./configure + make + make install + +If building from unpackaged developer sources, the simplest command sequence +that might work is: + + ./autogen.sh + make dist + make + make install + +Note that documentation is not built by the default target because doing so +would create a dependency on xsltproc in packaged releases, hence the +requirement to either run 'make dist' or avoid installing docs via the various +install_* targets documented below. + +=== Advanced configuration ===================================================== + +The 'configure' script supports numerous options that allow control of which +functionality is enabled, where jemalloc is installed, etc. Optionally, pass +any of the following arguments (not a definitive list) to 'configure': + +--help + Print a definitive list of options. + +--prefix= + Set the base directory in which to install. For example: + + ./configure --prefix=/usr/local + + will cause files to be installed into /usr/local/include, /usr/local/lib, + and /usr/local/man. + +--with-rpath= + Embed one or more library paths, so that libjemalloc can find the libraries + it is linked to. This works only on ELF-based systems. + +--with-mangling= + Mangle public symbols specified in which is a comma-separated list of + name:mangled pairs. + + For example, to use ld's --wrap option as an alternative method for + overriding libc's malloc implementation, specify something like: + + --with-mangling=malloc:__wrap_malloc,free:__wrap_free[...] + + Note that mangling happens prior to application of the prefix specified by + --with-jemalloc-prefix, and mangled symbols are then ignored when applying + the prefix. + +--with-jemalloc-prefix= + Prefix all public APIs with . For example, if is + "prefix_", API changes like the following occur: + + malloc() --> prefix_malloc() + malloc_conf --> prefix_malloc_conf + /etc/malloc.conf --> /etc/prefix_malloc.conf + MALLOC_CONF --> PREFIX_MALLOC_CONF + + This makes it possible to use jemalloc at the same time as the system + allocator, or even to use multiple copies of jemalloc simultaneously. + + By default, the prefix is "", except on OS X, where it is "je_". On OS X, + jemalloc overlays the default malloc zone, but makes no attempt to actually + replace the "malloc", "calloc", etc. symbols. + +--without-export + Don't export public APIs. This can be useful when building jemalloc as a + static library, or to avoid exporting public APIs when using the zone + allocator on OSX. + +--with-private-namespace= + Prefix all library-private APIs with je_. For shared libraries, + symbol visibility mechanisms prevent these symbols from being exported, but + for static libraries, naming collisions are a real possibility. By + default, is empty, which results in a symbol prefix of je_ . + +--with-install-suffix= + Append to the base name of all installed files, such that multiple + versions of jemalloc can coexist in the same installation directory. For + example, libjemalloc.so.0 becomes libjemalloc.so.0. + +--disable-cc-silence + Disable code that silences non-useful compiler warnings. This is mainly + useful during development when auditing the set of warnings that are being + silenced. + +--enable-debug + Enable assertions and validation code. This incurs a substantial + performance hit, but is very useful during application development. + Implies --enable-ivsalloc. + +--enable-code-coverage + Enable code coverage support, for use during jemalloc test development. + Additional testing targets are available if this option is enabled: + + coverage + coverage_unit + coverage_integration + coverage_stress + + These targets do not clear code coverage results from previous runs, and + there are interactions between the various coverage targets, so it is + usually advisable to run 'make clean' between repeated code coverage runs. + +--disable-stats + Disable statistics gathering functionality. See the "opt.stats_print" + option documentation for usage details. + +--enable-ivsalloc + Enable validation code, which verifies that pointers reside within + jemalloc-owned chunks before dereferencing them. This incurs a minor + performance hit. + +--enable-prof + Enable heap profiling and leak detection functionality. See the "opt.prof" + option documentation for usage details. When enabled, there are several + approaches to backtracing, and the configure script chooses the first one + in the following list that appears to function correctly: + + + libunwind (requires --enable-prof-libunwind) + + libgcc (unless --disable-prof-libgcc) + + gcc intrinsics (unless --disable-prof-gcc) + +--enable-prof-libunwind + Use the libunwind library (http://www.nongnu.org/libunwind/) for stack + backtracing. + +--disable-prof-libgcc + Disable the use of libgcc's backtracing functionality. + +--disable-prof-gcc + Disable the use of gcc intrinsics for backtracing. + +--with-static-libunwind= + Statically link against the specified libunwind.a rather than dynamically + linking with -lunwind. + +--disable-tcache + Disable thread-specific caches for small objects. Objects are cached and + released in bulk, thus reducing the total number of mutex operations. See + the "opt.tcache" option for usage details. + +--disable-munmap + Disable virtual memory deallocation via munmap(2); instead keep track of + the virtual memory for later use. munmap() is disabled by default (i.e. + --disable-munmap is implied) on Linux, which has a quirk in its virtual + memory allocation algorithm that causes semi-permanent VM map holes under + normal jemalloc operation. + +--disable-fill + Disable support for junk/zero filling of memory, quarantine, and redzones. + See the "opt.junk", "opt.zero", "opt.quarantine", and "opt.redzone" option + documentation for usage details. + +--disable-valgrind + Disable support for Valgrind. + +--disable-zone-allocator + Disable zone allocator for Darwin. This means jemalloc won't be hooked as + the default allocator on OSX/iOS. + +--enable-utrace + Enable utrace(2)-based allocation tracing. This feature is not broadly + portable (FreeBSD has it, but Linux and OS X do not). + +--enable-xmalloc + Enable support for optional immediate termination due to out-of-memory + errors, as is commonly implemented by "xmalloc" wrapper function for malloc. + See the "opt.xmalloc" option documentation for usage details. + +--enable-lazy-lock + Enable code that wraps pthread_create() to detect when an application + switches from single-threaded to multi-threaded mode, so that it can avoid + mutex locking/unlocking operations while in single-threaded mode. In + practice, this feature usually has little impact on performance unless + thread-specific caching is disabled. + +--disable-tls + Disable thread-local storage (TLS), which allows for fast access to + thread-local variables via the __thread keyword. If TLS is available, + jemalloc uses it for several purposes. + +--disable-cache-oblivious + Disable cache-oblivious large allocation alignment for large allocation + requests with no alignment constraints. If this feature is disabled, all + large allocations are page-aligned as an implementation artifact, which can + severely harm CPU cache utilization. However, the cache-oblivious layout + comes at the cost of one extra page per large allocation, which in the + most extreme case increases physical memory usage for the 16 KiB size class + to 20 KiB. + +--with-xslroot= + Specify where to find DocBook XSL stylesheets when building the + documentation. + +--with-lg-page= + Specify the base 2 log of the system page size. This option is only useful + when cross compiling, since the configure script automatically determines + the host's page size by default. + +--with-lg-page-sizes= + Specify the comma-separated base 2 logs of the page sizes to support. This + option may be useful when cross-compiling in combination with + --with-lg-page, but its primary use case is for integration with FreeBSD's + libc, wherein jemalloc is embedded. + +--with-lg-size-class-group= + Specify the base 2 log of how many size classes to use for each doubling in + size. By default jemalloc uses =2, which results in + e.g. the following size classes: + + [...], 64, + 80, 96, 112, 128, + 160, [...] + + =3 results in e.g. the following size classes: + + [...], 64, + 72, 80, 88, 96, 104, 112, 120, 128, + 144, [...] + + The minimal =0 causes jemalloc to only provide size + classes that are powers of 2: + + [...], + 64, + 128, + 256, + [...] + + An implementation detail currently limits the total number of small size + classes to 255, and a compilation error will result if the + you specify cannot be supported. The limit is + roughly =4, depending on page size. + +--with-lg-quantum= + Specify the base 2 log of the minimum allocation alignment. jemalloc needs + to know the minimum alignment that meets the following C standard + requirement (quoted from the April 12, 2011 draft of the C11 standard): + + The pointer returned if the allocation succeeds is suitably aligned so + that it may be assigned to a pointer to any type of object with a + fundamental alignment requirement and then used to access such an object + or an array of such objects in the space allocated [...] + + This setting is architecture-specific, and although jemalloc includes known + safe values for the most commonly used modern architectures, there is a + wrinkle related to GNU libc (glibc) that may impact your choice of + . On most modern architectures, this mandates 16-byte alignment + (=4), but the glibc developers chose not to meet this + requirement for performance reasons. An old discussion can be found at + https://sourceware.org/bugzilla/show_bug.cgi?id=206 . Unlike glibc, + jemalloc does follow the C standard by default (caveat: jemalloc + technically cheats if --with-lg-tiny-min is smaller than + --with-lg-quantum), but the fact that Linux systems already work around + this allocator noncompliance means that it is generally safe in practice to + let jemalloc's minimum alignment follow glibc's lead. If you specify + --with-lg-quantum=3 during configuration, jemalloc will provide additional + size classes that are not 16-byte-aligned (24, 40, and 56, assuming + --with-lg-size-class-group=2). + +--with-lg-tiny-min= + Specify the base 2 log of the minimum tiny size class to support. Tiny + size classes are powers of 2 less than the quantum, and are only + incorporated if is less than (see + --with-lg-quantum). Tiny size classes technically violate the C standard + requirement for minimum alignment, and crashes could conceivably result if + the compiler were to generate instructions that made alignment assumptions, + both because illegal instruction traps could result, and because accesses + could straddle page boundaries and cause segmentation faults due to + accessing unmapped addresses. + + The default of =3 works well in practice even on architectures + that technically require 16-byte alignment, probably for the same reason + --with-lg-quantum=3 works. Smaller tiny size classes can, and will, cause + crashes (see https://bugzilla.mozilla.org/show_bug.cgi?id=691003 for an + example). + + This option is rarely useful, and is mainly provided as documentation of a + subtle implementation detail. If you do use this option, specify a + value in [3, ..., ]. + +The following environment variables (not a definitive list) impact configure's +behavior: + +CFLAGS="?" + Pass these flags to the compiler. You probably shouldn't define this unless + you know what you are doing. (Use EXTRA_CFLAGS instead.) + +EXTRA_CFLAGS="?" + Append these flags to CFLAGS. This makes it possible to add flags such as + -Werror, while allowing the configure script to determine what other flags + are appropriate for the specified configuration. + + The configure script specifically checks whether an optimization flag (-O*) + is specified in EXTRA_CFLAGS, and refrains from specifying an optimization + level if it finds that one has already been specified. + +CPPFLAGS="?" + Pass these flags to the C preprocessor. Note that CFLAGS is not passed to + 'cpp' when 'configure' is looking for include files, so you must use + CPPFLAGS instead if you need to help 'configure' find header files. + +LD_LIBRARY_PATH="?" + 'ld' uses this colon-separated list to find libraries. + +LDFLAGS="?" + Pass these flags when linking. + +PATH="?" + 'configure' uses this to find programs. + +=== Advanced compilation ======================================================= + +To build only parts of jemalloc, use the following targets: + + build_lib_shared + build_lib_static + build_lib + build_doc_html + build_doc_man + build_doc + +To install only parts of jemalloc, use the following targets: + + install_bin + install_include + install_lib_shared + install_lib_static + install_lib + install_doc_html + install_doc_man + install_doc + +To clean up build results to varying degrees, use the following make targets: + + clean + distclean + relclean + +=== Advanced installation ====================================================== + +Optionally, define make variables when invoking make, including (not +exclusively): + +INCLUDEDIR="?" + Use this as the installation prefix for header files. + +LIBDIR="?" + Use this as the installation prefix for libraries. + +MANDIR="?" + Use this as the installation prefix for man pages. + +DESTDIR="?" + Prepend DESTDIR to INCLUDEDIR, LIBDIR, DATADIR, and MANDIR. This is useful + when installing to a different path than was specified via --prefix. + +CC="?" + Use this to invoke the C compiler. + +CFLAGS="?" + Pass these flags to the compiler. + +CPPFLAGS="?" + Pass these flags to the C preprocessor. + +LDFLAGS="?" + Pass these flags when linking. + +PATH="?" + Use this to search for programs used during configuration and building. + +=== Development ================================================================ + +If you intend to make non-trivial changes to jemalloc, use the 'autogen.sh' +script rather than 'configure'. This re-generates 'configure', enables +configuration dependency rules, and enables re-generation of automatically +generated source files. + +The build system supports using an object directory separate from the source +tree. For example, you can create an 'obj' directory, and from within that +directory, issue configuration and build commands: + + autoconf + mkdir obj + cd obj + ../configure --enable-autogen + make + +=== Documentation ============================================================== + +The manual page is generated in both html and roff formats. Any web browser +can be used to view the html manual. The roff manual page can be formatted +prior to installation via the following command: + + nroff -man -t doc/jemalloc.3 diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/Makefile.in b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/Makefile.in new file mode 100644 index 0000000..1ac6f29 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/Makefile.in @@ -0,0 +1,458 @@ +# Clear out all vpaths, then set just one (default vpath) for the main build +# directory. +vpath +vpath % . + +# Clear the default suffixes, so that built-in rules are not used. +.SUFFIXES : + +SHELL := /bin/sh + +CC := @CC@ + +# Configuration parameters. +DESTDIR = +BINDIR := $(DESTDIR)@BINDIR@ +INCLUDEDIR := $(DESTDIR)@INCLUDEDIR@ +LIBDIR := $(DESTDIR)@LIBDIR@ +DATADIR := $(DESTDIR)@DATADIR@ +MANDIR := $(DESTDIR)@MANDIR@ +srcroot := @srcroot@ +objroot := @objroot@ +abs_srcroot := @abs_srcroot@ +abs_objroot := @abs_objroot@ + +# Build parameters. +CPPFLAGS := @CPPFLAGS@ -I$(srcroot)include -I$(objroot)include +CFLAGS := @CFLAGS@ +LDFLAGS := @LDFLAGS@ +EXTRA_LDFLAGS := @EXTRA_LDFLAGS@ +LIBS := @LIBS@ +TESTLIBS := @TESTLIBS@ +RPATH_EXTRA := @RPATH_EXTRA@ +SO := @so@ +IMPORTLIB := @importlib@ +O := @o@ +A := @a@ +EXE := @exe@ +LIBPREFIX := @libprefix@ +REV := @rev@ +install_suffix := @install_suffix@ +ABI := @abi@ +XSLTPROC := @XSLTPROC@ +AUTOCONF := @AUTOCONF@ +_RPATH = @RPATH@ +RPATH = $(if $(1),$(call _RPATH,$(1))) +cfghdrs_in := $(addprefix $(srcroot),@cfghdrs_in@) +cfghdrs_out := @cfghdrs_out@ +cfgoutputs_in := $(addprefix $(srcroot),@cfgoutputs_in@) +cfgoutputs_out := @cfgoutputs_out@ +enable_autogen := @enable_autogen@ +enable_code_coverage := @enable_code_coverage@ +enable_prof := @enable_prof@ +enable_valgrind := @enable_valgrind@ +enable_zone_allocator := @enable_zone_allocator@ +MALLOC_CONF := @JEMALLOC_CPREFIX@MALLOC_CONF +DSO_LDFLAGS = @DSO_LDFLAGS@ +SOREV = @SOREV@ +PIC_CFLAGS = @PIC_CFLAGS@ +CTARGET = @CTARGET@ +LDTARGET = @LDTARGET@ +MKLIB = @MKLIB@ +AR = @AR@ +ARFLAGS = @ARFLAGS@ +CC_MM = @CC_MM@ + +ifeq (macho, $(ABI)) +TEST_LIBRARY_PATH := DYLD_FALLBACK_LIBRARY_PATH="$(objroot)lib" +else +ifeq (pecoff, $(ABI)) +TEST_LIBRARY_PATH := PATH="$(PATH):$(objroot)lib" +else +TEST_LIBRARY_PATH := +endif +endif + +LIBJEMALLOC := $(LIBPREFIX)jemalloc$(install_suffix) + +# Lists of files. +BINS := $(objroot)bin/jemalloc-config $(objroot)bin/jemalloc.sh $(objroot)bin/jeprof +C_HDRS := $(objroot)include/jemalloc/jemalloc$(install_suffix).h +C_SRCS := $(srcroot)src/jemalloc.c $(srcroot)src/arena.c \ + $(srcroot)src/atomic.c $(srcroot)src/base.c $(srcroot)src/bitmap.c \ + $(srcroot)src/chunk.c $(srcroot)src/chunk_dss.c \ + $(srcroot)src/chunk_mmap.c $(srcroot)src/ckh.c $(srcroot)src/ctl.c \ + $(srcroot)src/extent.c $(srcroot)src/hash.c $(srcroot)src/huge.c \ + $(srcroot)src/mb.c $(srcroot)src/mutex.c $(srcroot)src/pages.c \ + $(srcroot)src/prof.c $(srcroot)src/quarantine.c $(srcroot)src/rtree.c \ + $(srcroot)src/stats.c $(srcroot)src/tcache.c $(srcroot)src/util.c \ + $(srcroot)src/tsd.c +ifeq ($(enable_valgrind), 1) +C_SRCS += $(srcroot)src/valgrind.c +endif +ifeq ($(enable_zone_allocator), 1) +C_SRCS += $(srcroot)src/zone.c +endif +ifeq ($(IMPORTLIB),$(SO)) +STATIC_LIBS := $(objroot)lib/$(LIBJEMALLOC).$(A) +endif +ifdef PIC_CFLAGS +STATIC_LIBS += $(objroot)lib/$(LIBJEMALLOC)_pic.$(A) +else +STATIC_LIBS += $(objroot)lib/$(LIBJEMALLOC)_s.$(A) +endif +DSOS := $(objroot)lib/$(LIBJEMALLOC).$(SOREV) +ifneq ($(SOREV),$(SO)) +DSOS += $(objroot)lib/$(LIBJEMALLOC).$(SO) +endif +PC := $(objroot)jemalloc.pc +MAN3 := $(objroot)doc/jemalloc$(install_suffix).3 +DOCS_XML := $(objroot)doc/jemalloc$(install_suffix).xml +DOCS_HTML := $(DOCS_XML:$(objroot)%.xml=$(objroot)%.html) +DOCS_MAN3 := $(DOCS_XML:$(objroot)%.xml=$(objroot)%.3) +DOCS := $(DOCS_HTML) $(DOCS_MAN3) +C_TESTLIB_SRCS := $(srcroot)test/src/btalloc.c $(srcroot)test/src/btalloc_0.c \ + $(srcroot)test/src/btalloc_1.c $(srcroot)test/src/math.c \ + $(srcroot)test/src/mtx.c $(srcroot)test/src/mq.c \ + $(srcroot)test/src/SFMT.c $(srcroot)test/src/test.c \ + $(srcroot)test/src/thd.c $(srcroot)test/src/timer.c +C_UTIL_INTEGRATION_SRCS := $(srcroot)src/util.c +TESTS_UNIT := $(srcroot)test/unit/atomic.c \ + $(srcroot)test/unit/bitmap.c \ + $(srcroot)test/unit/ckh.c \ + $(srcroot)test/unit/hash.c \ + $(srcroot)test/unit/junk.c \ + $(srcroot)test/unit/junk_alloc.c \ + $(srcroot)test/unit/junk_free.c \ + $(srcroot)test/unit/lg_chunk.c \ + $(srcroot)test/unit/mallctl.c \ + $(srcroot)test/unit/math.c \ + $(srcroot)test/unit/mq.c \ + $(srcroot)test/unit/mtx.c \ + $(srcroot)test/unit/prof_accum.c \ + $(srcroot)test/unit/prof_active.c \ + $(srcroot)test/unit/prof_gdump.c \ + $(srcroot)test/unit/prof_idump.c \ + $(srcroot)test/unit/prof_reset.c \ + $(srcroot)test/unit/prof_thread_name.c \ + $(srcroot)test/unit/ql.c \ + $(srcroot)test/unit/qr.c \ + $(srcroot)test/unit/quarantine.c \ + $(srcroot)test/unit/rb.c \ + $(srcroot)test/unit/rtree.c \ + $(srcroot)test/unit/SFMT.c \ + $(srcroot)test/unit/size_classes.c \ + $(srcroot)test/unit/stats.c \ + $(srcroot)test/unit/tsd.c \ + $(srcroot)test/unit/util.c \ + $(srcroot)test/unit/zero.c +TESTS_INTEGRATION := $(srcroot)test/integration/aligned_alloc.c \ + $(srcroot)test/integration/allocated.c \ + $(srcroot)test/integration/sdallocx.c \ + $(srcroot)test/integration/mallocx.c \ + $(srcroot)test/integration/MALLOCX_ARENA.c \ + $(srcroot)test/integration/overflow.c \ + $(srcroot)test/integration/posix_memalign.c \ + $(srcroot)test/integration/rallocx.c \ + $(srcroot)test/integration/thread_arena.c \ + $(srcroot)test/integration/thread_tcache_enabled.c \ + $(srcroot)test/integration/xallocx.c \ + $(srcroot)test/integration/chunk.c +TESTS_STRESS := $(srcroot)test/stress/microbench.c +TESTS := $(TESTS_UNIT) $(TESTS_INTEGRATION) $(TESTS_STRESS) + +C_OBJS := $(C_SRCS:$(srcroot)%.c=$(objroot)%.$(O)) +C_PIC_OBJS := $(C_SRCS:$(srcroot)%.c=$(objroot)%.pic.$(O)) +C_JET_OBJS := $(C_SRCS:$(srcroot)%.c=$(objroot)%.jet.$(O)) +C_TESTLIB_UNIT_OBJS := $(C_TESTLIB_SRCS:$(srcroot)%.c=$(objroot)%.unit.$(O)) +C_TESTLIB_INTEGRATION_OBJS := $(C_TESTLIB_SRCS:$(srcroot)%.c=$(objroot)%.integration.$(O)) +C_UTIL_INTEGRATION_OBJS := $(C_UTIL_INTEGRATION_SRCS:$(srcroot)%.c=$(objroot)%.integration.$(O)) +C_TESTLIB_STRESS_OBJS := $(C_TESTLIB_SRCS:$(srcroot)%.c=$(objroot)%.stress.$(O)) +C_TESTLIB_OBJS := $(C_TESTLIB_UNIT_OBJS) $(C_TESTLIB_INTEGRATION_OBJS) $(C_UTIL_INTEGRATION_OBJS) $(C_TESTLIB_STRESS_OBJS) + +TESTS_UNIT_OBJS := $(TESTS_UNIT:$(srcroot)%.c=$(objroot)%.$(O)) +TESTS_INTEGRATION_OBJS := $(TESTS_INTEGRATION:$(srcroot)%.c=$(objroot)%.$(O)) +TESTS_STRESS_OBJS := $(TESTS_STRESS:$(srcroot)%.c=$(objroot)%.$(O)) +TESTS_OBJS := $(TESTS_UNIT_OBJS) $(TESTS_INTEGRATION_OBJS) $(TESTS_STRESS_OBJS) + +.PHONY: all dist build_doc_html build_doc_man build_doc +.PHONY: install_bin install_include install_lib +.PHONY: install_doc_html install_doc_man install_doc install +.PHONY: tests check clean distclean relclean + +.SECONDARY : $(TESTS_OBJS) + +# Default target. +all: build_lib + +dist: build_doc + +$(objroot)doc/%.html : $(objroot)doc/%.xml $(srcroot)doc/stylesheet.xsl $(objroot)doc/html.xsl + $(XSLTPROC) -o $@ $(objroot)doc/html.xsl $< + +$(objroot)doc/%.3 : $(objroot)doc/%.xml $(srcroot)doc/stylesheet.xsl $(objroot)doc/manpages.xsl + $(XSLTPROC) -o $@ $(objroot)doc/manpages.xsl $< + +build_doc_html: $(DOCS_HTML) +build_doc_man: $(DOCS_MAN3) +build_doc: $(DOCS) + +# +# Include generated dependency files. +# +ifdef CC_MM +-include $(C_OBJS:%.$(O)=%.d) +-include $(C_PIC_OBJS:%.$(O)=%.d) +-include $(C_JET_OBJS:%.$(O)=%.d) +-include $(C_TESTLIB_OBJS:%.$(O)=%.d) +-include $(TESTS_OBJS:%.$(O)=%.d) +endif + +$(C_OBJS): $(objroot)src/%.$(O): $(srcroot)src/%.c +$(C_PIC_OBJS): $(objroot)src/%.pic.$(O): $(srcroot)src/%.c +$(C_PIC_OBJS): CFLAGS += $(PIC_CFLAGS) +$(C_JET_OBJS): $(objroot)src/%.jet.$(O): $(srcroot)src/%.c +$(C_JET_OBJS): CFLAGS += -DJEMALLOC_JET +$(C_TESTLIB_UNIT_OBJS): $(objroot)test/src/%.unit.$(O): $(srcroot)test/src/%.c +$(C_TESTLIB_UNIT_OBJS): CPPFLAGS += -DJEMALLOC_UNIT_TEST +$(C_TESTLIB_INTEGRATION_OBJS): $(objroot)test/src/%.integration.$(O): $(srcroot)test/src/%.c +$(C_TESTLIB_INTEGRATION_OBJS): CPPFLAGS += -DJEMALLOC_INTEGRATION_TEST +$(C_UTIL_INTEGRATION_OBJS): $(objroot)src/%.integration.$(O): $(srcroot)src/%.c +$(C_TESTLIB_STRESS_OBJS): $(objroot)test/src/%.stress.$(O): $(srcroot)test/src/%.c +$(C_TESTLIB_STRESS_OBJS): CPPFLAGS += -DJEMALLOC_STRESS_TEST -DJEMALLOC_STRESS_TESTLIB +$(C_TESTLIB_OBJS): CPPFLAGS += -I$(srcroot)test/include -I$(objroot)test/include +$(TESTS_UNIT_OBJS): CPPFLAGS += -DJEMALLOC_UNIT_TEST +$(TESTS_INTEGRATION_OBJS): CPPFLAGS += -DJEMALLOC_INTEGRATION_TEST +$(TESTS_STRESS_OBJS): CPPFLAGS += -DJEMALLOC_STRESS_TEST +$(TESTS_OBJS): $(objroot)test/%.$(O): $(srcroot)test/%.c +$(TESTS_OBJS): CPPFLAGS += -I$(srcroot)test/include -I$(objroot)test/include +ifneq ($(IMPORTLIB),$(SO)) +$(C_OBJS) $(C_JET_OBJS): CPPFLAGS += -DDLLEXPORT +endif + +ifndef CC_MM +# Dependencies. +HEADER_DIRS = $(srcroot)include/jemalloc/internal \ + $(objroot)include/jemalloc $(objroot)include/jemalloc/internal +HEADERS = $(wildcard $(foreach dir,$(HEADER_DIRS),$(dir)/*.h)) +$(C_OBJS) $(C_PIC_OBJS) $(C_JET_OBJS) $(C_TESTLIB_OBJS) $(TESTS_OBJS): $(HEADERS) +$(TESTS_OBJS): $(objroot)test/include/test/jemalloc_test.h +endif + +$(C_OBJS) $(C_PIC_OBJS) $(C_JET_OBJS) $(C_TESTLIB_OBJS) $(TESTS_OBJS): %.$(O): + @mkdir -p $(@D) + $(CC) $(CFLAGS) -c $(CPPFLAGS) $(CTARGET) $< +ifdef CC_MM + @$(CC) -MM $(CPPFLAGS) -MT $@ -o $(@:%.$(O)=%.d) $< +endif + +ifneq ($(SOREV),$(SO)) +%.$(SO) : %.$(SOREV) + @mkdir -p $(@D) + ln -sf $( $(srcroot)config.stamp.in + +$(objroot)config.stamp : $(cfgoutputs_in) $(cfghdrs_in) $(srcroot)configure + ./$(objroot)config.status + @touch $@ + +# There must be some action in order for make to re-read Makefile when it is +# out of date. +$(cfgoutputs_out) $(cfghdrs_out) : $(objroot)config.stamp + @true +endif diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/README b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/README new file mode 100644 index 0000000..9b268f4 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/README @@ -0,0 +1,20 @@ +jemalloc is a general purpose malloc(3) implementation that emphasizes +fragmentation avoidance and scalable concurrency support. jemalloc first came +into use as the FreeBSD libc allocator in 2005, and since then it has found its +way into numerous applications that rely on its predictable behavior. In 2010 +jemalloc development efforts broadened to include developer support features +such as heap profiling, Valgrind integration, and extensive monitoring/tuning +hooks. Modern jemalloc releases continue to be integrated back into FreeBSD, +and therefore versatility remains critical. Ongoing development efforts trend +toward making jemalloc among the best allocators for a broad range of demanding +applications, and eliminating/mitigating weaknesses that have practical +repercussions for real world applications. + +The COPYING file contains copyright and licensing information. + +The INSTALL file contains information on how to configure, build, and install +jemalloc. + +The ChangeLog file contains a brief summary of changes for each release. + +URL: http://www.canonware.com/jemalloc/ diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/autogen.sh b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/autogen.sh new file mode 100755 index 0000000..75f32da --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/autogen.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +for i in autoconf; do + echo "$i" + $i + if [ $? -ne 0 ]; then + echo "Error $? in $i" + exit 1 + fi +done + +echo "./configure --enable-autogen $@" +./configure --enable-autogen $@ +if [ $? -ne 0 ]; then + echo "Error $? in ./configure" + exit 1 +fi diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/bin/jemalloc-config.in b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/bin/jemalloc-config.in new file mode 100644 index 0000000..b016c8d --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/bin/jemalloc-config.in @@ -0,0 +1,79 @@ +#!/bin/sh + +usage() { + cat < +Options: + --help | -h : Print usage. + --version : Print jemalloc version. + --revision : Print shared library revision number. + --config : Print configure options used to build jemalloc. + --prefix : Print installation directory prefix. + --bindir : Print binary installation directory. + --datadir : Print data installation directory. + --includedir : Print include installation directory. + --libdir : Print library installation directory. + --mandir : Print manual page installation directory. + --cc : Print compiler used to build jemalloc. + --cflags : Print compiler flags used to build jemalloc. + --cppflags : Print preprocessor flags used to build jemalloc. + --ldflags : Print library flags used to build jemalloc. + --libs : Print libraries jemalloc was linked against. +EOF +} + +prefix="@prefix@" +exec_prefix="@exec_prefix@" + +case "$1" in +--help | -h) + usage + exit 0 + ;; +--version) + echo "@jemalloc_version@" + ;; +--revision) + echo "@rev@" + ;; +--config) + echo "@CONFIG@" + ;; +--prefix) + echo "@PREFIX@" + ;; +--bindir) + echo "@BINDIR@" + ;; +--datadir) + echo "@DATADIR@" + ;; +--includedir) + echo "@INCLUDEDIR@" + ;; +--libdir) + echo "@LIBDIR@" + ;; +--mandir) + echo "@MANDIR@" + ;; +--cc) + echo "@CC@" + ;; +--cflags) + echo "@CFLAGS@" + ;; +--cppflags) + echo "@CPPFLAGS@" + ;; +--ldflags) + echo "@LDFLAGS@ @EXTRA_LDFLAGS@" + ;; +--libs) + echo "@LIBS@" + ;; +*) + usage + exit 1 +esac diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/bin/jemalloc.sh.in b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/bin/jemalloc.sh.in new file mode 100644 index 0000000..cdf3673 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/bin/jemalloc.sh.in @@ -0,0 +1,9 @@ +#!/bin/sh + +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ + +@LD_PRELOAD_VAR@=${libdir}/libjemalloc.@SOREV@ +export @LD_PRELOAD_VAR@ +exec "$@" diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/bin/jeprof.in b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/bin/jeprof.in new file mode 100644 index 0000000..e717807 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/bin/jeprof.in @@ -0,0 +1,5510 @@ +#! /usr/bin/env perl + +# Copyright (c) 1998-2007, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# --- +# Program for printing the profile generated by common/profiler.cc, +# or by the heap profiler (common/debugallocation.cc) +# +# The profile contains a sequence of entries of the form: +# +# This program parses the profile, and generates user-readable +# output. +# +# Examples: +# +# % tools/jeprof "program" "profile" +# Enters "interactive" mode +# +# % tools/jeprof --text "program" "profile" +# Generates one line per procedure +# +# % tools/jeprof --gv "program" "profile" +# Generates annotated call-graph and displays via "gv" +# +# % tools/jeprof --gv --focus=Mutex "program" "profile" +# Restrict to code paths that involve an entry that matches "Mutex" +# +# % tools/jeprof --gv --focus=Mutex --ignore=string "program" "profile" +# Restrict to code paths that involve an entry that matches "Mutex" +# and does not match "string" +# +# % tools/jeprof --list=IBF_CheckDocid "program" "profile" +# Generates disassembly listing of all routines with at least one +# sample that match the --list= pattern. The listing is +# annotated with the flat and cumulative sample counts at each line. +# +# % tools/jeprof --disasm=IBF_CheckDocid "program" "profile" +# Generates disassembly listing of all routines with at least one +# sample that match the --disasm= pattern. The listing is +# annotated with the flat and cumulative sample counts at each PC value. +# +# TODO: Use color to indicate files? + +use strict; +use warnings; +use Getopt::Long; + +my $JEPROF_VERSION = "@jemalloc_version@"; +my $PPROF_VERSION = "2.0"; + +# These are the object tools we use which can come from a +# user-specified location using --tools, from the JEPROF_TOOLS +# environment variable, or from the environment. +my %obj_tool_map = ( + "objdump" => "objdump", + "nm" => "nm", + "addr2line" => "addr2line", + "c++filt" => "c++filt", + ## ConfigureObjTools may add architecture-specific entries: + #"nm_pdb" => "nm-pdb", # for reading windows (PDB-format) executables + #"addr2line_pdb" => "addr2line-pdb", # ditto + #"otool" => "otool", # equivalent of objdump on OS X +); +# NOTE: these are lists, so you can put in commandline flags if you want. +my @DOT = ("dot"); # leave non-absolute, since it may be in /usr/local +my @GV = ("gv"); +my @EVINCE = ("evince"); # could also be xpdf or perhaps acroread +my @KCACHEGRIND = ("kcachegrind"); +my @PS2PDF = ("ps2pdf"); +# These are used for dynamic profiles +my @URL_FETCHER = ("curl", "-s"); + +# These are the web pages that servers need to support for dynamic profiles +my $HEAP_PAGE = "/pprof/heap"; +my $PROFILE_PAGE = "/pprof/profile"; # must support cgi-param "?seconds=#" +my $PMUPROFILE_PAGE = "/pprof/pmuprofile(?:\\?.*)?"; # must support cgi-param + # ?seconds=#&event=x&period=n +my $GROWTH_PAGE = "/pprof/growth"; +my $CONTENTION_PAGE = "/pprof/contention"; +my $WALL_PAGE = "/pprof/wall(?:\\?.*)?"; # accepts options like namefilter +my $FILTEREDPROFILE_PAGE = "/pprof/filteredprofile(?:\\?.*)?"; +my $CENSUSPROFILE_PAGE = "/pprof/censusprofile(?:\\?.*)?"; # must support cgi-param + # "?seconds=#", + # "?tags_regexp=#" and + # "?type=#". +my $SYMBOL_PAGE = "/pprof/symbol"; # must support symbol lookup via POST +my $PROGRAM_NAME_PAGE = "/pprof/cmdline"; + +# These are the web pages that can be named on the command line. +# All the alternatives must begin with /. +my $PROFILES = "($HEAP_PAGE|$PROFILE_PAGE|$PMUPROFILE_PAGE|" . + "$GROWTH_PAGE|$CONTENTION_PAGE|$WALL_PAGE|" . + "$FILTEREDPROFILE_PAGE|$CENSUSPROFILE_PAGE)"; + +# default binary name +my $UNKNOWN_BINARY = "(unknown)"; + +# There is a pervasive dependency on the length (in hex characters, +# i.e., nibbles) of an address, distinguishing between 32-bit and +# 64-bit profiles. To err on the safe size, default to 64-bit here: +my $address_length = 16; + +my $dev_null = "/dev/null"; +if (! -e $dev_null && $^O =~ /MSWin/) { # $^O is the OS perl was built for + $dev_null = "nul"; +} + +# A list of paths to search for shared object files +my @prefix_list = (); + +# Special routine name that should not have any symbols. +# Used as separator to parse "addr2line -i" output. +my $sep_symbol = '_fini'; +my $sep_address = undef; + +##### Argument parsing ##### + +sub usage_string { + return < + is a space separated list of profile names. +jeprof [options] + is a list of profile files where each file contains + the necessary symbol mappings as well as profile data (likely generated + with --raw). +jeprof [options] + is a remote form. Symbols are obtained from host:port$SYMBOL_PAGE + + Each name can be: + /path/to/profile - a path to a profile file + host:port[/] - a location of a service to get profile from + + The / can be $HEAP_PAGE, $PROFILE_PAGE, /pprof/pmuprofile, + $GROWTH_PAGE, $CONTENTION_PAGE, /pprof/wall, + $CENSUSPROFILE_PAGE, or /pprof/filteredprofile. + For instance: + jeprof http://myserver.com:80$HEAP_PAGE + If / is omitted, the service defaults to $PROFILE_PAGE (cpu profiling). +jeprof --symbols + Maps addresses to symbol names. In this mode, stdin should be a + list of library mappings, in the same format as is found in the heap- + and cpu-profile files (this loosely matches that of /proc/self/maps + on linux), followed by a list of hex addresses to map, one per line. + + For more help with querying remote servers, including how to add the + necessary server-side support code, see this filename (or one like it): + + /usr/doc/gperftools-$PPROF_VERSION/pprof_remote_servers.html + +Options: + --cum Sort by cumulative data + --base= Subtract from before display + --interactive Run in interactive mode (interactive "help" gives help) [default] + --seconds= Length of time for dynamic profiles [default=30 secs] + --add_lib= Read additional symbols and line info from the given library + --lib_prefix= Comma separated list of library path prefixes + +Reporting Granularity: + --addresses Report at address level + --lines Report at source line level + --functions Report at function level [default] + --files Report at source file level + +Output type: + --text Generate text report + --callgrind Generate callgrind format to stdout + --gv Generate Postscript and display + --evince Generate PDF and display + --web Generate SVG and display + --list= Generate source listing of matching routines + --disasm= Generate disassembly of matching routines + --symbols Print demangled symbol names found at given addresses + --dot Generate DOT file to stdout + --ps Generate Postcript to stdout + --pdf Generate PDF to stdout + --svg Generate SVG to stdout + --gif Generate GIF to stdout + --raw Generate symbolized jeprof data (useful with remote fetch) + +Heap-Profile Options: + --inuse_space Display in-use (mega)bytes [default] + --inuse_objects Display in-use objects + --alloc_space Display allocated (mega)bytes + --alloc_objects Display allocated objects + --show_bytes Display space in bytes + --drop_negative Ignore negative differences + +Contention-profile options: + --total_delay Display total delay at each region [default] + --contentions Display number of delays at each region + --mean_delay Display mean delay at each region + +Call-graph Options: + --nodecount= Show at most so many nodes [default=80] + --nodefraction= Hide nodes below *total [default=.005] + --edgefraction= Hide edges below *total [default=.001] + --maxdegree= Max incoming/outgoing edges per node [default=8] + --focus= Focus on nodes matching + --thread= Show profile for thread + --ignore= Ignore nodes matching + --scale= Set GV scaling [default=0] + --heapcheck Make nodes with non-0 object counts + (i.e. direct leak generators) more visible + +Miscellaneous: + --tools=[,...] \$PATH for object tool pathnames + --test Run unit tests + --help This message + --version Version information + +Environment Variables: + JEPROF_TMPDIR Profiles directory. Defaults to \$HOME/jeprof + JEPROF_TOOLS Prefix for object tools pathnames + +Examples: + +jeprof /bin/ls ls.prof + Enters "interactive" mode +jeprof --text /bin/ls ls.prof + Outputs one line per procedure +jeprof --web /bin/ls ls.prof + Displays annotated call-graph in web browser +jeprof --gv /bin/ls ls.prof + Displays annotated call-graph via 'gv' +jeprof --gv --focus=Mutex /bin/ls ls.prof + Restricts to code paths including a .*Mutex.* entry +jeprof --gv --focus=Mutex --ignore=string /bin/ls ls.prof + Code paths including Mutex but not string +jeprof --list=getdir /bin/ls ls.prof + (Per-line) annotated source listing for getdir() +jeprof --disasm=getdir /bin/ls ls.prof + (Per-PC) annotated disassembly for getdir() + +jeprof http://localhost:1234/ + Enters "interactive" mode +jeprof --text localhost:1234 + Outputs one line per procedure for localhost:1234 +jeprof --raw localhost:1234 > ./local.raw +jeprof --text ./local.raw + Fetches a remote profile for later analysis and then + analyzes it in text mode. +EOF +} + +sub version_string { + return < \$main::opt_help, + "version!" => \$main::opt_version, + "cum!" => \$main::opt_cum, + "base=s" => \$main::opt_base, + "seconds=i" => \$main::opt_seconds, + "add_lib=s" => \$main::opt_lib, + "lib_prefix=s" => \$main::opt_lib_prefix, + "functions!" => \$main::opt_functions, + "lines!" => \$main::opt_lines, + "addresses!" => \$main::opt_addresses, + "files!" => \$main::opt_files, + "text!" => \$main::opt_text, + "callgrind!" => \$main::opt_callgrind, + "list=s" => \$main::opt_list, + "disasm=s" => \$main::opt_disasm, + "symbols!" => \$main::opt_symbols, + "gv!" => \$main::opt_gv, + "evince!" => \$main::opt_evince, + "web!" => \$main::opt_web, + "dot!" => \$main::opt_dot, + "ps!" => \$main::opt_ps, + "pdf!" => \$main::opt_pdf, + "svg!" => \$main::opt_svg, + "gif!" => \$main::opt_gif, + "raw!" => \$main::opt_raw, + "interactive!" => \$main::opt_interactive, + "nodecount=i" => \$main::opt_nodecount, + "nodefraction=f" => \$main::opt_nodefraction, + "edgefraction=f" => \$main::opt_edgefraction, + "maxdegree=i" => \$main::opt_maxdegree, + "focus=s" => \$main::opt_focus, + "thread=s" => \$main::opt_thread, + "ignore=s" => \$main::opt_ignore, + "scale=i" => \$main::opt_scale, + "heapcheck" => \$main::opt_heapcheck, + "inuse_space!" => \$main::opt_inuse_space, + "inuse_objects!" => \$main::opt_inuse_objects, + "alloc_space!" => \$main::opt_alloc_space, + "alloc_objects!" => \$main::opt_alloc_objects, + "show_bytes!" => \$main::opt_show_bytes, + "drop_negative!" => \$main::opt_drop_negative, + "total_delay!" => \$main::opt_total_delay, + "contentions!" => \$main::opt_contentions, + "mean_delay!" => \$main::opt_mean_delay, + "tools=s" => \$main::opt_tools, + "test!" => \$main::opt_test, + "debug!" => \$main::opt_debug, + # Undocumented flags used only by unittests: + "test_stride=i" => \$main::opt_test_stride, + ) || usage("Invalid option(s)"); + + # Deal with the standard --help and --version + if ($main::opt_help) { + print usage_string(); + exit(0); + } + + if ($main::opt_version) { + print version_string(); + exit(0); + } + + # Disassembly/listing/symbols mode requires address-level info + if ($main::opt_disasm || $main::opt_list || $main::opt_symbols) { + $main::opt_functions = 0; + $main::opt_lines = 0; + $main::opt_addresses = 1; + $main::opt_files = 0; + } + + # Check heap-profiling flags + if ($main::opt_inuse_space + + $main::opt_inuse_objects + + $main::opt_alloc_space + + $main::opt_alloc_objects > 1) { + usage("Specify at most on of --inuse/--alloc options"); + } + + # Check output granularities + my $grains = + $main::opt_functions + + $main::opt_lines + + $main::opt_addresses + + $main::opt_files + + 0; + if ($grains > 1) { + usage("Only specify one output granularity option"); + } + if ($grains == 0) { + $main::opt_functions = 1; + } + + # Check output modes + my $modes = + $main::opt_text + + $main::opt_callgrind + + ($main::opt_list eq '' ? 0 : 1) + + ($main::opt_disasm eq '' ? 0 : 1) + + ($main::opt_symbols == 0 ? 0 : 1) + + $main::opt_gv + + $main::opt_evince + + $main::opt_web + + $main::opt_dot + + $main::opt_ps + + $main::opt_pdf + + $main::opt_svg + + $main::opt_gif + + $main::opt_raw + + $main::opt_interactive + + 0; + if ($modes > 1) { + usage("Only specify one output mode"); + } + if ($modes == 0) { + if (-t STDOUT) { # If STDOUT is a tty, activate interactive mode + $main::opt_interactive = 1; + } else { + $main::opt_text = 1; + } + } + + if ($main::opt_test) { + RunUnitTests(); + # Should not return + exit(1); + } + + # Binary name and profile arguments list + $main::prog = ""; + @main::pfile_args = (); + + # Remote profiling without a binary (using $SYMBOL_PAGE instead) + if (@ARGV > 0) { + if (IsProfileURL($ARGV[0])) { + $main::use_symbol_page = 1; + } elsif (IsSymbolizedProfileFile($ARGV[0])) { + $main::use_symbolized_profile = 1; + $main::prog = $UNKNOWN_BINARY; # will be set later from the profile file + } + } + + if ($main::use_symbol_page || $main::use_symbolized_profile) { + # We don't need a binary! + my %disabled = ('--lines' => $main::opt_lines, + '--disasm' => $main::opt_disasm); + for my $option (keys %disabled) { + usage("$option cannot be used without a binary") if $disabled{$option}; + } + # Set $main::prog later... + scalar(@ARGV) || usage("Did not specify profile file"); + } elsif ($main::opt_symbols) { + # --symbols needs a binary-name (to run nm on, etc) but not profiles + $main::prog = shift(@ARGV) || usage("Did not specify program"); + } else { + $main::prog = shift(@ARGV) || usage("Did not specify program"); + scalar(@ARGV) || usage("Did not specify profile file"); + } + + # Parse profile file/location arguments + foreach my $farg (@ARGV) { + if ($farg =~ m/(.*)\@([0-9]+)(|\/.*)$/ ) { + my $machine = $1; + my $num_machines = $2; + my $path = $3; + for (my $i = 0; $i < $num_machines; $i++) { + unshift(@main::pfile_args, "$i.$machine$path"); + } + } else { + unshift(@main::pfile_args, $farg); + } + } + + if ($main::use_symbol_page) { + unless (IsProfileURL($main::pfile_args[0])) { + error("The first profile should be a remote form to use $SYMBOL_PAGE\n"); + } + CheckSymbolPage(); + $main::prog = FetchProgramName(); + } elsif (!$main::use_symbolized_profile) { # may not need objtools! + ConfigureObjTools($main::prog) + } + + # Break the opt_lib_prefix into the prefix_list array + @prefix_list = split (',', $main::opt_lib_prefix); + + # Remove trailing / from the prefixes, in the list to prevent + # searching things like /my/path//lib/mylib.so + foreach (@prefix_list) { + s|/+$||; + } +} + +sub FilterAndPrint { + my ($profile, $symbols, $libs, $thread) = @_; + + # Get total data in profile + my $total = TotalProfile($profile); + + # Remove uniniteresting stack items + $profile = RemoveUninterestingFrames($symbols, $profile); + + # Focus? + if ($main::opt_focus ne '') { + $profile = FocusProfile($symbols, $profile, $main::opt_focus); + } + + # Ignore? + if ($main::opt_ignore ne '') { + $profile = IgnoreProfile($symbols, $profile, $main::opt_ignore); + } + + my $calls = ExtractCalls($symbols, $profile); + + # Reduce profiles to required output granularity, and also clean + # each stack trace so a given entry exists at most once. + my $reduced = ReduceProfile($symbols, $profile); + + # Get derived profiles + my $flat = FlatProfile($reduced); + my $cumulative = CumulativeProfile($reduced); + + # Print + if (!$main::opt_interactive) { + if ($main::opt_disasm) { + PrintDisassembly($libs, $flat, $cumulative, $main::opt_disasm); + } elsif ($main::opt_list) { + PrintListing($total, $libs, $flat, $cumulative, $main::opt_list, 0); + } elsif ($main::opt_text) { + # Make sure the output is empty when have nothing to report + # (only matters when --heapcheck is given but we must be + # compatible with old branches that did not pass --heapcheck always): + if ($total != 0) { + printf("Total%s: %s %s\n", + (defined($thread) ? " (t$thread)" : ""), + Unparse($total), Units()); + } + PrintText($symbols, $flat, $cumulative, -1); + } elsif ($main::opt_raw) { + PrintSymbolizedProfile($symbols, $profile, $main::prog); + } elsif ($main::opt_callgrind) { + PrintCallgrind($calls); + } else { + if (PrintDot($main::prog, $symbols, $profile, $flat, $cumulative, $total)) { + if ($main::opt_gv) { + RunGV(TempName($main::next_tmpfile, "ps"), ""); + } elsif ($main::opt_evince) { + RunEvince(TempName($main::next_tmpfile, "pdf"), ""); + } elsif ($main::opt_web) { + my $tmp = TempName($main::next_tmpfile, "svg"); + RunWeb($tmp); + # The command we run might hand the file name off + # to an already running browser instance and then exit. + # Normally, we'd remove $tmp on exit (right now), + # but fork a child to remove $tmp a little later, so that the + # browser has time to load it first. + delete $main::tempnames{$tmp}; + if (fork() == 0) { + sleep 5; + unlink($tmp); + exit(0); + } + } + } else { + cleanup(); + exit(1); + } + } + } else { + InteractiveMode($profile, $symbols, $libs, $total); + } +} + +sub Main() { + Init(); + $main::collected_profile = undef; + @main::profile_files = (); + $main::op_time = time(); + + # Printing symbols is special and requires a lot less info that most. + if ($main::opt_symbols) { + PrintSymbols(*STDIN); # Get /proc/maps and symbols output from stdin + return; + } + + # Fetch all profile data + FetchDynamicProfiles(); + + # this will hold symbols that we read from the profile files + my $symbol_map = {}; + + # Read one profile, pick the last item on the list + my $data = ReadProfile($main::prog, pop(@main::profile_files)); + my $profile = $data->{profile}; + my $pcs = $data->{pcs}; + my $libs = $data->{libs}; # Info about main program and shared libraries + $symbol_map = MergeSymbols($symbol_map, $data->{symbols}); + + # Add additional profiles, if available. + if (scalar(@main::profile_files) > 0) { + foreach my $pname (@main::profile_files) { + my $data2 = ReadProfile($main::prog, $pname); + $profile = AddProfile($profile, $data2->{profile}); + $pcs = AddPcs($pcs, $data2->{pcs}); + $symbol_map = MergeSymbols($symbol_map, $data2->{symbols}); + } + } + + # Subtract base from profile, if specified + if ($main::opt_base ne '') { + my $base = ReadProfile($main::prog, $main::opt_base); + $profile = SubtractProfile($profile, $base->{profile}); + $pcs = AddPcs($pcs, $base->{pcs}); + $symbol_map = MergeSymbols($symbol_map, $base->{symbols}); + } + + # Collect symbols + my $symbols; + if ($main::use_symbolized_profile) { + $symbols = FetchSymbols($pcs, $symbol_map); + } elsif ($main::use_symbol_page) { + $symbols = FetchSymbols($pcs); + } else { + # TODO(csilvers): $libs uses the /proc/self/maps data from profile1, + # which may differ from the data from subsequent profiles, especially + # if they were run on different machines. Use appropriate libs for + # each pc somehow. + $symbols = ExtractSymbols($libs, $pcs); + } + + if (!defined($main::opt_thread)) { + FilterAndPrint($profile, $symbols, $libs); + } + if (defined($data->{threads})) { + foreach my $thread (sort { $a <=> $b } keys(%{$data->{threads}})) { + if (defined($main::opt_thread) && + ($main::opt_thread eq '*' || $main::opt_thread == $thread)) { + my $thread_profile = $data->{threads}{$thread}; + FilterAndPrint($thread_profile, $symbols, $libs, $thread); + } + } + } + + cleanup(); + exit(0); +} + +##### Entry Point ##### + +Main(); + +# Temporary code to detect if we're running on a Goobuntu system. +# These systems don't have the right stuff installed for the special +# Readline libraries to work, so as a temporary workaround, we default +# to using the normal stdio code, rather than the fancier readline-based +# code +sub ReadlineMightFail { + if (-e '/lib/libtermcap.so.2') { + return 0; # libtermcap exists, so readline should be okay + } else { + return 1; + } +} + +sub RunGV { + my $fname = shift; + my $bg = shift; # "" or " &" if we should run in background + if (!system(ShellEscape(@GV, "--version") . " >$dev_null 2>&1")) { + # Options using double dash are supported by this gv version. + # Also, turn on noantialias to better handle bug in gv for + # postscript files with large dimensions. + # TODO: Maybe we should not pass the --noantialias flag + # if the gv version is known to work properly without the flag. + system(ShellEscape(@GV, "--scale=$main::opt_scale", "--noantialias", $fname) + . $bg); + } else { + # Old gv version - only supports options that use single dash. + print STDERR ShellEscape(@GV, "-scale", $main::opt_scale) . "\n"; + system(ShellEscape(@GV, "-scale", "$main::opt_scale", $fname) . $bg); + } +} + +sub RunEvince { + my $fname = shift; + my $bg = shift; # "" or " &" if we should run in background + system(ShellEscape(@EVINCE, $fname) . $bg); +} + +sub RunWeb { + my $fname = shift; + print STDERR "Loading web page file:///$fname\n"; + + if (`uname` =~ /Darwin/) { + # OS X: open will use standard preference for SVG files. + system("/usr/bin/open", $fname); + return; + } + + # Some kind of Unix; try generic symlinks, then specific browsers. + # (Stop once we find one.) + # Works best if the browser is already running. + my @alt = ( + "/etc/alternatives/gnome-www-browser", + "/etc/alternatives/x-www-browser", + "google-chrome", + "firefox", + ); + foreach my $b (@alt) { + if (system($b, $fname) == 0) { + return; + } + } + + print STDERR "Could not load web browser.\n"; +} + +sub RunKcachegrind { + my $fname = shift; + my $bg = shift; # "" or " &" if we should run in background + print STDERR "Starting '@KCACHEGRIND " . $fname . $bg . "'\n"; + system(ShellEscape(@KCACHEGRIND, $fname) . $bg); +} + + +##### Interactive helper routines ##### + +sub InteractiveMode { + $| = 1; # Make output unbuffered for interactive mode + my ($orig_profile, $symbols, $libs, $total) = @_; + + print STDERR "Welcome to jeprof! For help, type 'help'.\n"; + + # Use ReadLine if it's installed and input comes from a console. + if ( -t STDIN && + !ReadlineMightFail() && + defined(eval {require Term::ReadLine}) ) { + my $term = new Term::ReadLine 'jeprof'; + while ( defined ($_ = $term->readline('(jeprof) '))) { + $term->addhistory($_) if /\S/; + if (!InteractiveCommand($orig_profile, $symbols, $libs, $total, $_)) { + last; # exit when we get an interactive command to quit + } + } + } else { # don't have readline + while (1) { + print STDERR "(jeprof) "; + $_ = ; + last if ! defined $_ ; + s/\r//g; # turn windows-looking lines into unix-looking lines + + # Save some flags that might be reset by InteractiveCommand() + my $save_opt_lines = $main::opt_lines; + + if (!InteractiveCommand($orig_profile, $symbols, $libs, $total, $_)) { + last; # exit when we get an interactive command to quit + } + + # Restore flags + $main::opt_lines = $save_opt_lines; + } + } +} + +# Takes two args: orig profile, and command to run. +# Returns 1 if we should keep going, or 0 if we were asked to quit +sub InteractiveCommand { + my($orig_profile, $symbols, $libs, $total, $command) = @_; + $_ = $command; # just to make future m//'s easier + if (!defined($_)) { + print STDERR "\n"; + return 0; + } + if (m/^\s*quit/) { + return 0; + } + if (m/^\s*help/) { + InteractiveHelpMessage(); + return 1; + } + # Clear all the mode options -- mode is controlled by "$command" + $main::opt_text = 0; + $main::opt_callgrind = 0; + $main::opt_disasm = 0; + $main::opt_list = 0; + $main::opt_gv = 0; + $main::opt_evince = 0; + $main::opt_cum = 0; + + if (m/^\s*(text|top)(\d*)\s*(.*)/) { + $main::opt_text = 1; + + my $line_limit = ($2 ne "") ? int($2) : 10; + + my $routine; + my $ignore; + ($routine, $ignore) = ParseInteractiveArgs($3); + + my $profile = ProcessProfile($total, $orig_profile, $symbols, "", $ignore); + my $reduced = ReduceProfile($symbols, $profile); + + # Get derived profiles + my $flat = FlatProfile($reduced); + my $cumulative = CumulativeProfile($reduced); + + PrintText($symbols, $flat, $cumulative, $line_limit); + return 1; + } + if (m/^\s*callgrind\s*([^ \n]*)/) { + $main::opt_callgrind = 1; + + # Get derived profiles + my $calls = ExtractCalls($symbols, $orig_profile); + my $filename = $1; + if ( $1 eq '' ) { + $filename = TempName($main::next_tmpfile, "callgrind"); + } + PrintCallgrind($calls, $filename); + if ( $1 eq '' ) { + RunKcachegrind($filename, " & "); + $main::next_tmpfile++; + } + + return 1; + } + if (m/^\s*(web)?list\s*(.+)/) { + my $html = (defined($1) && ($1 eq "web")); + $main::opt_list = 1; + + my $routine; + my $ignore; + ($routine, $ignore) = ParseInteractiveArgs($2); + + my $profile = ProcessProfile($total, $orig_profile, $symbols, "", $ignore); + my $reduced = ReduceProfile($symbols, $profile); + + # Get derived profiles + my $flat = FlatProfile($reduced); + my $cumulative = CumulativeProfile($reduced); + + PrintListing($total, $libs, $flat, $cumulative, $routine, $html); + return 1; + } + if (m/^\s*disasm\s*(.+)/) { + $main::opt_disasm = 1; + + my $routine; + my $ignore; + ($routine, $ignore) = ParseInteractiveArgs($1); + + # Process current profile to account for various settings + my $profile = ProcessProfile($total, $orig_profile, $symbols, "", $ignore); + my $reduced = ReduceProfile($symbols, $profile); + + # Get derived profiles + my $flat = FlatProfile($reduced); + my $cumulative = CumulativeProfile($reduced); + + PrintDisassembly($libs, $flat, $cumulative, $routine); + return 1; + } + if (m/^\s*(gv|web|evince)\s*(.*)/) { + $main::opt_gv = 0; + $main::opt_evince = 0; + $main::opt_web = 0; + if ($1 eq "gv") { + $main::opt_gv = 1; + } elsif ($1 eq "evince") { + $main::opt_evince = 1; + } elsif ($1 eq "web") { + $main::opt_web = 1; + } + + my $focus; + my $ignore; + ($focus, $ignore) = ParseInteractiveArgs($2); + + # Process current profile to account for various settings + my $profile = ProcessProfile($total, $orig_profile, $symbols, + $focus, $ignore); + my $reduced = ReduceProfile($symbols, $profile); + + # Get derived profiles + my $flat = FlatProfile($reduced); + my $cumulative = CumulativeProfile($reduced); + + if (PrintDot($main::prog, $symbols, $profile, $flat, $cumulative, $total)) { + if ($main::opt_gv) { + RunGV(TempName($main::next_tmpfile, "ps"), " &"); + } elsif ($main::opt_evince) { + RunEvince(TempName($main::next_tmpfile, "pdf"), " &"); + } elsif ($main::opt_web) { + RunWeb(TempName($main::next_tmpfile, "svg")); + } + $main::next_tmpfile++; + } + return 1; + } + if (m/^\s*$/) { + return 1; + } + print STDERR "Unknown command: try 'help'.\n"; + return 1; +} + + +sub ProcessProfile { + my $total_count = shift; + my $orig_profile = shift; + my $symbols = shift; + my $focus = shift; + my $ignore = shift; + + # Process current profile to account for various settings + my $profile = $orig_profile; + printf("Total: %s %s\n", Unparse($total_count), Units()); + if ($focus ne '') { + $profile = FocusProfile($symbols, $profile, $focus); + my $focus_count = TotalProfile($profile); + printf("After focusing on '%s': %s %s of %s (%0.1f%%)\n", + $focus, + Unparse($focus_count), Units(), + Unparse($total_count), ($focus_count*100.0) / $total_count); + } + if ($ignore ne '') { + $profile = IgnoreProfile($symbols, $profile, $ignore); + my $ignore_count = TotalProfile($profile); + printf("After ignoring '%s': %s %s of %s (%0.1f%%)\n", + $ignore, + Unparse($ignore_count), Units(), + Unparse($total_count), + ($ignore_count*100.0) / $total_count); + } + + return $profile; +} + +sub InteractiveHelpMessage { + print STDERR <{$k}; + my @addrs = split(/\n/, $k); + if ($#addrs >= 0) { + my $depth = $#addrs + 1; + # int(foo / 2**32) is the only reliable way to get rid of bottom + # 32 bits on both 32- and 64-bit systems. + print pack('L*', $count & 0xFFFFFFFF, int($count / 2**32)); + print pack('L*', $depth & 0xFFFFFFFF, int($depth / 2**32)); + + foreach my $full_addr (@addrs) { + my $addr = $full_addr; + $addr =~ s/0x0*//; # strip off leading 0x, zeroes + if (length($addr) > 16) { + print STDERR "Invalid address in profile: $full_addr\n"; + next; + } + my $low_addr = substr($addr, -8); # get last 8 hex chars + my $high_addr = substr($addr, -16, 8); # get up to 8 more hex chars + print pack('L*', hex('0x' . $low_addr), hex('0x' . $high_addr)); + } + } + } +} + +# Print symbols and profile data +sub PrintSymbolizedProfile { + my $symbols = shift; + my $profile = shift; + my $prog = shift; + + $SYMBOL_PAGE =~ m,[^/]+$,; # matches everything after the last slash + my $symbol_marker = $&; + + print '--- ', $symbol_marker, "\n"; + if (defined($prog)) { + print 'binary=', $prog, "\n"; + } + while (my ($pc, $name) = each(%{$symbols})) { + my $sep = ' '; + print '0x', $pc; + # We have a list of function names, which include the inlined + # calls. They are separated (and terminated) by --, which is + # illegal in function names. + for (my $j = 2; $j <= $#{$name}; $j += 3) { + print $sep, $name->[$j]; + $sep = '--'; + } + print "\n"; + } + print '---', "\n"; + + $PROFILE_PAGE =~ m,[^/]+$,; # matches everything after the last slash + my $profile_marker = $&; + print '--- ', $profile_marker, "\n"; + if (defined($main::collected_profile)) { + # if used with remote fetch, simply dump the collected profile to output. + open(SRC, "<$main::collected_profile"); + while () { + print $_; + } + close(SRC); + } else { + # dump a cpu-format profile to standard out + PrintProfileData($profile); + } +} + +# Print text output +sub PrintText { + my $symbols = shift; + my $flat = shift; + my $cumulative = shift; + my $line_limit = shift; + + my $total = TotalProfile($flat); + + # Which profile to sort by? + my $s = $main::opt_cum ? $cumulative : $flat; + + my $running_sum = 0; + my $lines = 0; + foreach my $k (sort { GetEntry($s, $b) <=> GetEntry($s, $a) || $a cmp $b } + keys(%{$cumulative})) { + my $f = GetEntry($flat, $k); + my $c = GetEntry($cumulative, $k); + $running_sum += $f; + + my $sym = $k; + if (exists($symbols->{$k})) { + $sym = $symbols->{$k}->[0] . " " . $symbols->{$k}->[1]; + if ($main::opt_addresses) { + $sym = $k . " " . $sym; + } + } + + if ($f != 0 || $c != 0) { + printf("%8s %6s %6s %8s %6s %s\n", + Unparse($f), + Percent($f, $total), + Percent($running_sum, $total), + Unparse($c), + Percent($c, $total), + $sym); + } + $lines++; + last if ($line_limit >= 0 && $lines >= $line_limit); + } +} + +# Callgrind format has a compression for repeated function and file +# names. You show the name the first time, and just use its number +# subsequently. This can cut down the file to about a third or a +# quarter of its uncompressed size. $key and $val are the key/value +# pair that would normally be printed by callgrind; $map is a map from +# value to number. +sub CompressedCGName { + my($key, $val, $map) = @_; + my $idx = $map->{$val}; + # For very short keys, providing an index hurts rather than helps. + if (length($val) <= 3) { + return "$key=$val\n"; + } elsif (defined($idx)) { + return "$key=($idx)\n"; + } else { + # scalar(keys $map) gives the number of items in the map. + $idx = scalar(keys(%{$map})) + 1; + $map->{$val} = $idx; + return "$key=($idx) $val\n"; + } +} + +# Print the call graph in a way that's suiteable for callgrind. +sub PrintCallgrind { + my $calls = shift; + my $filename; + my %filename_to_index_map; + my %fnname_to_index_map; + + if ($main::opt_interactive) { + $filename = shift; + print STDERR "Writing callgrind file to '$filename'.\n" + } else { + $filename = "&STDOUT"; + } + open(CG, ">$filename"); + printf CG ("events: Hits\n\n"); + foreach my $call ( map { $_->[0] } + sort { $a->[1] cmp $b ->[1] || + $a->[2] <=> $b->[2] } + map { /([^:]+):(\d+):([^ ]+)( -> ([^:]+):(\d+):(.+))?/; + [$_, $1, $2] } + keys %$calls ) { + my $count = int($calls->{$call}); + $call =~ /([^:]+):(\d+):([^ ]+)( -> ([^:]+):(\d+):(.+))?/; + my ( $caller_file, $caller_line, $caller_function, + $callee_file, $callee_line, $callee_function ) = + ( $1, $2, $3, $5, $6, $7 ); + + # TODO(csilvers): for better compression, collect all the + # caller/callee_files and functions first, before printing + # anything, and only compress those referenced more than once. + printf CG CompressedCGName("fl", $caller_file, \%filename_to_index_map); + printf CG CompressedCGName("fn", $caller_function, \%fnname_to_index_map); + if (defined $6) { + printf CG CompressedCGName("cfl", $callee_file, \%filename_to_index_map); + printf CG CompressedCGName("cfn", $callee_function, \%fnname_to_index_map); + printf CG ("calls=$count $callee_line\n"); + } + printf CG ("$caller_line $count\n\n"); + } +} + +# Print disassembly for all all routines that match $main::opt_disasm +sub PrintDisassembly { + my $libs = shift; + my $flat = shift; + my $cumulative = shift; + my $disasm_opts = shift; + + my $total = TotalProfile($flat); + + foreach my $lib (@{$libs}) { + my $symbol_table = GetProcedureBoundaries($lib->[0], $disasm_opts); + my $offset = AddressSub($lib->[1], $lib->[3]); + foreach my $routine (sort ByName keys(%{$symbol_table})) { + my $start_addr = $symbol_table->{$routine}->[0]; + my $end_addr = $symbol_table->{$routine}->[1]; + # See if there are any samples in this routine + my $length = hex(AddressSub($end_addr, $start_addr)); + my $addr = AddressAdd($start_addr, $offset); + for (my $i = 0; $i < $length; $i++) { + if (defined($cumulative->{$addr})) { + PrintDisassembledFunction($lib->[0], $offset, + $routine, $flat, $cumulative, + $start_addr, $end_addr, $total); + last; + } + $addr = AddressInc($addr); + } + } + } +} + +# Return reference to array of tuples of the form: +# [start_address, filename, linenumber, instruction, limit_address] +# E.g., +# ["0x806c43d", "/foo/bar.cc", 131, "ret", "0x806c440"] +sub Disassemble { + my $prog = shift; + my $offset = shift; + my $start_addr = shift; + my $end_addr = shift; + + my $objdump = $obj_tool_map{"objdump"}; + my $cmd = ShellEscape($objdump, "-C", "-d", "-l", "--no-show-raw-insn", + "--start-address=0x$start_addr", + "--stop-address=0x$end_addr", $prog); + open(OBJDUMP, "$cmd |") || error("$cmd: $!\n"); + my @result = (); + my $filename = ""; + my $linenumber = -1; + my $last = ["", "", "", ""]; + while () { + s/\r//g; # turn windows-looking lines into unix-looking lines + chop; + if (m|\s*([^:\s]+):(\d+)\s*$|) { + # Location line of the form: + # : + $filename = $1; + $linenumber = $2; + } elsif (m/^ +([0-9a-f]+):\s*(.*)/) { + # Disassembly line -- zero-extend address to full length + my $addr = HexExtend($1); + my $k = AddressAdd($addr, $offset); + $last->[4] = $k; # Store ending address for previous instruction + $last = [$k, $filename, $linenumber, $2, $end_addr]; + push(@result, $last); + } + } + close(OBJDUMP); + return @result; +} + +# The input file should contain lines of the form /proc/maps-like +# output (same format as expected from the profiles) or that looks +# like hex addresses (like "0xDEADBEEF"). We will parse all +# /proc/maps output, and for all the hex addresses, we will output +# "short" symbol names, one per line, in the same order as the input. +sub PrintSymbols { + my $maps_and_symbols_file = shift; + + # ParseLibraries expects pcs to be in a set. Fine by us... + my @pclist = (); # pcs in sorted order + my $pcs = {}; + my $map = ""; + foreach my $line (<$maps_and_symbols_file>) { + $line =~ s/\r//g; # turn windows-looking lines into unix-looking lines + if ($line =~ /\b(0x[0-9a-f]+)\b/i) { + push(@pclist, HexExtend($1)); + $pcs->{$pclist[-1]} = 1; + } else { + $map .= $line; + } + } + + my $libs = ParseLibraries($main::prog, $map, $pcs); + my $symbols = ExtractSymbols($libs, $pcs); + + foreach my $pc (@pclist) { + # ->[0] is the shortname, ->[2] is the full name + print(($symbols->{$pc}->[0] || "??") . "\n"); + } +} + + +# For sorting functions by name +sub ByName { + return ShortFunctionName($a) cmp ShortFunctionName($b); +} + +# Print source-listing for all all routines that match $list_opts +sub PrintListing { + my $total = shift; + my $libs = shift; + my $flat = shift; + my $cumulative = shift; + my $list_opts = shift; + my $html = shift; + + my $output = \*STDOUT; + my $fname = ""; + + if ($html) { + # Arrange to write the output to a temporary file + $fname = TempName($main::next_tmpfile, "html"); + $main::next_tmpfile++; + if (!open(TEMP, ">$fname")) { + print STDERR "$fname: $!\n"; + return; + } + $output = \*TEMP; + print $output HtmlListingHeader(); + printf $output ("
%s
Total: %s %s
\n", + $main::prog, Unparse($total), Units()); + } + + my $listed = 0; + foreach my $lib (@{$libs}) { + my $symbol_table = GetProcedureBoundaries($lib->[0], $list_opts); + my $offset = AddressSub($lib->[1], $lib->[3]); + foreach my $routine (sort ByName keys(%{$symbol_table})) { + # Print if there are any samples in this routine + my $start_addr = $symbol_table->{$routine}->[0]; + my $end_addr = $symbol_table->{$routine}->[1]; + my $length = hex(AddressSub($end_addr, $start_addr)); + my $addr = AddressAdd($start_addr, $offset); + for (my $i = 0; $i < $length; $i++) { + if (defined($cumulative->{$addr})) { + $listed += PrintSource( + $lib->[0], $offset, + $routine, $flat, $cumulative, + $start_addr, $end_addr, + $html, + $output); + last; + } + $addr = AddressInc($addr); + } + } + } + + if ($html) { + if ($listed > 0) { + print $output HtmlListingFooter(); + close($output); + RunWeb($fname); + } else { + close($output); + unlink($fname); + } + } +} + +sub HtmlListingHeader { + return <<'EOF'; + + + +Pprof listing + + + + +EOF +} + +sub HtmlListingFooter { + return <<'EOF'; + + +EOF +} + +sub HtmlEscape { + my $text = shift; + $text =~ s/&/&/g; + $text =~ s//>/g; + return $text; +} + +# Returns the indentation of the line, if it has any non-whitespace +# characters. Otherwise, returns -1. +sub Indentation { + my $line = shift; + if (m/^(\s*)\S/) { + return length($1); + } else { + return -1; + } +} + +# If the symbol table contains inlining info, Disassemble() may tag an +# instruction with a location inside an inlined function. But for +# source listings, we prefer to use the location in the function we +# are listing. So use MapToSymbols() to fetch full location +# information for each instruction and then pick out the first +# location from a location list (location list contains callers before +# callees in case of inlining). +# +# After this routine has run, each entry in $instructions contains: +# [0] start address +# [1] filename for function we are listing +# [2] line number for function we are listing +# [3] disassembly +# [4] limit address +# [5] most specific filename (may be different from [1] due to inlining) +# [6] most specific line number (may be different from [2] due to inlining) +sub GetTopLevelLineNumbers { + my ($lib, $offset, $instructions) = @_; + my $pcs = []; + for (my $i = 0; $i <= $#{$instructions}; $i++) { + push(@{$pcs}, $instructions->[$i]->[0]); + } + my $symbols = {}; + MapToSymbols($lib, $offset, $pcs, $symbols); + for (my $i = 0; $i <= $#{$instructions}; $i++) { + my $e = $instructions->[$i]; + push(@{$e}, $e->[1]); + push(@{$e}, $e->[2]); + my $addr = $e->[0]; + my $sym = $symbols->{$addr}; + if (defined($sym)) { + if ($#{$sym} >= 2 && $sym->[1] =~ m/^(.*):(\d+)$/) { + $e->[1] = $1; # File name + $e->[2] = $2; # Line number + } + } + } +} + +# Print source-listing for one routine +sub PrintSource { + my $prog = shift; + my $offset = shift; + my $routine = shift; + my $flat = shift; + my $cumulative = shift; + my $start_addr = shift; + my $end_addr = shift; + my $html = shift; + my $output = shift; + + # Disassemble all instructions (just to get line numbers) + my @instructions = Disassemble($prog, $offset, $start_addr, $end_addr); + GetTopLevelLineNumbers($prog, $offset, \@instructions); + + # Hack 1: assume that the first source file encountered in the + # disassembly contains the routine + my $filename = undef; + for (my $i = 0; $i <= $#instructions; $i++) { + if ($instructions[$i]->[2] >= 0) { + $filename = $instructions[$i]->[1]; + last; + } + } + if (!defined($filename)) { + print STDERR "no filename found in $routine\n"; + return 0; + } + + # Hack 2: assume that the largest line number from $filename is the + # end of the procedure. This is typically safe since if P1 contains + # an inlined call to P2, then P2 usually occurs earlier in the + # source file. If this does not work, we might have to compute a + # density profile or just print all regions we find. + my $lastline = 0; + for (my $i = 0; $i <= $#instructions; $i++) { + my $f = $instructions[$i]->[1]; + my $l = $instructions[$i]->[2]; + if (($f eq $filename) && ($l > $lastline)) { + $lastline = $l; + } + } + + # Hack 3: assume the first source location from "filename" is the start of + # the source code. + my $firstline = 1; + for (my $i = 0; $i <= $#instructions; $i++) { + if ($instructions[$i]->[1] eq $filename) { + $firstline = $instructions[$i]->[2]; + last; + } + } + + # Hack 4: Extend last line forward until its indentation is less than + # the indentation we saw on $firstline + my $oldlastline = $lastline; + { + if (!open(FILE, "<$filename")) { + print STDERR "$filename: $!\n"; + return 0; + } + my $l = 0; + my $first_indentation = -1; + while () { + s/\r//g; # turn windows-looking lines into unix-looking lines + $l++; + my $indent = Indentation($_); + if ($l >= $firstline) { + if ($first_indentation < 0 && $indent >= 0) { + $first_indentation = $indent; + last if ($first_indentation == 0); + } + } + if ($l >= $lastline && $indent >= 0) { + if ($indent >= $first_indentation) { + $lastline = $l+1; + } else { + last; + } + } + } + close(FILE); + } + + # Assign all samples to the range $firstline,$lastline, + # Hack 4: If an instruction does not occur in the range, its samples + # are moved to the next instruction that occurs in the range. + my $samples1 = {}; # Map from line number to flat count + my $samples2 = {}; # Map from line number to cumulative count + my $running1 = 0; # Unassigned flat counts + my $running2 = 0; # Unassigned cumulative counts + my $total1 = 0; # Total flat counts + my $total2 = 0; # Total cumulative counts + my %disasm = (); # Map from line number to disassembly + my $running_disasm = ""; # Unassigned disassembly + my $skip_marker = "---\n"; + if ($html) { + $skip_marker = ""; + for (my $l = $firstline; $l <= $lastline; $l++) { + $disasm{$l} = ""; + } + } + my $last_dis_filename = ''; + my $last_dis_linenum = -1; + my $last_touched_line = -1; # To detect gaps in disassembly for a line + foreach my $e (@instructions) { + # Add up counts for all address that fall inside this instruction + my $c1 = 0; + my $c2 = 0; + for (my $a = $e->[0]; $a lt $e->[4]; $a = AddressInc($a)) { + $c1 += GetEntry($flat, $a); + $c2 += GetEntry($cumulative, $a); + } + + if ($html) { + my $dis = sprintf(" %6s %6s \t\t%8s: %s ", + HtmlPrintNumber($c1), + HtmlPrintNumber($c2), + UnparseAddress($offset, $e->[0]), + CleanDisassembly($e->[3])); + + # Append the most specific source line associated with this instruction + if (length($dis) < 80) { $dis .= (' ' x (80 - length($dis))) }; + $dis = HtmlEscape($dis); + my $f = $e->[5]; + my $l = $e->[6]; + if ($f ne $last_dis_filename) { + $dis .= sprintf("%s:%d", + HtmlEscape(CleanFileName($f)), $l); + } elsif ($l ne $last_dis_linenum) { + # De-emphasize the unchanged file name portion + $dis .= sprintf("%s" . + ":%d", + HtmlEscape(CleanFileName($f)), $l); + } else { + # De-emphasize the entire location + $dis .= sprintf("%s:%d", + HtmlEscape(CleanFileName($f)), $l); + } + $last_dis_filename = $f; + $last_dis_linenum = $l; + $running_disasm .= $dis; + $running_disasm .= "\n"; + } + + $running1 += $c1; + $running2 += $c2; + $total1 += $c1; + $total2 += $c2; + my $file = $e->[1]; + my $line = $e->[2]; + if (($file eq $filename) && + ($line >= $firstline) && + ($line <= $lastline)) { + # Assign all accumulated samples to this line + AddEntry($samples1, $line, $running1); + AddEntry($samples2, $line, $running2); + $running1 = 0; + $running2 = 0; + if ($html) { + if ($line != $last_touched_line && $disasm{$line} ne '') { + $disasm{$line} .= "\n"; + } + $disasm{$line} .= $running_disasm; + $running_disasm = ''; + $last_touched_line = $line; + } + } + } + + # Assign any leftover samples to $lastline + AddEntry($samples1, $lastline, $running1); + AddEntry($samples2, $lastline, $running2); + if ($html) { + if ($lastline != $last_touched_line && $disasm{$lastline} ne '') { + $disasm{$lastline} .= "\n"; + } + $disasm{$lastline} .= $running_disasm; + } + + if ($html) { + printf $output ( + "

%s

%s\n
\n" .
+      "Total:%6s %6s (flat / cumulative %s)\n",
+      HtmlEscape(ShortFunctionName($routine)),
+      HtmlEscape(CleanFileName($filename)),
+      Unparse($total1),
+      Unparse($total2),
+      Units());
+  } else {
+    printf $output (
+      "ROUTINE ====================== %s in %s\n" .
+      "%6s %6s Total %s (flat / cumulative)\n",
+      ShortFunctionName($routine),
+      CleanFileName($filename),
+      Unparse($total1),
+      Unparse($total2),
+      Units());
+  }
+  if (!open(FILE, "<$filename")) {
+    print STDERR "$filename: $!\n";
+    return 0;
+  }
+  my $l = 0;
+  while () {
+    s/\r//g;         # turn windows-looking lines into unix-looking lines
+    $l++;
+    if ($l >= $firstline - 5 &&
+        (($l <= $oldlastline + 5) || ($l <= $lastline))) {
+      chop;
+      my $text = $_;
+      if ($l == $firstline) { print $output $skip_marker; }
+      my $n1 = GetEntry($samples1, $l);
+      my $n2 = GetEntry($samples2, $l);
+      if ($html) {
+        # Emit a span that has one of the following classes:
+        #    livesrc -- has samples
+        #    deadsrc -- has disassembly, but with no samples
+        #    nop     -- has no matching disasembly
+        # Also emit an optional span containing disassembly.
+        my $dis = $disasm{$l};
+        my $asm = "";
+        if (defined($dis) && $dis ne '') {
+          $asm = "" . $dis . "";
+        }
+        my $source_class = (($n1 + $n2 > 0)
+                            ? "livesrc"
+                            : (($asm ne "") ? "deadsrc" : "nop"));
+        printf $output (
+          "%5d " .
+          "%6s %6s %s%s\n",
+          $l, $source_class,
+          HtmlPrintNumber($n1),
+          HtmlPrintNumber($n2),
+          HtmlEscape($text),
+          $asm);
+      } else {
+        printf $output(
+          "%6s %6s %4d: %s\n",
+          UnparseAlt($n1),
+          UnparseAlt($n2),
+          $l,
+          $text);
+      }
+      if ($l == $lastline)  { print $output $skip_marker; }
+    };
+  }
+  close(FILE);
+  if ($html) {
+    print $output "
\n"; + } + return 1; +} + +# Return the source line for the specified file/linenumber. +# Returns undef if not found. +sub SourceLine { + my $file = shift; + my $line = shift; + + # Look in cache + if (!defined($main::source_cache{$file})) { + if (100 < scalar keys(%main::source_cache)) { + # Clear the cache when it gets too big + $main::source_cache = (); + } + + # Read all lines from the file + if (!open(FILE, "<$file")) { + print STDERR "$file: $!\n"; + $main::source_cache{$file} = []; # Cache the negative result + return undef; + } + my $lines = []; + push(@{$lines}, ""); # So we can use 1-based line numbers as indices + while () { + push(@{$lines}, $_); + } + close(FILE); + + # Save the lines in the cache + $main::source_cache{$file} = $lines; + } + + my $lines = $main::source_cache{$file}; + if (($line < 0) || ($line > $#{$lines})) { + return undef; + } else { + return $lines->[$line]; + } +} + +# Print disassembly for one routine with interspersed source if available +sub PrintDisassembledFunction { + my $prog = shift; + my $offset = shift; + my $routine = shift; + my $flat = shift; + my $cumulative = shift; + my $start_addr = shift; + my $end_addr = shift; + my $total = shift; + + # Disassemble all instructions + my @instructions = Disassemble($prog, $offset, $start_addr, $end_addr); + + # Make array of counts per instruction + my @flat_count = (); + my @cum_count = (); + my $flat_total = 0; + my $cum_total = 0; + foreach my $e (@instructions) { + # Add up counts for all address that fall inside this instruction + my $c1 = 0; + my $c2 = 0; + for (my $a = $e->[0]; $a lt $e->[4]; $a = AddressInc($a)) { + $c1 += GetEntry($flat, $a); + $c2 += GetEntry($cumulative, $a); + } + push(@flat_count, $c1); + push(@cum_count, $c2); + $flat_total += $c1; + $cum_total += $c2; + } + + # Print header with total counts + printf("ROUTINE ====================== %s\n" . + "%6s %6s %s (flat, cumulative) %.1f%% of total\n", + ShortFunctionName($routine), + Unparse($flat_total), + Unparse($cum_total), + Units(), + ($cum_total * 100.0) / $total); + + # Process instructions in order + my $current_file = ""; + for (my $i = 0; $i <= $#instructions; ) { + my $e = $instructions[$i]; + + # Print the new file name whenever we switch files + if ($e->[1] ne $current_file) { + $current_file = $e->[1]; + my $fname = $current_file; + $fname =~ s|^\./||; # Trim leading "./" + + # Shorten long file names + if (length($fname) >= 58) { + $fname = "..." . substr($fname, -55); + } + printf("-------------------- %s\n", $fname); + } + + # TODO: Compute range of lines to print together to deal with + # small reorderings. + my $first_line = $e->[2]; + my $last_line = $first_line; + my %flat_sum = (); + my %cum_sum = (); + for (my $l = $first_line; $l <= $last_line; $l++) { + $flat_sum{$l} = 0; + $cum_sum{$l} = 0; + } + + # Find run of instructions for this range of source lines + my $first_inst = $i; + while (($i <= $#instructions) && + ($instructions[$i]->[2] >= $first_line) && + ($instructions[$i]->[2] <= $last_line)) { + $e = $instructions[$i]; + $flat_sum{$e->[2]} += $flat_count[$i]; + $cum_sum{$e->[2]} += $cum_count[$i]; + $i++; + } + my $last_inst = $i - 1; + + # Print source lines + for (my $l = $first_line; $l <= $last_line; $l++) { + my $line = SourceLine($current_file, $l); + if (!defined($line)) { + $line = "?\n"; + next; + } else { + $line =~ s/^\s+//; + } + printf("%6s %6s %5d: %s", + UnparseAlt($flat_sum{$l}), + UnparseAlt($cum_sum{$l}), + $l, + $line); + } + + # Print disassembly + for (my $x = $first_inst; $x <= $last_inst; $x++) { + my $e = $instructions[$x]; + printf("%6s %6s %8s: %6s\n", + UnparseAlt($flat_count[$x]), + UnparseAlt($cum_count[$x]), + UnparseAddress($offset, $e->[0]), + CleanDisassembly($e->[3])); + } + } +} + +# Print DOT graph +sub PrintDot { + my $prog = shift; + my $symbols = shift; + my $raw = shift; + my $flat = shift; + my $cumulative = shift; + my $overall_total = shift; + + # Get total + my $local_total = TotalProfile($flat); + my $nodelimit = int($main::opt_nodefraction * $local_total); + my $edgelimit = int($main::opt_edgefraction * $local_total); + my $nodecount = $main::opt_nodecount; + + # Find nodes to include + my @list = (sort { abs(GetEntry($cumulative, $b)) <=> + abs(GetEntry($cumulative, $a)) + || $a cmp $b } + keys(%{$cumulative})); + my $last = $nodecount - 1; + if ($last > $#list) { + $last = $#list; + } + while (($last >= 0) && + (abs(GetEntry($cumulative, $list[$last])) <= $nodelimit)) { + $last--; + } + if ($last < 0) { + print STDERR "No nodes to print\n"; + return 0; + } + + if ($nodelimit > 0 || $edgelimit > 0) { + printf STDERR ("Dropping nodes with <= %s %s; edges with <= %s abs(%s)\n", + Unparse($nodelimit), Units(), + Unparse($edgelimit), Units()); + } + + # Open DOT output file + my $output; + my $escaped_dot = ShellEscape(@DOT); + my $escaped_ps2pdf = ShellEscape(@PS2PDF); + if ($main::opt_gv) { + my $escaped_outfile = ShellEscape(TempName($main::next_tmpfile, "ps")); + $output = "| $escaped_dot -Tps2 >$escaped_outfile"; + } elsif ($main::opt_evince) { + my $escaped_outfile = ShellEscape(TempName($main::next_tmpfile, "pdf")); + $output = "| $escaped_dot -Tps2 | $escaped_ps2pdf - $escaped_outfile"; + } elsif ($main::opt_ps) { + $output = "| $escaped_dot -Tps2"; + } elsif ($main::opt_pdf) { + $output = "| $escaped_dot -Tps2 | $escaped_ps2pdf - -"; + } elsif ($main::opt_web || $main::opt_svg) { + # We need to post-process the SVG, so write to a temporary file always. + my $escaped_outfile = ShellEscape(TempName($main::next_tmpfile, "svg")); + $output = "| $escaped_dot -Tsvg >$escaped_outfile"; + } elsif ($main::opt_gif) { + $output = "| $escaped_dot -Tgif"; + } else { + $output = ">&STDOUT"; + } + open(DOT, $output) || error("$output: $!\n"); + + # Title + printf DOT ("digraph \"%s; %s %s\" {\n", + $prog, + Unparse($overall_total), + Units()); + if ($main::opt_pdf) { + # The output is more printable if we set the page size for dot. + printf DOT ("size=\"8,11\"\n"); + } + printf DOT ("node [width=0.375,height=0.25];\n"); + + # Print legend + printf DOT ("Legend [shape=box,fontsize=24,shape=plaintext," . + "label=\"%s\\l%s\\l%s\\l%s\\l%s\\l\"];\n", + $prog, + sprintf("Total %s: %s", Units(), Unparse($overall_total)), + sprintf("Focusing on: %s", Unparse($local_total)), + sprintf("Dropped nodes with <= %s abs(%s)", + Unparse($nodelimit), Units()), + sprintf("Dropped edges with <= %s %s", + Unparse($edgelimit), Units()) + ); + + # Print nodes + my %node = (); + my $nextnode = 1; + foreach my $a (@list[0..$last]) { + # Pick font size + my $f = GetEntry($flat, $a); + my $c = GetEntry($cumulative, $a); + + my $fs = 8; + if ($local_total > 0) { + $fs = 8 + (50.0 * sqrt(abs($f * 1.0 / $local_total))); + } + + $node{$a} = $nextnode++; + my $sym = $a; + $sym =~ s/\s+/\\n/g; + $sym =~ s/::/\\n/g; + + # Extra cumulative info to print for non-leaves + my $extra = ""; + if ($f != $c) { + $extra = sprintf("\\rof %s (%s)", + Unparse($c), + Percent($c, $local_total)); + } + my $style = ""; + if ($main::opt_heapcheck) { + if ($f > 0) { + # make leak-causing nodes more visible (add a background) + $style = ",style=filled,fillcolor=gray" + } elsif ($f < 0) { + # make anti-leak-causing nodes (which almost never occur) + # stand out as well (triple border) + $style = ",peripheries=3" + } + } + + printf DOT ("N%d [label=\"%s\\n%s (%s)%s\\r" . + "\",shape=box,fontsize=%.1f%s];\n", + $node{$a}, + $sym, + Unparse($f), + Percent($f, $local_total), + $extra, + $fs, + $style, + ); + } + + # Get edges and counts per edge + my %edge = (); + my $n; + my $fullname_to_shortname_map = {}; + FillFullnameToShortnameMap($symbols, $fullname_to_shortname_map); + foreach my $k (keys(%{$raw})) { + # TODO: omit low %age edges + $n = $raw->{$k}; + my @translated = TranslateStack($symbols, $fullname_to_shortname_map, $k); + for (my $i = 1; $i <= $#translated; $i++) { + my $src = $translated[$i]; + my $dst = $translated[$i-1]; + #next if ($src eq $dst); # Avoid self-edges? + if (exists($node{$src}) && exists($node{$dst})) { + my $edge_label = "$src\001$dst"; + if (!exists($edge{$edge_label})) { + $edge{$edge_label} = 0; + } + $edge{$edge_label} += $n; + } + } + } + + # Print edges (process in order of decreasing counts) + my %indegree = (); # Number of incoming edges added per node so far + my %outdegree = (); # Number of outgoing edges added per node so far + foreach my $e (sort { $edge{$b} <=> $edge{$a} } keys(%edge)) { + my @x = split(/\001/, $e); + $n = $edge{$e}; + + # Initialize degree of kept incoming and outgoing edges if necessary + my $src = $x[0]; + my $dst = $x[1]; + if (!exists($outdegree{$src})) { $outdegree{$src} = 0; } + if (!exists($indegree{$dst})) { $indegree{$dst} = 0; } + + my $keep; + if ($indegree{$dst} == 0) { + # Keep edge if needed for reachability + $keep = 1; + } elsif (abs($n) <= $edgelimit) { + # Drop if we are below --edgefraction + $keep = 0; + } elsif ($outdegree{$src} >= $main::opt_maxdegree || + $indegree{$dst} >= $main::opt_maxdegree) { + # Keep limited number of in/out edges per node + $keep = 0; + } else { + $keep = 1; + } + + if ($keep) { + $outdegree{$src}++; + $indegree{$dst}++; + + # Compute line width based on edge count + my $fraction = abs($local_total ? (3 * ($n / $local_total)) : 0); + if ($fraction > 1) { $fraction = 1; } + my $w = $fraction * 2; + if ($w < 1 && ($main::opt_web || $main::opt_svg)) { + # SVG output treats line widths < 1 poorly. + $w = 1; + } + + # Dot sometimes segfaults if given edge weights that are too large, so + # we cap the weights at a large value + my $edgeweight = abs($n) ** 0.7; + if ($edgeweight > 100000) { $edgeweight = 100000; } + $edgeweight = int($edgeweight); + + my $style = sprintf("setlinewidth(%f)", $w); + if ($x[1] =~ m/\(inline\)/) { + $style .= ",dashed"; + } + + # Use a slightly squashed function of the edge count as the weight + printf DOT ("N%s -> N%s [label=%s, weight=%d, style=\"%s\"];\n", + $node{$x[0]}, + $node{$x[1]}, + Unparse($n), + $edgeweight, + $style); + } + } + + print DOT ("}\n"); + close(DOT); + + if ($main::opt_web || $main::opt_svg) { + # Rewrite SVG to be more usable inside web browser. + RewriteSvg(TempName($main::next_tmpfile, "svg")); + } + + return 1; +} + +sub RewriteSvg { + my $svgfile = shift; + + open(SVG, $svgfile) || die "open temp svg: $!"; + my @svg = ; + close(SVG); + unlink $svgfile; + my $svg = join('', @svg); + + # Dot's SVG output is + # + # + # + # ... + # + # + # + # Change it to + # + # + # $svg_javascript + # + # + # ... + # + # + # + + # Fix width, height; drop viewBox. + $svg =~ s/(?s) above first + my $svg_javascript = SvgJavascript(); + my $viewport = "\n"; + $svg =~ s/ above . + $svg =~ s/(.*)(<\/svg>)/$1<\/g>$2/; + $svg =~ s/$svgfile") || die "open $svgfile: $!"; + print SVG $svg; + close(SVG); + } +} + +sub SvgJavascript { + return <<'EOF'; + +EOF +} + +# Provides a map from fullname to shortname for cases where the +# shortname is ambiguous. The symlist has both the fullname and +# shortname for all symbols, which is usually fine, but sometimes -- +# such as overloaded functions -- two different fullnames can map to +# the same shortname. In that case, we use the address of the +# function to disambiguate the two. This function fills in a map that +# maps fullnames to modified shortnames in such cases. If a fullname +# is not present in the map, the 'normal' shortname provided by the +# symlist is the appropriate one to use. +sub FillFullnameToShortnameMap { + my $symbols = shift; + my $fullname_to_shortname_map = shift; + my $shortnames_seen_once = {}; + my $shortnames_seen_more_than_once = {}; + + foreach my $symlist (values(%{$symbols})) { + # TODO(csilvers): deal with inlined symbols too. + my $shortname = $symlist->[0]; + my $fullname = $symlist->[2]; + if ($fullname !~ /<[0-9a-fA-F]+>$/) { # fullname doesn't end in an address + next; # the only collisions we care about are when addresses differ + } + if (defined($shortnames_seen_once->{$shortname}) && + $shortnames_seen_once->{$shortname} ne $fullname) { + $shortnames_seen_more_than_once->{$shortname} = 1; + } else { + $shortnames_seen_once->{$shortname} = $fullname; + } + } + + foreach my $symlist (values(%{$symbols})) { + my $shortname = $symlist->[0]; + my $fullname = $symlist->[2]; + # TODO(csilvers): take in a list of addresses we care about, and only + # store in the map if $symlist->[1] is in that list. Saves space. + next if defined($fullname_to_shortname_map->{$fullname}); + if (defined($shortnames_seen_more_than_once->{$shortname})) { + if ($fullname =~ /<0*([^>]*)>$/) { # fullname has address at end of it + $fullname_to_shortname_map->{$fullname} = "$shortname\@$1"; + } + } + } +} + +# Return a small number that identifies the argument. +# Multiple calls with the same argument will return the same number. +# Calls with different arguments will return different numbers. +sub ShortIdFor { + my $key = shift; + my $id = $main::uniqueid{$key}; + if (!defined($id)) { + $id = keys(%main::uniqueid) + 1; + $main::uniqueid{$key} = $id; + } + return $id; +} + +# Translate a stack of addresses into a stack of symbols +sub TranslateStack { + my $symbols = shift; + my $fullname_to_shortname_map = shift; + my $k = shift; + + my @addrs = split(/\n/, $k); + my @result = (); + for (my $i = 0; $i <= $#addrs; $i++) { + my $a = $addrs[$i]; + + # Skip large addresses since they sometimes show up as fake entries on RH9 + if (length($a) > 8 && $a gt "7fffffffffffffff") { + next; + } + + if ($main::opt_disasm || $main::opt_list) { + # We want just the address for the key + push(@result, $a); + next; + } + + my $symlist = $symbols->{$a}; + if (!defined($symlist)) { + $symlist = [$a, "", $a]; + } + + # We can have a sequence of symbols for a particular entry + # (more than one symbol in the case of inlining). Callers + # come before callees in symlist, so walk backwards since + # the translated stack should contain callees before callers. + for (my $j = $#{$symlist}; $j >= 2; $j -= 3) { + my $func = $symlist->[$j-2]; + my $fileline = $symlist->[$j-1]; + my $fullfunc = $symlist->[$j]; + if (defined($fullname_to_shortname_map->{$fullfunc})) { + $func = $fullname_to_shortname_map->{$fullfunc}; + } + if ($j > 2) { + $func = "$func (inline)"; + } + + # Do not merge nodes corresponding to Callback::Run since that + # causes confusing cycles in dot display. Instead, we synthesize + # a unique name for this frame per caller. + if ($func =~ m/Callback.*::Run$/) { + my $caller = ($i > 0) ? $addrs[$i-1] : 0; + $func = "Run#" . ShortIdFor($caller); + } + + if ($main::opt_addresses) { + push(@result, "$a $func $fileline"); + } elsif ($main::opt_lines) { + if ($func eq '??' && $fileline eq '??:0') { + push(@result, "$a"); + } else { + push(@result, "$func $fileline"); + } + } elsif ($main::opt_functions) { + if ($func eq '??') { + push(@result, "$a"); + } else { + push(@result, $func); + } + } elsif ($main::opt_files) { + if ($fileline eq '??:0' || $fileline eq '') { + push(@result, "$a"); + } else { + my $f = $fileline; + $f =~ s/:\d+$//; + push(@result, $f); + } + } else { + push(@result, $a); + last; # Do not print inlined info + } + } + } + + # print join(",", @addrs), " => ", join(",", @result), "\n"; + return @result; +} + +# Generate percent string for a number and a total +sub Percent { + my $num = shift; + my $tot = shift; + if ($tot != 0) { + return sprintf("%.1f%%", $num * 100.0 / $tot); + } else { + return ($num == 0) ? "nan" : (($num > 0) ? "+inf" : "-inf"); + } +} + +# Generate pretty-printed form of number +sub Unparse { + my $num = shift; + if ($main::profile_type eq 'heap' || $main::profile_type eq 'growth') { + if ($main::opt_inuse_objects || $main::opt_alloc_objects) { + return sprintf("%d", $num); + } else { + if ($main::opt_show_bytes) { + return sprintf("%d", $num); + } else { + return sprintf("%.1f", $num / 1048576.0); + } + } + } elsif ($main::profile_type eq 'contention' && !$main::opt_contentions) { + return sprintf("%.3f", $num / 1e9); # Convert nanoseconds to seconds + } else { + return sprintf("%d", $num); + } +} + +# Alternate pretty-printed form: 0 maps to "." +sub UnparseAlt { + my $num = shift; + if ($num == 0) { + return "."; + } else { + return Unparse($num); + } +} + +# Alternate pretty-printed form: 0 maps to "" +sub HtmlPrintNumber { + my $num = shift; + if ($num == 0) { + return ""; + } else { + return Unparse($num); + } +} + +# Return output units +sub Units { + if ($main::profile_type eq 'heap' || $main::profile_type eq 'growth') { + if ($main::opt_inuse_objects || $main::opt_alloc_objects) { + return "objects"; + } else { + if ($main::opt_show_bytes) { + return "B"; + } else { + return "MB"; + } + } + } elsif ($main::profile_type eq 'contention' && !$main::opt_contentions) { + return "seconds"; + } else { + return "samples"; + } +} + +##### Profile manipulation code ##### + +# Generate flattened profile: +# If count is charged to stack [a,b,c,d], in generated profile, +# it will be charged to [a] +sub FlatProfile { + my $profile = shift; + my $result = {}; + foreach my $k (keys(%{$profile})) { + my $count = $profile->{$k}; + my @addrs = split(/\n/, $k); + if ($#addrs >= 0) { + AddEntry($result, $addrs[0], $count); + } + } + return $result; +} + +# Generate cumulative profile: +# If count is charged to stack [a,b,c,d], in generated profile, +# it will be charged to [a], [b], [c], [d] +sub CumulativeProfile { + my $profile = shift; + my $result = {}; + foreach my $k (keys(%{$profile})) { + my $count = $profile->{$k}; + my @addrs = split(/\n/, $k); + foreach my $a (@addrs) { + AddEntry($result, $a, $count); + } + } + return $result; +} + +# If the second-youngest PC on the stack is always the same, returns +# that pc. Otherwise, returns undef. +sub IsSecondPcAlwaysTheSame { + my $profile = shift; + + my $second_pc = undef; + foreach my $k (keys(%{$profile})) { + my @addrs = split(/\n/, $k); + if ($#addrs < 1) { + return undef; + } + if (not defined $second_pc) { + $second_pc = $addrs[1]; + } else { + if ($second_pc ne $addrs[1]) { + return undef; + } + } + } + return $second_pc; +} + +sub ExtractSymbolLocation { + my $symbols = shift; + my $address = shift; + # 'addr2line' outputs "??:0" for unknown locations; we do the + # same to be consistent. + my $location = "??:0:unknown"; + if (exists $symbols->{$address}) { + my $file = $symbols->{$address}->[1]; + if ($file eq "?") { + $file = "??:0" + } + $location = $file . ":" . $symbols->{$address}->[0]; + } + return $location; +} + +# Extracts a graph of calls. +sub ExtractCalls { + my $symbols = shift; + my $profile = shift; + + my $calls = {}; + while( my ($stack_trace, $count) = each %$profile ) { + my @address = split(/\n/, $stack_trace); + my $destination = ExtractSymbolLocation($symbols, $address[0]); + AddEntry($calls, $destination, $count); + for (my $i = 1; $i <= $#address; $i++) { + my $source = ExtractSymbolLocation($symbols, $address[$i]); + my $call = "$source -> $destination"; + AddEntry($calls, $call, $count); + $destination = $source; + } + } + + return $calls; +} + +sub RemoveUninterestingFrames { + my $symbols = shift; + my $profile = shift; + + # List of function names to skip + my %skip = (); + my $skip_regexp = 'NOMATCH'; + if ($main::profile_type eq 'heap' || $main::profile_type eq 'growth') { + foreach my $name ('calloc', + 'cfree', + 'malloc', + 'free', + 'memalign', + 'posix_memalign', + 'aligned_alloc', + 'pvalloc', + 'valloc', + 'realloc', + 'mallocx', # jemalloc + 'rallocx', # jemalloc + 'xallocx', # jemalloc + 'dallocx', # jemalloc + 'sdallocx', # jemalloc + 'tc_calloc', + 'tc_cfree', + 'tc_malloc', + 'tc_free', + 'tc_memalign', + 'tc_posix_memalign', + 'tc_pvalloc', + 'tc_valloc', + 'tc_realloc', + 'tc_new', + 'tc_delete', + 'tc_newarray', + 'tc_deletearray', + 'tc_new_nothrow', + 'tc_newarray_nothrow', + 'do_malloc', + '::do_malloc', # new name -- got moved to an unnamed ns + '::do_malloc_or_cpp_alloc', + 'DoSampledAllocation', + 'simple_alloc::allocate', + '__malloc_alloc_template::allocate', + '__builtin_delete', + '__builtin_new', + '__builtin_vec_delete', + '__builtin_vec_new', + 'operator new', + 'operator new[]', + # The entry to our memory-allocation routines on OS X + 'malloc_zone_malloc', + 'malloc_zone_calloc', + 'malloc_zone_valloc', + 'malloc_zone_realloc', + 'malloc_zone_memalign', + 'malloc_zone_free', + # These mark the beginning/end of our custom sections + '__start_google_malloc', + '__stop_google_malloc', + '__start_malloc_hook', + '__stop_malloc_hook') { + $skip{$name} = 1; + $skip{"_" . $name} = 1; # Mach (OS X) adds a _ prefix to everything + } + # TODO: Remove TCMalloc once everything has been + # moved into the tcmalloc:: namespace and we have flushed + # old code out of the system. + $skip_regexp = "TCMalloc|^tcmalloc::"; + } elsif ($main::profile_type eq 'contention') { + foreach my $vname ('base::RecordLockProfileData', + 'base::SubmitMutexProfileData', + 'base::SubmitSpinLockProfileData', + 'Mutex::Unlock', + 'Mutex::UnlockSlow', + 'Mutex::ReaderUnlock', + 'MutexLock::~MutexLock', + 'SpinLock::Unlock', + 'SpinLock::SlowUnlock', + 'SpinLockHolder::~SpinLockHolder') { + $skip{$vname} = 1; + } + } elsif ($main::profile_type eq 'cpu') { + # Drop signal handlers used for CPU profile collection + # TODO(dpeng): this should not be necessary; it's taken + # care of by the general 2nd-pc mechanism below. + foreach my $name ('ProfileData::Add', # historical + 'ProfileData::prof_handler', # historical + 'CpuProfiler::prof_handler', + '__FRAME_END__', + '__pthread_sighandler', + '__restore') { + $skip{$name} = 1; + } + } else { + # Nothing skipped for unknown types + } + + if ($main::profile_type eq 'cpu') { + # If all the second-youngest program counters are the same, + # this STRONGLY suggests that it is an artifact of measurement, + # i.e., stack frames pushed by the CPU profiler signal handler. + # Hence, we delete them. + # (The topmost PC is read from the signal structure, not from + # the stack, so it does not get involved.) + while (my $second_pc = IsSecondPcAlwaysTheSame($profile)) { + my $result = {}; + my $func = ''; + if (exists($symbols->{$second_pc})) { + $second_pc = $symbols->{$second_pc}->[0]; + } + print STDERR "Removing $second_pc from all stack traces.\n"; + foreach my $k (keys(%{$profile})) { + my $count = $profile->{$k}; + my @addrs = split(/\n/, $k); + splice @addrs, 1, 1; + my $reduced_path = join("\n", @addrs); + AddEntry($result, $reduced_path, $count); + } + $profile = $result; + } + } + + my $result = {}; + foreach my $k (keys(%{$profile})) { + my $count = $profile->{$k}; + my @addrs = split(/\n/, $k); + my @path = (); + foreach my $a (@addrs) { + if (exists($symbols->{$a})) { + my $func = $symbols->{$a}->[0]; + if ($skip{$func} || ($func =~ m/$skip_regexp/)) { + # Throw away the portion of the backtrace seen so far, under the + # assumption that previous frames were for functions internal to the + # allocator. + @path = (); + next; + } + } + push(@path, $a); + } + my $reduced_path = join("\n", @path); + AddEntry($result, $reduced_path, $count); + } + return $result; +} + +# Reduce profile to granularity given by user +sub ReduceProfile { + my $symbols = shift; + my $profile = shift; + my $result = {}; + my $fullname_to_shortname_map = {}; + FillFullnameToShortnameMap($symbols, $fullname_to_shortname_map); + foreach my $k (keys(%{$profile})) { + my $count = $profile->{$k}; + my @translated = TranslateStack($symbols, $fullname_to_shortname_map, $k); + my @path = (); + my %seen = (); + $seen{''} = 1; # So that empty keys are skipped + foreach my $e (@translated) { + # To avoid double-counting due to recursion, skip a stack-trace + # entry if it has already been seen + if (!$seen{$e}) { + $seen{$e} = 1; + push(@path, $e); + } + } + my $reduced_path = join("\n", @path); + AddEntry($result, $reduced_path, $count); + } + return $result; +} + +# Does the specified symbol array match the regexp? +sub SymbolMatches { + my $sym = shift; + my $re = shift; + if (defined($sym)) { + for (my $i = 0; $i < $#{$sym}; $i += 3) { + if ($sym->[$i] =~ m/$re/ || $sym->[$i+1] =~ m/$re/) { + return 1; + } + } + } + return 0; +} + +# Focus only on paths involving specified regexps +sub FocusProfile { + my $symbols = shift; + my $profile = shift; + my $focus = shift; + my $result = {}; + foreach my $k (keys(%{$profile})) { + my $count = $profile->{$k}; + my @addrs = split(/\n/, $k); + foreach my $a (@addrs) { + # Reply if it matches either the address/shortname/fileline + if (($a =~ m/$focus/) || SymbolMatches($symbols->{$a}, $focus)) { + AddEntry($result, $k, $count); + last; + } + } + } + return $result; +} + +# Focus only on paths not involving specified regexps +sub IgnoreProfile { + my $symbols = shift; + my $profile = shift; + my $ignore = shift; + my $result = {}; + foreach my $k (keys(%{$profile})) { + my $count = $profile->{$k}; + my @addrs = split(/\n/, $k); + my $matched = 0; + foreach my $a (@addrs) { + # Reply if it matches either the address/shortname/fileline + if (($a =~ m/$ignore/) || SymbolMatches($symbols->{$a}, $ignore)) { + $matched = 1; + last; + } + } + if (!$matched) { + AddEntry($result, $k, $count); + } + } + return $result; +} + +# Get total count in profile +sub TotalProfile { + my $profile = shift; + my $result = 0; + foreach my $k (keys(%{$profile})) { + $result += $profile->{$k}; + } + return $result; +} + +# Add A to B +sub AddProfile { + my $A = shift; + my $B = shift; + + my $R = {}; + # add all keys in A + foreach my $k (keys(%{$A})) { + my $v = $A->{$k}; + AddEntry($R, $k, $v); + } + # add all keys in B + foreach my $k (keys(%{$B})) { + my $v = $B->{$k}; + AddEntry($R, $k, $v); + } + return $R; +} + +# Merges symbol maps +sub MergeSymbols { + my $A = shift; + my $B = shift; + + my $R = {}; + foreach my $k (keys(%{$A})) { + $R->{$k} = $A->{$k}; + } + if (defined($B)) { + foreach my $k (keys(%{$B})) { + $R->{$k} = $B->{$k}; + } + } + return $R; +} + + +# Add A to B +sub AddPcs { + my $A = shift; + my $B = shift; + + my $R = {}; + # add all keys in A + foreach my $k (keys(%{$A})) { + $R->{$k} = 1 + } + # add all keys in B + foreach my $k (keys(%{$B})) { + $R->{$k} = 1 + } + return $R; +} + +# Subtract B from A +sub SubtractProfile { + my $A = shift; + my $B = shift; + + my $R = {}; + foreach my $k (keys(%{$A})) { + my $v = $A->{$k} - GetEntry($B, $k); + if ($v < 0 && $main::opt_drop_negative) { + $v = 0; + } + AddEntry($R, $k, $v); + } + if (!$main::opt_drop_negative) { + # Take care of when subtracted profile has more entries + foreach my $k (keys(%{$B})) { + if (!exists($A->{$k})) { + AddEntry($R, $k, 0 - $B->{$k}); + } + } + } + return $R; +} + +# Get entry from profile; zero if not present +sub GetEntry { + my $profile = shift; + my $k = shift; + if (exists($profile->{$k})) { + return $profile->{$k}; + } else { + return 0; + } +} + +# Add entry to specified profile +sub AddEntry { + my $profile = shift; + my $k = shift; + my $n = shift; + if (!exists($profile->{$k})) { + $profile->{$k} = 0; + } + $profile->{$k} += $n; +} + +# Add a stack of entries to specified profile, and add them to the $pcs +# list. +sub AddEntries { + my $profile = shift; + my $pcs = shift; + my $stack = shift; + my $count = shift; + my @k = (); + + foreach my $e (split(/\s+/, $stack)) { + my $pc = HexExtend($e); + $pcs->{$pc} = 1; + push @k, $pc; + } + AddEntry($profile, (join "\n", @k), $count); +} + +##### Code to profile a server dynamically ##### + +sub CheckSymbolPage { + my $url = SymbolPageURL(); + my $command = ShellEscape(@URL_FETCHER, $url); + open(SYMBOL, "$command |") or error($command); + my $line = ; + $line =~ s/\r//g; # turn windows-looking lines into unix-looking lines + close(SYMBOL); + unless (defined($line)) { + error("$url doesn't exist\n"); + } + + if ($line =~ /^num_symbols:\s+(\d+)$/) { + if ($1 == 0) { + error("Stripped binary. No symbols available.\n"); + } + } else { + error("Failed to get the number of symbols from $url\n"); + } +} + +sub IsProfileURL { + my $profile_name = shift; + if (-f $profile_name) { + printf STDERR "Using local file $profile_name.\n"; + return 0; + } + return 1; +} + +sub ParseProfileURL { + my $profile_name = shift; + + if (!defined($profile_name) || $profile_name eq "") { + return (); + } + + # Split profile URL - matches all non-empty strings, so no test. + $profile_name =~ m,^(https?://)?([^/]+)(.*?)(/|$PROFILES)?$,; + + my $proto = $1 || "http://"; + my $hostport = $2; + my $prefix = $3; + my $profile = $4 || "/"; + + my $host = $hostport; + $host =~ s/:.*//; + + my $baseurl = "$proto$hostport$prefix"; + return ($host, $baseurl, $profile); +} + +# We fetch symbols from the first profile argument. +sub SymbolPageURL { + my ($host, $baseURL, $path) = ParseProfileURL($main::pfile_args[0]); + return "$baseURL$SYMBOL_PAGE"; +} + +sub FetchProgramName() { + my ($host, $baseURL, $path) = ParseProfileURL($main::pfile_args[0]); + my $url = "$baseURL$PROGRAM_NAME_PAGE"; + my $command_line = ShellEscape(@URL_FETCHER, $url); + open(CMDLINE, "$command_line |") or error($command_line); + my $cmdline = ; + $cmdline =~ s/\r//g; # turn windows-looking lines into unix-looking lines + close(CMDLINE); + error("Failed to get program name from $url\n") unless defined($cmdline); + $cmdline =~ s/\x00.+//; # Remove argv[1] and latters. + $cmdline =~ s!\n!!g; # Remove LFs. + return $cmdline; +} + +# Gee, curl's -L (--location) option isn't reliable at least +# with its 7.12.3 version. Curl will forget to post data if +# there is a redirection. This function is a workaround for +# curl. Redirection happens on borg hosts. +sub ResolveRedirectionForCurl { + my $url = shift; + my $command_line = ShellEscape(@URL_FETCHER, "--head", $url); + open(CMDLINE, "$command_line |") or error($command_line); + while () { + s/\r//g; # turn windows-looking lines into unix-looking lines + if (/^Location: (.*)/) { + $url = $1; + } + } + close(CMDLINE); + return $url; +} + +# Add a timeout flat to URL_FETCHER. Returns a new list. +sub AddFetchTimeout { + my $timeout = shift; + my @fetcher = shift; + if (defined($timeout)) { + if (join(" ", @fetcher) =~ m/\bcurl -s/) { + push(@fetcher, "--max-time", sprintf("%d", $timeout)); + } elsif (join(" ", @fetcher) =~ m/\brpcget\b/) { + push(@fetcher, sprintf("--deadline=%d", $timeout)); + } + } + return @fetcher; +} + +# Reads a symbol map from the file handle name given as $1, returning +# the resulting symbol map. Also processes variables relating to symbols. +# Currently, the only variable processed is 'binary=' which updates +# $main::prog to have the correct program name. +sub ReadSymbols { + my $in = shift; + my $map = {}; + while (<$in>) { + s/\r//g; # turn windows-looking lines into unix-looking lines + # Removes all the leading zeroes from the symbols, see comment below. + if (m/^0x0*([0-9a-f]+)\s+(.+)/) { + $map->{$1} = $2; + } elsif (m/^---/) { + last; + } elsif (m/^([a-z][^=]*)=(.*)$/ ) { + my ($variable, $value) = ($1, $2); + for ($variable, $value) { + s/^\s+//; + s/\s+$//; + } + if ($variable eq "binary") { + if ($main::prog ne $UNKNOWN_BINARY && $main::prog ne $value) { + printf STDERR ("Warning: Mismatched binary name '%s', using '%s'.\n", + $main::prog, $value); + } + $main::prog = $value; + } else { + printf STDERR ("Ignoring unknown variable in symbols list: " . + "'%s' = '%s'\n", $variable, $value); + } + } + } + return $map; +} + +# Fetches and processes symbols to prepare them for use in the profile output +# code. If the optional 'symbol_map' arg is not given, fetches symbols from +# $SYMBOL_PAGE for all PC values found in profile. Otherwise, the raw symbols +# are assumed to have already been fetched into 'symbol_map' and are simply +# extracted and processed. +sub FetchSymbols { + my $pcset = shift; + my $symbol_map = shift; + + my %seen = (); + my @pcs = grep { !$seen{$_}++ } keys(%$pcset); # uniq + + if (!defined($symbol_map)) { + my $post_data = join("+", sort((map {"0x" . "$_"} @pcs))); + + open(POSTFILE, ">$main::tmpfile_sym"); + print POSTFILE $post_data; + close(POSTFILE); + + my $url = SymbolPageURL(); + + my $command_line; + if (join(" ", @URL_FETCHER) =~ m/\bcurl -s/) { + $url = ResolveRedirectionForCurl($url); + $command_line = ShellEscape(@URL_FETCHER, "-d", "\@$main::tmpfile_sym", + $url); + } else { + $command_line = (ShellEscape(@URL_FETCHER, "--post", $url) + . " < " . ShellEscape($main::tmpfile_sym)); + } + # We use c++filt in case $SYMBOL_PAGE gives us mangled symbols. + my $escaped_cppfilt = ShellEscape($obj_tool_map{"c++filt"}); + open(SYMBOL, "$command_line | $escaped_cppfilt |") or error($command_line); + $symbol_map = ReadSymbols(*SYMBOL{IO}); + close(SYMBOL); + } + + my $symbols = {}; + foreach my $pc (@pcs) { + my $fullname; + # For 64 bits binaries, symbols are extracted with 8 leading zeroes. + # Then /symbol reads the long symbols in as uint64, and outputs + # the result with a "0x%08llx" format which get rid of the zeroes. + # By removing all the leading zeroes in both $pc and the symbols from + # /symbol, the symbols match and are retrievable from the map. + my $shortpc = $pc; + $shortpc =~ s/^0*//; + # Each line may have a list of names, which includes the function + # and also other functions it has inlined. They are separated (in + # PrintSymbolizedProfile), by --, which is illegal in function names. + my $fullnames; + if (defined($symbol_map->{$shortpc})) { + $fullnames = $symbol_map->{$shortpc}; + } else { + $fullnames = "0x" . $pc; # Just use addresses + } + my $sym = []; + $symbols->{$pc} = $sym; + foreach my $fullname (split("--", $fullnames)) { + my $name = ShortFunctionName($fullname); + push(@{$sym}, $name, "?", $fullname); + } + } + return $symbols; +} + +sub BaseName { + my $file_name = shift; + $file_name =~ s!^.*/!!; # Remove directory name + return $file_name; +} + +sub MakeProfileBaseName { + my ($binary_name, $profile_name) = @_; + my ($host, $baseURL, $path) = ParseProfileURL($profile_name); + my $binary_shortname = BaseName($binary_name); + return sprintf("%s.%s.%s", + $binary_shortname, $main::op_time, $host); +} + +sub FetchDynamicProfile { + my $binary_name = shift; + my $profile_name = shift; + my $fetch_name_only = shift; + my $encourage_patience = shift; + + if (!IsProfileURL($profile_name)) { + return $profile_name; + } else { + my ($host, $baseURL, $path) = ParseProfileURL($profile_name); + if ($path eq "" || $path eq "/") { + # Missing type specifier defaults to cpu-profile + $path = $PROFILE_PAGE; + } + + my $profile_file = MakeProfileBaseName($binary_name, $profile_name); + + my $url = "$baseURL$path"; + my $fetch_timeout = undef; + if ($path =~ m/$PROFILE_PAGE|$PMUPROFILE_PAGE/) { + if ($path =~ m/[?]/) { + $url .= "&"; + } else { + $url .= "?"; + } + $url .= sprintf("seconds=%d", $main::opt_seconds); + $fetch_timeout = $main::opt_seconds * 1.01 + 60; + } else { + # For non-CPU profiles, we add a type-extension to + # the target profile file name. + my $suffix = $path; + $suffix =~ s,/,.,g; + $profile_file .= $suffix; + } + + my $profile_dir = $ENV{"JEPROF_TMPDIR"} || ($ENV{HOME} . "/jeprof"); + if (! -d $profile_dir) { + mkdir($profile_dir) + || die("Unable to create profile directory $profile_dir: $!\n"); + } + my $tmp_profile = "$profile_dir/.tmp.$profile_file"; + my $real_profile = "$profile_dir/$profile_file"; + + if ($fetch_name_only > 0) { + return $real_profile; + } + + my @fetcher = AddFetchTimeout($fetch_timeout, @URL_FETCHER); + my $cmd = ShellEscape(@fetcher, $url) . " > " . ShellEscape($tmp_profile); + if ($path =~ m/$PROFILE_PAGE|$PMUPROFILE_PAGE|$CENSUSPROFILE_PAGE/){ + print STDERR "Gathering CPU profile from $url for $main::opt_seconds seconds to\n ${real_profile}\n"; + if ($encourage_patience) { + print STDERR "Be patient...\n"; + } + } else { + print STDERR "Fetching $path profile from $url to\n ${real_profile}\n"; + } + + (system($cmd) == 0) || error("Failed to get profile: $cmd: $!\n"); + (system("mv", $tmp_profile, $real_profile) == 0) || error("Unable to rename profile\n"); + print STDERR "Wrote profile to $real_profile\n"; + $main::collected_profile = $real_profile; + return $main::collected_profile; + } +} + +# Collect profiles in parallel +sub FetchDynamicProfiles { + my $items = scalar(@main::pfile_args); + my $levels = log($items) / log(2); + + if ($items == 1) { + $main::profile_files[0] = FetchDynamicProfile($main::prog, $main::pfile_args[0], 0, 1); + } else { + # math rounding issues + if ((2 ** $levels) < $items) { + $levels++; + } + my $count = scalar(@main::pfile_args); + for (my $i = 0; $i < $count; $i++) { + $main::profile_files[$i] = FetchDynamicProfile($main::prog, $main::pfile_args[$i], 1, 0); + } + print STDERR "Fetching $count profiles, Be patient...\n"; + FetchDynamicProfilesRecurse($levels, 0, 0); + $main::collected_profile = join(" \\\n ", @main::profile_files); + } +} + +# Recursively fork a process to get enough processes +# collecting profiles +sub FetchDynamicProfilesRecurse { + my $maxlevel = shift; + my $level = shift; + my $position = shift; + + if (my $pid = fork()) { + $position = 0 | ($position << 1); + TryCollectProfile($maxlevel, $level, $position); + wait; + } else { + $position = 1 | ($position << 1); + TryCollectProfile($maxlevel, $level, $position); + cleanup(); + exit(0); + } +} + +# Collect a single profile +sub TryCollectProfile { + my $maxlevel = shift; + my $level = shift; + my $position = shift; + + if ($level >= ($maxlevel - 1)) { + if ($position < scalar(@main::pfile_args)) { + FetchDynamicProfile($main::prog, $main::pfile_args[$position], 0, 0); + } + } else { + FetchDynamicProfilesRecurse($maxlevel, $level+1, $position); + } +} + +##### Parsing code ##### + +# Provide a small streaming-read module to handle very large +# cpu-profile files. Stream in chunks along a sliding window. +# Provides an interface to get one 'slot', correctly handling +# endian-ness differences. A slot is one 32-bit or 64-bit word +# (depending on the input profile). We tell endianness and bit-size +# for the profile by looking at the first 8 bytes: in cpu profiles, +# the second slot is always 3 (we'll accept anything that's not 0). +BEGIN { + package CpuProfileStream; + + sub new { + my ($class, $file, $fname) = @_; + my $self = { file => $file, + base => 0, + stride => 512 * 1024, # must be a multiple of bitsize/8 + slots => [], + unpack_code => "", # N for big-endian, V for little + perl_is_64bit => 1, # matters if profile is 64-bit + }; + bless $self, $class; + # Let unittests adjust the stride + if ($main::opt_test_stride > 0) { + $self->{stride} = $main::opt_test_stride; + } + # Read the first two slots to figure out bitsize and endianness. + my $slots = $self->{slots}; + my $str; + read($self->{file}, $str, 8); + # Set the global $address_length based on what we see here. + # 8 is 32-bit (8 hexadecimal chars); 16 is 64-bit (16 hexadecimal chars). + $address_length = ($str eq (chr(0)x8)) ? 16 : 8; + if ($address_length == 8) { + if (substr($str, 6, 2) eq chr(0)x2) { + $self->{unpack_code} = 'V'; # Little-endian. + } elsif (substr($str, 4, 2) eq chr(0)x2) { + $self->{unpack_code} = 'N'; # Big-endian + } else { + ::error("$fname: header size >= 2**16\n"); + } + @$slots = unpack($self->{unpack_code} . "*", $str); + } else { + # If we're a 64-bit profile, check if we're a 64-bit-capable + # perl. Otherwise, each slot will be represented as a float + # instead of an int64, losing precision and making all the + # 64-bit addresses wrong. We won't complain yet, but will + # later if we ever see a value that doesn't fit in 32 bits. + my $has_q = 0; + eval { $has_q = pack("Q", "1") ? 1 : 1; }; + if (!$has_q) { + $self->{perl_is_64bit} = 0; + } + read($self->{file}, $str, 8); + if (substr($str, 4, 4) eq chr(0)x4) { + # We'd love to use 'Q', but it's a) not universal, b) not endian-proof. + $self->{unpack_code} = 'V'; # Little-endian. + } elsif (substr($str, 0, 4) eq chr(0)x4) { + $self->{unpack_code} = 'N'; # Big-endian + } else { + ::error("$fname: header size >= 2**32\n"); + } + my @pair = unpack($self->{unpack_code} . "*", $str); + # Since we know one of the pair is 0, it's fine to just add them. + @$slots = (0, $pair[0] + $pair[1]); + } + return $self; + } + + # Load more data when we access slots->get(X) which is not yet in memory. + sub overflow { + my ($self) = @_; + my $slots = $self->{slots}; + $self->{base} += $#$slots + 1; # skip over data we're replacing + my $str; + read($self->{file}, $str, $self->{stride}); + if ($address_length == 8) { # the 32-bit case + # This is the easy case: unpack provides 32-bit unpacking primitives. + @$slots = unpack($self->{unpack_code} . "*", $str); + } else { + # We need to unpack 32 bits at a time and combine. + my @b32_values = unpack($self->{unpack_code} . "*", $str); + my @b64_values = (); + for (my $i = 0; $i < $#b32_values; $i += 2) { + # TODO(csilvers): if this is a 32-bit perl, the math below + # could end up in a too-large int, which perl will promote + # to a double, losing necessary precision. Deal with that. + # Right now, we just die. + my ($lo, $hi) = ($b32_values[$i], $b32_values[$i+1]); + if ($self->{unpack_code} eq 'N') { # big-endian + ($lo, $hi) = ($hi, $lo); + } + my $value = $lo + $hi * (2**32); + if (!$self->{perl_is_64bit} && # check value is exactly represented + (($value % (2**32)) != $lo || int($value / (2**32)) != $hi)) { + ::error("Need a 64-bit perl to process this 64-bit profile.\n"); + } + push(@b64_values, $value); + } + @$slots = @b64_values; + } + } + + # Access the i-th long in the file (logically), or -1 at EOF. + sub get { + my ($self, $idx) = @_; + my $slots = $self->{slots}; + while ($#$slots >= 0) { + if ($idx < $self->{base}) { + # The only time we expect a reference to $slots[$i - something] + # after referencing $slots[$i] is reading the very first header. + # Since $stride > |header|, that shouldn't cause any lookback + # errors. And everything after the header is sequential. + print STDERR "Unexpected look-back reading CPU profile"; + return -1; # shrug, don't know what better to return + } elsif ($idx > $self->{base} + $#$slots) { + $self->overflow(); + } else { + return $slots->[$idx - $self->{base}]; + } + } + # If we get here, $slots is [], which means we've reached EOF + return -1; # unique since slots is supposed to hold unsigned numbers + } +} + +# Reads the top, 'header' section of a profile, and returns the last +# line of the header, commonly called a 'header line'. The header +# section of a profile consists of zero or more 'command' lines that +# are instructions to jeprof, which jeprof executes when reading the +# header. All 'command' lines start with a %. After the command +# lines is the 'header line', which is a profile-specific line that +# indicates what type of profile it is, and perhaps other global +# information about the profile. For instance, here's a header line +# for a heap profile: +# heap profile: 53: 38236 [ 5525: 1284029] @ heapprofile +# For historical reasons, the CPU profile does not contain a text- +# readable header line. If the profile looks like a CPU profile, +# this function returns "". If no header line could be found, this +# function returns undef. +# +# The following commands are recognized: +# %warn -- emit the rest of this line to stderr, prefixed by 'WARNING:' +# +# The input file should be in binmode. +sub ReadProfileHeader { + local *PROFILE = shift; + my $firstchar = ""; + my $line = ""; + read(PROFILE, $firstchar, 1); + seek(PROFILE, -1, 1); # unread the firstchar + if ($firstchar !~ /[[:print:]]/) { # is not a text character + return ""; + } + while (defined($line = )) { + $line =~ s/\r//g; # turn windows-looking lines into unix-looking lines + if ($line =~ /^%warn\s+(.*)/) { # 'warn' command + # Note this matches both '%warn blah\n' and '%warn\n'. + print STDERR "WARNING: $1\n"; # print the rest of the line + } elsif ($line =~ /^%/) { + print STDERR "Ignoring unknown command from profile header: $line"; + } else { + # End of commands, must be the header line. + return $line; + } + } + return undef; # got to EOF without seeing a header line +} + +sub IsSymbolizedProfileFile { + my $file_name = shift; + if (!(-e $file_name) || !(-r $file_name)) { + return 0; + } + # Check if the file contains a symbol-section marker. + open(TFILE, "<$file_name"); + binmode TFILE; + my $firstline = ReadProfileHeader(*TFILE); + close(TFILE); + if (!$firstline) { + return 0; + } + $SYMBOL_PAGE =~ m,[^/]+$,; # matches everything after the last slash + my $symbol_marker = $&; + return $firstline =~ /^--- *$symbol_marker/; +} + +# Parse profile generated by common/profiler.cc and return a reference +# to a map: +# $result->{version} Version number of profile file +# $result->{period} Sampling period (in microseconds) +# $result->{profile} Profile object +# $result->{threads} Map of thread IDs to profile objects +# $result->{map} Memory map info from profile +# $result->{pcs} Hash of all PC values seen, key is hex address +sub ReadProfile { + my $prog = shift; + my $fname = shift; + my $result; # return value + + $CONTENTION_PAGE =~ m,[^/]+$,; # matches everything after the last slash + my $contention_marker = $&; + $GROWTH_PAGE =~ m,[^/]+$,; # matches everything after the last slash + my $growth_marker = $&; + $SYMBOL_PAGE =~ m,[^/]+$,; # matches everything after the last slash + my $symbol_marker = $&; + $PROFILE_PAGE =~ m,[^/]+$,; # matches everything after the last slash + my $profile_marker = $&; + + # Look at first line to see if it is a heap or a CPU profile. + # CPU profile may start with no header at all, and just binary data + # (starting with \0\0\0\0) -- in that case, don't try to read the + # whole firstline, since it may be gigabytes(!) of data. + open(PROFILE, "<$fname") || error("$fname: $!\n"); + binmode PROFILE; # New perls do UTF-8 processing + my $header = ReadProfileHeader(*PROFILE); + if (!defined($header)) { # means "at EOF" + error("Profile is empty.\n"); + } + + my $symbols; + if ($header =~ m/^--- *$symbol_marker/o) { + # Verify that the user asked for a symbolized profile + if (!$main::use_symbolized_profile) { + # we have both a binary and symbolized profiles, abort + error("FATAL ERROR: Symbolized profile\n $fname\ncannot be used with " . + "a binary arg. Try again without passing\n $prog\n"); + } + # Read the symbol section of the symbolized profile file. + $symbols = ReadSymbols(*PROFILE{IO}); + # Read the next line to get the header for the remaining profile. + $header = ReadProfileHeader(*PROFILE) || ""; + } + + $main::profile_type = ''; + if ($header =~ m/^heap profile:.*$growth_marker/o) { + $main::profile_type = 'growth'; + $result = ReadHeapProfile($prog, *PROFILE, $header); + } elsif ($header =~ m/^heap profile:/) { + $main::profile_type = 'heap'; + $result = ReadHeapProfile($prog, *PROFILE, $header); + } elsif ($header =~ m/^heap/) { + $main::profile_type = 'heap'; + $result = ReadThreadedHeapProfile($prog, $fname, $header); + } elsif ($header =~ m/^--- *$contention_marker/o) { + $main::profile_type = 'contention'; + $result = ReadSynchProfile($prog, *PROFILE); + } elsif ($header =~ m/^--- *Stacks:/) { + print STDERR + "Old format contention profile: mistakenly reports " . + "condition variable signals as lock contentions.\n"; + $main::profile_type = 'contention'; + $result = ReadSynchProfile($prog, *PROFILE); + } elsif ($header =~ m/^--- *$profile_marker/) { + # the binary cpu profile data starts immediately after this line + $main::profile_type = 'cpu'; + $result = ReadCPUProfile($prog, $fname, *PROFILE); + } else { + if (defined($symbols)) { + # a symbolized profile contains a format we don't recognize, bail out + error("$fname: Cannot recognize profile section after symbols.\n"); + } + # no ascii header present -- must be a CPU profile + $main::profile_type = 'cpu'; + $result = ReadCPUProfile($prog, $fname, *PROFILE); + } + + close(PROFILE); + + # if we got symbols along with the profile, return those as well + if (defined($symbols)) { + $result->{symbols} = $symbols; + } + + return $result; +} + +# Subtract one from caller pc so we map back to call instr. +# However, don't do this if we're reading a symbolized profile +# file, in which case the subtract-one was done when the file +# was written. +# +# We apply the same logic to all readers, though ReadCPUProfile uses an +# independent implementation. +sub FixCallerAddresses { + my $stack = shift; + if ($main::use_symbolized_profile) { + return $stack; + } else { + $stack =~ /(\s)/; + my $delimiter = $1; + my @addrs = split(' ', $stack); + my @fixedaddrs; + $#fixedaddrs = $#addrs; + if ($#addrs >= 0) { + $fixedaddrs[0] = $addrs[0]; + } + for (my $i = 1; $i <= $#addrs; $i++) { + $fixedaddrs[$i] = AddressSub($addrs[$i], "0x1"); + } + return join $delimiter, @fixedaddrs; + } +} + +# CPU profile reader +sub ReadCPUProfile { + my $prog = shift; + my $fname = shift; # just used for logging + local *PROFILE = shift; + my $version; + my $period; + my $i; + my $profile = {}; + my $pcs = {}; + + # Parse string into array of slots. + my $slots = CpuProfileStream->new(*PROFILE, $fname); + + # Read header. The current header version is a 5-element structure + # containing: + # 0: header count (always 0) + # 1: header "words" (after this one: 3) + # 2: format version (0) + # 3: sampling period (usec) + # 4: unused padding (always 0) + if ($slots->get(0) != 0 ) { + error("$fname: not a profile file, or old format profile file\n"); + } + $i = 2 + $slots->get(1); + $version = $slots->get(2); + $period = $slots->get(3); + # Do some sanity checking on these header values. + if ($version > (2**32) || $period > (2**32) || $i > (2**32) || $i < 5) { + error("$fname: not a profile file, or corrupted profile file\n"); + } + + # Parse profile + while ($slots->get($i) != -1) { + my $n = $slots->get($i++); + my $d = $slots->get($i++); + if ($d > (2**16)) { # TODO(csilvers): what's a reasonable max-stack-depth? + my $addr = sprintf("0%o", $i * ($address_length == 8 ? 4 : 8)); + print STDERR "At index $i (address $addr):\n"; + error("$fname: stack trace depth >= 2**32\n"); + } + if ($slots->get($i) == 0) { + # End of profile data marker + $i += $d; + last; + } + + # Make key out of the stack entries + my @k = (); + for (my $j = 0; $j < $d; $j++) { + my $pc = $slots->get($i+$j); + # Subtract one from caller pc so we map back to call instr. + # However, don't do this if we're reading a symbolized profile + # file, in which case the subtract-one was done when the file + # was written. + if ($j > 0 && !$main::use_symbolized_profile) { + $pc--; + } + $pc = sprintf("%0*x", $address_length, $pc); + $pcs->{$pc} = 1; + push @k, $pc; + } + + AddEntry($profile, (join "\n", @k), $n); + $i += $d; + } + + # Parse map + my $map = ''; + seek(PROFILE, $i * 4, 0); + read(PROFILE, $map, (stat PROFILE)[7]); + + my $r = {}; + $r->{version} = $version; + $r->{period} = $period; + $r->{profile} = $profile; + $r->{libs} = ParseLibraries($prog, $map, $pcs); + $r->{pcs} = $pcs; + + return $r; +} + +sub HeapProfileIndex { + my $index = 1; + if ($main::opt_inuse_space) { + $index = 1; + } elsif ($main::opt_inuse_objects) { + $index = 0; + } elsif ($main::opt_alloc_space) { + $index = 3; + } elsif ($main::opt_alloc_objects) { + $index = 2; + } + return $index; +} + +sub ReadMappedLibraries { + my $fh = shift; + my $map = ""; + # Read the /proc/self/maps data + while (<$fh>) { + s/\r//g; # turn windows-looking lines into unix-looking lines + $map .= $_; + } + return $map; +} + +sub ReadMemoryMap { + my $fh = shift; + my $map = ""; + # Read /proc/self/maps data as formatted by DumpAddressMap() + my $buildvar = ""; + while () { + s/\r//g; # turn windows-looking lines into unix-looking lines + # Parse "build=" specification if supplied + if (m/^\s*build=(.*)\n/) { + $buildvar = $1; + } + + # Expand "$build" variable if available + $_ =~ s/\$build\b/$buildvar/g; + + $map .= $_; + } + return $map; +} + +sub AdjustSamples { + my ($sample_adjustment, $sampling_algorithm, $n1, $s1, $n2, $s2) = @_; + if ($sample_adjustment) { + if ($sampling_algorithm == 2) { + # Remote-heap version 2 + # The sampling frequency is the rate of a Poisson process. + # This means that the probability of sampling an allocation of + # size X with sampling rate Y is 1 - exp(-X/Y) + if ($n1 != 0) { + my $ratio = (($s1*1.0)/$n1)/($sample_adjustment); + my $scale_factor = 1/(1 - exp(-$ratio)); + $n1 *= $scale_factor; + $s1 *= $scale_factor; + } + if ($n2 != 0) { + my $ratio = (($s2*1.0)/$n2)/($sample_adjustment); + my $scale_factor = 1/(1 - exp(-$ratio)); + $n2 *= $scale_factor; + $s2 *= $scale_factor; + } + } else { + # Remote-heap version 1 + my $ratio; + $ratio = (($s1*1.0)/$n1)/($sample_adjustment); + if ($ratio < 1) { + $n1 /= $ratio; + $s1 /= $ratio; + } + $ratio = (($s2*1.0)/$n2)/($sample_adjustment); + if ($ratio < 1) { + $n2 /= $ratio; + $s2 /= $ratio; + } + } + } + return ($n1, $s1, $n2, $s2); +} + +sub ReadHeapProfile { + my $prog = shift; + local *PROFILE = shift; + my $header = shift; + + my $index = HeapProfileIndex(); + + # Find the type of this profile. The header line looks like: + # heap profile: 1246: 8800744 [ 1246: 8800744] @ /266053 + # There are two pairs , the first inuse objects/space, and the + # second allocated objects/space. This is followed optionally by a profile + # type, and if that is present, optionally by a sampling frequency. + # For remote heap profiles (v1): + # The interpretation of the sampling frequency is that the profiler, for + # each sample, calculates a uniformly distributed random integer less than + # the given value, and records the next sample after that many bytes have + # been allocated. Therefore, the expected sample interval is half of the + # given frequency. By default, if not specified, the expected sample + # interval is 128KB. Only remote-heap-page profiles are adjusted for + # sample size. + # For remote heap profiles (v2): + # The sampling frequency is the rate of a Poisson process. This means that + # the probability of sampling an allocation of size X with sampling rate Y + # is 1 - exp(-X/Y) + # For version 2, a typical header line might look like this: + # heap profile: 1922: 127792360 [ 1922: 127792360] @ _v2/524288 + # the trailing number (524288) is the sampling rate. (Version 1 showed + # double the 'rate' here) + my $sampling_algorithm = 0; + my $sample_adjustment = 0; + chomp($header); + my $type = "unknown"; + if ($header =~ m"^heap profile:\s*(\d+):\s+(\d+)\s+\[\s*(\d+):\s+(\d+)\](\s*@\s*([^/]*)(/(\d+))?)?") { + if (defined($6) && ($6 ne '')) { + $type = $6; + my $sample_period = $8; + # $type is "heapprofile" for profiles generated by the + # heap-profiler, and either "heap" or "heap_v2" for profiles + # generated by sampling directly within tcmalloc. It can also + # be "growth" for heap-growth profiles. The first is typically + # found for profiles generated locally, and the others for + # remote profiles. + if (($type eq "heapprofile") || ($type !~ /heap/) ) { + # No need to adjust for the sampling rate with heap-profiler-derived data + $sampling_algorithm = 0; + } elsif ($type =~ /_v2/) { + $sampling_algorithm = 2; # version 2 sampling + if (defined($sample_period) && ($sample_period ne '')) { + $sample_adjustment = int($sample_period); + } + } else { + $sampling_algorithm = 1; # version 1 sampling + if (defined($sample_period) && ($sample_period ne '')) { + $sample_adjustment = int($sample_period)/2; + } + } + } else { + # We detect whether or not this is a remote-heap profile by checking + # that the total-allocated stats ($n2,$s2) are exactly the + # same as the in-use stats ($n1,$s1). It is remotely conceivable + # that a non-remote-heap profile may pass this check, but it is hard + # to imagine how that could happen. + # In this case it's so old it's guaranteed to be remote-heap version 1. + my ($n1, $s1, $n2, $s2) = ($1, $2, $3, $4); + if (($n1 == $n2) && ($s1 == $s2)) { + # This is likely to be a remote-heap based sample profile + $sampling_algorithm = 1; + } + } + } + + if ($sampling_algorithm > 0) { + # For remote-heap generated profiles, adjust the counts and sizes to + # account for the sample rate (we sample once every 128KB by default). + if ($sample_adjustment == 0) { + # Turn on profile adjustment. + $sample_adjustment = 128*1024; + print STDERR "Adjusting heap profiles for 1-in-128KB sampling rate\n"; + } else { + printf STDERR ("Adjusting heap profiles for 1-in-%d sampling rate\n", + $sample_adjustment); + } + if ($sampling_algorithm > 1) { + # We don't bother printing anything for the original version (version 1) + printf STDERR "Heap version $sampling_algorithm\n"; + } + } + + my $profile = {}; + my $pcs = {}; + my $map = ""; + + while () { + s/\r//g; # turn windows-looking lines into unix-looking lines + if (/^MAPPED_LIBRARIES:/) { + $map .= ReadMappedLibraries(*PROFILE); + last; + } + + if (/^--- Memory map:/) { + $map .= ReadMemoryMap(*PROFILE); + last; + } + + # Read entry of the form: + # : [: ] @ a1 a2 a3 ... an + s/^\s*//; + s/\s*$//; + if (m/^\s*(\d+):\s+(\d+)\s+\[\s*(\d+):\s+(\d+)\]\s+@\s+(.*)$/) { + my $stack = $5; + my ($n1, $s1, $n2, $s2) = ($1, $2, $3, $4); + my @counts = AdjustSamples($sample_adjustment, $sampling_algorithm, + $n1, $s1, $n2, $s2); + AddEntries($profile, $pcs, FixCallerAddresses($stack), $counts[$index]); + } + } + + my $r = {}; + $r->{version} = "heap"; + $r->{period} = 1; + $r->{profile} = $profile; + $r->{libs} = ParseLibraries($prog, $map, $pcs); + $r->{pcs} = $pcs; + return $r; +} + +sub ReadThreadedHeapProfile { + my ($prog, $fname, $header) = @_; + + my $index = HeapProfileIndex(); + my $sampling_algorithm = 0; + my $sample_adjustment = 0; + chomp($header); + my $type = "unknown"; + # Assuming a very specific type of header for now. + if ($header =~ m"^heap_v2/(\d+)") { + $type = "_v2"; + $sampling_algorithm = 2; + $sample_adjustment = int($1); + } + if ($type ne "_v2" || !defined($sample_adjustment)) { + die "Threaded heap profiles require v2 sampling with a sample rate\n"; + } + + my $profile = {}; + my $thread_profiles = {}; + my $pcs = {}; + my $map = ""; + my $stack = ""; + + while () { + s/\r//g; + if (/^MAPPED_LIBRARIES:/) { + $map .= ReadMappedLibraries(*PROFILE); + last; + } + + if (/^--- Memory map:/) { + $map .= ReadMemoryMap(*PROFILE); + last; + } + + # Read entry of the form: + # @ a1 a2 ... an + # t*: : [: ] + # t1: : [: ] + # ... + # tn: : [: ] + s/^\s*//; + s/\s*$//; + if (m/^@\s+(.*)$/) { + $stack = $1; + } elsif (m/^\s*(t(\*|\d+)):\s+(\d+):\s+(\d+)\s+\[\s*(\d+):\s+(\d+)\]$/) { + if ($stack eq "") { + # Still in the header, so this is just a per-thread summary. + next; + } + my $thread = $2; + my ($n1, $s1, $n2, $s2) = ($3, $4, $5, $6); + my @counts = AdjustSamples($sample_adjustment, $sampling_algorithm, + $n1, $s1, $n2, $s2); + if ($thread eq "*") { + AddEntries($profile, $pcs, FixCallerAddresses($stack), $counts[$index]); + } else { + if (!exists($thread_profiles->{$thread})) { + $thread_profiles->{$thread} = {}; + } + AddEntries($thread_profiles->{$thread}, $pcs, + FixCallerAddresses($stack), $counts[$index]); + } + } + } + + my $r = {}; + $r->{version} = "heap"; + $r->{period} = 1; + $r->{profile} = $profile; + $r->{threads} = $thread_profiles; + $r->{libs} = ParseLibraries($prog, $map, $pcs); + $r->{pcs} = $pcs; + return $r; +} + +sub ReadSynchProfile { + my $prog = shift; + local *PROFILE = shift; + my $header = shift; + + my $map = ''; + my $profile = {}; + my $pcs = {}; + my $sampling_period = 1; + my $cyclespernanosec = 2.8; # Default assumption for old binaries + my $seen_clockrate = 0; + my $line; + + my $index = 0; + if ($main::opt_total_delay) { + $index = 0; + } elsif ($main::opt_contentions) { + $index = 1; + } elsif ($main::opt_mean_delay) { + $index = 2; + } + + while ( $line = ) { + $line =~ s/\r//g; # turn windows-looking lines into unix-looking lines + if ( $line =~ /^\s*(\d+)\s+(\d+) \@\s*(.*?)\s*$/ ) { + my ($cycles, $count, $stack) = ($1, $2, $3); + + # Convert cycles to nanoseconds + $cycles /= $cyclespernanosec; + + # Adjust for sampling done by application + $cycles *= $sampling_period; + $count *= $sampling_period; + + my @values = ($cycles, $count, $cycles / $count); + AddEntries($profile, $pcs, FixCallerAddresses($stack), $values[$index]); + + } elsif ( $line =~ /^(slow release).*thread \d+ \@\s*(.*?)\s*$/ || + $line =~ /^\s*(\d+) \@\s*(.*?)\s*$/ ) { + my ($cycles, $stack) = ($1, $2); + if ($cycles !~ /^\d+$/) { + next; + } + + # Convert cycles to nanoseconds + $cycles /= $cyclespernanosec; + + # Adjust for sampling done by application + $cycles *= $sampling_period; + + AddEntries($profile, $pcs, FixCallerAddresses($stack), $cycles); + + } elsif ( $line =~ m/^([a-z][^=]*)=(.*)$/ ) { + my ($variable, $value) = ($1,$2); + for ($variable, $value) { + s/^\s+//; + s/\s+$//; + } + if ($variable eq "cycles/second") { + $cyclespernanosec = $value / 1e9; + $seen_clockrate = 1; + } elsif ($variable eq "sampling period") { + $sampling_period = $value; + } elsif ($variable eq "ms since reset") { + # Currently nothing is done with this value in jeprof + # So we just silently ignore it for now + } elsif ($variable eq "discarded samples") { + # Currently nothing is done with this value in jeprof + # So we just silently ignore it for now + } else { + printf STDERR ("Ignoring unnknown variable in /contention output: " . + "'%s' = '%s'\n",$variable,$value); + } + } else { + # Memory map entry + $map .= $line; + } + } + + if (!$seen_clockrate) { + printf STDERR ("No cycles/second entry in profile; Guessing %.1f GHz\n", + $cyclespernanosec); + } + + my $r = {}; + $r->{version} = 0; + $r->{period} = $sampling_period; + $r->{profile} = $profile; + $r->{libs} = ParseLibraries($prog, $map, $pcs); + $r->{pcs} = $pcs; + return $r; +} + +# Given a hex value in the form "0x1abcd" or "1abcd", return either +# "0001abcd" or "000000000001abcd", depending on the current (global) +# address length. +sub HexExtend { + my $addr = shift; + + $addr =~ s/^(0x)?0*//; + my $zeros_needed = $address_length - length($addr); + if ($zeros_needed < 0) { + printf STDERR "Warning: address $addr is longer than address length $address_length\n"; + return $addr; + } + return ("0" x $zeros_needed) . $addr; +} + +##### Symbol extraction ##### + +# Aggressively search the lib_prefix values for the given library +# If all else fails, just return the name of the library unmodified. +# If the lib_prefix is "/my/path,/other/path" and $file is "/lib/dir/mylib.so" +# it will search the following locations in this order, until it finds a file: +# /my/path/lib/dir/mylib.so +# /other/path/lib/dir/mylib.so +# /my/path/dir/mylib.so +# /other/path/dir/mylib.so +# /my/path/mylib.so +# /other/path/mylib.so +# /lib/dir/mylib.so (returned as last resort) +sub FindLibrary { + my $file = shift; + my $suffix = $file; + + # Search for the library as described above + do { + foreach my $prefix (@prefix_list) { + my $fullpath = $prefix . $suffix; + if (-e $fullpath) { + return $fullpath; + } + } + } while ($suffix =~ s|^/[^/]+/|/|); + return $file; +} + +# Return path to library with debugging symbols. +# For libc libraries, the copy in /usr/lib/debug contains debugging symbols +sub DebuggingLibrary { + my $file = shift; + if ($file =~ m|^/|) { + if (-f "/usr/lib/debug$file") { + return "/usr/lib/debug$file"; + } elsif (-f "/usr/lib/debug$file.debug") { + return "/usr/lib/debug$file.debug"; + } + } + return undef; +} + +# Parse text section header of a library using objdump +sub ParseTextSectionHeaderFromObjdump { + my $lib = shift; + + my $size = undef; + my $vma; + my $file_offset; + # Get objdump output from the library file to figure out how to + # map between mapped addresses and addresses in the library. + my $cmd = ShellEscape($obj_tool_map{"objdump"}, "-h", $lib); + open(OBJDUMP, "$cmd |") || error("$cmd: $!\n"); + while () { + s/\r//g; # turn windows-looking lines into unix-looking lines + # Idx Name Size VMA LMA File off Algn + # 10 .text 00104b2c 420156f0 420156f0 000156f0 2**4 + # For 64-bit objects, VMA and LMA will be 16 hex digits, size and file + # offset may still be 8. But AddressSub below will still handle that. + my @x = split; + if (($#x >= 6) && ($x[1] eq '.text')) { + $size = $x[2]; + $vma = $x[3]; + $file_offset = $x[5]; + last; + } + } + close(OBJDUMP); + + if (!defined($size)) { + return undef; + } + + my $r = {}; + $r->{size} = $size; + $r->{vma} = $vma; + $r->{file_offset} = $file_offset; + + return $r; +} + +# Parse text section header of a library using otool (on OS X) +sub ParseTextSectionHeaderFromOtool { + my $lib = shift; + + my $size = undef; + my $vma = undef; + my $file_offset = undef; + # Get otool output from the library file to figure out how to + # map between mapped addresses and addresses in the library. + my $command = ShellEscape($obj_tool_map{"otool"}, "-l", $lib); + open(OTOOL, "$command |") || error("$command: $!\n"); + my $cmd = ""; + my $sectname = ""; + my $segname = ""; + foreach my $line () { + $line =~ s/\r//g; # turn windows-looking lines into unix-looking lines + # Load command <#> + # cmd LC_SEGMENT + # [...] + # Section + # sectname __text + # segname __TEXT + # addr 0x000009f8 + # size 0x00018b9e + # offset 2552 + # align 2^2 (4) + # We will need to strip off the leading 0x from the hex addresses, + # and convert the offset into hex. + if ($line =~ /Load command/) { + $cmd = ""; + $sectname = ""; + $segname = ""; + } elsif ($line =~ /Section/) { + $sectname = ""; + $segname = ""; + } elsif ($line =~ /cmd (\w+)/) { + $cmd = $1; + } elsif ($line =~ /sectname (\w+)/) { + $sectname = $1; + } elsif ($line =~ /segname (\w+)/) { + $segname = $1; + } elsif (!(($cmd eq "LC_SEGMENT" || $cmd eq "LC_SEGMENT_64") && + $sectname eq "__text" && + $segname eq "__TEXT")) { + next; + } elsif ($line =~ /\baddr 0x([0-9a-fA-F]+)/) { + $vma = $1; + } elsif ($line =~ /\bsize 0x([0-9a-fA-F]+)/) { + $size = $1; + } elsif ($line =~ /\boffset ([0-9]+)/) { + $file_offset = sprintf("%016x", $1); + } + if (defined($vma) && defined($size) && defined($file_offset)) { + last; + } + } + close(OTOOL); + + if (!defined($vma) || !defined($size) || !defined($file_offset)) { + return undef; + } + + my $r = {}; + $r->{size} = $size; + $r->{vma} = $vma; + $r->{file_offset} = $file_offset; + + return $r; +} + +sub ParseTextSectionHeader { + # obj_tool_map("otool") is only defined if we're in a Mach-O environment + if (defined($obj_tool_map{"otool"})) { + my $r = ParseTextSectionHeaderFromOtool(@_); + if (defined($r)){ + return $r; + } + } + # If otool doesn't work, or we don't have it, fall back to objdump + return ParseTextSectionHeaderFromObjdump(@_); +} + +# Split /proc/pid/maps dump into a list of libraries +sub ParseLibraries { + return if $main::use_symbol_page; # We don't need libraries info. + my $prog = shift; + my $map = shift; + my $pcs = shift; + + my $result = []; + my $h = "[a-f0-9]+"; + my $zero_offset = HexExtend("0"); + + my $buildvar = ""; + foreach my $l (split("\n", $map)) { + if ($l =~ m/^\s*build=(.*)$/) { + $buildvar = $1; + } + + my $start; + my $finish; + my $offset; + my $lib; + if ($l =~ /^($h)-($h)\s+..x.\s+($h)\s+\S+:\S+\s+\d+\s+(\S+\.(so|dll|dylib|bundle)((\.\d+)+\w*(\.\d+){0,3})?)$/i) { + # Full line from /proc/self/maps. Example: + # 40000000-40015000 r-xp 00000000 03:01 12845071 /lib/ld-2.3.2.so + $start = HexExtend($1); + $finish = HexExtend($2); + $offset = HexExtend($3); + $lib = $4; + $lib =~ s|\\|/|g; # turn windows-style paths into unix-style paths + } elsif ($l =~ /^\s*($h)-($h):\s*(\S+\.so(\.\d+)*)/) { + # Cooked line from DumpAddressMap. Example: + # 40000000-40015000: /lib/ld-2.3.2.so + $start = HexExtend($1); + $finish = HexExtend($2); + $offset = $zero_offset; + $lib = $3; + } + # FreeBSD 10.0 virtual memory map /proc/curproc/map as defined in + # function procfs_doprocmap (sys/fs/procfs/procfs_map.c) + # + # Example: + # 0x800600000 0x80061a000 26 0 0xfffff800035a0000 r-x 75 33 0x1004 COW NC vnode /libexec/ld-elf.s + # o.1 NCH -1 + elsif ($l =~ /^(0x$h)\s(0x$h)\s\d+\s\d+\s0x$h\sr-x\s\d+\s\d+\s0x\d+\s(COW|NCO)\s(NC|NNC)\svnode\s(\S+\.so(\.\d+)*)/) { + $start = HexExtend($1); + $finish = HexExtend($2); + $offset = $zero_offset; + $lib = FindLibrary($5); + + } else { + next; + } + + # Expand "$build" variable if available + $lib =~ s/\$build\b/$buildvar/g; + + $lib = FindLibrary($lib); + + # Check for pre-relocated libraries, which use pre-relocated symbol tables + # and thus require adjusting the offset that we'll use to translate + # VM addresses into symbol table addresses. + # Only do this if we're not going to fetch the symbol table from a + # debugging copy of the library. + if (!DebuggingLibrary($lib)) { + my $text = ParseTextSectionHeader($lib); + if (defined($text)) { + my $vma_offset = AddressSub($text->{vma}, $text->{file_offset}); + $offset = AddressAdd($offset, $vma_offset); + } + } + + if($main::opt_debug) { printf STDERR "$start:$finish ($offset) $lib\n"; } + push(@{$result}, [$lib, $start, $finish, $offset]); + } + + # Append special entry for additional library (not relocated) + if ($main::opt_lib ne "") { + my $text = ParseTextSectionHeader($main::opt_lib); + if (defined($text)) { + my $start = $text->{vma}; + my $finish = AddressAdd($start, $text->{size}); + + push(@{$result}, [$main::opt_lib, $start, $finish, $start]); + } + } + + # Append special entry for the main program. This covers + # 0..max_pc_value_seen, so that we assume pc values not found in one + # of the library ranges will be treated as coming from the main + # program binary. + my $min_pc = HexExtend("0"); + my $max_pc = $min_pc; # find the maximal PC value in any sample + foreach my $pc (keys(%{$pcs})) { + if (HexExtend($pc) gt $max_pc) { $max_pc = HexExtend($pc); } + } + push(@{$result}, [$prog, $min_pc, $max_pc, $zero_offset]); + + return $result; +} + +# Add two hex addresses of length $address_length. +# Run jeprof --test for unit test if this is changed. +sub AddressAdd { + my $addr1 = shift; + my $addr2 = shift; + my $sum; + + if ($address_length == 8) { + # Perl doesn't cope with wraparound arithmetic, so do it explicitly: + $sum = (hex($addr1)+hex($addr2)) % (0x10000000 * 16); + return sprintf("%08x", $sum); + + } else { + # Do the addition in 7-nibble chunks to trivialize carry handling. + + if ($main::opt_debug and $main::opt_test) { + print STDERR "AddressAdd $addr1 + $addr2 = "; + } + + my $a1 = substr($addr1,-7); + $addr1 = substr($addr1,0,-7); + my $a2 = substr($addr2,-7); + $addr2 = substr($addr2,0,-7); + $sum = hex($a1) + hex($a2); + my $c = 0; + if ($sum > 0xfffffff) { + $c = 1; + $sum -= 0x10000000; + } + my $r = sprintf("%07x", $sum); + + $a1 = substr($addr1,-7); + $addr1 = substr($addr1,0,-7); + $a2 = substr($addr2,-7); + $addr2 = substr($addr2,0,-7); + $sum = hex($a1) + hex($a2) + $c; + $c = 0; + if ($sum > 0xfffffff) { + $c = 1; + $sum -= 0x10000000; + } + $r = sprintf("%07x", $sum) . $r; + + $sum = hex($addr1) + hex($addr2) + $c; + if ($sum > 0xff) { $sum -= 0x100; } + $r = sprintf("%02x", $sum) . $r; + + if ($main::opt_debug and $main::opt_test) { print STDERR "$r\n"; } + + return $r; + } +} + + +# Subtract two hex addresses of length $address_length. +# Run jeprof --test for unit test if this is changed. +sub AddressSub { + my $addr1 = shift; + my $addr2 = shift; + my $diff; + + if ($address_length == 8) { + # Perl doesn't cope with wraparound arithmetic, so do it explicitly: + $diff = (hex($addr1)-hex($addr2)) % (0x10000000 * 16); + return sprintf("%08x", $diff); + + } else { + # Do the addition in 7-nibble chunks to trivialize borrow handling. + # if ($main::opt_debug) { print STDERR "AddressSub $addr1 - $addr2 = "; } + + my $a1 = hex(substr($addr1,-7)); + $addr1 = substr($addr1,0,-7); + my $a2 = hex(substr($addr2,-7)); + $addr2 = substr($addr2,0,-7); + my $b = 0; + if ($a2 > $a1) { + $b = 1; + $a1 += 0x10000000; + } + $diff = $a1 - $a2; + my $r = sprintf("%07x", $diff); + + $a1 = hex(substr($addr1,-7)); + $addr1 = substr($addr1,0,-7); + $a2 = hex(substr($addr2,-7)) + $b; + $addr2 = substr($addr2,0,-7); + $b = 0; + if ($a2 > $a1) { + $b = 1; + $a1 += 0x10000000; + } + $diff = $a1 - $a2; + $r = sprintf("%07x", $diff) . $r; + + $a1 = hex($addr1); + $a2 = hex($addr2) + $b; + if ($a2 > $a1) { $a1 += 0x100; } + $diff = $a1 - $a2; + $r = sprintf("%02x", $diff) . $r; + + # if ($main::opt_debug) { print STDERR "$r\n"; } + + return $r; + } +} + +# Increment a hex addresses of length $address_length. +# Run jeprof --test for unit test if this is changed. +sub AddressInc { + my $addr = shift; + my $sum; + + if ($address_length == 8) { + # Perl doesn't cope with wraparound arithmetic, so do it explicitly: + $sum = (hex($addr)+1) % (0x10000000 * 16); + return sprintf("%08x", $sum); + + } else { + # Do the addition in 7-nibble chunks to trivialize carry handling. + # We are always doing this to step through the addresses in a function, + # and will almost never overflow the first chunk, so we check for this + # case and exit early. + + # if ($main::opt_debug) { print STDERR "AddressInc $addr1 = "; } + + my $a1 = substr($addr,-7); + $addr = substr($addr,0,-7); + $sum = hex($a1) + 1; + my $r = sprintf("%07x", $sum); + if ($sum <= 0xfffffff) { + $r = $addr . $r; + # if ($main::opt_debug) { print STDERR "$r\n"; } + return HexExtend($r); + } else { + $r = "0000000"; + } + + $a1 = substr($addr,-7); + $addr = substr($addr,0,-7); + $sum = hex($a1) + 1; + $r = sprintf("%07x", $sum) . $r; + if ($sum <= 0xfffffff) { + $r = $addr . $r; + # if ($main::opt_debug) { print STDERR "$r\n"; } + return HexExtend($r); + } else { + $r = "00000000000000"; + } + + $sum = hex($addr) + 1; + if ($sum > 0xff) { $sum -= 0x100; } + $r = sprintf("%02x", $sum) . $r; + + # if ($main::opt_debug) { print STDERR "$r\n"; } + return $r; + } +} + +# Extract symbols for all PC values found in profile +sub ExtractSymbols { + my $libs = shift; + my $pcset = shift; + + my $symbols = {}; + + # Map each PC value to the containing library. To make this faster, + # we sort libraries by their starting pc value (highest first), and + # advance through the libraries as we advance the pc. Sometimes the + # addresses of libraries may overlap with the addresses of the main + # binary, so to make sure the libraries 'win', we iterate over the + # libraries in reverse order (which assumes the binary doesn't start + # in the middle of a library, which seems a fair assumption). + my @pcs = (sort { $a cmp $b } keys(%{$pcset})); # pcset is 0-extended strings + foreach my $lib (sort {$b->[1] cmp $a->[1]} @{$libs}) { + my $libname = $lib->[0]; + my $start = $lib->[1]; + my $finish = $lib->[2]; + my $offset = $lib->[3]; + + # Use debug library if it exists + my $debug_libname = DebuggingLibrary($libname); + if ($debug_libname) { + $libname = $debug_libname; + } + + # Get list of pcs that belong in this library. + my $contained = []; + my ($start_pc_index, $finish_pc_index); + # Find smallest finish_pc_index such that $finish < $pc[$finish_pc_index]. + for ($finish_pc_index = $#pcs + 1; $finish_pc_index > 0; + $finish_pc_index--) { + last if $pcs[$finish_pc_index - 1] le $finish; + } + # Find smallest start_pc_index such that $start <= $pc[$start_pc_index]. + for ($start_pc_index = $finish_pc_index; $start_pc_index > 0; + $start_pc_index--) { + last if $pcs[$start_pc_index - 1] lt $start; + } + # This keeps PC values higher than $pc[$finish_pc_index] in @pcs, + # in case there are overlaps in libraries and the main binary. + @{$contained} = splice(@pcs, $start_pc_index, + $finish_pc_index - $start_pc_index); + # Map to symbols + MapToSymbols($libname, AddressSub($start, $offset), $contained, $symbols); + } + + return $symbols; +} + +# Map list of PC values to symbols for a given image +sub MapToSymbols { + my $image = shift; + my $offset = shift; + my $pclist = shift; + my $symbols = shift; + + my $debug = 0; + + # Ignore empty binaries + if ($#{$pclist} < 0) { return; } + + # Figure out the addr2line command to use + my $addr2line = $obj_tool_map{"addr2line"}; + my $cmd = ShellEscape($addr2line, "-f", "-C", "-e", $image); + if (exists $obj_tool_map{"addr2line_pdb"}) { + $addr2line = $obj_tool_map{"addr2line_pdb"}; + $cmd = ShellEscape($addr2line, "--demangle", "-f", "-C", "-e", $image); + } + + # If "addr2line" isn't installed on the system at all, just use + # nm to get what info we can (function names, but not line numbers). + if (system(ShellEscape($addr2line, "--help") . " >$dev_null 2>&1") != 0) { + MapSymbolsWithNM($image, $offset, $pclist, $symbols); + return; + } + + # "addr2line -i" can produce a variable number of lines per input + # address, with no separator that allows us to tell when data for + # the next address starts. So we find the address for a special + # symbol (_fini) and interleave this address between all real + # addresses passed to addr2line. The name of this special symbol + # can then be used as a separator. + $sep_address = undef; # May be filled in by MapSymbolsWithNM() + my $nm_symbols = {}; + MapSymbolsWithNM($image, $offset, $pclist, $nm_symbols); + if (defined($sep_address)) { + # Only add " -i" to addr2line if the binary supports it. + # addr2line --help returns 0, but not if it sees an unknown flag first. + if (system("$cmd -i --help >$dev_null 2>&1") == 0) { + $cmd .= " -i"; + } else { + $sep_address = undef; # no need for sep_address if we don't support -i + } + } + + # Make file with all PC values with intervening 'sep_address' so + # that we can reliably detect the end of inlined function list + open(ADDRESSES, ">$main::tmpfile_sym") || error("$main::tmpfile_sym: $!\n"); + if ($debug) { print("---- $image ---\n"); } + for (my $i = 0; $i <= $#{$pclist}; $i++) { + # addr2line always reads hex addresses, and does not need '0x' prefix. + if ($debug) { printf STDERR ("%s\n", $pclist->[$i]); } + printf ADDRESSES ("%s\n", AddressSub($pclist->[$i], $offset)); + if (defined($sep_address)) { + printf ADDRESSES ("%s\n", $sep_address); + } + } + close(ADDRESSES); + if ($debug) { + print("----\n"); + system("cat", $main::tmpfile_sym); + print("----\n"); + system("$cmd < " . ShellEscape($main::tmpfile_sym)); + print("----\n"); + } + + open(SYMBOLS, "$cmd <" . ShellEscape($main::tmpfile_sym) . " |") + || error("$cmd: $!\n"); + my $count = 0; # Index in pclist + while () { + # Read fullfunction and filelineinfo from next pair of lines + s/\r?\n$//g; + my $fullfunction = $_; + $_ = ; + s/\r?\n$//g; + my $filelinenum = $_; + + if (defined($sep_address) && $fullfunction eq $sep_symbol) { + # Terminating marker for data for this address + $count++; + next; + } + + $filelinenum =~ s|\\|/|g; # turn windows-style paths into unix-style paths + + my $pcstr = $pclist->[$count]; + my $function = ShortFunctionName($fullfunction); + my $nms = $nm_symbols->{$pcstr}; + if (defined($nms)) { + if ($fullfunction eq '??') { + # nm found a symbol for us. + $function = $nms->[0]; + $fullfunction = $nms->[2]; + } else { + # MapSymbolsWithNM tags each routine with its starting address, + # useful in case the image has multiple occurrences of this + # routine. (It uses a syntax that resembles template paramters, + # that are automatically stripped out by ShortFunctionName().) + # addr2line does not provide the same information. So we check + # if nm disambiguated our symbol, and if so take the annotated + # (nm) version of the routine-name. TODO(csilvers): this won't + # catch overloaded, inlined symbols, which nm doesn't see. + # Better would be to do a check similar to nm's, in this fn. + if ($nms->[2] =~ m/^\Q$function\E/) { # sanity check it's the right fn + $function = $nms->[0]; + $fullfunction = $nms->[2]; + } + } + } + + # Prepend to accumulated symbols for pcstr + # (so that caller comes before callee) + my $sym = $symbols->{$pcstr}; + if (!defined($sym)) { + $sym = []; + $symbols->{$pcstr} = $sym; + } + unshift(@{$sym}, $function, $filelinenum, $fullfunction); + if ($debug) { printf STDERR ("%s => [%s]\n", $pcstr, join(" ", @{$sym})); } + if (!defined($sep_address)) { + # Inlining is off, so this entry ends immediately + $count++; + } + } + close(SYMBOLS); +} + +# Use nm to map the list of referenced PCs to symbols. Return true iff we +# are able to read procedure information via nm. +sub MapSymbolsWithNM { + my $image = shift; + my $offset = shift; + my $pclist = shift; + my $symbols = shift; + + # Get nm output sorted by increasing address + my $symbol_table = GetProcedureBoundaries($image, "."); + if (!%{$symbol_table}) { + return 0; + } + # Start addresses are already the right length (8 or 16 hex digits). + my @names = sort { $symbol_table->{$a}->[0] cmp $symbol_table->{$b}->[0] } + keys(%{$symbol_table}); + + if ($#names < 0) { + # No symbols: just use addresses + foreach my $pc (@{$pclist}) { + my $pcstr = "0x" . $pc; + $symbols->{$pc} = [$pcstr, "?", $pcstr]; + } + return 0; + } + + # Sort addresses so we can do a join against nm output + my $index = 0; + my $fullname = $names[0]; + my $name = ShortFunctionName($fullname); + foreach my $pc (sort { $a cmp $b } @{$pclist}) { + # Adjust for mapped offset + my $mpc = AddressSub($pc, $offset); + while (($index < $#names) && ($mpc ge $symbol_table->{$fullname}->[1])){ + $index++; + $fullname = $names[$index]; + $name = ShortFunctionName($fullname); + } + if ($mpc lt $symbol_table->{$fullname}->[1]) { + $symbols->{$pc} = [$name, "?", $fullname]; + } else { + my $pcstr = "0x" . $pc; + $symbols->{$pc} = [$pcstr, "?", $pcstr]; + } + } + return 1; +} + +sub ShortFunctionName { + my $function = shift; + while ($function =~ s/\([^()]*\)(\s*const)?//g) { } # Argument types + while ($function =~ s/<[^<>]*>//g) { } # Remove template arguments + $function =~ s/^.*\s+(\w+::)/$1/; # Remove leading type + return $function; +} + +# Trim overly long symbols found in disassembler output +sub CleanDisassembly { + my $d = shift; + while ($d =~ s/\([^()%]*\)(\s*const)?//g) { } # Argument types, not (%rax) + while ($d =~ s/(\w+)<[^<>]*>/$1/g) { } # Remove template arguments + return $d; +} + +# Clean file name for display +sub CleanFileName { + my ($f) = @_; + $f =~ s|^/proc/self/cwd/||; + $f =~ s|^\./||; + return $f; +} + +# Make address relative to section and clean up for display +sub UnparseAddress { + my ($offset, $address) = @_; + $address = AddressSub($address, $offset); + $address =~ s/^0x//; + $address =~ s/^0*//; + return $address; +} + +##### Miscellaneous ##### + +# Find the right versions of the above object tools to use. The +# argument is the program file being analyzed, and should be an ELF +# 32-bit or ELF 64-bit executable file. The location of the tools +# is determined by considering the following options in this order: +# 1) --tools option, if set +# 2) JEPROF_TOOLS environment variable, if set +# 3) the environment +sub ConfigureObjTools { + my $prog_file = shift; + + # Check for the existence of $prog_file because /usr/bin/file does not + # predictably return error status in prod. + (-e $prog_file) || error("$prog_file does not exist.\n"); + + my $file_type = undef; + if (-e "/usr/bin/file") { + # Follow symlinks (at least for systems where "file" supports that). + my $escaped_prog_file = ShellEscape($prog_file); + $file_type = `/usr/bin/file -L $escaped_prog_file 2>$dev_null || + /usr/bin/file $escaped_prog_file`; + } elsif ($^O == "MSWin32") { + $file_type = "MS Windows"; + } else { + print STDERR "WARNING: Can't determine the file type of $prog_file"; + } + + if ($file_type =~ /64-bit/) { + # Change $address_length to 16 if the program file is ELF 64-bit. + # We can't detect this from many (most?) heap or lock contention + # profiles, since the actual addresses referenced are generally in low + # memory even for 64-bit programs. + $address_length = 16; + } + + if ($file_type =~ /MS Windows/) { + # For windows, we provide a version of nm and addr2line as part of + # the opensource release, which is capable of parsing + # Windows-style PDB executables. It should live in the path, or + # in the same directory as jeprof. + $obj_tool_map{"nm_pdb"} = "nm-pdb"; + $obj_tool_map{"addr2line_pdb"} = "addr2line-pdb"; + } + + if ($file_type =~ /Mach-O/) { + # OS X uses otool to examine Mach-O files, rather than objdump. + $obj_tool_map{"otool"} = "otool"; + $obj_tool_map{"addr2line"} = "false"; # no addr2line + $obj_tool_map{"objdump"} = "false"; # no objdump + } + + # Go fill in %obj_tool_map with the pathnames to use: + foreach my $tool (keys %obj_tool_map) { + $obj_tool_map{$tool} = ConfigureTool($obj_tool_map{$tool}); + } +} + +# Returns the path of a caller-specified object tool. If --tools or +# JEPROF_TOOLS are specified, then returns the full path to the tool +# with that prefix. Otherwise, returns the path unmodified (which +# means we will look for it on PATH). +sub ConfigureTool { + my $tool = shift; + my $path; + + # --tools (or $JEPROF_TOOLS) is a comma separated list, where each + # item is either a) a pathname prefix, or b) a map of the form + # :. First we look for an entry of type (b) for our + # tool. If one is found, we use it. Otherwise, we consider all the + # pathname prefixes in turn, until one yields an existing file. If + # none does, we use a default path. + my $tools = $main::opt_tools || $ENV{"JEPROF_TOOLS"} || ""; + if ($tools =~ m/(,|^)\Q$tool\E:([^,]*)/) { + $path = $2; + # TODO(csilvers): sanity-check that $path exists? Hard if it's relative. + } elsif ($tools ne '') { + foreach my $prefix (split(',', $tools)) { + next if ($prefix =~ /:/); # ignore "tool:fullpath" entries in the list + if (-x $prefix . $tool) { + $path = $prefix . $tool; + last; + } + } + if (!$path) { + error("No '$tool' found with prefix specified by " . + "--tools (or \$JEPROF_TOOLS) '$tools'\n"); + } + } else { + # ... otherwise use the version that exists in the same directory as + # jeprof. If there's nothing there, use $PATH. + $0 =~ m,[^/]*$,; # this is everything after the last slash + my $dirname = $`; # this is everything up to and including the last slash + if (-x "$dirname$tool") { + $path = "$dirname$tool"; + } else { + $path = $tool; + } + } + if ($main::opt_debug) { print STDERR "Using '$path' for '$tool'.\n"; } + return $path; +} + +sub ShellEscape { + my @escaped_words = (); + foreach my $word (@_) { + my $escaped_word = $word; + if ($word =~ m![^a-zA-Z0-9/.,_=-]!) { # check for anything not in whitelist + $escaped_word =~ s/'/'\\''/; + $escaped_word = "'$escaped_word'"; + } + push(@escaped_words, $escaped_word); + } + return join(" ", @escaped_words); +} + +sub cleanup { + unlink($main::tmpfile_sym); + unlink(keys %main::tempnames); + + # We leave any collected profiles in $HOME/jeprof in case the user wants + # to look at them later. We print a message informing them of this. + if ((scalar(@main::profile_files) > 0) && + defined($main::collected_profile)) { + if (scalar(@main::profile_files) == 1) { + print STDERR "Dynamically gathered profile is in $main::collected_profile\n"; + } + print STDERR "If you want to investigate this profile further, you can do:\n"; + print STDERR "\n"; + print STDERR " jeprof \\\n"; + print STDERR " $main::prog \\\n"; + print STDERR " $main::collected_profile\n"; + print STDERR "\n"; + } +} + +sub sighandler { + cleanup(); + exit(1); +} + +sub error { + my $msg = shift; + print STDERR $msg; + cleanup(); + exit(1); +} + + +# Run $nm_command and get all the resulting procedure boundaries whose +# names match "$regexp" and returns them in a hashtable mapping from +# procedure name to a two-element vector of [start address, end address] +sub GetProcedureBoundariesViaNm { + my $escaped_nm_command = shift; # shell-escaped + my $regexp = shift; + + my $symbol_table = {}; + open(NM, "$escaped_nm_command |") || error("$escaped_nm_command: $!\n"); + my $last_start = "0"; + my $routine = ""; + while () { + s/\r//g; # turn windows-looking lines into unix-looking lines + if (m/^\s*([0-9a-f]+) (.) (..*)/) { + my $start_val = $1; + my $type = $2; + my $this_routine = $3; + + # It's possible for two symbols to share the same address, if + # one is a zero-length variable (like __start_google_malloc) or + # one symbol is a weak alias to another (like __libc_malloc). + # In such cases, we want to ignore all values except for the + # actual symbol, which in nm-speak has type "T". The logic + # below does this, though it's a bit tricky: what happens when + # we have a series of lines with the same address, is the first + # one gets queued up to be processed. However, it won't + # *actually* be processed until later, when we read a line with + # a different address. That means that as long as we're reading + # lines with the same address, we have a chance to replace that + # item in the queue, which we do whenever we see a 'T' entry -- + # that is, a line with type 'T'. If we never see a 'T' entry, + # we'll just go ahead and process the first entry (which never + # got touched in the queue), and ignore the others. + if ($start_val eq $last_start && $type =~ /t/i) { + # We are the 'T' symbol at this address, replace previous symbol. + $routine = $this_routine; + next; + } elsif ($start_val eq $last_start) { + # We're not the 'T' symbol at this address, so ignore us. + next; + } + + if ($this_routine eq $sep_symbol) { + $sep_address = HexExtend($start_val); + } + + # Tag this routine with the starting address in case the image + # has multiple occurrences of this routine. We use a syntax + # that resembles template parameters that are automatically + # stripped out by ShortFunctionName() + $this_routine .= "<$start_val>"; + + if (defined($routine) && $routine =~ m/$regexp/) { + $symbol_table->{$routine} = [HexExtend($last_start), + HexExtend($start_val)]; + } + $last_start = $start_val; + $routine = $this_routine; + } elsif (m/^Loaded image name: (.+)/) { + # The win32 nm workalike emits information about the binary it is using. + if ($main::opt_debug) { print STDERR "Using Image $1\n"; } + } elsif (m/^PDB file name: (.+)/) { + # The win32 nm workalike emits information about the pdb it is using. + if ($main::opt_debug) { print STDERR "Using PDB $1\n"; } + } + } + close(NM); + # Handle the last line in the nm output. Unfortunately, we don't know + # how big this last symbol is, because we don't know how big the file + # is. For now, we just give it a size of 0. + # TODO(csilvers): do better here. + if (defined($routine) && $routine =~ m/$regexp/) { + $symbol_table->{$routine} = [HexExtend($last_start), + HexExtend($last_start)]; + } + return $symbol_table; +} + +# Gets the procedure boundaries for all routines in "$image" whose names +# match "$regexp" and returns them in a hashtable mapping from procedure +# name to a two-element vector of [start address, end address]. +# Will return an empty map if nm is not installed or not working properly. +sub GetProcedureBoundaries { + my $image = shift; + my $regexp = shift; + + # If $image doesn't start with /, then put ./ in front of it. This works + # around an obnoxious bug in our probing of nm -f behavior. + # "nm -f $image" is supposed to fail on GNU nm, but if: + # + # a. $image starts with [BbSsPp] (for example, bin/foo/bar), AND + # b. you have a.out in your current directory (a not uncommon occurence) + # + # then "nm -f $image" succeeds because -f only looks at the first letter of + # the argument, which looks valid because it's [BbSsPp], and then since + # there's no image provided, it looks for a.out and finds it. + # + # This regex makes sure that $image starts with . or /, forcing the -f + # parsing to fail since . and / are not valid formats. + $image =~ s#^[^/]#./$&#; + + # For libc libraries, the copy in /usr/lib/debug contains debugging symbols + my $debugging = DebuggingLibrary($image); + if ($debugging) { + $image = $debugging; + } + + my $nm = $obj_tool_map{"nm"}; + my $cppfilt = $obj_tool_map{"c++filt"}; + + # nm can fail for two reasons: 1) $image isn't a debug library; 2) nm + # binary doesn't support --demangle. In addition, for OS X we need + # to use the -f flag to get 'flat' nm output (otherwise we don't sort + # properly and get incorrect results). Unfortunately, GNU nm uses -f + # in an incompatible way. So first we test whether our nm supports + # --demangle and -f. + my $demangle_flag = ""; + my $cppfilt_flag = ""; + my $to_devnull = ">$dev_null 2>&1"; + if (system(ShellEscape($nm, "--demangle", "image") . $to_devnull) == 0) { + # In this mode, we do "nm --demangle " + $demangle_flag = "--demangle"; + $cppfilt_flag = ""; + } elsif (system(ShellEscape($cppfilt, $image) . $to_devnull) == 0) { + # In this mode, we do "nm | c++filt" + $cppfilt_flag = " | " . ShellEscape($cppfilt); + }; + my $flatten_flag = ""; + if (system(ShellEscape($nm, "-f", $image) . $to_devnull) == 0) { + $flatten_flag = "-f"; + } + + # Finally, in the case $imagie isn't a debug library, we try again with + # -D to at least get *exported* symbols. If we can't use --demangle, + # we use c++filt instead, if it exists on this system. + my @nm_commands = (ShellEscape($nm, "-n", $flatten_flag, $demangle_flag, + $image) . " 2>$dev_null $cppfilt_flag", + ShellEscape($nm, "-D", "-n", $flatten_flag, $demangle_flag, + $image) . " 2>$dev_null $cppfilt_flag", + # 6nm is for Go binaries + ShellEscape("6nm", "$image") . " 2>$dev_null | sort", + ); + + # If the executable is an MS Windows PDB-format executable, we'll + # have set up obj_tool_map("nm_pdb"). In this case, we actually + # want to use both unix nm and windows-specific nm_pdb, since + # PDB-format executables can apparently include dwarf .o files. + if (exists $obj_tool_map{"nm_pdb"}) { + push(@nm_commands, + ShellEscape($obj_tool_map{"nm_pdb"}, "--demangle", $image) + . " 2>$dev_null"); + } + + foreach my $nm_command (@nm_commands) { + my $symbol_table = GetProcedureBoundariesViaNm($nm_command, $regexp); + return $symbol_table if (%{$symbol_table}); + } + my $symbol_table = {}; + return $symbol_table; +} + + +# The test vectors for AddressAdd/Sub/Inc are 8-16-nibble hex strings. +# To make them more readable, we add underscores at interesting places. +# This routine removes the underscores, producing the canonical representation +# used by jeprof to represent addresses, particularly in the tested routines. +sub CanonicalHex { + my $arg = shift; + return join '', (split '_',$arg); +} + + +# Unit test for AddressAdd: +sub AddressAddUnitTest { + my $test_data_8 = shift; + my $test_data_16 = shift; + my $error_count = 0; + my $fail_count = 0; + my $pass_count = 0; + # print STDERR "AddressAddUnitTest: ", 1+$#{$test_data_8}, " tests\n"; + + # First a few 8-nibble addresses. Note that this implementation uses + # plain old arithmetic, so a quick sanity check along with verifying what + # happens to overflow (we want it to wrap): + $address_length = 8; + foreach my $row (@{$test_data_8}) { + if ($main::opt_debug and $main::opt_test) { print STDERR "@{$row}\n"; } + my $sum = AddressAdd ($row->[0], $row->[1]); + if ($sum ne $row->[2]) { + printf STDERR "ERROR: %s != %s + %s = %s\n", $sum, + $row->[0], $row->[1], $row->[2]; + ++$fail_count; + } else { + ++$pass_count; + } + } + printf STDERR "AddressAdd 32-bit tests: %d passes, %d failures\n", + $pass_count, $fail_count; + $error_count = $fail_count; + $fail_count = 0; + $pass_count = 0; + + # Now 16-nibble addresses. + $address_length = 16; + foreach my $row (@{$test_data_16}) { + if ($main::opt_debug and $main::opt_test) { print STDERR "@{$row}\n"; } + my $sum = AddressAdd (CanonicalHex($row->[0]), CanonicalHex($row->[1])); + my $expected = join '', (split '_',$row->[2]); + if ($sum ne CanonicalHex($row->[2])) { + printf STDERR "ERROR: %s != %s + %s = %s\n", $sum, + $row->[0], $row->[1], $row->[2]; + ++$fail_count; + } else { + ++$pass_count; + } + } + printf STDERR "AddressAdd 64-bit tests: %d passes, %d failures\n", + $pass_count, $fail_count; + $error_count += $fail_count; + + return $error_count; +} + + +# Unit test for AddressSub: +sub AddressSubUnitTest { + my $test_data_8 = shift; + my $test_data_16 = shift; + my $error_count = 0; + my $fail_count = 0; + my $pass_count = 0; + # print STDERR "AddressSubUnitTest: ", 1+$#{$test_data_8}, " tests\n"; + + # First a few 8-nibble addresses. Note that this implementation uses + # plain old arithmetic, so a quick sanity check along with verifying what + # happens to overflow (we want it to wrap): + $address_length = 8; + foreach my $row (@{$test_data_8}) { + if ($main::opt_debug and $main::opt_test) { print STDERR "@{$row}\n"; } + my $sum = AddressSub ($row->[0], $row->[1]); + if ($sum ne $row->[3]) { + printf STDERR "ERROR: %s != %s - %s = %s\n", $sum, + $row->[0], $row->[1], $row->[3]; + ++$fail_count; + } else { + ++$pass_count; + } + } + printf STDERR "AddressSub 32-bit tests: %d passes, %d failures\n", + $pass_count, $fail_count; + $error_count = $fail_count; + $fail_count = 0; + $pass_count = 0; + + # Now 16-nibble addresses. + $address_length = 16; + foreach my $row (@{$test_data_16}) { + if ($main::opt_debug and $main::opt_test) { print STDERR "@{$row}\n"; } + my $sum = AddressSub (CanonicalHex($row->[0]), CanonicalHex($row->[1])); + if ($sum ne CanonicalHex($row->[3])) { + printf STDERR "ERROR: %s != %s - %s = %s\n", $sum, + $row->[0], $row->[1], $row->[3]; + ++$fail_count; + } else { + ++$pass_count; + } + } + printf STDERR "AddressSub 64-bit tests: %d passes, %d failures\n", + $pass_count, $fail_count; + $error_count += $fail_count; + + return $error_count; +} + + +# Unit test for AddressInc: +sub AddressIncUnitTest { + my $test_data_8 = shift; + my $test_data_16 = shift; + my $error_count = 0; + my $fail_count = 0; + my $pass_count = 0; + # print STDERR "AddressIncUnitTest: ", 1+$#{$test_data_8}, " tests\n"; + + # First a few 8-nibble addresses. Note that this implementation uses + # plain old arithmetic, so a quick sanity check along with verifying what + # happens to overflow (we want it to wrap): + $address_length = 8; + foreach my $row (@{$test_data_8}) { + if ($main::opt_debug and $main::opt_test) { print STDERR "@{$row}\n"; } + my $sum = AddressInc ($row->[0]); + if ($sum ne $row->[4]) { + printf STDERR "ERROR: %s != %s + 1 = %s\n", $sum, + $row->[0], $row->[4]; + ++$fail_count; + } else { + ++$pass_count; + } + } + printf STDERR "AddressInc 32-bit tests: %d passes, %d failures\n", + $pass_count, $fail_count; + $error_count = $fail_count; + $fail_count = 0; + $pass_count = 0; + + # Now 16-nibble addresses. + $address_length = 16; + foreach my $row (@{$test_data_16}) { + if ($main::opt_debug and $main::opt_test) { print STDERR "@{$row}\n"; } + my $sum = AddressInc (CanonicalHex($row->[0])); + if ($sum ne CanonicalHex($row->[4])) { + printf STDERR "ERROR: %s != %s + 1 = %s\n", $sum, + $row->[0], $row->[4]; + ++$fail_count; + } else { + ++$pass_count; + } + } + printf STDERR "AddressInc 64-bit tests: %d passes, %d failures\n", + $pass_count, $fail_count; + $error_count += $fail_count; + + return $error_count; +} + + +# Driver for unit tests. +# Currently just the address add/subtract/increment routines for 64-bit. +sub RunUnitTests { + my $error_count = 0; + + # This is a list of tuples [a, b, a+b, a-b, a+1] + my $unit_test_data_8 = [ + [qw(aaaaaaaa 50505050 fafafafa 5a5a5a5a aaaaaaab)], + [qw(50505050 aaaaaaaa fafafafa a5a5a5a6 50505051)], + [qw(ffffffff aaaaaaaa aaaaaaa9 55555555 00000000)], + [qw(00000001 ffffffff 00000000 00000002 00000002)], + [qw(00000001 fffffff0 fffffff1 00000011 00000002)], + ]; + my $unit_test_data_16 = [ + # The implementation handles data in 7-nibble chunks, so those are the + # interesting boundaries. + [qw(aaaaaaaa 50505050 + 00_000000f_afafafa 00_0000005_a5a5a5a 00_000000a_aaaaaab)], + [qw(50505050 aaaaaaaa + 00_000000f_afafafa ff_ffffffa_5a5a5a6 00_0000005_0505051)], + [qw(ffffffff aaaaaaaa + 00_000001a_aaaaaa9 00_0000005_5555555 00_0000010_0000000)], + [qw(00000001 ffffffff + 00_0000010_0000000 ff_ffffff0_0000002 00_0000000_0000002)], + [qw(00000001 fffffff0 + 00_000000f_ffffff1 ff_ffffff0_0000011 00_0000000_0000002)], + + [qw(00_a00000a_aaaaaaa 50505050 + 00_a00000f_afafafa 00_a000005_a5a5a5a 00_a00000a_aaaaaab)], + [qw(0f_fff0005_0505050 aaaaaaaa + 0f_fff000f_afafafa 0f_ffefffa_5a5a5a6 0f_fff0005_0505051)], + [qw(00_000000f_fffffff 01_800000a_aaaaaaa + 01_800001a_aaaaaa9 fe_8000005_5555555 00_0000010_0000000)], + [qw(00_0000000_0000001 ff_fffffff_fffffff + 00_0000000_0000000 00_0000000_0000002 00_0000000_0000002)], + [qw(00_0000000_0000001 ff_fffffff_ffffff0 + ff_fffffff_ffffff1 00_0000000_0000011 00_0000000_0000002)], + ]; + + $error_count += AddressAddUnitTest($unit_test_data_8, $unit_test_data_16); + $error_count += AddressSubUnitTest($unit_test_data_8, $unit_test_data_16); + $error_count += AddressIncUnitTest($unit_test_data_8, $unit_test_data_16); + if ($error_count > 0) { + print STDERR $error_count, " errors: FAILED\n"; + } else { + print STDERR "PASS\n"; + } + exit ($error_count); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/config.guess b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/config.guess new file mode 100755 index 0000000..1f5c50c --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/config.guess @@ -0,0 +1,1420 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright 1992-2014 Free Software Foundation, Inc. + +timestamp='2014-03-23' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). +# +# Originally written by Per Bothner. +# +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD +# +# Please send patches with a ChangeLog entry to config-patches@gnu.org. + + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright 1992-2014 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +case "${UNAME_SYSTEM}" in +Linux|GNU|GNU/*) + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + LIBC=gnu + + eval $set_cc_for_build + cat <<-EOF > $dummy.c + #include + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #else + LIBC=gnu + #endif + EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` + ;; +esac + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm*:riscos:*:*|arm*:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` + case ${UNAME_PROCESSOR} in + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW64*:*) + echo ${UNAME_MACHINE}-pc-mingw64 + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + *:MSYS*:*) + echo ${UNAME_MACHINE}-pc-msys + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + aarch64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC="gnulibc1" ; fi + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arc:Linux:*:* | arceb:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi + else + echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + cris:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-${LIBC} + exit ;; + crisv32:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-${LIBC} + exit ;; + frv:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + hexagon:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + i*86:Linux:*:*) + echo ${UNAME_MACHINE}-pc-linux-${LIBC} + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } + ;; + openrisc*:Linux:*:*) + echo or1k-unknown-linux-${LIBC} + exit ;; + or32:Linux:*:* | or1k*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-${LIBC} + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-${LIBC} + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; + PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; + *) echo hppa-unknown-linux-${LIBC} ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-${LIBC} + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-${LIBC} + exit ;; + ppc64le:Linux:*:*) + echo powerpc64le-unknown-linux-${LIBC} + exit ;; + ppcle:Linux:*:*) + echo powerpcle-unknown-linux-${LIBC} + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux-${LIBC} + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + tile*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-${LIBC} + exit ;; + x86_64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + x86_64:Haiku:*:*) + echo x86_64-unknown-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + eval $set_cc_for_build + if test "$UNAME_PROCESSOR" = unknown ; then + UNAME_PROCESSOR=powerpc + fi + if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + fi + elif test "$UNAME_PROCESSOR" = i386 ; then + # Avoid executing cc on OS X 10.9, as it ships with a stub + # that puts up a graphical alert prompting to install + # developer tools. Any system running Mac OS X 10.7 or + # later (Darwin 11 and later) is required to have a 64-bit + # processor. This is not true of the ARM version of Darwin + # that Apple uses in portable devices. + UNAME_PROCESSOR=x86_64 + fi + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-?:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk${UNAME_RELEASE} + exit ;; + NSE-*:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; + x86_64:VMkernel:*:*) + echo ${UNAME_MACHINE}-unknown-esx + exit ;; +esac + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/redis-android/src/main/jni/redis-4.0.6/release.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/config.stamp.in similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/release.c rename to redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/config.stamp.in diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/config.sub b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/config.sub new file mode 100755 index 0000000..0ccff77 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/config.sub @@ -0,0 +1,1797 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright 1992-2014 Free Software Foundation, Inc. + +timestamp='2014-05-01' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). + + +# Please send patches with a ChangeLog entry to config-patches@gnu.org. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright 1992-2014 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + android-linux) + os=-linux-android + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray | -microblaze*) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*178) + os=-lynxos178 + ;; + -lynx*5) + os=-lynxos5 + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arceb \ + | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ + | avr | avr32 \ + | be32 | be64 \ + | bfin \ + | c4x | c8051 | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | epiphany \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | k1om \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa32r6 | mipsisa32r6el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64r6 | mipsisa64r6el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 | nios2eb | nios2el \ + | ns16k | ns32k \ + | open8 | or1k | or1knd | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pyramid \ + | rl78 | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | we32k \ + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + xgate) + basic_machine=$basic_machine-unknown + os=-none + ;; + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | aarch64-* | aarch64_be-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | be32-* | be64-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | c8051-* | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | k1om-* \ + | le32-* | le64-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ + | microblaze-* | microblazeel-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa32r6-* | mipsisa32r6el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64r6-* | mipsisa64r6el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipsr5900-* | mipsr5900el-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* | nios2eb-* | nios2el-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ + | or1k*-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pyramid-* \ + | rl78-* | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ + | tahoe-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile*-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze*) + basic_machine=microblaze-xilinx + ;; + mingw64) + basic_machine=x86_64-pc + os=-mingw64 + ;; + mingw32) + basic_machine=i686-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + msys) + basic_machine=i686-pc + os=-msys + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc | ppcbe) basic_machine=powerpc-unknown + ;; + ppc-* | ppcbe-*) + basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + os=-rdos + ;; + rdos32) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tile*) + basic_machine=$basic_machine-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* | -plan9* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -bitrig* | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-musl* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + # Apple iOS + -ios*) + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -nacl*) + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + c8051-*) + os=-elf + ;; + hexagon-*) + os=-elf + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/configure.ac b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/configure.ac new file mode 100644 index 0000000..7a1290e --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/configure.ac @@ -0,0 +1,1745 @@ +dnl Process this file with autoconf to produce a configure script. +AC_INIT([Makefile.in]) + +dnl ============================================================================ +dnl Custom macro definitions. + +dnl JE_CFLAGS_APPEND(cflag) +AC_DEFUN([JE_CFLAGS_APPEND], +[ +AC_MSG_CHECKING([whether compiler supports $1]) +TCFLAGS="${CFLAGS}" +if test "x${CFLAGS}" = "x" ; then + CFLAGS="$1" +else + CFLAGS="${CFLAGS} $1" +fi +AC_COMPILE_IFELSE([AC_LANG_PROGRAM( +[[ +]], [[ + return 0; +]])], + [je_cv_cflags_appended=$1] + AC_MSG_RESULT([yes]), + [je_cv_cflags_appended=] + AC_MSG_RESULT([no]) + [CFLAGS="${TCFLAGS}"] +) +]) + +dnl JE_COMPILABLE(label, hcode, mcode, rvar) +dnl +dnl Use AC_LINK_IFELSE() rather than AC_COMPILE_IFELSE() so that linker errors +dnl cause failure. +AC_DEFUN([JE_COMPILABLE], +[ +AC_CACHE_CHECK([whether $1 is compilable], + [$4], + [AC_LINK_IFELSE([AC_LANG_PROGRAM([$2], + [$3])], + [$4=yes], + [$4=no])]) +]) + +dnl ============================================================================ + +CONFIG=`echo ${ac_configure_args} | sed -e 's#'"'"'\([^ ]*\)'"'"'#\1#g'` +AC_SUBST([CONFIG]) + +dnl Library revision. +rev=2 +AC_SUBST([rev]) + +srcroot=$srcdir +if test "x${srcroot}" = "x." ; then + srcroot="" +else + srcroot="${srcroot}/" +fi +AC_SUBST([srcroot]) +abs_srcroot="`cd \"${srcdir}\"; pwd`/" +AC_SUBST([abs_srcroot]) + +objroot="" +AC_SUBST([objroot]) +abs_objroot="`pwd`/" +AC_SUBST([abs_objroot]) + +dnl Munge install path variables. +if test "x$prefix" = "xNONE" ; then + prefix="/usr/local" +fi +if test "x$exec_prefix" = "xNONE" ; then + exec_prefix=$prefix +fi +PREFIX=$prefix +AC_SUBST([PREFIX]) +BINDIR=`eval echo $bindir` +BINDIR=`eval echo $BINDIR` +AC_SUBST([BINDIR]) +INCLUDEDIR=`eval echo $includedir` +INCLUDEDIR=`eval echo $INCLUDEDIR` +AC_SUBST([INCLUDEDIR]) +LIBDIR=`eval echo $libdir` +LIBDIR=`eval echo $LIBDIR` +AC_SUBST([LIBDIR]) +DATADIR=`eval echo $datadir` +DATADIR=`eval echo $DATADIR` +AC_SUBST([DATADIR]) +MANDIR=`eval echo $mandir` +MANDIR=`eval echo $MANDIR` +AC_SUBST([MANDIR]) + +dnl Support for building documentation. +AC_PATH_PROG([XSLTPROC], [xsltproc], [false], [$PATH]) +if test -d "/usr/share/xml/docbook/stylesheet/docbook-xsl" ; then + DEFAULT_XSLROOT="/usr/share/xml/docbook/stylesheet/docbook-xsl" +elif test -d "/usr/share/sgml/docbook/xsl-stylesheets" ; then + DEFAULT_XSLROOT="/usr/share/sgml/docbook/xsl-stylesheets" +else + dnl Documentation building will fail if this default gets used. + DEFAULT_XSLROOT="" +fi +AC_ARG_WITH([xslroot], + [AS_HELP_STRING([--with-xslroot=], [XSL stylesheet root path])], [ +if test "x$with_xslroot" = "xno" ; then + XSLROOT="${DEFAULT_XSLROOT}" +else + XSLROOT="${with_xslroot}" +fi +], + XSLROOT="${DEFAULT_XSLROOT}" +) +AC_SUBST([XSLROOT]) + +dnl If CFLAGS isn't defined, set CFLAGS to something reasonable. Otherwise, +dnl just prevent autoconf from molesting CFLAGS. +CFLAGS=$CFLAGS +AC_PROG_CC +if test "x$GCC" != "xyes" ; then + AC_CACHE_CHECK([whether compiler is MSVC], + [je_cv_msvc], + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], + [ +#ifndef _MSC_VER + int fail[-1]; +#endif +])], + [je_cv_msvc=yes], + [je_cv_msvc=no])]) +fi + +if test "x$CFLAGS" = "x" ; then + no_CFLAGS="yes" + if test "x$GCC" = "xyes" ; then + JE_CFLAGS_APPEND([-std=gnu99]) + if test "x$je_cv_cflags_appended" = "x-std=gnu99" ; then + AC_DEFINE_UNQUOTED([JEMALLOC_HAS_RESTRICT]) + fi + JE_CFLAGS_APPEND([-Wall]) + JE_CFLAGS_APPEND([-Werror=declaration-after-statement]) + JE_CFLAGS_APPEND([-pipe]) + JE_CFLAGS_APPEND([-g3]) + elif test "x$je_cv_msvc" = "xyes" ; then + CC="$CC -nologo" + JE_CFLAGS_APPEND([-Zi]) + JE_CFLAGS_APPEND([-MT]) + JE_CFLAGS_APPEND([-W3]) + JE_CFLAGS_APPEND([-FS]) + CPPFLAGS="$CPPFLAGS -I${srcdir}/include/msvc_compat" + fi +fi +dnl Append EXTRA_CFLAGS to CFLAGS, if defined. +if test "x$EXTRA_CFLAGS" != "x" ; then + JE_CFLAGS_APPEND([$EXTRA_CFLAGS]) +fi +AC_PROG_CPP + +AC_C_BIGENDIAN([ac_cv_big_endian=1], [ac_cv_big_endian=0]) +if test "x${ac_cv_big_endian}" = "x1" ; then + AC_DEFINE_UNQUOTED([JEMALLOC_BIG_ENDIAN], [ ]) +fi + +if test "x${je_cv_msvc}" = "xyes" -a "x${ac_cv_header_inttypes_h}" = "xno"; then + CPPFLAGS="$CPPFLAGS -I${srcdir}/include/msvc_compat/C99" +fi + +AC_CHECK_SIZEOF([void *]) +if test "x${ac_cv_sizeof_void_p}" = "x8" ; then + LG_SIZEOF_PTR=3 +elif test "x${ac_cv_sizeof_void_p}" = "x4" ; then + LG_SIZEOF_PTR=2 +else + AC_MSG_ERROR([Unsupported pointer size: ${ac_cv_sizeof_void_p}]) +fi +AC_DEFINE_UNQUOTED([LG_SIZEOF_PTR], [$LG_SIZEOF_PTR]) + +AC_CHECK_SIZEOF([int]) +if test "x${ac_cv_sizeof_int}" = "x8" ; then + LG_SIZEOF_INT=3 +elif test "x${ac_cv_sizeof_int}" = "x4" ; then + LG_SIZEOF_INT=2 +else + AC_MSG_ERROR([Unsupported int size: ${ac_cv_sizeof_int}]) +fi +AC_DEFINE_UNQUOTED([LG_SIZEOF_INT], [$LG_SIZEOF_INT]) + +AC_CHECK_SIZEOF([long]) +if test "x${ac_cv_sizeof_long}" = "x8" ; then + LG_SIZEOF_LONG=3 +elif test "x${ac_cv_sizeof_long}" = "x4" ; then + LG_SIZEOF_LONG=2 +else + AC_MSG_ERROR([Unsupported long size: ${ac_cv_sizeof_long}]) +fi +AC_DEFINE_UNQUOTED([LG_SIZEOF_LONG], [$LG_SIZEOF_LONG]) + +AC_CHECK_SIZEOF([intmax_t]) +if test "x${ac_cv_sizeof_intmax_t}" = "x16" ; then + LG_SIZEOF_INTMAX_T=4 +elif test "x${ac_cv_sizeof_intmax_t}" = "x8" ; then + LG_SIZEOF_INTMAX_T=3 +elif test "x${ac_cv_sizeof_intmax_t}" = "x4" ; then + LG_SIZEOF_INTMAX_T=2 +else + AC_MSG_ERROR([Unsupported intmax_t size: ${ac_cv_sizeof_intmax_t}]) +fi +AC_DEFINE_UNQUOTED([LG_SIZEOF_INTMAX_T], [$LG_SIZEOF_INTMAX_T]) + +AC_CANONICAL_HOST +dnl CPU-specific settings. +CPU_SPINWAIT="" +case "${host_cpu}" in + i686|x86_64) + AC_CACHE_VAL([je_cv_pause], + [JE_COMPILABLE([pause instruction], [], + [[__asm__ volatile("pause"); return 0;]], + [je_cv_pause])]) + if test "x${je_cv_pause}" = "xyes" ; then + CPU_SPINWAIT='__asm__ volatile("pause")' + fi + ;; + powerpc) + AC_DEFINE_UNQUOTED([HAVE_ALTIVEC], [ ]) + ;; + *) + ;; +esac +AC_DEFINE_UNQUOTED([CPU_SPINWAIT], [$CPU_SPINWAIT]) + +LD_PRELOAD_VAR="LD_PRELOAD" +so="so" +importlib="${so}" +o="$ac_objext" +a="a" +exe="$ac_exeext" +libprefix="lib" +DSO_LDFLAGS='-shared -Wl,-soname,$(@F)' +RPATH='-Wl,-rpath,$(1)' +SOREV="${so}.${rev}" +PIC_CFLAGS='-fPIC -DPIC' +CTARGET='-o $@' +LDTARGET='-o $@' +EXTRA_LDFLAGS= +ARFLAGS='crus' +AROUT=' $@' +CC_MM=1 + +AN_MAKEVAR([AR], [AC_PROG_AR]) +AN_PROGRAM([ar], [AC_PROG_AR]) +AC_DEFUN([AC_PROG_AR], [AC_CHECK_TOOL(AR, ar, :)]) +AC_PROG_AR + +dnl Platform-specific settings. abi and RPATH can probably be determined +dnl programmatically, but doing so is error-prone, which makes it generally +dnl not worth the trouble. +dnl +dnl Define cpp macros in CPPFLAGS, rather than doing AC_DEFINE(macro), since the +dnl definitions need to be seen before any headers are included, which is a pain +dnl to make happen otherwise. +default_munmap="1" +maps_coalesce="1" +case "${host}" in + *-*-darwin* | *-*-ios*) + CFLAGS="$CFLAGS" + abi="macho" + AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ]) + RPATH="" + LD_PRELOAD_VAR="DYLD_INSERT_LIBRARIES" + so="dylib" + importlib="${so}" + force_tls="0" + DSO_LDFLAGS='-shared -Wl,-install_name,$(LIBDIR)/$(@F)' + SOREV="${rev}.${so}" + sbrk_deprecated="1" + ;; + *-*-freebsd*) + CFLAGS="$CFLAGS" + abi="elf" + AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ]) + force_lazy_lock="1" + ;; + *-*-dragonfly*) + CFLAGS="$CFLAGS" + abi="elf" + AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ]) + ;; + *-*-openbsd*) + CFLAGS="$CFLAGS" + abi="elf" + AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ]) + force_tls="0" + ;; + *-*-bitrig*) + CFLAGS="$CFLAGS" + abi="elf" + AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ]) + ;; + *-*-linux*) + CFLAGS="$CFLAGS" + CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE" + abi="elf" + AC_DEFINE([JEMALLOC_HAS_ALLOCA_H]) + AC_DEFINE([JEMALLOC_PURGE_MADVISE_DONTNEED], [ ]) + AC_DEFINE([JEMALLOC_THREADED_INIT], [ ]) + AC_DEFINE([JEMALLOC_USE_CXX_THROW], [ ]) + default_munmap="0" + ;; + *-*-netbsd*) + AC_MSG_CHECKING([ABI]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM( +[[#ifdef __ELF__ +/* ELF */ +#else +#error aout +#endif +]])], + [CFLAGS="$CFLAGS"; abi="elf"], + [abi="aout"]) + AC_MSG_RESULT([$abi]) + AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ]) + ;; + *-*-solaris2*) + CFLAGS="$CFLAGS" + abi="elf" + AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ]) + RPATH='-Wl,-R,$(1)' + dnl Solaris needs this for sigwait(). + CPPFLAGS="$CPPFLAGS -D_POSIX_PTHREAD_SEMANTICS" + LIBS="$LIBS -lposix4 -lsocket -lnsl" + ;; + *-ibm-aix*) + if "$LG_SIZEOF_PTR" = "8"; then + dnl 64bit AIX + LD_PRELOAD_VAR="LDR_PRELOAD64" + else + dnl 32bit AIX + LD_PRELOAD_VAR="LDR_PRELOAD" + fi + abi="xcoff" + ;; + *-*-mingw* | *-*-cygwin*) + abi="pecoff" + force_tls="0" + force_lazy_lock="1" + maps_coalesce="0" + RPATH="" + so="dll" + if test "x$je_cv_msvc" = "xyes" ; then + importlib="lib" + DSO_LDFLAGS="-LD" + EXTRA_LDFLAGS="-link -DEBUG" + CTARGET='-Fo$@' + LDTARGET='-Fe$@' + AR='lib' + ARFLAGS='-nologo -out:' + AROUT='$@' + CC_MM= + else + importlib="${so}" + DSO_LDFLAGS="-shared" + fi + a="lib" + libprefix="" + SOREV="${so}" + PIC_CFLAGS="" + ;; + *) + AC_MSG_RESULT([Unsupported operating system: ${host}]) + abi="elf" + ;; +esac + +JEMALLOC_USABLE_SIZE_CONST=const +AC_CHECK_HEADERS([malloc.h], [ + AC_MSG_CHECKING([whether malloc_usable_size definition can use const argument]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM( + [#include + #include + size_t malloc_usable_size(const void *ptr); + ], + [])],[ + AC_MSG_RESULT([yes]) + ],[ + JEMALLOC_USABLE_SIZE_CONST= + AC_MSG_RESULT([no]) + ]) +]) +AC_DEFINE_UNQUOTED([JEMALLOC_USABLE_SIZE_CONST], [$JEMALLOC_USABLE_SIZE_CONST]) +AC_SUBST([abi]) +AC_SUBST([RPATH]) +AC_SUBST([LD_PRELOAD_VAR]) +AC_SUBST([so]) +AC_SUBST([importlib]) +AC_SUBST([o]) +AC_SUBST([a]) +AC_SUBST([exe]) +AC_SUBST([libprefix]) +AC_SUBST([DSO_LDFLAGS]) +AC_SUBST([EXTRA_LDFLAGS]) +AC_SUBST([SOREV]) +AC_SUBST([PIC_CFLAGS]) +AC_SUBST([CTARGET]) +AC_SUBST([LDTARGET]) +AC_SUBST([MKLIB]) +AC_SUBST([ARFLAGS]) +AC_SUBST([AROUT]) +AC_SUBST([CC_MM]) + +JE_COMPILABLE([__attribute__ syntax], + [static __attribute__((unused)) void foo(void){}], + [], + [je_cv_attribute]) +if test "x${je_cv_attribute}" = "xyes" ; then + AC_DEFINE([JEMALLOC_HAVE_ATTR], [ ]) + if test "x${GCC}" = "xyes" -a "x${abi}" = "xelf"; then + JE_CFLAGS_APPEND([-fvisibility=hidden]) + fi +fi +dnl Check for tls_model attribute support (clang 3.0 still lacks support). +SAVED_CFLAGS="${CFLAGS}" +JE_CFLAGS_APPEND([-Werror]) +JE_COMPILABLE([tls_model attribute], [], + [static __thread int + __attribute__((tls_model("initial-exec"), unused)) foo; + foo = 0;], + [je_cv_tls_model]) +CFLAGS="${SAVED_CFLAGS}" +if test "x${je_cv_tls_model}" = "xyes" ; then + AC_DEFINE([JEMALLOC_TLS_MODEL], + [__attribute__((tls_model("initial-exec")))]) +else + AC_DEFINE([JEMALLOC_TLS_MODEL], [ ]) +fi +dnl Check for alloc_size attribute support. +SAVED_CFLAGS="${CFLAGS}" +JE_CFLAGS_APPEND([-Werror]) +JE_COMPILABLE([alloc_size attribute], [#include ], + [void *foo(size_t size) __attribute__((alloc_size(1)));], + [je_cv_alloc_size]) +CFLAGS="${SAVED_CFLAGS}" +if test "x${je_cv_alloc_size}" = "xyes" ; then + AC_DEFINE([JEMALLOC_HAVE_ATTR_ALLOC_SIZE], [ ]) +fi +dnl Check for format(gnu_printf, ...) attribute support. +SAVED_CFLAGS="${CFLAGS}" +JE_CFLAGS_APPEND([-Werror]) +JE_COMPILABLE([format(gnu_printf, ...) attribute], [#include ], + [void *foo(const char *format, ...) __attribute__((format(gnu_printf, 1, 2)));], + [je_cv_format_gnu_printf]) +CFLAGS="${SAVED_CFLAGS}" +if test "x${je_cv_format_gnu_printf}" = "xyes" ; then + AC_DEFINE([JEMALLOC_HAVE_ATTR_FORMAT_GNU_PRINTF], [ ]) +fi +dnl Check for format(printf, ...) attribute support. +SAVED_CFLAGS="${CFLAGS}" +JE_CFLAGS_APPEND([-Werror]) +JE_COMPILABLE([format(printf, ...) attribute], [#include ], + [void *foo(const char *format, ...) __attribute__((format(printf, 1, 2)));], + [je_cv_format_printf]) +CFLAGS="${SAVED_CFLAGS}" +if test "x${je_cv_format_printf}" = "xyes" ; then + AC_DEFINE([JEMALLOC_HAVE_ATTR_FORMAT_PRINTF], [ ]) +fi + +dnl Support optional additions to rpath. +AC_ARG_WITH([rpath], + [AS_HELP_STRING([--with-rpath=], [Colon-separated rpath (ELF systems only)])], +if test "x$with_rpath" = "xno" ; then + RPATH_EXTRA= +else + RPATH_EXTRA="`echo $with_rpath | tr \":\" \" \"`" +fi, + RPATH_EXTRA= +) +AC_SUBST([RPATH_EXTRA]) + +dnl Disable rules that do automatic regeneration of configure output by default. +AC_ARG_ENABLE([autogen], + [AS_HELP_STRING([--enable-autogen], [Automatically regenerate configure output])], +if test "x$enable_autogen" = "xno" ; then + enable_autogen="0" +else + enable_autogen="1" +fi +, +enable_autogen="0" +) +AC_SUBST([enable_autogen]) + +AC_PROG_INSTALL +AC_PROG_RANLIB +AC_PATH_PROG([LD], [ld], [false], [$PATH]) +AC_PATH_PROG([AUTOCONF], [autoconf], [false], [$PATH]) + +public_syms="malloc_conf malloc_message malloc calloc posix_memalign aligned_alloc realloc free mallocx rallocx xallocx sallocx dallocx sdallocx nallocx mallctl mallctlnametomib mallctlbymib malloc_stats_print malloc_usable_size" + +dnl Check for allocator-related functions that should be wrapped. +AC_CHECK_FUNC([memalign], + [AC_DEFINE([JEMALLOC_OVERRIDE_MEMALIGN], [ ]) + public_syms="${public_syms} memalign"]) +AC_CHECK_FUNC([valloc], + [AC_DEFINE([JEMALLOC_OVERRIDE_VALLOC], [ ]) + public_syms="${public_syms} valloc"]) + +dnl Do not compute test code coverage by default. +GCOV_FLAGS= +AC_ARG_ENABLE([code-coverage], + [AS_HELP_STRING([--enable-code-coverage], + [Enable code coverage])], +[if test "x$enable_code_coverage" = "xno" ; then + enable_code_coverage="0" +else + enable_code_coverage="1" +fi +], +[enable_code_coverage="0"] +) +if test "x$enable_code_coverage" = "x1" ; then + deoptimize="no" + echo "$CFLAGS $EXTRA_CFLAGS" | grep '\-O' >/dev/null || deoptimize="yes" + if test "x${deoptimize}" = "xyes" ; then + JE_CFLAGS_APPEND([-O0]) + fi + JE_CFLAGS_APPEND([-fprofile-arcs -ftest-coverage]) + EXTRA_LDFLAGS="$EXTRA_LDFLAGS -fprofile-arcs -ftest-coverage" + AC_DEFINE([JEMALLOC_CODE_COVERAGE], [ ]) +fi +AC_SUBST([enable_code_coverage]) + +dnl Perform no name mangling by default. +AC_ARG_WITH([mangling], + [AS_HELP_STRING([--with-mangling=], [Mangle symbols in ])], + [mangling_map="$with_mangling"], [mangling_map=""]) + +dnl Do not prefix public APIs by default. +AC_ARG_WITH([jemalloc_prefix], + [AS_HELP_STRING([--with-jemalloc-prefix=], [Prefix to prepend to all public APIs])], + [JEMALLOC_PREFIX="$with_jemalloc_prefix"], + [if test "x$abi" != "xmacho" -a "x$abi" != "xpecoff"; then + JEMALLOC_PREFIX="" +else + JEMALLOC_PREFIX="je_" +fi] +) +if test "x$JEMALLOC_PREFIX" != "x" ; then + JEMALLOC_CPREFIX=`echo ${JEMALLOC_PREFIX} | tr "a-z" "A-Z"` + AC_DEFINE_UNQUOTED([JEMALLOC_PREFIX], ["$JEMALLOC_PREFIX"]) + AC_DEFINE_UNQUOTED([JEMALLOC_CPREFIX], ["$JEMALLOC_CPREFIX"]) +fi +AC_SUBST([JEMALLOC_CPREFIX]) + +AC_ARG_WITH([export], + [AS_HELP_STRING([--without-export], [disable exporting jemalloc public APIs])], + [if test "x$with_export" = "xno"; then + AC_DEFINE([JEMALLOC_EXPORT],[]) +fi] +) + +dnl Mangle library-private APIs. +AC_ARG_WITH([private_namespace], + [AS_HELP_STRING([--with-private-namespace=], [Prefix to prepend to all library-private APIs])], + [JEMALLOC_PRIVATE_NAMESPACE="${with_private_namespace}je_"], + [JEMALLOC_PRIVATE_NAMESPACE="je_"] +) +AC_DEFINE_UNQUOTED([JEMALLOC_PRIVATE_NAMESPACE], [$JEMALLOC_PRIVATE_NAMESPACE]) +private_namespace="$JEMALLOC_PRIVATE_NAMESPACE" +AC_SUBST([private_namespace]) + +dnl Do not add suffix to installed files by default. +AC_ARG_WITH([install_suffix], + [AS_HELP_STRING([--with-install-suffix=], [Suffix to append to all installed files])], + [INSTALL_SUFFIX="$with_install_suffix"], + [INSTALL_SUFFIX=] +) +install_suffix="$INSTALL_SUFFIX" +AC_SUBST([install_suffix]) + +dnl Substitute @je_@ in jemalloc_protos.h.in, primarily to make generation of +dnl jemalloc_protos_jet.h easy. +je_="je_" +AC_SUBST([je_]) + +cfgoutputs_in="Makefile.in" +cfgoutputs_in="${cfgoutputs_in} jemalloc.pc.in" +cfgoutputs_in="${cfgoutputs_in} doc/html.xsl.in" +cfgoutputs_in="${cfgoutputs_in} doc/manpages.xsl.in" +cfgoutputs_in="${cfgoutputs_in} doc/jemalloc.xml.in" +cfgoutputs_in="${cfgoutputs_in} include/jemalloc/jemalloc_macros.h.in" +cfgoutputs_in="${cfgoutputs_in} include/jemalloc/jemalloc_protos.h.in" +cfgoutputs_in="${cfgoutputs_in} include/jemalloc/jemalloc_typedefs.h.in" +cfgoutputs_in="${cfgoutputs_in} include/jemalloc/internal/jemalloc_internal.h.in" +cfgoutputs_in="${cfgoutputs_in} test/test.sh.in" +cfgoutputs_in="${cfgoutputs_in} test/include/test/jemalloc_test.h.in" + +cfgoutputs_out="Makefile" +cfgoutputs_out="${cfgoutputs_out} jemalloc.pc" +cfgoutputs_out="${cfgoutputs_out} doc/html.xsl" +cfgoutputs_out="${cfgoutputs_out} doc/manpages.xsl" +cfgoutputs_out="${cfgoutputs_out} doc/jemalloc.xml" +cfgoutputs_out="${cfgoutputs_out} include/jemalloc/jemalloc_macros.h" +cfgoutputs_out="${cfgoutputs_out} include/jemalloc/jemalloc_protos.h" +cfgoutputs_out="${cfgoutputs_out} include/jemalloc/jemalloc_typedefs.h" +cfgoutputs_out="${cfgoutputs_out} include/jemalloc/internal/jemalloc_internal.h" +cfgoutputs_out="${cfgoutputs_out} test/test.sh" +cfgoutputs_out="${cfgoutputs_out} test/include/test/jemalloc_test.h" + +cfgoutputs_tup="Makefile" +cfgoutputs_tup="${cfgoutputs_tup} jemalloc.pc:jemalloc.pc.in" +cfgoutputs_tup="${cfgoutputs_tup} doc/html.xsl:doc/html.xsl.in" +cfgoutputs_tup="${cfgoutputs_tup} doc/manpages.xsl:doc/manpages.xsl.in" +cfgoutputs_tup="${cfgoutputs_tup} doc/jemalloc.xml:doc/jemalloc.xml.in" +cfgoutputs_tup="${cfgoutputs_tup} include/jemalloc/jemalloc_macros.h:include/jemalloc/jemalloc_macros.h.in" +cfgoutputs_tup="${cfgoutputs_tup} include/jemalloc/jemalloc_protos.h:include/jemalloc/jemalloc_protos.h.in" +cfgoutputs_tup="${cfgoutputs_tup} include/jemalloc/jemalloc_typedefs.h:include/jemalloc/jemalloc_typedefs.h.in" +cfgoutputs_tup="${cfgoutputs_tup} include/jemalloc/internal/jemalloc_internal.h" +cfgoutputs_tup="${cfgoutputs_tup} test/test.sh:test/test.sh.in" +cfgoutputs_tup="${cfgoutputs_tup} test/include/test/jemalloc_test.h:test/include/test/jemalloc_test.h.in" + +cfghdrs_in="include/jemalloc/jemalloc_defs.h.in" +cfghdrs_in="${cfghdrs_in} include/jemalloc/internal/jemalloc_internal_defs.h.in" +cfghdrs_in="${cfghdrs_in} include/jemalloc/internal/private_namespace.sh" +cfghdrs_in="${cfghdrs_in} include/jemalloc/internal/private_unnamespace.sh" +cfghdrs_in="${cfghdrs_in} include/jemalloc/internal/private_symbols.txt" +cfghdrs_in="${cfghdrs_in} include/jemalloc/internal/public_namespace.sh" +cfghdrs_in="${cfghdrs_in} include/jemalloc/internal/public_unnamespace.sh" +cfghdrs_in="${cfghdrs_in} include/jemalloc/internal/size_classes.sh" +cfghdrs_in="${cfghdrs_in} include/jemalloc/jemalloc_rename.sh" +cfghdrs_in="${cfghdrs_in} include/jemalloc/jemalloc_mangle.sh" +cfghdrs_in="${cfghdrs_in} include/jemalloc/jemalloc.sh" +cfghdrs_in="${cfghdrs_in} test/include/test/jemalloc_test_defs.h.in" + +cfghdrs_out="include/jemalloc/jemalloc_defs.h" +cfghdrs_out="${cfghdrs_out} include/jemalloc/jemalloc${install_suffix}.h" +cfghdrs_out="${cfghdrs_out} include/jemalloc/internal/private_namespace.h" +cfghdrs_out="${cfghdrs_out} include/jemalloc/internal/private_unnamespace.h" +cfghdrs_out="${cfghdrs_out} include/jemalloc/internal/public_symbols.txt" +cfghdrs_out="${cfghdrs_out} include/jemalloc/internal/public_namespace.h" +cfghdrs_out="${cfghdrs_out} include/jemalloc/internal/public_unnamespace.h" +cfghdrs_out="${cfghdrs_out} include/jemalloc/internal/size_classes.h" +cfghdrs_out="${cfghdrs_out} include/jemalloc/jemalloc_protos_jet.h" +cfghdrs_out="${cfghdrs_out} include/jemalloc/jemalloc_rename.h" +cfghdrs_out="${cfghdrs_out} include/jemalloc/jemalloc_mangle.h" +cfghdrs_out="${cfghdrs_out} include/jemalloc/jemalloc_mangle_jet.h" +cfghdrs_out="${cfghdrs_out} include/jemalloc/internal/jemalloc_internal_defs.h" +cfghdrs_out="${cfghdrs_out} test/include/test/jemalloc_test_defs.h" + +cfghdrs_tup="include/jemalloc/jemalloc_defs.h:include/jemalloc/jemalloc_defs.h.in" +cfghdrs_tup="${cfghdrs_tup} include/jemalloc/internal/jemalloc_internal_defs.h:include/jemalloc/internal/jemalloc_internal_defs.h.in" +cfghdrs_tup="${cfghdrs_tup} test/include/test/jemalloc_test_defs.h:test/include/test/jemalloc_test_defs.h.in" + +dnl Silence irrelevant compiler warnings by default. +AC_ARG_ENABLE([cc-silence], + [AS_HELP_STRING([--disable-cc-silence], + [Do not silence irrelevant compiler warnings])], +[if test "x$enable_cc_silence" = "xno" ; then + enable_cc_silence="0" +else + enable_cc_silence="1" +fi +], +[enable_cc_silence="1"] +) +if test "x$enable_cc_silence" = "x1" ; then + AC_DEFINE([JEMALLOC_CC_SILENCE], [ ]) +fi + +dnl Do not compile with debugging by default. +AC_ARG_ENABLE([debug], + [AS_HELP_STRING([--enable-debug], + [Build debugging code (implies --enable-ivsalloc)])], +[if test "x$enable_debug" = "xno" ; then + enable_debug="0" +else + enable_debug="1" +fi +], +[enable_debug="0"] +) +if test "x$enable_debug" = "x1" ; then + AC_DEFINE([JEMALLOC_DEBUG], [ ]) +fi +if test "x$enable_debug" = "x1" ; then + AC_DEFINE([JEMALLOC_DEBUG], [ ]) + enable_ivsalloc="1" +fi +AC_SUBST([enable_debug]) + +dnl Do not validate pointers by default. +AC_ARG_ENABLE([ivsalloc], + [AS_HELP_STRING([--enable-ivsalloc], + [Validate pointers passed through the public API])], +[if test "x$enable_ivsalloc" = "xno" ; then + enable_ivsalloc="0" +else + enable_ivsalloc="1" +fi +], +[enable_ivsalloc="0"] +) +if test "x$enable_ivsalloc" = "x1" ; then + AC_DEFINE([JEMALLOC_IVSALLOC], [ ]) +fi + +dnl Only optimize if not debugging. +if test "x$enable_debug" = "x0" -a "x$no_CFLAGS" = "xyes" ; then + dnl Make sure that an optimization flag was not specified in EXTRA_CFLAGS. + optimize="no" + echo "$CFLAGS $EXTRA_CFLAGS" | grep '\-O' >/dev/null || optimize="yes" + if test "x${optimize}" = "xyes" ; then + if test "x$GCC" = "xyes" ; then + JE_CFLAGS_APPEND([-O3]) + JE_CFLAGS_APPEND([-funroll-loops]) + elif test "x$je_cv_msvc" = "xyes" ; then + JE_CFLAGS_APPEND([-O2]) + else + JE_CFLAGS_APPEND([-O]) + fi + fi +fi + +dnl Enable statistics calculation by default. +AC_ARG_ENABLE([stats], + [AS_HELP_STRING([--disable-stats], + [Disable statistics calculation/reporting])], +[if test "x$enable_stats" = "xno" ; then + enable_stats="0" +else + enable_stats="1" +fi +], +[enable_stats="1"] +) +if test "x$enable_stats" = "x1" ; then + AC_DEFINE([JEMALLOC_STATS], [ ]) +fi +AC_SUBST([enable_stats]) + +dnl Do not enable profiling by default. +AC_ARG_ENABLE([prof], + [AS_HELP_STRING([--enable-prof], [Enable allocation profiling])], +[if test "x$enable_prof" = "xno" ; then + enable_prof="0" +else + enable_prof="1" +fi +], +[enable_prof="0"] +) +if test "x$enable_prof" = "x1" ; then + backtrace_method="" +else + backtrace_method="N/A" +fi + +AC_ARG_ENABLE([prof-libunwind], + [AS_HELP_STRING([--enable-prof-libunwind], [Use libunwind for backtracing])], +[if test "x$enable_prof_libunwind" = "xno" ; then + enable_prof_libunwind="0" +else + enable_prof_libunwind="1" +fi +], +[enable_prof_libunwind="0"] +) +AC_ARG_WITH([static_libunwind], + [AS_HELP_STRING([--with-static-libunwind=], + [Path to static libunwind library; use rather than dynamically linking])], +if test "x$with_static_libunwind" = "xno" ; then + LUNWIND="-lunwind" +else + if test ! -f "$with_static_libunwind" ; then + AC_MSG_ERROR([Static libunwind not found: $with_static_libunwind]) + fi + LUNWIND="$with_static_libunwind" +fi, + LUNWIND="-lunwind" +) +if test "x$backtrace_method" = "x" -a "x$enable_prof_libunwind" = "x1" ; then + AC_CHECK_HEADERS([libunwind.h], , [enable_prof_libunwind="0"]) + if test "x$LUNWIND" = "x-lunwind" ; then + AC_CHECK_LIB([unwind], [unw_backtrace], [LIBS="$LIBS $LUNWIND"], + [enable_prof_libunwind="0"]) + else + LIBS="$LIBS $LUNWIND" + fi + if test "x${enable_prof_libunwind}" = "x1" ; then + backtrace_method="libunwind" + AC_DEFINE([JEMALLOC_PROF_LIBUNWIND], [ ]) + fi +fi + +AC_ARG_ENABLE([prof-libgcc], + [AS_HELP_STRING([--disable-prof-libgcc], + [Do not use libgcc for backtracing])], +[if test "x$enable_prof_libgcc" = "xno" ; then + enable_prof_libgcc="0" +else + enable_prof_libgcc="1" +fi +], +[enable_prof_libgcc="1"] +) +if test "x$backtrace_method" = "x" -a "x$enable_prof_libgcc" = "x1" \ + -a "x$GCC" = "xyes" ; then + AC_CHECK_HEADERS([unwind.h], , [enable_prof_libgcc="0"]) + AC_CHECK_LIB([gcc], [_Unwind_Backtrace], [LIBS="$LIBS -lgcc"], [enable_prof_libgcc="0"]) + if test "x${enable_prof_libgcc}" = "x1" ; then + backtrace_method="libgcc" + AC_DEFINE([JEMALLOC_PROF_LIBGCC], [ ]) + fi +else + enable_prof_libgcc="0" +fi + +AC_ARG_ENABLE([prof-gcc], + [AS_HELP_STRING([--disable-prof-gcc], + [Do not use gcc intrinsics for backtracing])], +[if test "x$enable_prof_gcc" = "xno" ; then + enable_prof_gcc="0" +else + enable_prof_gcc="1" +fi +], +[enable_prof_gcc="1"] +) +if test "x$backtrace_method" = "x" -a "x$enable_prof_gcc" = "x1" \ + -a "x$GCC" = "xyes" ; then + JE_CFLAGS_APPEND([-fno-omit-frame-pointer]) + backtrace_method="gcc intrinsics" + AC_DEFINE([JEMALLOC_PROF_GCC], [ ]) +else + enable_prof_gcc="0" +fi + +if test "x$backtrace_method" = "x" ; then + backtrace_method="none (disabling profiling)" + enable_prof="0" +fi +AC_MSG_CHECKING([configured backtracing method]) +AC_MSG_RESULT([$backtrace_method]) +if test "x$enable_prof" = "x1" ; then + if test "x$abi" != "xpecoff"; then + dnl Heap profiling uses the log(3) function. + LIBS="$LIBS -lm" + fi + + AC_DEFINE([JEMALLOC_PROF], [ ]) +fi +AC_SUBST([enable_prof]) + +dnl Enable thread-specific caching by default. +AC_ARG_ENABLE([tcache], + [AS_HELP_STRING([--disable-tcache], [Disable per thread caches])], +[if test "x$enable_tcache" = "xno" ; then + enable_tcache="0" +else + enable_tcache="1" +fi +], +[enable_tcache="1"] +) +if test "x$enable_tcache" = "x1" ; then + AC_DEFINE([JEMALLOC_TCACHE], [ ]) +fi +AC_SUBST([enable_tcache]) + +dnl Indicate whether adjacent virtual memory mappings automatically coalesce +dnl (and fragment on demand). +if test "x${maps_coalesce}" = "x1" ; then + AC_DEFINE([JEMALLOC_MAPS_COALESCE], [ ]) +fi + +dnl Enable VM deallocation via munmap() by default. +AC_ARG_ENABLE([munmap], + [AS_HELP_STRING([--disable-munmap], [Disable VM deallocation via munmap(2)])], +[if test "x$enable_munmap" = "xno" ; then + enable_munmap="0" +else + enable_munmap="1" +fi +], +[enable_munmap="${default_munmap}"] +) +if test "x$enable_munmap" = "x1" ; then + AC_DEFINE([JEMALLOC_MUNMAP], [ ]) +fi +AC_SUBST([enable_munmap]) + +dnl Enable allocation from DSS if supported by the OS. +have_dss="1" +dnl Check whether the BSD/SUSv1 sbrk() exists. If not, disable DSS support. +AC_CHECK_FUNC([sbrk], [have_sbrk="1"], [have_sbrk="0"]) +if test "x$have_sbrk" = "x1" ; then + if test "x$sbrk_deprecated" = "x1" ; then + AC_MSG_RESULT([Disabling dss allocation because sbrk is deprecated]) + have_dss="0" + fi +else + have_dss="0" +fi + +if test "x$have_dss" = "x1" ; then + AC_DEFINE([JEMALLOC_DSS], [ ]) +fi + +dnl Support the junk/zero filling option by default. +AC_ARG_ENABLE([fill], + [AS_HELP_STRING([--disable-fill], + [Disable support for junk/zero filling, quarantine, and redzones])], +[if test "x$enable_fill" = "xno" ; then + enable_fill="0" +else + enable_fill="1" +fi +], +[enable_fill="1"] +) +if test "x$enable_fill" = "x1" ; then + AC_DEFINE([JEMALLOC_FILL], [ ]) +fi +AC_SUBST([enable_fill]) + +dnl Disable utrace(2)-based tracing by default. +AC_ARG_ENABLE([utrace], + [AS_HELP_STRING([--enable-utrace], [Enable utrace(2)-based tracing])], +[if test "x$enable_utrace" = "xno" ; then + enable_utrace="0" +else + enable_utrace="1" +fi +], +[enable_utrace="0"] +) +JE_COMPILABLE([utrace(2)], [ +#include +#include +#include +#include +#include +], [ + utrace((void *)0, 0); +], [je_cv_utrace]) +if test "x${je_cv_utrace}" = "xno" ; then + enable_utrace="0" +fi +if test "x$enable_utrace" = "x1" ; then + AC_DEFINE([JEMALLOC_UTRACE], [ ]) +fi +AC_SUBST([enable_utrace]) + +dnl Support Valgrind by default. +AC_ARG_ENABLE([valgrind], + [AS_HELP_STRING([--disable-valgrind], [Disable support for Valgrind])], +[if test "x$enable_valgrind" = "xno" ; then + enable_valgrind="0" +else + enable_valgrind="1" +fi +], +[enable_valgrind="1"] +) +if test "x$enable_valgrind" = "x1" ; then + JE_COMPILABLE([valgrind], [ +#include +#include + +#if !defined(VALGRIND_RESIZEINPLACE_BLOCK) +# error "Incompatible Valgrind version" +#endif +], [], [je_cv_valgrind]) + if test "x${je_cv_valgrind}" = "xno" ; then + enable_valgrind="0" + fi + if test "x$enable_valgrind" = "x1" ; then + AC_DEFINE([JEMALLOC_VALGRIND], [ ]) + fi +fi +AC_SUBST([enable_valgrind]) + +dnl Do not support the xmalloc option by default. +AC_ARG_ENABLE([xmalloc], + [AS_HELP_STRING([--enable-xmalloc], [Support xmalloc option])], +[if test "x$enable_xmalloc" = "xno" ; then + enable_xmalloc="0" +else + enable_xmalloc="1" +fi +], +[enable_xmalloc="0"] +) +if test "x$enable_xmalloc" = "x1" ; then + AC_DEFINE([JEMALLOC_XMALLOC], [ ]) +fi +AC_SUBST([enable_xmalloc]) + +dnl Support cache-oblivious allocation alignment by default. +AC_ARG_ENABLE([cache-oblivious], + [AS_HELP_STRING([--disable-cache-oblivious], + [Disable support for cache-oblivious allocation alignment])], +[if test "x$enable_cache_oblivious" = "xno" ; then + enable_cache_oblivious="0" +else + enable_cache_oblivious="1" +fi +], +[enable_cache_oblivious="1"] +) +if test "x$enable_cache_oblivious" = "x1" ; then + AC_DEFINE([JEMALLOC_CACHE_OBLIVIOUS], [ ]) +fi +AC_SUBST([enable_cache_oblivious]) + +dnl ============================================================================ +dnl Check for __builtin_ffsl(), then ffsl(3), and fail if neither are found. +dnl One of those two functions should (theoretically) exist on all platforms +dnl that jemalloc currently has a chance of functioning on without modification. +dnl We additionally assume ffs() or __builtin_ffs() are defined if +dnl ffsl() or __builtin_ffsl() are defined, respectively. +JE_COMPILABLE([a program using __builtin_ffsl], [ +#include +#include +#include +], [ + { + int rv = __builtin_ffsl(0x08); + printf("%d\n", rv); + } +], [je_cv_gcc_builtin_ffsl]) +if test "x${je_cv_gcc_builtin_ffsl}" = "xyes" ; then + AC_DEFINE([JEMALLOC_INTERNAL_FFSL], [__builtin_ffsl]) + AC_DEFINE([JEMALLOC_INTERNAL_FFS], [__builtin_ffs]) +else + JE_COMPILABLE([a program using ffsl], [ + #include + #include + #include + ], [ + { + int rv = ffsl(0x08); + printf("%d\n", rv); + } + ], [je_cv_function_ffsl]) + if test "x${je_cv_function_ffsl}" = "xyes" ; then + AC_DEFINE([JEMALLOC_INTERNAL_FFSL], [ffsl]) + AC_DEFINE([JEMALLOC_INTERNAL_FFS], [ffs]) + else + AC_MSG_ERROR([Cannot build without ffsl(3) or __builtin_ffsl()]) + fi +fi + +AC_ARG_WITH([lg_tiny_min], + [AS_HELP_STRING([--with-lg-tiny-min=], + [Base 2 log of minimum tiny size class to support])], + [LG_TINY_MIN="$with_lg_tiny_min"], + [LG_TINY_MIN="3"]) +AC_DEFINE_UNQUOTED([LG_TINY_MIN], [$LG_TINY_MIN]) + +AC_ARG_WITH([lg_quantum], + [AS_HELP_STRING([--with-lg-quantum=], + [Base 2 log of minimum allocation alignment])], + [LG_QUANTA="$with_lg_quantum"], + [LG_QUANTA="3 4"]) +if test "x$with_lg_quantum" != "x" ; then + AC_DEFINE_UNQUOTED([LG_QUANTUM], [$with_lg_quantum]) +fi + +AC_ARG_WITH([lg_page], + [AS_HELP_STRING([--with-lg-page=], [Base 2 log of system page size])], + [LG_PAGE="$with_lg_page"], [LG_PAGE="detect"]) +if test "x$LG_PAGE" = "xdetect"; then + AC_CACHE_CHECK([LG_PAGE], + [je_cv_lg_page], + AC_RUN_IFELSE([AC_LANG_PROGRAM( +[[ +#include +#ifdef _WIN32 +#include +#else +#include +#endif +#include +]], +[[ + int result; + FILE *f; + +#ifdef _WIN32 + SYSTEM_INFO si; + GetSystemInfo(&si); + result = si.dwPageSize; +#else + result = sysconf(_SC_PAGESIZE); +#endif + if (result == -1) { + return 1; + } + result = JEMALLOC_INTERNAL_FFSL(result) - 1; + + f = fopen("conftest.out", "w"); + if (f == NULL) { + return 1; + } + fprintf(f, "%d\n", result); + fclose(f); + + return 0; +]])], + [je_cv_lg_page=`cat conftest.out`], + [je_cv_lg_page=undefined], + [je_cv_lg_page=12])) +fi +if test "x${je_cv_lg_page}" != "x" ; then + LG_PAGE="${je_cv_lg_page}" +fi +if test "x${LG_PAGE}" != "xundefined" ; then + AC_DEFINE_UNQUOTED([LG_PAGE], [$LG_PAGE]) +else + AC_MSG_ERROR([cannot determine value for LG_PAGE]) +fi + +AC_ARG_WITH([lg_page_sizes], + [AS_HELP_STRING([--with-lg-page-sizes=], + [Base 2 logs of system page sizes to support])], + [LG_PAGE_SIZES="$with_lg_page_sizes"], [LG_PAGE_SIZES="$LG_PAGE"]) + +AC_ARG_WITH([lg_size_class_group], + [AS_HELP_STRING([--with-lg-size-class-group=], + [Base 2 log of size classes per doubling])], + [LG_SIZE_CLASS_GROUP="$with_lg_size_class_group"], + [LG_SIZE_CLASS_GROUP="2"]) + +dnl ============================================================================ +dnl jemalloc configuration. +dnl + +dnl Set VERSION if source directory is inside a git repository. +if test "x`test ! \"${srcroot}\" && cd \"${srcroot}\"; git rev-parse --is-inside-work-tree 2>/dev/null`" = "xtrue" ; then + dnl Pattern globs aren't powerful enough to match both single- and + dnl double-digit version numbers, so iterate over patterns to support up to + dnl version 99.99.99 without any accidental matches. + rm -f "${objroot}VERSION" + for pattern in ['[0-9].[0-9].[0-9]' '[0-9].[0-9].[0-9][0-9]' \ + '[0-9].[0-9][0-9].[0-9]' '[0-9].[0-9][0-9].[0-9][0-9]' \ + '[0-9][0-9].[0-9].[0-9]' '[0-9][0-9].[0-9].[0-9][0-9]' \ + '[0-9][0-9].[0-9][0-9].[0-9]' \ + '[0-9][0-9].[0-9][0-9].[0-9][0-9]']; do + if test ! -e "${objroot}VERSION" ; then + (test ! "${srcroot}" && cd "${srcroot}"; git describe --long --abbrev=40 --match="${pattern}") > "${objroot}VERSION.tmp" 2>/dev/null + if test $? -eq 0 ; then + mv "${objroot}VERSION.tmp" "${objroot}VERSION" + break + fi + fi + done +fi +rm -f "${objroot}VERSION.tmp" +if test ! -e "${objroot}VERSION" ; then + if test ! -e "${srcroot}VERSION" ; then + AC_MSG_RESULT( + [Missing VERSION file, and unable to generate it; creating bogus VERSION]) + echo "0.0.0-0-g0000000000000000000000000000000000000000" > "${objroot}VERSION" + else + cp ${srcroot}VERSION ${objroot}VERSION + fi +fi +jemalloc_version=`cat "${objroot}VERSION"` +jemalloc_version_major=`echo ${jemalloc_version} | tr ".g-" " " | awk '{print [$]1}'` +jemalloc_version_minor=`echo ${jemalloc_version} | tr ".g-" " " | awk '{print [$]2}'` +jemalloc_version_bugfix=`echo ${jemalloc_version} | tr ".g-" " " | awk '{print [$]3}'` +jemalloc_version_nrev=`echo ${jemalloc_version} | tr ".g-" " " | awk '{print [$]4}'` +jemalloc_version_gid=`echo ${jemalloc_version} | tr ".g-" " " | awk '{print [$]5}'` +AC_SUBST([jemalloc_version]) +AC_SUBST([jemalloc_version_major]) +AC_SUBST([jemalloc_version_minor]) +AC_SUBST([jemalloc_version_bugfix]) +AC_SUBST([jemalloc_version_nrev]) +AC_SUBST([jemalloc_version_gid]) + +dnl ============================================================================ +dnl Configure pthreads. + +if test "x$abi" != "xpecoff" ; then + AC_CHECK_HEADERS([pthread.h], , [AC_MSG_ERROR([pthread.h is missing])]) + dnl Some systems may embed pthreads functionality in libc; check for libpthread + dnl first, but try libc too before failing. + AC_CHECK_LIB([pthread], [pthread_create], [LIBS="$LIBS -lpthread"], + [AC_SEARCH_LIBS([pthread_create], , , + AC_MSG_ERROR([libpthread is missing]))]) +fi + +CPPFLAGS="$CPPFLAGS -D_REENTRANT" + +dnl Check whether clock_gettime(2) is in libc or librt. This function is only +dnl used in test code, so save the result to TESTLIBS to avoid poluting LIBS. +SAVED_LIBS="${LIBS}" +LIBS= +AC_SEARCH_LIBS([clock_gettime], [rt], [TESTLIBS="${LIBS}"]) +AC_SUBST([TESTLIBS]) +LIBS="${SAVED_LIBS}" + +dnl Check if the GNU-specific secure_getenv function exists. +AC_CHECK_FUNC([secure_getenv], + [have_secure_getenv="1"], + [have_secure_getenv="0"] + ) +if test "x$have_secure_getenv" = "x1" ; then + AC_DEFINE([JEMALLOC_HAVE_SECURE_GETENV], [ ]) +fi + +dnl Check if the Solaris/BSD issetugid function exists. +AC_CHECK_FUNC([issetugid], + [have_issetugid="1"], + [have_issetugid="0"] + ) +if test "x$have_issetugid" = "x1" ; then + AC_DEFINE([JEMALLOC_HAVE_ISSETUGID], [ ]) +fi + +dnl Check whether the BSD-specific _malloc_thread_cleanup() exists. If so, use +dnl it rather than pthreads TSD cleanup functions to support cleanup during +dnl thread exit, in order to avoid pthreads library recursion during +dnl bootstrapping. +AC_CHECK_FUNC([_malloc_thread_cleanup], + [have__malloc_thread_cleanup="1"], + [have__malloc_thread_cleanup="0"] + ) +if test "x$have__malloc_thread_cleanup" = "x1" ; then + AC_DEFINE([JEMALLOC_MALLOC_THREAD_CLEANUP], [ ]) + force_tls="1" +fi + +dnl Check whether the BSD-specific _pthread_mutex_init_calloc_cb() exists. If +dnl so, mutex initialization causes allocation, and we need to implement this +dnl callback function in order to prevent recursive allocation. +AC_CHECK_FUNC([_pthread_mutex_init_calloc_cb], + [have__pthread_mutex_init_calloc_cb="1"], + [have__pthread_mutex_init_calloc_cb="0"] + ) +if test "x$have__pthread_mutex_init_calloc_cb" = "x1" ; then + AC_DEFINE([JEMALLOC_MUTEX_INIT_CB]) +fi + +dnl Disable lazy locking by default. +AC_ARG_ENABLE([lazy_lock], + [AS_HELP_STRING([--enable-lazy-lock], + [Enable lazy locking (only lock when multi-threaded)])], +[if test "x$enable_lazy_lock" = "xno" ; then + enable_lazy_lock="0" +else + enable_lazy_lock="1" +fi +], +[enable_lazy_lock=""] +) +if test "x$enable_lazy_lock" = "x" -a "x${force_lazy_lock}" = "x1" ; then + AC_MSG_RESULT([Forcing lazy-lock to avoid allocator/threading bootstrap issues]) + enable_lazy_lock="1" +fi +if test "x$enable_lazy_lock" = "x1" ; then + if test "x$abi" != "xpecoff" ; then + AC_CHECK_HEADERS([dlfcn.h], , [AC_MSG_ERROR([dlfcn.h is missing])]) + AC_CHECK_FUNC([dlsym], [], + [AC_CHECK_LIB([dl], [dlsym], [LIBS="$LIBS -ldl"], + [AC_MSG_ERROR([libdl is missing])]) + ]) + fi + AC_DEFINE([JEMALLOC_LAZY_LOCK], [ ]) +else + enable_lazy_lock="0" +fi +AC_SUBST([enable_lazy_lock]) + +AC_ARG_ENABLE([tls], + [AS_HELP_STRING([--disable-tls], [Disable thread-local storage (__thread keyword)])], +if test "x$enable_tls" = "xno" ; then + enable_tls="0" +else + enable_tls="1" +fi +, +enable_tls="" +) +if test "x${enable_tls}" = "x" ; then + if test "x${force_tls}" = "x1" ; then + AC_MSG_RESULT([Forcing TLS to avoid allocator/threading bootstrap issues]) + enable_tls="1" + elif test "x${force_tls}" = "x0" ; then + AC_MSG_RESULT([Forcing no TLS to avoid allocator/threading bootstrap issues]) + enable_tls="0" + else + enable_tls="1" + fi +fi +if test "x${enable_tls}" = "x1" ; then +AC_MSG_CHECKING([for TLS]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM( +[[ + __thread int x; +]], [[ + x = 42; + + return 0; +]])], + AC_MSG_RESULT([yes]), + AC_MSG_RESULT([no]) + enable_tls="0") +else + enable_tls="0" +fi +AC_SUBST([enable_tls]) +if test "x${enable_tls}" = "x1" ; then + if test "x${force_tls}" = "x0" ; then + AC_MSG_WARN([TLS enabled despite being marked unusable on this platform]) + fi + AC_DEFINE_UNQUOTED([JEMALLOC_TLS], [ ]) +elif test "x${force_tls}" = "x1" ; then + AC_MSG_WARN([TLS disabled despite being marked critical on this platform]) +fi + +dnl ============================================================================ +dnl Check for C11 atomics. + +JE_COMPILABLE([C11 atomics], [ +#include +#if (__STDC_VERSION__ >= 201112L) && !defined(__STDC_NO_ATOMICS__) +#include +#else +#error Atomics not available +#endif +], [ + uint64_t *p = (uint64_t *)0; + uint64_t x = 1; + volatile atomic_uint_least64_t *a = (volatile atomic_uint_least64_t *)p; + uint64_t r = atomic_fetch_add(a, x) + x; + return (r == 0); +], [je_cv_c11atomics]) +if test "x${je_cv_c11atomics}" = "xyes" ; then + AC_DEFINE([JEMALLOC_C11ATOMICS]) +fi + +dnl ============================================================================ +dnl Check for atomic(9) operations as provided on FreeBSD. + +JE_COMPILABLE([atomic(9)], [ +#include +#include +#include +], [ + { + uint32_t x32 = 0; + volatile uint32_t *x32p = &x32; + atomic_fetchadd_32(x32p, 1); + } + { + unsigned long xlong = 0; + volatile unsigned long *xlongp = &xlong; + atomic_fetchadd_long(xlongp, 1); + } +], [je_cv_atomic9]) +if test "x${je_cv_atomic9}" = "xyes" ; then + AC_DEFINE([JEMALLOC_ATOMIC9]) +fi + +dnl ============================================================================ +dnl Check for atomic(3) operations as provided on Darwin. + +JE_COMPILABLE([Darwin OSAtomic*()], [ +#include +#include +], [ + { + int32_t x32 = 0; + volatile int32_t *x32p = &x32; + OSAtomicAdd32(1, x32p); + } + { + int64_t x64 = 0; + volatile int64_t *x64p = &x64; + OSAtomicAdd64(1, x64p); + } +], [je_cv_osatomic]) +if test "x${je_cv_osatomic}" = "xyes" ; then + AC_DEFINE([JEMALLOC_OSATOMIC], [ ]) +fi + +dnl ============================================================================ +dnl Check for madvise(2). + +JE_COMPILABLE([madvise(2)], [ +#include +], [ + { + madvise((void *)0, 0, 0); + } +], [je_cv_madvise]) +if test "x${je_cv_madvise}" = "xyes" ; then + AC_DEFINE([JEMALLOC_HAVE_MADVISE], [ ]) +fi + +dnl ============================================================================ +dnl Check whether __sync_{add,sub}_and_fetch() are available despite +dnl __GCC_HAVE_SYNC_COMPARE_AND_SWAP_n macros being undefined. + +AC_DEFUN([JE_SYNC_COMPARE_AND_SWAP_CHECK],[ + AC_CACHE_CHECK([whether to force $1-bit __sync_{add,sub}_and_fetch()], + [je_cv_sync_compare_and_swap_$2], + [AC_LINK_IFELSE([AC_LANG_PROGRAM([ + #include + ], + [ + #ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_$2 + { + uint$1_t x$1 = 0; + __sync_add_and_fetch(&x$1, 42); + __sync_sub_and_fetch(&x$1, 1); + } + #else + #error __GCC_HAVE_SYNC_COMPARE_AND_SWAP_$2 is defined, no need to force + #endif + ])], + [je_cv_sync_compare_and_swap_$2=yes], + [je_cv_sync_compare_and_swap_$2=no])]) + + if test "x${je_cv_sync_compare_and_swap_$2}" = "xyes" ; then + AC_DEFINE([JE_FORCE_SYNC_COMPARE_AND_SWAP_$2], [ ]) + fi +]) + +if test "x${je_cv_atomic9}" != "xyes" -a "x${je_cv_osatomic}" != "xyes" ; then + JE_SYNC_COMPARE_AND_SWAP_CHECK(32, 4) + JE_SYNC_COMPARE_AND_SWAP_CHECK(64, 8) +fi + +dnl ============================================================================ +dnl Check for __builtin_clz() and __builtin_clzl(). + +AC_CACHE_CHECK([for __builtin_clz], + [je_cv_builtin_clz], + [AC_LINK_IFELSE([AC_LANG_PROGRAM([], + [ + { + unsigned x = 0; + int y = __builtin_clz(x); + } + { + unsigned long x = 0; + int y = __builtin_clzl(x); + } + ])], + [je_cv_builtin_clz=yes], + [je_cv_builtin_clz=no])]) + +if test "x${je_cv_builtin_clz}" = "xyes" ; then + AC_DEFINE([JEMALLOC_HAVE_BUILTIN_CLZ], [ ]) +fi + +dnl ============================================================================ +dnl Check for spinlock(3) operations as provided on Darwin. + +JE_COMPILABLE([Darwin OSSpin*()], [ +#include +#include +], [ + OSSpinLock lock = 0; + OSSpinLockLock(&lock); + OSSpinLockUnlock(&lock); +], [je_cv_osspin]) +if test "x${je_cv_osspin}" = "xyes" ; then + AC_DEFINE([JEMALLOC_OSSPIN], [ ]) +fi + +dnl ============================================================================ +dnl Darwin-related configuration. + +AC_ARG_ENABLE([zone-allocator], + [AS_HELP_STRING([--disable-zone-allocator], + [Disable zone allocator for Darwin])], +[if test "x$enable_zone_allocator" = "xno" ; then + enable_zone_allocator="0" +else + enable_zone_allocator="1" +fi +], +[if test "x${abi}" = "xmacho"; then + enable_zone_allocator="1" +fi +] +) +AC_SUBST([enable_zone_allocator]) + +if test "x${enable_zone_allocator}" = "x1" ; then + if test "x${abi}" != "xmacho"; then + AC_MSG_ERROR([--enable-zone-allocator is only supported on Darwin]) + fi + AC_DEFINE([JEMALLOC_ZONE], [ ]) + + dnl The szone version jumped from 3 to 6 between the OS X 10.5.x and 10.6 + dnl releases. malloc_zone_t and malloc_introspection_t have new fields in + dnl 10.6, which is the only source-level indication of the change. + AC_MSG_CHECKING([malloc zone version]) + AC_DEFUN([JE_ZONE_PROGRAM], + [AC_LANG_PROGRAM( + [#include ], + [static int foo[[sizeof($1) $2 sizeof(void *) * $3 ? 1 : -1]]] + )]) + + AC_COMPILE_IFELSE([JE_ZONE_PROGRAM(malloc_zone_t,==,14)],[JEMALLOC_ZONE_VERSION=3],[ + AC_COMPILE_IFELSE([JE_ZONE_PROGRAM(malloc_zone_t,==,15)],[JEMALLOC_ZONE_VERSION=5],[ + AC_COMPILE_IFELSE([JE_ZONE_PROGRAM(malloc_zone_t,==,16)],[ + AC_COMPILE_IFELSE([JE_ZONE_PROGRAM(malloc_introspection_t,==,9)],[JEMALLOC_ZONE_VERSION=6],[ + AC_COMPILE_IFELSE([JE_ZONE_PROGRAM(malloc_introspection_t,==,13)],[JEMALLOC_ZONE_VERSION=7],[JEMALLOC_ZONE_VERSION=] + )])],[ + AC_COMPILE_IFELSE([JE_ZONE_PROGRAM(malloc_zone_t,==,17)],[JEMALLOC_ZONE_VERSION=8],[ + AC_COMPILE_IFELSE([JE_ZONE_PROGRAM(malloc_zone_t,>,17)],[JEMALLOC_ZONE_VERSION=9],[JEMALLOC_ZONE_VERSION=] + )])])])]) + if test "x${JEMALLOC_ZONE_VERSION}" = "x"; then + AC_MSG_RESULT([unsupported]) + AC_MSG_ERROR([Unsupported malloc zone version]) + fi + if test "${JEMALLOC_ZONE_VERSION}" = 9; then + JEMALLOC_ZONE_VERSION=8 + AC_MSG_RESULT([> 8]) + else + AC_MSG_RESULT([$JEMALLOC_ZONE_VERSION]) + fi + AC_DEFINE_UNQUOTED(JEMALLOC_ZONE_VERSION, [$JEMALLOC_ZONE_VERSION]) +fi + +dnl ============================================================================ +dnl Check for glibc malloc hooks + +JE_COMPILABLE([glibc malloc hook], [ +#include + +extern void (* __free_hook)(void *ptr); +extern void *(* __malloc_hook)(size_t size); +extern void *(* __realloc_hook)(void *ptr, size_t size); +], [ + void *ptr = 0L; + if (__malloc_hook) ptr = __malloc_hook(1); + if (__realloc_hook) ptr = __realloc_hook(ptr, 2); + if (__free_hook && ptr) __free_hook(ptr); +], [je_cv_glibc_malloc_hook]) +if test "x${je_cv_glibc_malloc_hook}" = "xyes" ; then + AC_DEFINE([JEMALLOC_GLIBC_MALLOC_HOOK], [ ]) +fi + +JE_COMPILABLE([glibc memalign hook], [ +#include + +extern void *(* __memalign_hook)(size_t alignment, size_t size); +], [ + void *ptr = 0L; + if (__memalign_hook) ptr = __memalign_hook(16, 7); +], [je_cv_glibc_memalign_hook]) +if test "x${je_cv_glibc_memalign_hook}" = "xyes" ; then + AC_DEFINE([JEMALLOC_GLIBC_MEMALIGN_HOOK], [ ]) +fi + +JE_COMPILABLE([pthreads adaptive mutexes], [ +#include +], [ + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP); + pthread_mutexattr_destroy(&attr); +], [je_cv_pthread_mutex_adaptive_np]) +if test "x${je_cv_pthread_mutex_adaptive_np}" = "xyes" ; then + AC_DEFINE([JEMALLOC_HAVE_PTHREAD_MUTEX_ADAPTIVE_NP], [ ]) +fi + +dnl ============================================================================ +dnl Check for typedefs, structures, and compiler characteristics. +AC_HEADER_STDBOOL + +dnl ============================================================================ +dnl Define commands that generate output files. + +AC_CONFIG_COMMANDS([include/jemalloc/internal/private_namespace.h], [ + mkdir -p "${objroot}include/jemalloc/internal" + "${srcdir}/include/jemalloc/internal/private_namespace.sh" "${srcdir}/include/jemalloc/internal/private_symbols.txt" > "${objroot}include/jemalloc/internal/private_namespace.h" +], [ + srcdir="${srcdir}" + objroot="${objroot}" +]) +AC_CONFIG_COMMANDS([include/jemalloc/internal/private_unnamespace.h], [ + mkdir -p "${objroot}include/jemalloc/internal" + "${srcdir}/include/jemalloc/internal/private_unnamespace.sh" "${srcdir}/include/jemalloc/internal/private_symbols.txt" > "${objroot}include/jemalloc/internal/private_unnamespace.h" +], [ + srcdir="${srcdir}" + objroot="${objroot}" +]) +AC_CONFIG_COMMANDS([include/jemalloc/internal/public_symbols.txt], [ + f="${objroot}include/jemalloc/internal/public_symbols.txt" + mkdir -p "${objroot}include/jemalloc/internal" + cp /dev/null "${f}" + for nm in `echo ${mangling_map} |tr ',' ' '` ; do + n=`echo ${nm} |tr ':' ' ' |awk '{print $[]1}'` + m=`echo ${nm} |tr ':' ' ' |awk '{print $[]2}'` + echo "${n}:${m}" >> "${f}" + dnl Remove name from public_syms so that it isn't redefined later. + public_syms=`for sym in ${public_syms}; do echo "${sym}"; done |grep -v "^${n}\$" |tr '\n' ' '` + done + for sym in ${public_syms} ; do + n="${sym}" + m="${JEMALLOC_PREFIX}${sym}" + echo "${n}:${m}" >> "${f}" + done +], [ + srcdir="${srcdir}" + objroot="${objroot}" + mangling_map="${mangling_map}" + public_syms="${public_syms}" + JEMALLOC_PREFIX="${JEMALLOC_PREFIX}" +]) +AC_CONFIG_COMMANDS([include/jemalloc/internal/public_namespace.h], [ + mkdir -p "${objroot}include/jemalloc/internal" + "${srcdir}/include/jemalloc/internal/public_namespace.sh" "${objroot}include/jemalloc/internal/public_symbols.txt" > "${objroot}include/jemalloc/internal/public_namespace.h" +], [ + srcdir="${srcdir}" + objroot="${objroot}" +]) +AC_CONFIG_COMMANDS([include/jemalloc/internal/public_unnamespace.h], [ + mkdir -p "${objroot}include/jemalloc/internal" + "${srcdir}/include/jemalloc/internal/public_unnamespace.sh" "${objroot}include/jemalloc/internal/public_symbols.txt" > "${objroot}include/jemalloc/internal/public_unnamespace.h" +], [ + srcdir="${srcdir}" + objroot="${objroot}" +]) +AC_CONFIG_COMMANDS([include/jemalloc/internal/size_classes.h], [ + mkdir -p "${objroot}include/jemalloc/internal" + "${SHELL}" "${srcdir}/include/jemalloc/internal/size_classes.sh" "${LG_QUANTA}" ${LG_TINY_MIN} "${LG_PAGE_SIZES}" ${LG_SIZE_CLASS_GROUP} > "${objroot}include/jemalloc/internal/size_classes.h" +], [ + SHELL="${SHELL}" + srcdir="${srcdir}" + objroot="${objroot}" + LG_QUANTA="${LG_QUANTA}" + LG_TINY_MIN=${LG_TINY_MIN} + LG_PAGE_SIZES="${LG_PAGE_SIZES}" + LG_SIZE_CLASS_GROUP=${LG_SIZE_CLASS_GROUP} +]) +AC_CONFIG_COMMANDS([include/jemalloc/jemalloc_protos_jet.h], [ + mkdir -p "${objroot}include/jemalloc" + cat "${srcdir}/include/jemalloc/jemalloc_protos.h.in" | sed -e 's/@je_@/jet_/g' > "${objroot}include/jemalloc/jemalloc_protos_jet.h" +], [ + srcdir="${srcdir}" + objroot="${objroot}" +]) +AC_CONFIG_COMMANDS([include/jemalloc/jemalloc_rename.h], [ + mkdir -p "${objroot}include/jemalloc" + "${srcdir}/include/jemalloc/jemalloc_rename.sh" "${objroot}include/jemalloc/internal/public_symbols.txt" > "${objroot}include/jemalloc/jemalloc_rename.h" +], [ + srcdir="${srcdir}" + objroot="${objroot}" +]) +AC_CONFIG_COMMANDS([include/jemalloc/jemalloc_mangle.h], [ + mkdir -p "${objroot}include/jemalloc" + "${srcdir}/include/jemalloc/jemalloc_mangle.sh" "${objroot}include/jemalloc/internal/public_symbols.txt" je_ > "${objroot}include/jemalloc/jemalloc_mangle.h" +], [ + srcdir="${srcdir}" + objroot="${objroot}" +]) +AC_CONFIG_COMMANDS([include/jemalloc/jemalloc_mangle_jet.h], [ + mkdir -p "${objroot}include/jemalloc" + "${srcdir}/include/jemalloc/jemalloc_mangle.sh" "${objroot}include/jemalloc/internal/public_symbols.txt" jet_ > "${objroot}include/jemalloc/jemalloc_mangle_jet.h" +], [ + srcdir="${srcdir}" + objroot="${objroot}" +]) +AC_CONFIG_COMMANDS([include/jemalloc/jemalloc.h], [ + mkdir -p "${objroot}include/jemalloc" + "${srcdir}/include/jemalloc/jemalloc.sh" "${objroot}" > "${objroot}include/jemalloc/jemalloc${install_suffix}.h" +], [ + srcdir="${srcdir}" + objroot="${objroot}" + install_suffix="${install_suffix}" +]) + +dnl Process .in files. +AC_SUBST([cfghdrs_in]) +AC_SUBST([cfghdrs_out]) +AC_CONFIG_HEADERS([$cfghdrs_tup]) + +dnl ============================================================================ +dnl Generate outputs. + +AC_CONFIG_FILES([$cfgoutputs_tup config.stamp bin/jemalloc-config bin/jemalloc.sh bin/jeprof]) +AC_SUBST([cfgoutputs_in]) +AC_SUBST([cfgoutputs_out]) +AC_OUTPUT + +dnl ============================================================================ +dnl Print out the results of configuration. +AC_MSG_RESULT([===============================================================================]) +AC_MSG_RESULT([jemalloc version : ${jemalloc_version}]) +AC_MSG_RESULT([library revision : ${rev}]) +AC_MSG_RESULT([]) +AC_MSG_RESULT([CONFIG : ${CONFIG}]) +AC_MSG_RESULT([CC : ${CC}]) +AC_MSG_RESULT([CFLAGS : ${CFLAGS}]) +AC_MSG_RESULT([CPPFLAGS : ${CPPFLAGS}]) +AC_MSG_RESULT([LDFLAGS : ${LDFLAGS}]) +AC_MSG_RESULT([EXTRA_LDFLAGS : ${EXTRA_LDFLAGS}]) +AC_MSG_RESULT([LIBS : ${LIBS}]) +AC_MSG_RESULT([TESTLIBS : ${TESTLIBS}]) +AC_MSG_RESULT([RPATH_EXTRA : ${RPATH_EXTRA}]) +AC_MSG_RESULT([]) +AC_MSG_RESULT([XSLTPROC : ${XSLTPROC}]) +AC_MSG_RESULT([XSLROOT : ${XSLROOT}]) +AC_MSG_RESULT([]) +AC_MSG_RESULT([PREFIX : ${PREFIX}]) +AC_MSG_RESULT([BINDIR : ${BINDIR}]) +AC_MSG_RESULT([DATADIR : ${DATADIR}]) +AC_MSG_RESULT([INCLUDEDIR : ${INCLUDEDIR}]) +AC_MSG_RESULT([LIBDIR : ${LIBDIR}]) +AC_MSG_RESULT([MANDIR : ${MANDIR}]) +AC_MSG_RESULT([]) +AC_MSG_RESULT([srcroot : ${srcroot}]) +AC_MSG_RESULT([abs_srcroot : ${abs_srcroot}]) +AC_MSG_RESULT([objroot : ${objroot}]) +AC_MSG_RESULT([abs_objroot : ${abs_objroot}]) +AC_MSG_RESULT([]) +AC_MSG_RESULT([JEMALLOC_PREFIX : ${JEMALLOC_PREFIX}]) +AC_MSG_RESULT([JEMALLOC_PRIVATE_NAMESPACE]) +AC_MSG_RESULT([ : ${JEMALLOC_PRIVATE_NAMESPACE}]) +AC_MSG_RESULT([install_suffix : ${install_suffix}]) +AC_MSG_RESULT([autogen : ${enable_autogen}]) +AC_MSG_RESULT([cc-silence : ${enable_cc_silence}]) +AC_MSG_RESULT([debug : ${enable_debug}]) +AC_MSG_RESULT([code-coverage : ${enable_code_coverage}]) +AC_MSG_RESULT([stats : ${enable_stats}]) +AC_MSG_RESULT([prof : ${enable_prof}]) +AC_MSG_RESULT([prof-libunwind : ${enable_prof_libunwind}]) +AC_MSG_RESULT([prof-libgcc : ${enable_prof_libgcc}]) +AC_MSG_RESULT([prof-gcc : ${enable_prof_gcc}]) +AC_MSG_RESULT([tcache : ${enable_tcache}]) +AC_MSG_RESULT([fill : ${enable_fill}]) +AC_MSG_RESULT([utrace : ${enable_utrace}]) +AC_MSG_RESULT([valgrind : ${enable_valgrind}]) +AC_MSG_RESULT([xmalloc : ${enable_xmalloc}]) +AC_MSG_RESULT([munmap : ${enable_munmap}]) +AC_MSG_RESULT([lazy_lock : ${enable_lazy_lock}]) +AC_MSG_RESULT([tls : ${enable_tls}]) +AC_MSG_RESULT([cache-oblivious : ${enable_cache_oblivious}]) +AC_MSG_RESULT([===============================================================================]) diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/coverage.sh b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/coverage.sh new file mode 100755 index 0000000..6d1362a --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/coverage.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +set -e + +objdir=$1 +suffix=$2 +shift 2 +objs=$@ + +gcov -b -p -f -o "${objdir}" ${objs} + +# Move gcov outputs so that subsequent gcov invocations won't clobber results +# for the same sources with different compilation flags. +for f in `find . -maxdepth 1 -type f -name '*.gcov'` ; do + mv "${f}" "${f}.${suffix}" +done diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/doc/html.xsl.in b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/doc/html.xsl.in new file mode 100644 index 0000000..a91d974 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/doc/html.xsl.in @@ -0,0 +1,4 @@ + + + + diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/doc/jemalloc.xml.in b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/doc/jemalloc.xml.in new file mode 100644 index 0000000..8fc774b --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/doc/jemalloc.xml.in @@ -0,0 +1,2762 @@ + + + + + + + User Manual + jemalloc + @jemalloc_version@ + + + Jason + Evans + Author + + + + + JEMALLOC + 3 + + + jemalloc + jemalloc + + general purpose memory allocation functions + + + LIBRARY + This manual describes jemalloc @jemalloc_version@. More information + can be found at the jemalloc website. + + + SYNOPSIS + + #include <jemalloc/jemalloc.h> + + Standard API + + void *malloc + size_t size + + + void *calloc + size_t number + size_t size + + + int posix_memalign + void **ptr + size_t alignment + size_t size + + + void *aligned_alloc + size_t alignment + size_t size + + + void *realloc + void *ptr + size_t size + + + void free + void *ptr + + + + Non-standard API + + void *mallocx + size_t size + int flags + + + void *rallocx + void *ptr + size_t size + int flags + + + size_t xallocx + void *ptr + size_t size + size_t extra + int flags + + + size_t sallocx + void *ptr + int flags + + + void dallocx + void *ptr + int flags + + + void sdallocx + void *ptr + size_t size + int flags + + + size_t nallocx + size_t size + int flags + + + int mallctl + const char *name + void *oldp + size_t *oldlenp + void *newp + size_t newlen + + + int mallctlnametomib + const char *name + size_t *mibp + size_t *miblenp + + + int mallctlbymib + const size_t *mib + size_t miblen + void *oldp + size_t *oldlenp + void *newp + size_t newlen + + + void malloc_stats_print + void (*write_cb) + void *, const char * + + void *cbopaque + const char *opts + + + size_t malloc_usable_size + const void *ptr + + + void (*malloc_message) + void *cbopaque + const char *s + + const char *malloc_conf; + + + + + DESCRIPTION + + Standard API + + The malloc function allocates + size bytes of uninitialized memory. The allocated + space is suitably aligned (after possible pointer coercion) for storage + of any type of object. + + The calloc function allocates + space for number objects, each + size bytes in length. The result is identical to + calling malloc with an argument of + number * size, with the + exception that the allocated memory is explicitly initialized to zero + bytes. + + The posix_memalign function + allocates size bytes of memory such that the + allocation's base address is a multiple of + alignment, and returns the allocation in the value + pointed to by ptr. The requested + alignment must be a power of 2 at least as large as + sizeof(void *). + + The aligned_alloc function + allocates size bytes of memory such that the + allocation's base address is a multiple of + alignment. The requested + alignment must be a power of 2. Behavior is + undefined if size is not an integral multiple of + alignment. + + The realloc function changes the + size of the previously allocated memory referenced by + ptr to size bytes. The + contents of the memory are unchanged up to the lesser of the new and old + sizes. If the new size is larger, the contents of the newly allocated + portion of the memory are undefined. Upon success, the memory referenced + by ptr is freed and a pointer to the newly + allocated memory is returned. Note that + realloc may move the memory allocation, + resulting in a different return value than ptr. + If ptr is NULL, the + realloc function behaves identically to + malloc for the specified size. + + The free function causes the + allocated memory referenced by ptr to be made + available for future allocations. If ptr is + NULL, no action occurs. + + + Non-standard API + The mallocx, + rallocx, + xallocx, + sallocx, + dallocx, + sdallocx, and + nallocx functions all have a + flags argument that can be used to specify + options. The functions only check the options that are contextually + relevant. Use bitwise or (|) operations to + specify one or more of the following: + + + MALLOCX_LG_ALIGN(la) + + + Align the memory allocation to start at an address + that is a multiple of (1 << + la). This macro does not validate + that la is within the valid + range. + + + MALLOCX_ALIGN(a) + + + Align the memory allocation to start at an address + that is a multiple of a, where + a is a power of two. This macro does not + validate that a is a power of 2. + + + + MALLOCX_ZERO + + Initialize newly allocated memory to contain zero + bytes. In the growing reallocation case, the real size prior to + reallocation defines the boundary between untouched bytes and those + that are initialized to contain zero bytes. If this macro is + absent, newly allocated memory is uninitialized. + + + MALLOCX_TCACHE(tc) + + + Use the thread-specific cache (tcache) specified by + the identifier tc, which must have been + acquired via the tcache.create + mallctl. This macro does not validate that + tc specifies a valid + identifier. + + + MALLOCX_TCACHE_NONE + + Do not use a thread-specific cache (tcache). Unless + MALLOCX_TCACHE(tc) or + MALLOCX_TCACHE_NONE is specified, an + automatically managed tcache will be used under many circumstances. + This macro cannot be used in the same flags + argument as + MALLOCX_TCACHE(tc). + + + MALLOCX_ARENA(a) + + + Use the arena specified by the index + a. This macro has no effect for regions that + were allocated via an arena other than the one specified. This + macro does not validate that a specifies an + arena index in the valid range. + + + + + The mallocx function allocates at + least size bytes of memory, and returns a pointer + to the base address of the allocation. Behavior is undefined if + size is 0, or if request size + overflows due to size class and/or alignment constraints. + + The rallocx function resizes the + allocation at ptr to be at least + size bytes, and returns a pointer to the base + address of the resulting allocation, which may or may not have moved from + its original location. Behavior is undefined if + size is 0, or if request size + overflows due to size class and/or alignment constraints. + + The xallocx function resizes the + allocation at ptr in place to be at least + size bytes, and returns the real size of the + allocation. If extra is non-zero, an attempt is + made to resize the allocation to be at least (size + + extra) bytes, though inability to allocate + the extra byte(s) will not by itself result in failure to resize. + Behavior is undefined if size is + 0, or if (size + extra + > SIZE_T_MAX). + + The sallocx function returns the + real size of the allocation at ptr. + + The dallocx function causes the + memory referenced by ptr to be made available for + future allocations. + + The sdallocx function is an + extension of dallocx with a + size parameter to allow the caller to pass in the + allocation size as an optimization. The minimum valid input size is the + original requested size of the allocation, and the maximum valid input + size is the corresponding value returned by + nallocx or + sallocx. + + The nallocx function allocates no + memory, but it performs the same size computation as the + mallocx function, and returns the real + size of the allocation that would result from the equivalent + mallocx function call. Behavior is + undefined if size is 0, or if + request size overflows due to size class and/or alignment + constraints. + + The mallctl function provides a + general interface for introspecting the memory allocator, as well as + setting modifiable parameters and triggering actions. The + period-separated name argument specifies a + location in a tree-structured namespace; see the section for + documentation on the tree contents. To read a value, pass a pointer via + oldp to adequate space to contain the value, and a + pointer to its length via oldlenp; otherwise pass + NULL and NULL. Similarly, to + write a value, pass a pointer to the value via + newp, and its length via + newlen; otherwise pass NULL + and 0. + + The mallctlnametomib function + provides a way to avoid repeated name lookups for applications that + repeatedly query the same portion of the namespace, by translating a name + to a “Management Information Base” (MIB) that can be passed + repeatedly to mallctlbymib. Upon + successful return from mallctlnametomib, + mibp contains an array of + *miblenp integers, where + *miblenp is the lesser of the number of components + in name and the input value of + *miblenp. Thus it is possible to pass a + *miblenp that is smaller than the number of + period-separated name components, which results in a partial MIB that can + be used as the basis for constructing a complete MIB. For name + components that are integers (e.g. the 2 in + arenas.bin.2.size), + the corresponding MIB component will always be that integer. Therefore, + it is legitimate to construct code like the following: + + The malloc_stats_print function + writes human-readable summary statistics via the + write_cb callback function pointer and + cbopaque data passed to + write_cb, or + malloc_message if + write_cb is NULL. This + function can be called repeatedly. General information that never + changes during execution can be omitted by specifying "g" as a character + within the opts string. Note that + malloc_message uses the + mallctl* functions internally, so + inconsistent statistics can be reported if multiple threads use these + functions simultaneously. If is + specified during configuration, “m” and “a” can + be specified to omit merged arena and per arena statistics, respectively; + “b”, “l”, and “h” can be specified to + omit per size class statistics for bins, large objects, and huge objects, + respectively. Unrecognized characters are silently ignored. Note that + thread caching may prevent some statistics from being completely up to + date, since extra locking would be required to merge counters that track + thread cache operations. + + + The malloc_usable_size function + returns the usable size of the allocation pointed to by + ptr. The return value may be larger than the size + that was requested during allocation. The + malloc_usable_size function is not a + mechanism for in-place realloc; rather + it is provided solely as a tool for introspection purposes. Any + discrepancy between the requested allocation size and the size reported + by malloc_usable_size should not be + depended on, since such behavior is entirely implementation-dependent. + + + + + TUNING + Once, when the first call is made to one of the memory allocation + routines, the allocator initializes its internals based in part on various + options that can be specified at compile- or run-time. + + The string pointed to by the global variable + malloc_conf, the “name” of the file + referenced by the symbolic link named /etc/malloc.conf, and the value of the + environment variable MALLOC_CONF, will be interpreted, in + that order, from left to right as options. Note that + malloc_conf may be read before + main is entered, so the declaration of + malloc_conf should specify an initializer that contains + the final value to be read by jemalloc. malloc_conf is + a compile-time setting, whereas /etc/malloc.conf and MALLOC_CONF + can be safely set any time prior to program invocation. + + An options string is a comma-separated list of option:value pairs. + There is one key corresponding to each opt.* mallctl (see the section for options + documentation). For example, abort:true,narenas:1 sets + the opt.abort and opt.narenas options. Some + options have boolean values (true/false), others have integer values (base + 8, 10, or 16, depending on prefix), and yet others have raw string + values. + + + IMPLEMENTATION NOTES + Traditionally, allocators have used + sbrk + 2 to obtain memory, which is + suboptimal for several reasons, including race conditions, increased + fragmentation, and artificial limitations on maximum usable memory. If + sbrk + 2 is supported by the operating + system, this allocator uses both + mmap + 2 and + sbrk + 2, in that order of preference; + otherwise only mmap + 2 is used. + + This allocator uses multiple arenas in order to reduce lock + contention for threaded programs on multi-processor systems. This works + well with regard to threading scalability, but incurs some costs. There is + a small fixed per-arena overhead, and additionally, arenas manage memory + completely independently of each other, which means a small fixed increase + in overall memory fragmentation. These overheads are not generally an + issue, given the number of arenas normally used. Note that using + substantially more arenas than the default is not likely to improve + performance, mainly due to reduced cache performance. However, it may make + sense to reduce the number of arenas if an application does not make much + use of the allocation functions. + + In addition to multiple arenas, unless + is specified during configuration, this + allocator supports thread-specific caching for small and large objects, in + order to make it possible to completely avoid synchronization for most + allocation requests. Such caching allows very fast allocation in the + common case, but it increases memory usage and fragmentation, since a + bounded number of objects can remain allocated in each thread cache. + + Memory is conceptually broken into equal-sized chunks, where the + chunk size is a power of two that is greater than the page size. Chunks + are always aligned to multiples of the chunk size. This alignment makes it + possible to find metadata for user objects very quickly. + + User objects are broken into three categories according to size: + small, large, and huge. Small and large objects are managed entirely by + arenas; huge objects are additionally aggregated in a single data structure + that is shared by all threads. Huge objects are typically used by + applications infrequently enough that this single data structure is not a + scalability issue. + + Each chunk that is managed by an arena tracks its contents as runs of + contiguous pages (unused, backing a set of small objects, or backing one + large object). The combination of chunk alignment and chunk page maps + makes it possible to determine all metadata regarding small and large + allocations in constant time. + + Small objects are managed in groups by page runs. Each run maintains + a bitmap to track which regions are in use. Allocation requests that are no + more than half the quantum (8 or 16, depending on architecture) are rounded + up to the nearest power of two that is at least sizeof(double). All other object size + classes are multiples of the quantum, spaced such that there are four size + classes for each doubling in size, which limits internal fragmentation to + approximately 20% for all but the smallest size classes. Small size classes + are smaller than four times the page size, large size classes are smaller + than the chunk size (see the opt.lg_chunk option), and + huge size classes extend from the chunk size up to one size class less than + the full address space size. + + Allocations are packed tightly together, which can be an issue for + multi-threaded applications. If you need to assure that allocations do not + suffer from cacheline sharing, round your allocation requests up to the + nearest multiple of the cacheline size, or specify cacheline alignment when + allocating. + + The realloc, + rallocx, and + xallocx functions may resize allocations + without moving them under limited circumstances. Unlike the + *allocx API, the standard API does not + officially round up the usable size of an allocation to the nearest size + class, so technically it is necessary to call + realloc to grow e.g. a 9-byte allocation to + 16 bytes, or shrink a 16-byte allocation to 9 bytes. Growth and shrinkage + trivially succeeds in place as long as the pre-size and post-size both round + up to the same size class. No other API guarantees are made regarding + in-place resizing, but the current implementation also tries to resize large + and huge allocations in place, as long as the pre-size and post-size are + both large or both huge. In such cases shrinkage always succeeds for large + size classes, but for huge size classes the chunk allocator must support + splitting (see arena.<i>.chunk_hooks). + Growth only succeeds if the trailing memory is currently available, and + additionally for huge size classes the chunk allocator must support + merging. + + Assuming 2 MiB chunks, 4 KiB pages, and a 16-byte quantum on a + 64-bit system, the size classes in each category are as shown in . + + + Size classes + + + + + + + Category + Spacing + Size + + + + + Small + lg + [8] + + + 16 + [16, 32, 48, 64, 80, 96, 112, 128] + + + 32 + [160, 192, 224, 256] + + + 64 + [320, 384, 448, 512] + + + 128 + [640, 768, 896, 1024] + + + 256 + [1280, 1536, 1792, 2048] + + + 512 + [2560, 3072, 3584, 4096] + + + 1 KiB + [5 KiB, 6 KiB, 7 KiB, 8 KiB] + + + 2 KiB + [10 KiB, 12 KiB, 14 KiB] + + + Large + 2 KiB + [16 KiB] + + + 4 KiB + [20 KiB, 24 KiB, 28 KiB, 32 KiB] + + + 8 KiB + [40 KiB, 48 KiB, 54 KiB, 64 KiB] + + + 16 KiB + [80 KiB, 96 KiB, 112 KiB, 128 KiB] + + + 32 KiB + [160 KiB, 192 KiB, 224 KiB, 256 KiB] + + + 64 KiB + [320 KiB, 384 KiB, 448 KiB, 512 KiB] + + + 128 KiB + [640 KiB, 768 KiB, 896 KiB, 1 MiB] + + + 256 KiB + [1280 KiB, 1536 KiB, 1792 KiB] + + + Huge + 256 KiB + [2 MiB] + + + 512 KiB + [2560 KiB, 3 MiB, 3584 KiB, 4 MiB] + + + 1 MiB + [5 MiB, 6 MiB, 7 MiB, 8 MiB] + + + 2 MiB + [10 MiB, 12 MiB, 14 MiB, 16 MiB] + + + 4 MiB + [20 MiB, 24 MiB, 28 MiB, 32 MiB] + + + 8 MiB + [40 MiB, 48 MiB, 56 MiB, 64 MiB] + + + ... + ... + + + +
+
+ + MALLCTL NAMESPACE + The following names are defined in the namespace accessible via the + mallctl* functions. Value types are + specified in parentheses, their readable/writable statuses are encoded as + rw, r-, -w, or + --, and required build configuration flags follow, if + any. A name element encoded as <i> or + <j> indicates an integer component, where the + integer varies from 0 to some upper value that must be determined via + introspection. In the case of stats.arenas.<i>.*, + <i> equal to arenas.narenas can be + used to access the summation of statistics from all arenas. Take special + note of the epoch mallctl, + which controls refreshing of cached dynamic statistics. + + + + + version + (const char *) + r- + + Return the jemalloc version string. + + + + + epoch + (uint64_t) + rw + + If a value is passed in, refresh the data from which + the mallctl* functions report values, + and increment the epoch. Return the current epoch. This is useful for + detecting whether another thread caused a refresh. + + + + + config.cache_oblivious + (bool) + r- + + was specified + during build configuration. + + + + + config.debug + (bool) + r- + + was specified during + build configuration. + + + + + config.fill + (bool) + r- + + was specified during + build configuration. + + + + + config.lazy_lock + (bool) + r- + + was specified + during build configuration. + + + + + config.munmap + (bool) + r- + + was specified during + build configuration. + + + + + config.prof + (bool) + r- + + was specified during + build configuration. + + + + + config.prof_libgcc + (bool) + r- + + was not + specified during build configuration. + + + + + config.prof_libunwind + (bool) + r- + + was specified + during build configuration. + + + + + config.stats + (bool) + r- + + was specified during + build configuration. + + + + + config.tcache + (bool) + r- + + was not specified + during build configuration. + + + + + config.tls + (bool) + r- + + was not specified during + build configuration. + + + + + config.utrace + (bool) + r- + + was specified during + build configuration. + + + + + config.valgrind + (bool) + r- + + was specified during + build configuration. + + + + + config.xmalloc + (bool) + r- + + was specified during + build configuration. + + + + + opt.abort + (bool) + r- + + Abort-on-warning enabled/disabled. If true, most + warnings are fatal. The process will call + abort + 3 in these cases. This option is + disabled by default unless is + specified during configuration, in which case it is enabled by default. + + + + + + opt.dss + (const char *) + r- + + dss (sbrk + 2) allocation precedence as + related to mmap + 2 allocation. The following + settings are supported if + sbrk + 2 is supported by the operating + system: “disabled”, “primary”, and + “secondary”; otherwise only “disabled” is + supported. The default is “secondary” if + sbrk + 2 is supported by the operating + system; “disabled” otherwise. + + + + + + opt.lg_chunk + (size_t) + r- + + Virtual memory chunk size (log base 2). If a chunk + size outside the supported size range is specified, the size is + silently clipped to the minimum/maximum supported size. The default + chunk size is 2 MiB (2^21). + + + + + + opt.narenas + (size_t) + r- + + Maximum number of arenas to use for automatic + multiplexing of threads and arenas. The default is four times the + number of CPUs, or one if there is a single CPU. + + + + + opt.lg_dirty_mult + (ssize_t) + r- + + Per-arena minimum ratio (log base 2) of active to dirty + pages. Some dirty unused pages may be allowed to accumulate, within + the limit set by the ratio (or one chunk worth of dirty pages, + whichever is greater), before informing the kernel about some of those + pages via madvise + 2 or a similar system call. This + provides the kernel with sufficient information to recycle dirty pages + if physical memory becomes scarce and the pages remain unused. The + default minimum ratio is 8:1 (2^3:1); an option value of -1 will + disable dirty page purging. See arenas.lg_dirty_mult + and arena.<i>.lg_dirty_mult + for related dynamic control options. + + + + + opt.stats_print + (bool) + r- + + Enable/disable statistics printing at exit. If + enabled, the malloc_stats_print + function is called at program exit via an + atexit + 3 function. If + is specified during configuration, this + has the potential to cause deadlock for a multi-threaded process that + exits while one or more threads are executing in the memory allocation + functions. Furthermore, atexit may + allocate memory during application initialization and then deadlock + internally when jemalloc in turn calls + atexit, so this option is not + univerally usable (though the application can register its own + atexit function with equivalent + functionality). Therefore, this option should only be used with care; + it is primarily intended as a performance tuning aid during application + development. This option is disabled by default. + + + + + opt.junk + (const char *) + r- + [] + + Junk filling. If set to "alloc", each byte of + uninitialized allocated memory will be initialized to + 0xa5. If set to "free", all deallocated memory will + be initialized to 0x5a. If set to "true", both + allocated and deallocated memory will be initialized, and if set to + "false", junk filling be disabled entirely. This is intended for + debugging and will impact performance negatively. This option is + "false" by default unless is specified + during configuration, in which case it is "true" by default unless + running inside Valgrind. + + + + + opt.quarantine + (size_t) + r- + [] + + Per thread quarantine size in bytes. If non-zero, each + thread maintains a FIFO object quarantine that stores up to the + specified number of bytes of memory. The quarantined memory is not + freed until it is released from quarantine, though it is immediately + junk-filled if the opt.junk option is + enabled. This feature is of particular use in combination with Valgrind, which can detect attempts + to access quarantined objects. This is intended for debugging and will + impact performance negatively. The default quarantine size is 0 unless + running inside Valgrind, in which case the default is 16 + MiB. + + + + + opt.redzone + (bool) + r- + [] + + Redzones enabled/disabled. If enabled, small + allocations have redzones before and after them. Furthermore, if the + opt.junk option is + enabled, the redzones are checked for corruption during deallocation. + However, the primary intended purpose of this feature is to be used in + combination with Valgrind, + which needs redzones in order to do effective buffer overflow/underflow + detection. This option is intended for debugging and will impact + performance negatively. This option is disabled by + default unless running inside Valgrind. + + + + + opt.zero + (bool) + r- + [] + + Zero filling enabled/disabled. If enabled, each byte + of uninitialized allocated memory will be initialized to 0. Note that + this initialization only happens once for each byte, so + realloc and + rallocx calls do not zero memory that + was previously allocated. This is intended for debugging and will + impact performance negatively. This option is disabled by default. + + + + + + opt.utrace + (bool) + r- + [] + + Allocation tracing based on + utrace + 2 enabled/disabled. This option + is disabled by default. + + + + + opt.xmalloc + (bool) + r- + [] + + Abort-on-out-of-memory enabled/disabled. If enabled, + rather than returning failure for any allocation function, display a + diagnostic message on STDERR_FILENO and cause the + program to drop core (using + abort + 3). If an application is + designed to depend on this behavior, set the option at compile time by + including the following in the source code: + + This option is disabled by default. + + + + + opt.tcache + (bool) + r- + [] + + Thread-specific caching (tcache) enabled/disabled. When + there are multiple threads, each thread uses a tcache for objects up to + a certain size. Thread-specific caching allows many allocations to be + satisfied without performing any thread synchronization, at the cost of + increased memory use. See the opt.lg_tcache_max + option for related tuning information. This option is enabled by + default unless running inside Valgrind, in which case it is + forcefully disabled. + + + + + opt.lg_tcache_max + (size_t) + r- + [] + + Maximum size class (log base 2) to cache in the + thread-specific cache (tcache). At a minimum, all small size classes + are cached, and at a maximum all large size classes are cached. The + default maximum is 32 KiB (2^15). + + + + + opt.prof + (bool) + r- + [] + + Memory profiling enabled/disabled. If enabled, profile + memory allocation activity. See the opt.prof_active + option for on-the-fly activation/deactivation. See the opt.lg_prof_sample + option for probabilistic sampling control. See the opt.prof_accum + option for control of cumulative sample reporting. See the opt.lg_prof_interval + option for information on interval-triggered profile dumping, the opt.prof_gdump + option for information on high-water-triggered profile dumping, and the + opt.prof_final + option for final profile dumping. Profile output is compatible with + the jeprof command, which is based on the + pprof that is developed as part of the gperftools + package. + + + + + opt.prof_prefix + (const char *) + r- + [] + + Filename prefix for profile dumps. If the prefix is + set to the empty string, no automatic dumps will occur; this is + primarily useful for disabling the automatic final heap dump (which + also disables leak reporting, if enabled). The default prefix is + jeprof. + + + + + opt.prof_active + (bool) + r- + [] + + Profiling activated/deactivated. This is a secondary + control mechanism that makes it possible to start the application with + profiling enabled (see the opt.prof option) but + inactive, then toggle profiling at any time during program execution + with the prof.active mallctl. + This option is enabled by default. + + + + + opt.prof_thread_active_init + (bool) + r- + [] + + Initial setting for thread.prof.active + in newly created threads. The initial setting for newly created threads + can also be changed during execution via the prof.thread_active_init + mallctl. This option is enabled by default. + + + + + opt.lg_prof_sample + (size_t) + r- + [] + + Average interval (log base 2) between allocation + samples, as measured in bytes of allocation activity. Increasing the + sampling interval decreases profile fidelity, but also decreases the + computational overhead. The default sample interval is 512 KiB (2^19 + B). + + + + + opt.prof_accum + (bool) + r- + [] + + Reporting of cumulative object/byte counts in profile + dumps enabled/disabled. If this option is enabled, every unique + backtrace must be stored for the duration of execution. Depending on + the application, this can impose a large memory overhead, and the + cumulative counts are not always of interest. This option is disabled + by default. + + + + + opt.lg_prof_interval + (ssize_t) + r- + [] + + Average interval (log base 2) between memory profile + dumps, as measured in bytes of allocation activity. The actual + interval between dumps may be sporadic because decentralized allocation + counters are used to avoid synchronization bottlenecks. Profiles are + dumped to files named according to the pattern + <prefix>.<pid>.<seq>.i<iseq>.heap, + where <prefix> is controlled by the + opt.prof_prefix + option. By default, interval-triggered profile dumping is disabled + (encoded as -1). + + + + + + opt.prof_gdump + (bool) + r- + [] + + Set the initial state of prof.gdump, which when + enabled triggers a memory profile dump every time the total virtual + memory exceeds the previous maximum. This option is disabled by + default. + + + + + opt.prof_final + (bool) + r- + [] + + Use an + atexit + 3 function to dump final memory + usage to a file named according to the pattern + <prefix>.<pid>.<seq>.f.heap, + where <prefix> is controlled by the opt.prof_prefix + option. Note that atexit may allocate + memory during application initialization and then deadlock internally + when jemalloc in turn calls atexit, so + this option is not univerally usable (though the application can + register its own atexit function with + equivalent functionality). This option is disabled by + default. + + + + + opt.prof_leak + (bool) + r- + [] + + Leak reporting enabled/disabled. If enabled, use an + atexit + 3 function to report memory leaks + detected by allocation sampling. See the + opt.prof option for + information on analyzing heap profile output. This option is disabled + by default. + + + + + thread.arena + (unsigned) + rw + + Get or set the arena associated with the calling + thread. If the specified arena was not initialized beforehand (see the + arenas.initialized + mallctl), it will be automatically initialized as a side effect of + calling this interface. + + + + + thread.allocated + (uint64_t) + r- + [] + + Get the total number of bytes ever allocated by the + calling thread. This counter has the potential to wrap around; it is + up to the application to appropriately interpret the counter in such + cases. + + + + + thread.allocatedp + (uint64_t *) + r- + [] + + Get a pointer to the the value that is returned by the + thread.allocated + mallctl. This is useful for avoiding the overhead of repeated + mallctl* calls. + + + + + thread.deallocated + (uint64_t) + r- + [] + + Get the total number of bytes ever deallocated by the + calling thread. This counter has the potential to wrap around; it is + up to the application to appropriately interpret the counter in such + cases. + + + + + thread.deallocatedp + (uint64_t *) + r- + [] + + Get a pointer to the the value that is returned by the + thread.deallocated + mallctl. This is useful for avoiding the overhead of repeated + mallctl* calls. + + + + + thread.tcache.enabled + (bool) + rw + [] + + Enable/disable calling thread's tcache. The tcache is + implicitly flushed as a side effect of becoming + disabled (see thread.tcache.flush). + + + + + + thread.tcache.flush + (void) + -- + [] + + Flush calling thread's thread-specific cache (tcache). + This interface releases all cached objects and internal data structures + associated with the calling thread's tcache. Ordinarily, this interface + need not be called, since automatic periodic incremental garbage + collection occurs, and the thread cache is automatically discarded when + a thread exits. However, garbage collection is triggered by allocation + activity, so it is possible for a thread that stops + allocating/deallocating to retain its cache indefinitely, in which case + the developer may find manual flushing useful. + + + + + thread.prof.name + (const char *) + r- or + -w + [] + + Get/set the descriptive name associated with the calling + thread in memory profile dumps. An internal copy of the name string is + created, so the input string need not be maintained after this interface + completes execution. The output string of this interface should be + copied for non-ephemeral uses, because multiple implementation details + can cause asynchronous string deallocation. Furthermore, each + invocation of this interface can only read or write; simultaneous + read/write is not supported due to string lifetime limitations. The + name string must nil-terminated and comprised only of characters in the + sets recognized + by isgraph + 3 and + isblank + 3. + + + + + thread.prof.active + (bool) + rw + [] + + Control whether sampling is currently active for the + calling thread. This is an activation mechanism in addition to prof.active; both must + be active for the calling thread to sample. This flag is enabled by + default. + + + + + tcache.create + (unsigned) + r- + [] + + Create an explicit thread-specific cache (tcache) and + return an identifier that can be passed to the MALLOCX_TCACHE(tc) + macro to explicitly use the specified cache rather than the + automatically managed one that is used by default. Each explicit cache + can be used by only one thread at a time; the application must assure + that this constraint holds. + + + + + + tcache.flush + (unsigned) + -w + [] + + Flush the specified thread-specific cache (tcache). The + same considerations apply to this interface as to thread.tcache.flush, + except that the tcache will never be automatically be discarded. + + + + + + tcache.destroy + (unsigned) + -w + [] + + Flush the specified thread-specific cache (tcache) and + make the identifier available for use during a future tcache creation. + + + + + + arena.<i>.purge + (void) + -- + + Purge unused dirty pages for arena <i>, or for + all arenas if <i> equals arenas.narenas. + + + + + + arena.<i>.dss + (const char *) + rw + + Set the precedence of dss allocation as related to mmap + allocation for arena <i>, or for all arenas if <i> equals + arenas.narenas. See + opt.dss for supported + settings. + + + + + arena.<i>.lg_dirty_mult + (ssize_t) + rw + + Current per-arena minimum ratio (log base 2) of active + to dirty pages for arena <i>. Each time this interface is set and + the ratio is increased, pages are synchronously purged as necessary to + impose the new ratio. See opt.lg_dirty_mult + for additional information. + + + + + arena.<i>.chunk_hooks + (chunk_hooks_t) + rw + + Get or set the chunk management hook functions for arena + <i>. The functions must be capable of operating on all extant + chunks associated with arena <i>, usually by passing unknown + chunks to the replaced functions. In practice, it is feasible to + control allocation for arenas created via arenas.extend such + that all chunks originate from an application-supplied chunk allocator + (by setting custom chunk hook functions just after arena creation), but + the automatically created arenas may have already created chunks prior + to the application having an opportunity to take over chunk + allocation. + + + The chunk_hooks_t structure comprises function + pointers which are described individually below. jemalloc uses these + functions to manage chunk lifetime, which starts off with allocation of + mapped committed memory, in the simplest case followed by deallocation. + However, there are performance and platform reasons to retain chunks for + later reuse. Cleanup attempts cascade from deallocation to decommit to + purging, which gives the chunk management functions opportunities to + reject the most permanent cleanup operations in favor of less permanent + (and often less costly) operations. The chunk splitting and merging + operations can also be opted out of, but this is mainly intended to + support platforms on which virtual memory mappings provided by the + operating system kernel do not automatically coalesce and split, e.g. + Windows. + + + typedef void *(chunk_alloc_t) + void *chunk + size_t size + size_t alignment + bool *zero + bool *commit + unsigned arena_ind + + + A chunk allocation function conforms to the + chunk_alloc_t type and upon success returns a pointer to + size bytes of mapped memory on behalf of arena + arena_ind such that the chunk's base address is a + multiple of alignment, as well as setting + *zero to indicate whether the chunk is zeroed and + *commit to indicate whether the chunk is + committed. Upon error the function returns NULL + and leaves *zero and + *commit unmodified. The + size parameter is always a multiple of the chunk + size. The alignment parameter is always a power + of two at least as large as the chunk size. Zeroing is mandatory if + *zero is true upon function entry. Committing is + mandatory if *commit is true upon function entry. + If chunk is not NULL, the + returned pointer must be chunk on success or + NULL on error. Committed memory may be committed + in absolute terms as on a system that does not overcommit, or in + implicit terms as on a system that overcommits and satisfies physical + memory needs on demand via soft page faults. Note that replacing the + default chunk allocation function makes the arena's arena.<i>.dss + setting irrelevant. + + + typedef bool (chunk_dalloc_t) + void *chunk + size_t size + bool committed + unsigned arena_ind + + + + A chunk deallocation function conforms to the + chunk_dalloc_t type and deallocates a + chunk of given size with + committed/decommited memory as indicated, on + behalf of arena arena_ind, returning false upon + success. If the function returns true, this indicates opt-out from + deallocation; the virtual memory mapping associated with the chunk + remains mapped, in the same commit state, and available for future use, + in which case it will be automatically retained for later reuse. + + + typedef bool (chunk_commit_t) + void *chunk + size_t size + size_t offset + size_t length + unsigned arena_ind + + + A chunk commit function conforms to the + chunk_commit_t type and commits zeroed physical memory to + back pages within a chunk of given + size at offset bytes, + extending for length on behalf of arena + arena_ind, returning false upon success. + Committed memory may be committed in absolute terms as on a system that + does not overcommit, or in implicit terms as on a system that + overcommits and satisfies physical memory needs on demand via soft page + faults. If the function returns true, this indicates insufficient + physical memory to satisfy the request. + + + typedef bool (chunk_decommit_t) + void *chunk + size_t size + size_t offset + size_t length + unsigned arena_ind + + + A chunk decommit function conforms to the + chunk_decommit_t type and decommits any physical memory + that is backing pages within a chunk of given + size at offset bytes, + extending for length on behalf of arena + arena_ind, returning false upon success, in which + case the pages will be committed via the chunk commit function before + being reused. If the function returns true, this indicates opt-out from + decommit; the memory remains committed and available for future use, in + which case it will be automatically retained for later reuse. + + + typedef bool (chunk_purge_t) + void *chunk + size_tsize + size_t offset + size_t length + unsigned arena_ind + + + A chunk purge function conforms to the chunk_purge_t + type and optionally discards physical pages within the virtual memory + mapping associated with chunk of given + size at offset bytes, + extending for length on behalf of arena + arena_ind, returning false if pages within the + purged virtual memory range will be zero-filled the next time they are + accessed. + + + typedef bool (chunk_split_t) + void *chunk + size_t size + size_t size_a + size_t size_b + bool committed + unsigned arena_ind + + + A chunk split function conforms to the chunk_split_t + type and optionally splits chunk of given + size into two adjacent chunks, the first of + size_a bytes, and the second of + size_b bytes, operating on + committed/decommitted memory as indicated, on + behalf of arena arena_ind, returning false upon + success. If the function returns true, this indicates that the chunk + remains unsplit and therefore should continue to be operated on as a + whole. + + + typedef bool (chunk_merge_t) + void *chunk_a + size_t size_a + void *chunk_b + size_t size_b + bool committed + unsigned arena_ind + + + A chunk merge function conforms to the chunk_merge_t + type and optionally merges adjacent chunks, + chunk_a of given size_a + and chunk_b of given + size_b into one contiguous chunk, operating on + committed/decommitted memory as indicated, on + behalf of arena arena_ind, returning false upon + success. If the function returns true, this indicates that the chunks + remain distinct mappings and therefore should continue to be operated on + independently. + + + + + + arenas.narenas + (unsigned) + r- + + Current limit on number of arenas. + + + + + arenas.initialized + (bool *) + r- + + An array of arenas.narenas + booleans. Each boolean indicates whether the corresponding arena is + initialized. + + + + + arenas.lg_dirty_mult + (ssize_t) + rw + + Current default per-arena minimum ratio (log base 2) of + active to dirty pages, used to initialize arena.<i>.lg_dirty_mult + during arena creation. See opt.lg_dirty_mult + for additional information. + + + + + arenas.quantum + (size_t) + r- + + Quantum size. + + + + + arenas.page + (size_t) + r- + + Page size. + + + + + arenas.tcache_max + (size_t) + r- + [] + + Maximum thread-cached size class. + + + + + arenas.nbins + (unsigned) + r- + + Number of bin size classes. + + + + + arenas.nhbins + (unsigned) + r- + [] + + Total number of thread cache bin size + classes. + + + + + arenas.bin.<i>.size + (size_t) + r- + + Maximum size supported by size class. + + + + + arenas.bin.<i>.nregs + (uint32_t) + r- + + Number of regions per page run. + + + + + arenas.bin.<i>.run_size + (size_t) + r- + + Number of bytes per page run. + + + + + arenas.nlruns + (unsigned) + r- + + Total number of large size classes. + + + + + arenas.lrun.<i>.size + (size_t) + r- + + Maximum size supported by this large size + class. + + + + + arenas.nhchunks + (unsigned) + r- + + Total number of huge size classes. + + + + + arenas.hchunk.<i>.size + (size_t) + r- + + Maximum size supported by this huge size + class. + + + + + arenas.extend + (unsigned) + r- + + Extend the array of arenas by appending a new arena, + and returning the new arena index. + + + + + prof.thread_active_init + (bool) + rw + [] + + Control the initial setting for thread.prof.active + in newly created threads. See the opt.prof_thread_active_init + option for additional information. + + + + + prof.active + (bool) + rw + [] + + Control whether sampling is currently active. See the + opt.prof_active + option for additional information, as well as the interrelated thread.prof.active + mallctl. + + + + + prof.dump + (const char *) + -w + [] + + Dump a memory profile to the specified file, or if NULL + is specified, to a file according to the pattern + <prefix>.<pid>.<seq>.m<mseq>.heap, + where <prefix> is controlled by the + opt.prof_prefix + option. + + + + + prof.gdump + (bool) + rw + [] + + When enabled, trigger a memory profile dump every time + the total virtual memory exceeds the previous maximum. Profiles are + dumped to files named according to the pattern + <prefix>.<pid>.<seq>.u<useq>.heap, + where <prefix> is controlled by the opt.prof_prefix + option. + + + + + prof.reset + (size_t) + -w + [] + + Reset all memory profile statistics, and optionally + update the sample rate (see opt.lg_prof_sample + and prof.lg_sample). + + + + + + prof.lg_sample + (size_t) + r- + [] + + Get the current sample rate (see opt.lg_prof_sample). + + + + + + prof.interval + (uint64_t) + r- + [] + + Average number of bytes allocated between + inverval-based profile dumps. See the + opt.lg_prof_interval + option for additional information. + + + + + stats.cactive + (size_t *) + r- + [] + + Pointer to a counter that contains an approximate count + of the current number of bytes in active pages. The estimate may be + high, but never low, because each arena rounds up when computing its + contribution to the counter. Note that the epoch mallctl has no bearing + on this counter. Furthermore, counter consistency is maintained via + atomic operations, so it is necessary to use an atomic operation in + order to guarantee a consistent read when dereferencing the pointer. + + + + + + stats.allocated + (size_t) + r- + [] + + Total number of bytes allocated by the + application. + + + + + stats.active + (size_t) + r- + [] + + Total number of bytes in active pages allocated by the + application. This is a multiple of the page size, and greater than or + equal to stats.allocated. + This does not include + stats.arenas.<i>.pdirty, nor pages + entirely devoted to allocator metadata. + + + + + stats.metadata + (size_t) + r- + [] + + Total number of bytes dedicated to metadata, which + comprise base allocations used for bootstrap-sensitive internal + allocator data structures, arena chunk headers (see stats.arenas.<i>.metadata.mapped), + and internal allocations (see stats.arenas.<i>.metadata.allocated). + + + + + stats.resident + (size_t) + r- + [] + + Maximum number of bytes in physically resident data + pages mapped by the allocator, comprising all pages dedicated to + allocator metadata, pages backing active allocations, and unused dirty + pages. This is a maximum rather than precise because pages may not + actually be physically resident if they correspond to demand-zeroed + virtual memory that has not yet been touched. This is a multiple of the + page size, and is larger than stats.active. + + + + + stats.mapped + (size_t) + r- + [] + + Total number of bytes in active chunks mapped by the + allocator. This is a multiple of the chunk size, and is larger than + stats.active. + This does not include inactive chunks, even those that contain unused + dirty pages, which means that there is no strict ordering between this + and stats.resident. + + + + + stats.arenas.<i>.dss + (const char *) + r- + + dss (sbrk + 2) allocation precedence as + related to mmap + 2 allocation. See opt.dss for details. + + + + + + stats.arenas.<i>.lg_dirty_mult + (ssize_t) + r- + + Minimum ratio (log base 2) of active to dirty pages. + See opt.lg_dirty_mult + for details. + + + + + stats.arenas.<i>.nthreads + (unsigned) + r- + + Number of threads currently assigned to + arena. + + + + + stats.arenas.<i>.pactive + (size_t) + r- + + Number of pages in active runs. + + + + + stats.arenas.<i>.pdirty + (size_t) + r- + + Number of pages within unused runs that are potentially + dirty, and for which madvise... + MADV_DONTNEED or + similar has not been called. + + + + + stats.arenas.<i>.mapped + (size_t) + r- + [] + + Number of mapped bytes. + + + + + stats.arenas.<i>.metadata.mapped + (size_t) + r- + [] + + Number of mapped bytes in arena chunk headers, which + track the states of the non-metadata pages. + + + + + stats.arenas.<i>.metadata.allocated + (size_t) + r- + [] + + Number of bytes dedicated to internal allocations. + Internal allocations differ from application-originated allocations in + that they are for internal use, and that they are omitted from heap + profiles. This statistic is reported separately from stats.metadata and + stats.arenas.<i>.metadata.mapped + because it overlaps with e.g. the stats.allocated and + stats.active + statistics, whereas the other metadata statistics do + not. + + + + + stats.arenas.<i>.npurge + (uint64_t) + r- + [] + + Number of dirty page purge sweeps performed. + + + + + + stats.arenas.<i>.nmadvise + (uint64_t) + r- + [] + + Number of madvise... + MADV_DONTNEED or + similar calls made to purge dirty pages. + + + + + stats.arenas.<i>.purged + (uint64_t) + r- + [] + + Number of pages purged. + + + + + stats.arenas.<i>.small.allocated + (size_t) + r- + [] + + Number of bytes currently allocated by small objects. + + + + + + stats.arenas.<i>.small.nmalloc + (uint64_t) + r- + [] + + Cumulative number of allocation requests served by + small bins. + + + + + stats.arenas.<i>.small.ndalloc + (uint64_t) + r- + [] + + Cumulative number of small objects returned to bins. + + + + + + stats.arenas.<i>.small.nrequests + (uint64_t) + r- + [] + + Cumulative number of small allocation requests. + + + + + + stats.arenas.<i>.large.allocated + (size_t) + r- + [] + + Number of bytes currently allocated by large objects. + + + + + + stats.arenas.<i>.large.nmalloc + (uint64_t) + r- + [] + + Cumulative number of large allocation requests served + directly by the arena. + + + + + stats.arenas.<i>.large.ndalloc + (uint64_t) + r- + [] + + Cumulative number of large deallocation requests served + directly by the arena. + + + + + stats.arenas.<i>.large.nrequests + (uint64_t) + r- + [] + + Cumulative number of large allocation requests. + + + + + + stats.arenas.<i>.huge.allocated + (size_t) + r- + [] + + Number of bytes currently allocated by huge objects. + + + + + + stats.arenas.<i>.huge.nmalloc + (uint64_t) + r- + [] + + Cumulative number of huge allocation requests served + directly by the arena. + + + + + stats.arenas.<i>.huge.ndalloc + (uint64_t) + r- + [] + + Cumulative number of huge deallocation requests served + directly by the arena. + + + + + stats.arenas.<i>.huge.nrequests + (uint64_t) + r- + [] + + Cumulative number of huge allocation requests. + + + + + + stats.arenas.<i>.bins.<j>.nmalloc + (uint64_t) + r- + [] + + Cumulative number of allocations served by bin. + + + + + + stats.arenas.<i>.bins.<j>.ndalloc + (uint64_t) + r- + [] + + Cumulative number of allocations returned to bin. + + + + + + stats.arenas.<i>.bins.<j>.nrequests + (uint64_t) + r- + [] + + Cumulative number of allocation + requests. + + + + + stats.arenas.<i>.bins.<j>.curregs + (size_t) + r- + [] + + Current number of regions for this size + class. + + + + + stats.arenas.<i>.bins.<j>.nfills + (uint64_t) + r- + [ ] + + Cumulative number of tcache fills. + + + + + stats.arenas.<i>.bins.<j>.nflushes + (uint64_t) + r- + [ ] + + Cumulative number of tcache flushes. + + + + + stats.arenas.<i>.bins.<j>.nruns + (uint64_t) + r- + [] + + Cumulative number of runs created. + + + + + stats.arenas.<i>.bins.<j>.nreruns + (uint64_t) + r- + [] + + Cumulative number of times the current run from which + to allocate changed. + + + + + stats.arenas.<i>.bins.<j>.curruns + (size_t) + r- + [] + + Current number of runs. + + + + + stats.arenas.<i>.lruns.<j>.nmalloc + (uint64_t) + r- + [] + + Cumulative number of allocation requests for this size + class served directly by the arena. + + + + + stats.arenas.<i>.lruns.<j>.ndalloc + (uint64_t) + r- + [] + + Cumulative number of deallocation requests for this + size class served directly by the arena. + + + + + stats.arenas.<i>.lruns.<j>.nrequests + (uint64_t) + r- + [] + + Cumulative number of allocation requests for this size + class. + + + + + stats.arenas.<i>.lruns.<j>.curruns + (size_t) + r- + [] + + Current number of runs for this size class. + + + + + + stats.arenas.<i>.hchunks.<j>.nmalloc + (uint64_t) + r- + [] + + Cumulative number of allocation requests for this size + class served directly by the arena. + + + + + stats.arenas.<i>.hchunks.<j>.ndalloc + (uint64_t) + r- + [] + + Cumulative number of deallocation requests for this + size class served directly by the arena. + + + + + stats.arenas.<i>.hchunks.<j>.nrequests + (uint64_t) + r- + [] + + Cumulative number of allocation requests for this size + class. + + + + + stats.arenas.<i>.hchunks.<j>.curhchunks + (size_t) + r- + [] + + Current number of huge allocations for this size class. + + + + + + DEBUGGING MALLOC PROBLEMS + When debugging, it is a good idea to configure/build jemalloc with + the and + options, and recompile the program with suitable options and symbols for + debugger support. When so configured, jemalloc incorporates a wide variety + of run-time assertions that catch application errors such as double-free, + write-after-free, etc. + + Programs often accidentally depend on “uninitialized” + memory actually being filled with zero bytes. Junk filling + (see the opt.junk + option) tends to expose such bugs in the form of obviously incorrect + results and/or coredumps. Conversely, zero + filling (see the opt.zero option) eliminates + the symptoms of such bugs. Between these two options, it is usually + possible to quickly detect, diagnose, and eliminate such bugs. + + This implementation does not provide much detail about the problems + it detects, because the performance impact for storing such information + would be prohibitive. However, jemalloc does integrate with the most + excellent Valgrind tool if the + configuration option is enabled. + + + DIAGNOSTIC MESSAGES + If any of the memory allocation/deallocation functions detect an + error or warning condition, a message will be printed to file descriptor + STDERR_FILENO. Errors will result in the process + dumping core. If the opt.abort option is set, most + warnings are treated as errors. + + The malloc_message variable allows the programmer + to override the function which emits the text strings forming the errors + and warnings if for some reason the STDERR_FILENO file + descriptor is not suitable for this. + malloc_message takes the + cbopaque pointer argument that is + NULL unless overridden by the arguments in a call to + malloc_stats_print, followed by a string + pointer. Please note that doing anything which tries to allocate memory in + this function is likely to result in a crash or deadlock. + + All messages are prefixed by + “<jemalloc>: ”. + + + RETURN VALUES + + Standard API + The malloc and + calloc functions return a pointer to the + allocated memory if successful; otherwise a NULL + pointer is returned and errno is set to + ENOMEM. + + The posix_memalign function + returns the value 0 if successful; otherwise it returns an error value. + The posix_memalign function will fail + if: + + + EINVAL + + The alignment parameter is + not a power of 2 at least as large as + sizeof(void *). + + + + ENOMEM + + Memory allocation error. + + + + + The aligned_alloc function returns + a pointer to the allocated memory if successful; otherwise a + NULL pointer is returned and + errno is set. The + aligned_alloc function will fail if: + + + EINVAL + + The alignment parameter is + not a power of 2. + + + + ENOMEM + + Memory allocation error. + + + + + The realloc function returns a + pointer, possibly identical to ptr, to the + allocated memory if successful; otherwise a NULL + pointer is returned, and errno is set to + ENOMEM if the error was the result of an + allocation failure. The realloc + function always leaves the original buffer intact when an error occurs. + + + The free function returns no + value. + + + Non-standard API + The mallocx and + rallocx functions return a pointer to + the allocated memory if successful; otherwise a NULL + pointer is returned to indicate insufficient contiguous memory was + available to service the allocation request. + + The xallocx function returns the + real size of the resulting resized allocation pointed to by + ptr, which is a value less than + size if the allocation could not be adequately + grown in place. + + The sallocx function returns the + real size of the allocation pointed to by ptr. + + + The nallocx returns the real size + that would result from a successful equivalent + mallocx function call, or zero if + insufficient memory is available to perform the size computation. + + The mallctl, + mallctlnametomib, and + mallctlbymib functions return 0 on + success; otherwise they return an error value. The functions will fail + if: + + + EINVAL + + newp is not + NULL, and newlen is too + large or too small. Alternatively, *oldlenp + is too large or too small; in this case as much data as possible + are read despite the error. + + + ENOENT + + name or + mib specifies an unknown/invalid + value. + + + EPERM + + Attempt to read or write void value, or attempt to + write read-only value. + + + EAGAIN + + A memory allocation failure + occurred. + + + EFAULT + + An interface with side effects failed in some way + not directly related to mallctl* + read/write processing. + + + + + The malloc_usable_size function + returns the usable size of the allocation pointed to by + ptr. + + + + ENVIRONMENT + The following environment variable affects the execution of the + allocation functions: + + + MALLOC_CONF + + If the environment variable + MALLOC_CONF is set, the characters it contains + will be interpreted as options. + + + + + + EXAMPLES + To dump core whenever a problem occurs: + ln -s 'abort:true' /etc/malloc.conf + + To specify in the source a chunk size that is 16 MiB: + + + + SEE ALSO + madvise + 2, + mmap + 2, + sbrk + 2, + utrace + 2, + alloca + 3, + atexit + 3, + getpagesize + 3 + + + STANDARDS + The malloc, + calloc, + realloc, and + free functions conform to ISO/IEC + 9899:1990 (“ISO C90”). + + The posix_memalign function conforms + to IEEE Std 1003.1-2001 (“POSIX.1”). + + diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/doc/manpages.xsl.in b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/doc/manpages.xsl.in new file mode 100644 index 0000000..88b2626 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/doc/manpages.xsl.in @@ -0,0 +1,4 @@ + + + + diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/doc/stylesheet.xsl b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/doc/stylesheet.xsl new file mode 100644 index 0000000..4e334a8 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/doc/stylesheet.xsl @@ -0,0 +1,7 @@ + + ansi + + + "" + + diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/arena.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/arena.h new file mode 100644 index 0000000..12c6179 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/arena.h @@ -0,0 +1,1347 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +#define LARGE_MINCLASS (ZU(1) << LG_LARGE_MINCLASS) + +/* Maximum number of regions in one run. */ +#define LG_RUN_MAXREGS (LG_PAGE - LG_TINY_MIN) +#define RUN_MAXREGS (1U << LG_RUN_MAXREGS) + +/* + * Minimum redzone size. Redzones may be larger than this if necessary to + * preserve region alignment. + */ +#define REDZONE_MINSIZE 16 + +/* + * The minimum ratio of active:dirty pages per arena is computed as: + * + * (nactive >> lg_dirty_mult) >= ndirty + * + * So, supposing that lg_dirty_mult is 3, there can be no less than 8 times as + * many active pages as dirty pages. + */ +#define LG_DIRTY_MULT_DEFAULT 3 + +typedef struct arena_runs_dirty_link_s arena_runs_dirty_link_t; +typedef struct arena_run_s arena_run_t; +typedef struct arena_chunk_map_bits_s arena_chunk_map_bits_t; +typedef struct arena_chunk_map_misc_s arena_chunk_map_misc_t; +typedef struct arena_chunk_s arena_chunk_t; +typedef struct arena_bin_info_s arena_bin_info_t; +typedef struct arena_bin_s arena_bin_t; +typedef struct arena_s arena_t; + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +#ifdef JEMALLOC_ARENA_STRUCTS_A +struct arena_run_s { + /* Index of bin this run is associated with. */ + szind_t binind; + + /* Number of free regions in run. */ + unsigned nfree; + + /* Per region allocated/deallocated bitmap. */ + bitmap_t bitmap[BITMAP_GROUPS_MAX]; +}; + +/* Each element of the chunk map corresponds to one page within the chunk. */ +struct arena_chunk_map_bits_s { + /* + * Run address (or size) and various flags are stored together. The bit + * layout looks like (assuming 32-bit system): + * + * ???????? ???????? ???nnnnn nnndumla + * + * ? : Unallocated: Run address for first/last pages, unset for internal + * pages. + * Small: Run page offset. + * Large: Run page count for first page, unset for trailing pages. + * n : binind for small size class, BININD_INVALID for large size class. + * d : dirty? + * u : unzeroed? + * m : decommitted? + * l : large? + * a : allocated? + * + * Following are example bit patterns for the three types of runs. + * + * p : run page offset + * s : run size + * n : binind for size class; large objects set these to BININD_INVALID + * x : don't care + * - : 0 + * + : 1 + * [DUMLA] : bit set + * [dumla] : bit unset + * + * Unallocated (clean): + * ssssssss ssssssss sss+++++ +++dum-a + * xxxxxxxx xxxxxxxx xxxxxxxx xxx-Uxxx + * ssssssss ssssssss sss+++++ +++dUm-a + * + * Unallocated (dirty): + * ssssssss ssssssss sss+++++ +++D-m-a + * xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx + * ssssssss ssssssss sss+++++ +++D-m-a + * + * Small: + * pppppppp pppppppp pppnnnnn nnnd---A + * pppppppp pppppppp pppnnnnn nnn----A + * pppppppp pppppppp pppnnnnn nnnd---A + * + * Large: + * ssssssss ssssssss sss+++++ +++D--LA + * xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx + * -------- -------- ---+++++ +++D--LA + * + * Large (sampled, size <= LARGE_MINCLASS): + * ssssssss ssssssss sssnnnnn nnnD--LA + * xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx + * -------- -------- ---+++++ +++D--LA + * + * Large (not sampled, size == LARGE_MINCLASS): + * ssssssss ssssssss sss+++++ +++D--LA + * xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx + * -------- -------- ---+++++ +++D--LA + */ + size_t bits; +#define CHUNK_MAP_ALLOCATED ((size_t)0x01U) +#define CHUNK_MAP_LARGE ((size_t)0x02U) +#define CHUNK_MAP_STATE_MASK ((size_t)0x3U) + +#define CHUNK_MAP_DECOMMITTED ((size_t)0x04U) +#define CHUNK_MAP_UNZEROED ((size_t)0x08U) +#define CHUNK_MAP_DIRTY ((size_t)0x10U) +#define CHUNK_MAP_FLAGS_MASK ((size_t)0x1cU) + +#define CHUNK_MAP_BININD_SHIFT 5 +#define BININD_INVALID ((size_t)0xffU) +#define CHUNK_MAP_BININD_MASK (BININD_INVALID << CHUNK_MAP_BININD_SHIFT) +#define CHUNK_MAP_BININD_INVALID CHUNK_MAP_BININD_MASK + +#define CHUNK_MAP_RUNIND_SHIFT (CHUNK_MAP_BININD_SHIFT + 8) +#define CHUNK_MAP_SIZE_SHIFT (CHUNK_MAP_RUNIND_SHIFT - LG_PAGE) +#define CHUNK_MAP_SIZE_MASK \ + (~(CHUNK_MAP_BININD_MASK | CHUNK_MAP_FLAGS_MASK | CHUNK_MAP_STATE_MASK)) +}; + +struct arena_runs_dirty_link_s { + qr(arena_runs_dirty_link_t) rd_link; +}; + +/* + * Each arena_chunk_map_misc_t corresponds to one page within the chunk, just + * like arena_chunk_map_bits_t. Two separate arrays are stored within each + * chunk header in order to improve cache locality. + */ +struct arena_chunk_map_misc_s { + /* + * Linkage for run trees. There are two disjoint uses: + * + * 1) arena_t's runs_avail tree. + * 2) arena_run_t conceptually uses this linkage for in-use non-full + * runs, rather than directly embedding linkage. + */ + rb_node(arena_chunk_map_misc_t) rb_link; + + union { + /* Linkage for list of dirty runs. */ + arena_runs_dirty_link_t rd; + + /* Profile counters, used for large object runs. */ + union { + void *prof_tctx_pun; + prof_tctx_t *prof_tctx; + }; + + /* Small region run metadata. */ + arena_run_t run; + }; +}; +typedef rb_tree(arena_chunk_map_misc_t) arena_avail_tree_t; +typedef rb_tree(arena_chunk_map_misc_t) arena_run_tree_t; +#endif /* JEMALLOC_ARENA_STRUCTS_A */ + +#ifdef JEMALLOC_ARENA_STRUCTS_B +/* Arena chunk header. */ +struct arena_chunk_s { + /* + * A pointer to the arena that owns the chunk is stored within the node. + * This field as a whole is used by chunks_rtree to support both + * ivsalloc() and core-based debugging. + */ + extent_node_t node; + + /* + * Map of pages within chunk that keeps track of free/large/small. The + * first map_bias entries are omitted, since the chunk header does not + * need to be tracked in the map. This omission saves a header page + * for common chunk sizes (e.g. 4 MiB). + */ + arena_chunk_map_bits_t map_bits[1]; /* Dynamically sized. */ +}; + +/* + * Read-only information associated with each element of arena_t's bins array + * is stored separately, partly to reduce memory usage (only one copy, rather + * than one per arena), but mainly to avoid false cacheline sharing. + * + * Each run has the following layout: + * + * /--------------------\ + * | pad? | + * |--------------------| + * | redzone | + * reg0_offset | region 0 | + * | redzone | + * |--------------------| \ + * | redzone | | + * | region 1 | > reg_interval + * | redzone | / + * |--------------------| + * | ... | + * | ... | + * | ... | + * |--------------------| + * | redzone | + * | region nregs-1 | + * | redzone | + * |--------------------| + * | alignment pad? | + * \--------------------/ + * + * reg_interval has at least the same minimum alignment as reg_size; this + * preserves the alignment constraint that sa2u() depends on. Alignment pad is + * either 0 or redzone_size; it is present only if needed to align reg0_offset. + */ +struct arena_bin_info_s { + /* Size of regions in a run for this bin's size class. */ + size_t reg_size; + + /* Redzone size. */ + size_t redzone_size; + + /* Interval between regions (reg_size + (redzone_size << 1)). */ + size_t reg_interval; + + /* Total size of a run for this bin's size class. */ + size_t run_size; + + /* Total number of regions in a run for this bin's size class. */ + uint32_t nregs; + + /* + * Metadata used to manipulate bitmaps for runs associated with this + * bin. + */ + bitmap_info_t bitmap_info; + + /* Offset of first region in a run for this bin's size class. */ + uint32_t reg0_offset; +}; + +struct arena_bin_s { + /* + * All operations on runcur, runs, and stats require that lock be + * locked. Run allocation/deallocation are protected by the arena lock, + * which may be acquired while holding one or more bin locks, but not + * vise versa. + */ + malloc_mutex_t lock; + + /* + * Current run being used to service allocations of this bin's size + * class. + */ + arena_run_t *runcur; + + /* + * Tree of non-full runs. This tree is used when looking for an + * existing run when runcur is no longer usable. We choose the + * non-full run that is lowest in memory; this policy tends to keep + * objects packed well, and it can also help reduce the number of + * almost-empty chunks. + */ + arena_run_tree_t runs; + + /* Bin statistics. */ + malloc_bin_stats_t stats; +}; + +struct arena_s { + /* This arena's index within the arenas array. */ + unsigned ind; + + /* + * Number of threads currently assigned to this arena. This field is + * protected by arenas_lock. + */ + unsigned nthreads; + + /* + * There are three classes of arena operations from a locking + * perspective: + * 1) Thread assignment (modifies nthreads) is protected by arenas_lock. + * 2) Bin-related operations are protected by bin locks. + * 3) Chunk- and run-related operations are protected by this mutex. + */ + malloc_mutex_t lock; + + arena_stats_t stats; + /* + * List of tcaches for extant threads associated with this arena. + * Stats from these are merged incrementally, and at exit if + * opt_stats_print is enabled. + */ + ql_head(tcache_t) tcache_ql; + + uint64_t prof_accumbytes; + + /* + * PRNG state for cache index randomization of large allocation base + * pointers. + */ + uint64_t offset_state; + + dss_prec_t dss_prec; + + /* + * In order to avoid rapid chunk allocation/deallocation when an arena + * oscillates right on the cusp of needing a new chunk, cache the most + * recently freed chunk. The spare is left in the arena's chunk trees + * until it is deleted. + * + * There is one spare chunk per arena, rather than one spare total, in + * order to avoid interactions between multiple threads that could make + * a single spare inadequate. + */ + arena_chunk_t *spare; + + /* Minimum ratio (log base 2) of nactive:ndirty. */ + ssize_t lg_dirty_mult; + + /* True if a thread is currently executing arena_purge(). */ + bool purging; + + /* Number of pages in active runs and huge regions. */ + size_t nactive; + + /* + * Current count of pages within unused runs that are potentially + * dirty, and for which madvise(... MADV_DONTNEED) has not been called. + * By tracking this, we can institute a limit on how much dirty unused + * memory is mapped for each arena. + */ + size_t ndirty; + + /* + * Size/address-ordered tree of this arena's available runs. The tree + * is used for first-best-fit run allocation. + */ + arena_avail_tree_t runs_avail; + + /* + * Unused dirty memory this arena manages. Dirty memory is conceptually + * tracked as an arbitrarily interleaved LRU of dirty runs and cached + * chunks, but the list linkage is actually semi-duplicated in order to + * avoid extra arena_chunk_map_misc_t space overhead. + * + * LRU-----------------------------------------------------------MRU + * + * /-- arena ---\ + * | | + * | | + * |------------| /- chunk -\ + * ...->|chunks_cache|<--------------------------->| /----\ |<--... + * |------------| | |node| | + * | | | | | | + * | | /- run -\ /- run -\ | | | | + * | | | | | | | | | | + * | | | | | | | | | | + * |------------| |-------| |-------| | |----| | + * ...->|runs_dirty |<-->|rd |<-->|rd |<---->|rd |<----... + * |------------| |-------| |-------| | |----| | + * | | | | | | | | | | + * | | | | | | | \----/ | + * | | \-------/ \-------/ | | + * | | | | + * | | | | + * \------------/ \---------/ + */ + arena_runs_dirty_link_t runs_dirty; + extent_node_t chunks_cache; + + /* Extant huge allocations. */ + ql_head(extent_node_t) huge; + /* Synchronizes all huge allocation/update/deallocation. */ + malloc_mutex_t huge_mtx; + + /* + * Trees of chunks that were previously allocated (trees differ only in + * node ordering). These are used when allocating chunks, in an attempt + * to re-use address space. Depending on function, different tree + * orderings are needed, which is why there are two trees with the same + * contents. + */ + extent_tree_t chunks_szad_cached; + extent_tree_t chunks_ad_cached; + extent_tree_t chunks_szad_retained; + extent_tree_t chunks_ad_retained; + + malloc_mutex_t chunks_mtx; + /* Cache of nodes that were allocated via base_alloc(). */ + ql_head(extent_node_t) node_cache; + malloc_mutex_t node_cache_mtx; + + /* User-configurable chunk hook functions. */ + chunk_hooks_t chunk_hooks; + + /* bins is used to store trees of free regions. */ + arena_bin_t bins[NBINS]; +}; +#endif /* JEMALLOC_ARENA_STRUCTS_B */ + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +static const size_t large_pad = +#ifdef JEMALLOC_CACHE_OBLIVIOUS + PAGE +#else + 0 +#endif + ; + +extern ssize_t opt_lg_dirty_mult; + +extern arena_bin_info_t arena_bin_info[NBINS]; + +extern size_t map_bias; /* Number of arena chunk header pages. */ +extern size_t map_misc_offset; +extern size_t arena_maxrun; /* Max run size for arenas. */ +extern size_t large_maxclass; /* Max large size class. */ +extern unsigned nlclasses; /* Number of large size classes. */ +extern unsigned nhclasses; /* Number of huge size classes. */ + +void arena_chunk_cache_maybe_insert(arena_t *arena, extent_node_t *node, + bool cache); +void arena_chunk_cache_maybe_remove(arena_t *arena, extent_node_t *node, + bool cache); +extent_node_t *arena_node_alloc(arena_t *arena); +void arena_node_dalloc(arena_t *arena, extent_node_t *node); +void *arena_chunk_alloc_huge(arena_t *arena, size_t usize, size_t alignment, + bool *zero); +void arena_chunk_dalloc_huge(arena_t *arena, void *chunk, size_t usize); +void arena_chunk_ralloc_huge_similar(arena_t *arena, void *chunk, + size_t oldsize, size_t usize); +void arena_chunk_ralloc_huge_shrink(arena_t *arena, void *chunk, + size_t oldsize, size_t usize); +bool arena_chunk_ralloc_huge_expand(arena_t *arena, void *chunk, + size_t oldsize, size_t usize, bool *zero); +ssize_t arena_lg_dirty_mult_get(arena_t *arena); +bool arena_lg_dirty_mult_set(arena_t *arena, ssize_t lg_dirty_mult); +void arena_maybe_purge(arena_t *arena); +void arena_purge_all(arena_t *arena); +void arena_tcache_fill_small(arena_t *arena, tcache_bin_t *tbin, + szind_t binind, uint64_t prof_accumbytes); +void arena_alloc_junk_small(void *ptr, arena_bin_info_t *bin_info, + bool zero); +#ifdef JEMALLOC_JET +typedef void (arena_redzone_corruption_t)(void *, size_t, bool, size_t, + uint8_t); +extern arena_redzone_corruption_t *arena_redzone_corruption; +typedef void (arena_dalloc_junk_small_t)(void *, arena_bin_info_t *); +extern arena_dalloc_junk_small_t *arena_dalloc_junk_small; +#else +void arena_dalloc_junk_small(void *ptr, arena_bin_info_t *bin_info); +#endif +void arena_quarantine_junk_small(void *ptr, size_t usize); +void *arena_malloc_small(arena_t *arena, size_t size, bool zero); +void *arena_malloc_large(arena_t *arena, size_t size, bool zero); +void *arena_palloc(tsd_t *tsd, arena_t *arena, size_t usize, + size_t alignment, bool zero, tcache_t *tcache); +void arena_prof_promoted(const void *ptr, size_t size); +void arena_dalloc_bin_junked_locked(arena_t *arena, arena_chunk_t *chunk, + void *ptr, arena_chunk_map_bits_t *bitselm); +void arena_dalloc_bin(arena_t *arena, arena_chunk_t *chunk, void *ptr, + size_t pageind, arena_chunk_map_bits_t *bitselm); +void arena_dalloc_small(arena_t *arena, arena_chunk_t *chunk, void *ptr, + size_t pageind); +#ifdef JEMALLOC_JET +typedef void (arena_dalloc_junk_large_t)(void *, size_t); +extern arena_dalloc_junk_large_t *arena_dalloc_junk_large; +#else +void arena_dalloc_junk_large(void *ptr, size_t usize); +#endif +void arena_dalloc_large_junked_locked(arena_t *arena, arena_chunk_t *chunk, + void *ptr); +void arena_dalloc_large(arena_t *arena, arena_chunk_t *chunk, void *ptr); +#ifdef JEMALLOC_JET +typedef void (arena_ralloc_junk_large_t)(void *, size_t, size_t); +extern arena_ralloc_junk_large_t *arena_ralloc_junk_large; +#endif +bool arena_ralloc_no_move(void *ptr, size_t oldsize, size_t size, + size_t extra, bool zero); +void *arena_ralloc(tsd_t *tsd, arena_t *arena, void *ptr, size_t oldsize, + size_t size, size_t alignment, bool zero, tcache_t *tcache); +dss_prec_t arena_dss_prec_get(arena_t *arena); +bool arena_dss_prec_set(arena_t *arena, dss_prec_t dss_prec); +ssize_t arena_lg_dirty_mult_default_get(void); +bool arena_lg_dirty_mult_default_set(ssize_t lg_dirty_mult); +void arena_stats_merge(arena_t *arena, const char **dss, + ssize_t *lg_dirty_mult, size_t *nactive, size_t *ndirty, + arena_stats_t *astats, malloc_bin_stats_t *bstats, + malloc_large_stats_t *lstats, malloc_huge_stats_t *hstats); +arena_t *arena_new(unsigned ind); +bool arena_boot(void); +void arena_prefork(arena_t *arena); +void arena_postfork_parent(arena_t *arena); +void arena_postfork_child(arena_t *arena); + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#ifndef JEMALLOC_ENABLE_INLINE +arena_chunk_map_bits_t *arena_bitselm_get(arena_chunk_t *chunk, + size_t pageind); +arena_chunk_map_misc_t *arena_miscelm_get(arena_chunk_t *chunk, + size_t pageind); +size_t arena_miscelm_to_pageind(arena_chunk_map_misc_t *miscelm); +void *arena_miscelm_to_rpages(arena_chunk_map_misc_t *miscelm); +arena_chunk_map_misc_t *arena_rd_to_miscelm(arena_runs_dirty_link_t *rd); +arena_chunk_map_misc_t *arena_run_to_miscelm(arena_run_t *run); +size_t *arena_mapbitsp_get(arena_chunk_t *chunk, size_t pageind); +size_t arena_mapbitsp_read(size_t *mapbitsp); +size_t arena_mapbits_get(arena_chunk_t *chunk, size_t pageind); +size_t arena_mapbits_size_decode(size_t mapbits); +size_t arena_mapbits_unallocated_size_get(arena_chunk_t *chunk, + size_t pageind); +size_t arena_mapbits_large_size_get(arena_chunk_t *chunk, size_t pageind); +size_t arena_mapbits_small_runind_get(arena_chunk_t *chunk, size_t pageind); +szind_t arena_mapbits_binind_get(arena_chunk_t *chunk, size_t pageind); +size_t arena_mapbits_dirty_get(arena_chunk_t *chunk, size_t pageind); +size_t arena_mapbits_unzeroed_get(arena_chunk_t *chunk, size_t pageind); +size_t arena_mapbits_decommitted_get(arena_chunk_t *chunk, size_t pageind); +size_t arena_mapbits_large_get(arena_chunk_t *chunk, size_t pageind); +size_t arena_mapbits_allocated_get(arena_chunk_t *chunk, size_t pageind); +void arena_mapbitsp_write(size_t *mapbitsp, size_t mapbits); +size_t arena_mapbits_size_encode(size_t size); +void arena_mapbits_unallocated_set(arena_chunk_t *chunk, size_t pageind, + size_t size, size_t flags); +void arena_mapbits_unallocated_size_set(arena_chunk_t *chunk, size_t pageind, + size_t size); +void arena_mapbits_internal_set(arena_chunk_t *chunk, size_t pageind, + size_t flags); +void arena_mapbits_large_set(arena_chunk_t *chunk, size_t pageind, + size_t size, size_t flags); +void arena_mapbits_large_binind_set(arena_chunk_t *chunk, size_t pageind, + szind_t binind); +void arena_mapbits_small_set(arena_chunk_t *chunk, size_t pageind, + size_t runind, szind_t binind, size_t flags); +void arena_metadata_allocated_add(arena_t *arena, size_t size); +void arena_metadata_allocated_sub(arena_t *arena, size_t size); +size_t arena_metadata_allocated_get(arena_t *arena); +bool arena_prof_accum_impl(arena_t *arena, uint64_t accumbytes); +bool arena_prof_accum_locked(arena_t *arena, uint64_t accumbytes); +bool arena_prof_accum(arena_t *arena, uint64_t accumbytes); +szind_t arena_ptr_small_binind_get(const void *ptr, size_t mapbits); +szind_t arena_bin_index(arena_t *arena, arena_bin_t *bin); +unsigned arena_run_regind(arena_run_t *run, arena_bin_info_t *bin_info, + const void *ptr); +prof_tctx_t *arena_prof_tctx_get(const void *ptr); +void arena_prof_tctx_set(const void *ptr, size_t usize, prof_tctx_t *tctx); +void arena_prof_tctx_reset(const void *ptr, size_t usize, + const void *old_ptr, prof_tctx_t *old_tctx); +void *arena_malloc(tsd_t *tsd, arena_t *arena, size_t size, bool zero, + tcache_t *tcache); +arena_t *arena_aalloc(const void *ptr); +size_t arena_salloc(const void *ptr, bool demote); +void arena_dalloc(tsd_t *tsd, void *ptr, tcache_t *tcache); +void arena_sdalloc(tsd_t *tsd, void *ptr, size_t size, tcache_t *tcache); +#endif + +#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_ARENA_C_)) +# ifdef JEMALLOC_ARENA_INLINE_A +JEMALLOC_ALWAYS_INLINE arena_chunk_map_bits_t * +arena_bitselm_get(arena_chunk_t *chunk, size_t pageind) +{ + + assert(pageind >= map_bias); + assert(pageind < chunk_npages); + + return (&chunk->map_bits[pageind-map_bias]); +} + +JEMALLOC_ALWAYS_INLINE arena_chunk_map_misc_t * +arena_miscelm_get(arena_chunk_t *chunk, size_t pageind) +{ + + assert(pageind >= map_bias); + assert(pageind < chunk_npages); + + return ((arena_chunk_map_misc_t *)((uintptr_t)chunk + + (uintptr_t)map_misc_offset) + pageind-map_bias); +} + +JEMALLOC_ALWAYS_INLINE size_t +arena_miscelm_to_pageind(arena_chunk_map_misc_t *miscelm) +{ + arena_chunk_t *chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(miscelm); + size_t pageind = ((uintptr_t)miscelm - ((uintptr_t)chunk + + map_misc_offset)) / sizeof(arena_chunk_map_misc_t) + map_bias; + + assert(pageind >= map_bias); + assert(pageind < chunk_npages); + + return (pageind); +} + +JEMALLOC_ALWAYS_INLINE void * +arena_miscelm_to_rpages(arena_chunk_map_misc_t *miscelm) +{ + arena_chunk_t *chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(miscelm); + size_t pageind = arena_miscelm_to_pageind(miscelm); + + return ((void *)((uintptr_t)chunk + (pageind << LG_PAGE))); +} + +JEMALLOC_ALWAYS_INLINE arena_chunk_map_misc_t * +arena_rd_to_miscelm(arena_runs_dirty_link_t *rd) +{ + arena_chunk_map_misc_t *miscelm = (arena_chunk_map_misc_t + *)((uintptr_t)rd - offsetof(arena_chunk_map_misc_t, rd)); + + assert(arena_miscelm_to_pageind(miscelm) >= map_bias); + assert(arena_miscelm_to_pageind(miscelm) < chunk_npages); + + return (miscelm); +} + +JEMALLOC_ALWAYS_INLINE arena_chunk_map_misc_t * +arena_run_to_miscelm(arena_run_t *run) +{ + arena_chunk_map_misc_t *miscelm = (arena_chunk_map_misc_t + *)((uintptr_t)run - offsetof(arena_chunk_map_misc_t, run)); + + assert(arena_miscelm_to_pageind(miscelm) >= map_bias); + assert(arena_miscelm_to_pageind(miscelm) < chunk_npages); + + return (miscelm); +} + +JEMALLOC_ALWAYS_INLINE size_t * +arena_mapbitsp_get(arena_chunk_t *chunk, size_t pageind) +{ + + return (&arena_bitselm_get(chunk, pageind)->bits); +} + +JEMALLOC_ALWAYS_INLINE size_t +arena_mapbitsp_read(size_t *mapbitsp) +{ + + return (*mapbitsp); +} + +JEMALLOC_ALWAYS_INLINE size_t +arena_mapbits_get(arena_chunk_t *chunk, size_t pageind) +{ + + return (arena_mapbitsp_read(arena_mapbitsp_get(chunk, pageind))); +} + +JEMALLOC_ALWAYS_INLINE size_t +arena_mapbits_size_decode(size_t mapbits) +{ + size_t size; + +#if CHUNK_MAP_SIZE_SHIFT > 0 + size = (mapbits & CHUNK_MAP_SIZE_MASK) >> CHUNK_MAP_SIZE_SHIFT; +#elif CHUNK_MAP_SIZE_SHIFT == 0 + size = mapbits & CHUNK_MAP_SIZE_MASK; +#else + size = (mapbits & CHUNK_MAP_SIZE_MASK) << -CHUNK_MAP_SIZE_SHIFT; +#endif + + return (size); +} + +JEMALLOC_ALWAYS_INLINE size_t +arena_mapbits_unallocated_size_get(arena_chunk_t *chunk, size_t pageind) +{ + size_t mapbits; + + mapbits = arena_mapbits_get(chunk, pageind); + assert((mapbits & (CHUNK_MAP_LARGE|CHUNK_MAP_ALLOCATED)) == 0); + return (arena_mapbits_size_decode(mapbits)); +} + +JEMALLOC_ALWAYS_INLINE size_t +arena_mapbits_large_size_get(arena_chunk_t *chunk, size_t pageind) +{ + size_t mapbits; + + mapbits = arena_mapbits_get(chunk, pageind); + assert((mapbits & (CHUNK_MAP_LARGE|CHUNK_MAP_ALLOCATED)) == + (CHUNK_MAP_LARGE|CHUNK_MAP_ALLOCATED)); + return (arena_mapbits_size_decode(mapbits)); +} + +JEMALLOC_ALWAYS_INLINE size_t +arena_mapbits_small_runind_get(arena_chunk_t *chunk, size_t pageind) +{ + size_t mapbits; + + mapbits = arena_mapbits_get(chunk, pageind); + assert((mapbits & (CHUNK_MAP_LARGE|CHUNK_MAP_ALLOCATED)) == + CHUNK_MAP_ALLOCATED); + return (mapbits >> CHUNK_MAP_RUNIND_SHIFT); +} + +JEMALLOC_ALWAYS_INLINE szind_t +arena_mapbits_binind_get(arena_chunk_t *chunk, size_t pageind) +{ + size_t mapbits; + szind_t binind; + + mapbits = arena_mapbits_get(chunk, pageind); + binind = (mapbits & CHUNK_MAP_BININD_MASK) >> CHUNK_MAP_BININD_SHIFT; + assert(binind < NBINS || binind == BININD_INVALID); + return (binind); +} + +JEMALLOC_ALWAYS_INLINE size_t +arena_mapbits_dirty_get(arena_chunk_t *chunk, size_t pageind) +{ + size_t mapbits; + + mapbits = arena_mapbits_get(chunk, pageind); + assert((mapbits & CHUNK_MAP_DECOMMITTED) == 0 || (mapbits & + (CHUNK_MAP_DIRTY|CHUNK_MAP_UNZEROED)) == 0); + return (mapbits & CHUNK_MAP_DIRTY); +} + +JEMALLOC_ALWAYS_INLINE size_t +arena_mapbits_unzeroed_get(arena_chunk_t *chunk, size_t pageind) +{ + size_t mapbits; + + mapbits = arena_mapbits_get(chunk, pageind); + assert((mapbits & CHUNK_MAP_DECOMMITTED) == 0 || (mapbits & + (CHUNK_MAP_DIRTY|CHUNK_MAP_UNZEROED)) == 0); + return (mapbits & CHUNK_MAP_UNZEROED); +} + +JEMALLOC_ALWAYS_INLINE size_t +arena_mapbits_decommitted_get(arena_chunk_t *chunk, size_t pageind) +{ + size_t mapbits; + + mapbits = arena_mapbits_get(chunk, pageind); + assert((mapbits & CHUNK_MAP_DECOMMITTED) == 0 || (mapbits & + (CHUNK_MAP_DIRTY|CHUNK_MAP_UNZEROED)) == 0); + return (mapbits & CHUNK_MAP_DECOMMITTED); +} + +JEMALLOC_ALWAYS_INLINE size_t +arena_mapbits_large_get(arena_chunk_t *chunk, size_t pageind) +{ + size_t mapbits; + + mapbits = arena_mapbits_get(chunk, pageind); + return (mapbits & CHUNK_MAP_LARGE); +} + +JEMALLOC_ALWAYS_INLINE size_t +arena_mapbits_allocated_get(arena_chunk_t *chunk, size_t pageind) +{ + size_t mapbits; + + mapbits = arena_mapbits_get(chunk, pageind); + return (mapbits & CHUNK_MAP_ALLOCATED); +} + +JEMALLOC_ALWAYS_INLINE void +arena_mapbitsp_write(size_t *mapbitsp, size_t mapbits) +{ + + *mapbitsp = mapbits; +} + +JEMALLOC_ALWAYS_INLINE size_t +arena_mapbits_size_encode(size_t size) +{ + size_t mapbits; + +#if CHUNK_MAP_SIZE_SHIFT > 0 + mapbits = size << CHUNK_MAP_SIZE_SHIFT; +#elif CHUNK_MAP_SIZE_SHIFT == 0 + mapbits = size; +#else + mapbits = size >> -CHUNK_MAP_SIZE_SHIFT; +#endif + + assert((mapbits & ~CHUNK_MAP_SIZE_MASK) == 0); + return (mapbits); +} + +JEMALLOC_ALWAYS_INLINE void +arena_mapbits_unallocated_set(arena_chunk_t *chunk, size_t pageind, size_t size, + size_t flags) +{ + size_t *mapbitsp = arena_mapbitsp_get(chunk, pageind); + + assert((size & PAGE_MASK) == 0); + assert((flags & CHUNK_MAP_FLAGS_MASK) == flags); + assert((flags & CHUNK_MAP_DECOMMITTED) == 0 || (flags & + (CHUNK_MAP_DIRTY|CHUNK_MAP_UNZEROED)) == 0); + arena_mapbitsp_write(mapbitsp, arena_mapbits_size_encode(size) | + CHUNK_MAP_BININD_INVALID | flags); +} + +JEMALLOC_ALWAYS_INLINE void +arena_mapbits_unallocated_size_set(arena_chunk_t *chunk, size_t pageind, + size_t size) +{ + size_t *mapbitsp = arena_mapbitsp_get(chunk, pageind); + size_t mapbits = arena_mapbitsp_read(mapbitsp); + + assert((size & PAGE_MASK) == 0); + assert((mapbits & (CHUNK_MAP_LARGE|CHUNK_MAP_ALLOCATED)) == 0); + arena_mapbitsp_write(mapbitsp, arena_mapbits_size_encode(size) | + (mapbits & ~CHUNK_MAP_SIZE_MASK)); +} + +JEMALLOC_ALWAYS_INLINE void +arena_mapbits_internal_set(arena_chunk_t *chunk, size_t pageind, size_t flags) +{ + size_t *mapbitsp = arena_mapbitsp_get(chunk, pageind); + + assert((flags & CHUNK_MAP_UNZEROED) == flags); + arena_mapbitsp_write(mapbitsp, flags); +} + +JEMALLOC_ALWAYS_INLINE void +arena_mapbits_large_set(arena_chunk_t *chunk, size_t pageind, size_t size, + size_t flags) +{ + size_t *mapbitsp = arena_mapbitsp_get(chunk, pageind); + + assert((size & PAGE_MASK) == 0); + assert((flags & CHUNK_MAP_FLAGS_MASK) == flags); + assert((flags & CHUNK_MAP_DECOMMITTED) == 0 || (flags & + (CHUNK_MAP_DIRTY|CHUNK_MAP_UNZEROED)) == 0); + arena_mapbitsp_write(mapbitsp, arena_mapbits_size_encode(size) | + CHUNK_MAP_BININD_INVALID | flags | CHUNK_MAP_LARGE | + CHUNK_MAP_ALLOCATED); +} + +JEMALLOC_ALWAYS_INLINE void +arena_mapbits_large_binind_set(arena_chunk_t *chunk, size_t pageind, + szind_t binind) +{ + size_t *mapbitsp = arena_mapbitsp_get(chunk, pageind); + size_t mapbits = arena_mapbitsp_read(mapbitsp); + + assert(binind <= BININD_INVALID); + assert(arena_mapbits_large_size_get(chunk, pageind) == LARGE_MINCLASS + + large_pad); + arena_mapbitsp_write(mapbitsp, (mapbits & ~CHUNK_MAP_BININD_MASK) | + (binind << CHUNK_MAP_BININD_SHIFT)); +} + +JEMALLOC_ALWAYS_INLINE void +arena_mapbits_small_set(arena_chunk_t *chunk, size_t pageind, size_t runind, + szind_t binind, size_t flags) +{ + size_t *mapbitsp = arena_mapbitsp_get(chunk, pageind); + + assert(binind < BININD_INVALID); + assert(pageind - runind >= map_bias); + assert((flags & CHUNK_MAP_UNZEROED) == flags); + arena_mapbitsp_write(mapbitsp, (runind << CHUNK_MAP_RUNIND_SHIFT) | + (binind << CHUNK_MAP_BININD_SHIFT) | flags | CHUNK_MAP_ALLOCATED); +} + +JEMALLOC_INLINE void +arena_metadata_allocated_add(arena_t *arena, size_t size) +{ + + atomic_add_z(&arena->stats.metadata_allocated, size); +} + +JEMALLOC_INLINE void +arena_metadata_allocated_sub(arena_t *arena, size_t size) +{ + + atomic_sub_z(&arena->stats.metadata_allocated, size); +} + +JEMALLOC_INLINE size_t +arena_metadata_allocated_get(arena_t *arena) +{ + + return (atomic_read_z(&arena->stats.metadata_allocated)); +} + +JEMALLOC_INLINE bool +arena_prof_accum_impl(arena_t *arena, uint64_t accumbytes) +{ + + cassert(config_prof); + assert(prof_interval != 0); + + arena->prof_accumbytes += accumbytes; + if (arena->prof_accumbytes >= prof_interval) { + arena->prof_accumbytes -= prof_interval; + return (true); + } + return (false); +} + +JEMALLOC_INLINE bool +arena_prof_accum_locked(arena_t *arena, uint64_t accumbytes) +{ + + cassert(config_prof); + + if (likely(prof_interval == 0)) + return (false); + return (arena_prof_accum_impl(arena, accumbytes)); +} + +JEMALLOC_INLINE bool +arena_prof_accum(arena_t *arena, uint64_t accumbytes) +{ + + cassert(config_prof); + + if (likely(prof_interval == 0)) + return (false); + + { + bool ret; + + malloc_mutex_lock(&arena->lock); + ret = arena_prof_accum_impl(arena, accumbytes); + malloc_mutex_unlock(&arena->lock); + return (ret); + } +} + +JEMALLOC_ALWAYS_INLINE szind_t +arena_ptr_small_binind_get(const void *ptr, size_t mapbits) +{ + szind_t binind; + + binind = (mapbits & CHUNK_MAP_BININD_MASK) >> CHUNK_MAP_BININD_SHIFT; + + if (config_debug) { + arena_chunk_t *chunk; + arena_t *arena; + size_t pageind; + size_t actual_mapbits; + size_t rpages_ind; + arena_run_t *run; + arena_bin_t *bin; + szind_t run_binind, actual_binind; + arena_bin_info_t *bin_info; + arena_chunk_map_misc_t *miscelm; + void *rpages; + + assert(binind != BININD_INVALID); + assert(binind < NBINS); + chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr); + arena = extent_node_arena_get(&chunk->node); + pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE; + actual_mapbits = arena_mapbits_get(chunk, pageind); + assert(mapbits == actual_mapbits); + assert(arena_mapbits_large_get(chunk, pageind) == 0); + assert(arena_mapbits_allocated_get(chunk, pageind) != 0); + rpages_ind = pageind - arena_mapbits_small_runind_get(chunk, + pageind); + miscelm = arena_miscelm_get(chunk, rpages_ind); + run = &miscelm->run; + run_binind = run->binind; + bin = &arena->bins[run_binind]; + actual_binind = bin - arena->bins; + assert(run_binind == actual_binind); + bin_info = &arena_bin_info[actual_binind]; + rpages = arena_miscelm_to_rpages(miscelm); + assert(((uintptr_t)ptr - ((uintptr_t)rpages + + (uintptr_t)bin_info->reg0_offset)) % bin_info->reg_interval + == 0); + } + + return (binind); +} +# endif /* JEMALLOC_ARENA_INLINE_A */ + +# ifdef JEMALLOC_ARENA_INLINE_B +JEMALLOC_INLINE szind_t +arena_bin_index(arena_t *arena, arena_bin_t *bin) +{ + szind_t binind = bin - arena->bins; + assert(binind < NBINS); + return (binind); +} + +JEMALLOC_INLINE unsigned +arena_run_regind(arena_run_t *run, arena_bin_info_t *bin_info, const void *ptr) +{ + unsigned shift, diff, regind; + size_t interval; + arena_chunk_map_misc_t *miscelm = arena_run_to_miscelm(run); + void *rpages = arena_miscelm_to_rpages(miscelm); + + /* + * Freeing a pointer lower than region zero can cause assertion + * failure. + */ + assert((uintptr_t)ptr >= (uintptr_t)rpages + + (uintptr_t)bin_info->reg0_offset); + + /* + * Avoid doing division with a variable divisor if possible. Using + * actual division here can reduce allocator throughput by over 20%! + */ + diff = (unsigned)((uintptr_t)ptr - (uintptr_t)rpages - + bin_info->reg0_offset); + + /* Rescale (factor powers of 2 out of the numerator and denominator). */ + interval = bin_info->reg_interval; + shift = jemalloc_ffs(interval) - 1; + diff >>= shift; + interval >>= shift; + + if (interval == 1) { + /* The divisor was a power of 2. */ + regind = diff; + } else { + /* + * To divide by a number D that is not a power of two we + * multiply by (2^21 / D) and then right shift by 21 positions. + * + * X / D + * + * becomes + * + * (X * interval_invs[D - 3]) >> SIZE_INV_SHIFT + * + * We can omit the first three elements, because we never + * divide by 0, and 1 and 2 are both powers of two, which are + * handled above. + */ +#define SIZE_INV_SHIFT ((sizeof(unsigned) << 3) - LG_RUN_MAXREGS) +#define SIZE_INV(s) (((1U << SIZE_INV_SHIFT) / (s)) + 1) + static const unsigned interval_invs[] = { + SIZE_INV(3), + SIZE_INV(4), SIZE_INV(5), SIZE_INV(6), SIZE_INV(7), + SIZE_INV(8), SIZE_INV(9), SIZE_INV(10), SIZE_INV(11), + SIZE_INV(12), SIZE_INV(13), SIZE_INV(14), SIZE_INV(15), + SIZE_INV(16), SIZE_INV(17), SIZE_INV(18), SIZE_INV(19), + SIZE_INV(20), SIZE_INV(21), SIZE_INV(22), SIZE_INV(23), + SIZE_INV(24), SIZE_INV(25), SIZE_INV(26), SIZE_INV(27), + SIZE_INV(28), SIZE_INV(29), SIZE_INV(30), SIZE_INV(31) + }; + + if (likely(interval <= ((sizeof(interval_invs) / + sizeof(unsigned)) + 2))) { + regind = (diff * interval_invs[interval - 3]) >> + SIZE_INV_SHIFT; + } else + regind = diff / interval; +#undef SIZE_INV +#undef SIZE_INV_SHIFT + } + assert(diff == regind * interval); + assert(regind < bin_info->nregs); + + return (regind); +} + +JEMALLOC_INLINE prof_tctx_t * +arena_prof_tctx_get(const void *ptr) +{ + prof_tctx_t *ret; + arena_chunk_t *chunk; + + cassert(config_prof); + assert(ptr != NULL); + + chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr); + if (likely(chunk != ptr)) { + size_t pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE; + size_t mapbits = arena_mapbits_get(chunk, pageind); + assert((mapbits & CHUNK_MAP_ALLOCATED) != 0); + if (likely((mapbits & CHUNK_MAP_LARGE) == 0)) + ret = (prof_tctx_t *)(uintptr_t)1U; + else { + arena_chunk_map_misc_t *elm = arena_miscelm_get(chunk, + pageind); + ret = atomic_read_p(&elm->prof_tctx_pun); + } + } else + ret = huge_prof_tctx_get(ptr); + + return (ret); +} + +JEMALLOC_INLINE void +arena_prof_tctx_set(const void *ptr, size_t usize, prof_tctx_t *tctx) +{ + arena_chunk_t *chunk; + + cassert(config_prof); + assert(ptr != NULL); + + chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr); + if (likely(chunk != ptr)) { + size_t pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE; + + assert(arena_mapbits_allocated_get(chunk, pageind) != 0); + + if (unlikely(usize > SMALL_MAXCLASS || (uintptr_t)tctx > + (uintptr_t)1U)) { + arena_chunk_map_misc_t *elm; + + assert(arena_mapbits_large_get(chunk, pageind) != 0); + + elm = arena_miscelm_get(chunk, pageind); + atomic_write_p(&elm->prof_tctx_pun, tctx); + } else { + /* + * tctx must always be initialized for large runs. + * Assert that the surrounding conditional logic is + * equivalent to checking whether ptr refers to a large + * run. + */ + assert(arena_mapbits_large_get(chunk, pageind) == 0); + } + } else + huge_prof_tctx_set(ptr, tctx); +} + +JEMALLOC_INLINE void +arena_prof_tctx_reset(const void *ptr, size_t usize, const void *old_ptr, + prof_tctx_t *old_tctx) +{ + + cassert(config_prof); + assert(ptr != NULL); + + if (unlikely(usize > SMALL_MAXCLASS || (ptr == old_ptr && + (uintptr_t)old_tctx > (uintptr_t)1U))) { + arena_chunk_t *chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr); + if (likely(chunk != ptr)) { + size_t pageind; + arena_chunk_map_misc_t *elm; + + pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> + LG_PAGE; + assert(arena_mapbits_allocated_get(chunk, pageind) != + 0); + assert(arena_mapbits_large_get(chunk, pageind) != 0); + + elm = arena_miscelm_get(chunk, pageind); + atomic_write_p(&elm->prof_tctx_pun, + (prof_tctx_t *)(uintptr_t)1U); + } else + huge_prof_tctx_reset(ptr); + } +} + +JEMALLOC_ALWAYS_INLINE void * +arena_malloc(tsd_t *tsd, arena_t *arena, size_t size, bool zero, + tcache_t *tcache) +{ + + assert(size != 0); + + arena = arena_choose(tsd, arena); + if (unlikely(arena == NULL)) + return (NULL); + + if (likely(size <= SMALL_MAXCLASS)) { + if (likely(tcache != NULL)) { + return (tcache_alloc_small(tsd, arena, tcache, size, + zero)); + } else + return (arena_malloc_small(arena, size, zero)); + } else if (likely(size <= large_maxclass)) { + /* + * Initialize tcache after checking size in order to avoid + * infinite recursion during tcache initialization. + */ + if (likely(tcache != NULL) && size <= tcache_maxclass) { + return (tcache_alloc_large(tsd, arena, tcache, size, + zero)); + } else + return (arena_malloc_large(arena, size, zero)); + } else + return (huge_malloc(tsd, arena, size, zero, tcache)); +} + +JEMALLOC_ALWAYS_INLINE arena_t * +arena_aalloc(const void *ptr) +{ + arena_chunk_t *chunk; + + chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr); + if (likely(chunk != ptr)) + return (extent_node_arena_get(&chunk->node)); + else + return (huge_aalloc(ptr)); +} + +/* Return the size of the allocation pointed to by ptr. */ +JEMALLOC_ALWAYS_INLINE size_t +arena_salloc(const void *ptr, bool demote) +{ + size_t ret; + arena_chunk_t *chunk; + size_t pageind; + szind_t binind; + + assert(ptr != NULL); + + chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr); + if (likely(chunk != ptr)) { + pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE; + assert(arena_mapbits_allocated_get(chunk, pageind) != 0); + binind = arena_mapbits_binind_get(chunk, pageind); + if (unlikely(binind == BININD_INVALID || (config_prof && !demote + && arena_mapbits_large_get(chunk, pageind) != 0))) { + /* + * Large allocation. In the common case (demote), and + * as this is an inline function, most callers will only + * end up looking at binind to determine that ptr is a + * small allocation. + */ + assert(config_cache_oblivious || ((uintptr_t)ptr & + PAGE_MASK) == 0); + ret = arena_mapbits_large_size_get(chunk, pageind) - + large_pad; + assert(ret != 0); + assert(pageind + ((ret+large_pad)>>LG_PAGE) <= + chunk_npages); + assert(arena_mapbits_dirty_get(chunk, pageind) == + arena_mapbits_dirty_get(chunk, + pageind+((ret+large_pad)>>LG_PAGE)-1)); + } else { + /* + * Small allocation (possibly promoted to a large + * object). + */ + assert(arena_mapbits_large_get(chunk, pageind) != 0 || + arena_ptr_small_binind_get(ptr, + arena_mapbits_get(chunk, pageind)) == binind); + ret = index2size(binind); + } + } else + ret = huge_salloc(ptr); + + return (ret); +} + +JEMALLOC_ALWAYS_INLINE void +arena_dalloc(tsd_t *tsd, void *ptr, tcache_t *tcache) +{ + arena_chunk_t *chunk; + size_t pageind, mapbits; + + assert(ptr != NULL); + + chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr); + if (likely(chunk != ptr)) { + pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE; + mapbits = arena_mapbits_get(chunk, pageind); + assert(arena_mapbits_allocated_get(chunk, pageind) != 0); + if (likely((mapbits & CHUNK_MAP_LARGE) == 0)) { + /* Small allocation. */ + if (likely(tcache != NULL)) { + szind_t binind = arena_ptr_small_binind_get(ptr, + mapbits); + tcache_dalloc_small(tsd, tcache, ptr, binind); + } else { + arena_dalloc_small(extent_node_arena_get( + &chunk->node), chunk, ptr, pageind); + } + } else { + size_t size = arena_mapbits_large_size_get(chunk, + pageind); + + assert(config_cache_oblivious || ((uintptr_t)ptr & + PAGE_MASK) == 0); + + if (likely(tcache != NULL) && size - large_pad <= + tcache_maxclass) { + tcache_dalloc_large(tsd, tcache, ptr, size - + large_pad); + } else { + arena_dalloc_large(extent_node_arena_get( + &chunk->node), chunk, ptr); + } + } + } else + huge_dalloc(tsd, ptr, tcache); +} + +JEMALLOC_ALWAYS_INLINE void +arena_sdalloc(tsd_t *tsd, void *ptr, size_t size, tcache_t *tcache) +{ + arena_chunk_t *chunk; + + chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr); + if (likely(chunk != ptr)) { + if (config_prof && opt_prof) { + size_t pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> + LG_PAGE; + assert(arena_mapbits_allocated_get(chunk, pageind) != 0); + if (arena_mapbits_large_get(chunk, pageind) != 0) { + /* + * Make sure to use promoted size, not request + * size. + */ + size = arena_mapbits_large_size_get(chunk, + pageind) - large_pad; + } + } + assert(s2u(size) == s2u(arena_salloc(ptr, false))); + + if (likely(size <= SMALL_MAXCLASS)) { + /* Small allocation. */ + if (likely(tcache != NULL)) { + szind_t binind = size2index(size); + tcache_dalloc_small(tsd, tcache, ptr, binind); + } else { + size_t pageind = ((uintptr_t)ptr - + (uintptr_t)chunk) >> LG_PAGE; + arena_dalloc_small(extent_node_arena_get( + &chunk->node), chunk, ptr, pageind); + } + } else { + assert(config_cache_oblivious || ((uintptr_t)ptr & + PAGE_MASK) == 0); + + if (likely(tcache != NULL) && size <= tcache_maxclass) + tcache_dalloc_large(tsd, tcache, ptr, size); + else { + arena_dalloc_large(extent_node_arena_get( + &chunk->node), chunk, ptr); + } + } + } else + huge_dalloc(tsd, ptr, tcache); +} +# endif /* JEMALLOC_ARENA_INLINE_B */ +#endif + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/atomic.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/atomic.h new file mode 100644 index 0000000..a9aad35 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/atomic.h @@ -0,0 +1,651 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +#define atomic_read_uint64(p) atomic_add_uint64(p, 0) +#define atomic_read_uint32(p) atomic_add_uint32(p, 0) +#define atomic_read_p(p) atomic_add_p(p, NULL) +#define atomic_read_z(p) atomic_add_z(p, 0) +#define atomic_read_u(p) atomic_add_u(p, 0) + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +/* + * All arithmetic functions return the arithmetic result of the atomic + * operation. Some atomic operation APIs return the value prior to mutation, in + * which case the following functions must redundantly compute the result so + * that it can be returned. These functions are normally inlined, so the extra + * operations can be optimized away if the return values aren't used by the + * callers. + * + * atomic_read_( *p) { return (*p); } + * atomic_add_( *p, x) { return (*p + x); } + * atomic_sub_( *p, x) { return (*p - x); } + * bool atomic_cas_( *p, c, s) + * { + * if (*p != c) + * return (true); + * *p = s; + * return (false); + * } + * void atomic_write_( *p, x) { *p = x; } + */ + +#ifndef JEMALLOC_ENABLE_INLINE +uint64_t atomic_add_uint64(uint64_t *p, uint64_t x); +uint64_t atomic_sub_uint64(uint64_t *p, uint64_t x); +bool atomic_cas_uint64(uint64_t *p, uint64_t c, uint64_t s); +void atomic_write_uint64(uint64_t *p, uint64_t x); +uint32_t atomic_add_uint32(uint32_t *p, uint32_t x); +uint32_t atomic_sub_uint32(uint32_t *p, uint32_t x); +bool atomic_cas_uint32(uint32_t *p, uint32_t c, uint32_t s); +void atomic_write_uint32(uint32_t *p, uint32_t x); +void *atomic_add_p(void **p, void *x); +void *atomic_sub_p(void **p, void *x); +bool atomic_cas_p(void **p, void *c, void *s); +void atomic_write_p(void **p, const void *x); +size_t atomic_add_z(size_t *p, size_t x); +size_t atomic_sub_z(size_t *p, size_t x); +bool atomic_cas_z(size_t *p, size_t c, size_t s); +void atomic_write_z(size_t *p, size_t x); +unsigned atomic_add_u(unsigned *p, unsigned x); +unsigned atomic_sub_u(unsigned *p, unsigned x); +bool atomic_cas_u(unsigned *p, unsigned c, unsigned s); +void atomic_write_u(unsigned *p, unsigned x); +#endif + +#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_ATOMIC_C_)) +/******************************************************************************/ +/* 64-bit operations. */ +#if (LG_SIZEOF_PTR == 3 || LG_SIZEOF_INT == 3) +# if (defined(__amd64__) || defined(__x86_64__)) +JEMALLOC_INLINE uint64_t +atomic_add_uint64(uint64_t *p, uint64_t x) +{ + uint64_t t = x; + + asm volatile ( + "lock; xaddq %0, %1;" + : "+r" (t), "=m" (*p) /* Outputs. */ + : "m" (*p) /* Inputs. */ + ); + + return (t + x); +} + +JEMALLOC_INLINE uint64_t +atomic_sub_uint64(uint64_t *p, uint64_t x) +{ + uint64_t t; + + x = (uint64_t)(-(int64_t)x); + t = x; + asm volatile ( + "lock; xaddq %0, %1;" + : "+r" (t), "=m" (*p) /* Outputs. */ + : "m" (*p) /* Inputs. */ + ); + + return (t + x); +} + +JEMALLOC_INLINE bool +atomic_cas_uint64(uint64_t *p, uint64_t c, uint64_t s) +{ + uint8_t success; + + asm volatile ( + "lock; cmpxchgq %4, %0;" + "sete %1;" + : "=m" (*p), "=a" (success) /* Outputs. */ + : "m" (*p), "a" (c), "r" (s) /* Inputs. */ + : "memory" /* Clobbers. */ + ); + + return (!(bool)success); +} + +JEMALLOC_INLINE void +atomic_write_uint64(uint64_t *p, uint64_t x) +{ + + asm volatile ( + "xchgq %1, %0;" /* Lock is implied by xchgq. */ + : "=m" (*p), "+r" (x) /* Outputs. */ + : "m" (*p) /* Inputs. */ + : "memory" /* Clobbers. */ + ); +} +# elif (defined(JEMALLOC_C11ATOMICS)) +JEMALLOC_INLINE uint64_t +atomic_add_uint64(uint64_t *p, uint64_t x) +{ + volatile atomic_uint_least64_t *a = (volatile atomic_uint_least64_t *)p; + return (atomic_fetch_add(a, x) + x); +} + +JEMALLOC_INLINE uint64_t +atomic_sub_uint64(uint64_t *p, uint64_t x) +{ + volatile atomic_uint_least64_t *a = (volatile atomic_uint_least64_t *)p; + return (atomic_fetch_sub(a, x) - x); +} + +JEMALLOC_INLINE bool +atomic_cas_uint64(uint64_t *p, uint64_t c, uint64_t s) +{ + volatile atomic_uint_least64_t *a = (volatile atomic_uint_least64_t *)p; + return (!atomic_compare_exchange_strong(a, &c, s)); +} + +JEMALLOC_INLINE void +atomic_write_uint64(uint64_t *p, uint64_t x) +{ + volatile atomic_uint_least64_t *a = (volatile atomic_uint_least64_t *)p; + atomic_store(a, x); +} +# elif (defined(JEMALLOC_ATOMIC9)) +JEMALLOC_INLINE uint64_t +atomic_add_uint64(uint64_t *p, uint64_t x) +{ + + /* + * atomic_fetchadd_64() doesn't exist, but we only ever use this + * function on LP64 systems, so atomic_fetchadd_long() will do. + */ + assert(sizeof(uint64_t) == sizeof(unsigned long)); + + return (atomic_fetchadd_long(p, (unsigned long)x) + x); +} + +JEMALLOC_INLINE uint64_t +atomic_sub_uint64(uint64_t *p, uint64_t x) +{ + + assert(sizeof(uint64_t) == sizeof(unsigned long)); + + return (atomic_fetchadd_long(p, (unsigned long)(-(long)x)) - x); +} + +JEMALLOC_INLINE bool +atomic_cas_uint64(uint64_t *p, uint64_t c, uint64_t s) +{ + + assert(sizeof(uint64_t) == sizeof(unsigned long)); + + return (!atomic_cmpset_long(p, (unsigned long)c, (unsigned long)s)); +} + +JEMALLOC_INLINE void +atomic_write_uint64(uint64_t *p, uint64_t x) +{ + + assert(sizeof(uint64_t) == sizeof(unsigned long)); + + atomic_store_rel_long(p, x); +} +# elif (defined(JEMALLOC_OSATOMIC)) +JEMALLOC_INLINE uint64_t +atomic_add_uint64(uint64_t *p, uint64_t x) +{ + + return (OSAtomicAdd64((int64_t)x, (int64_t *)p)); +} + +JEMALLOC_INLINE uint64_t +atomic_sub_uint64(uint64_t *p, uint64_t x) +{ + + return (OSAtomicAdd64(-((int64_t)x), (int64_t *)p)); +} + +JEMALLOC_INLINE bool +atomic_cas_uint64(uint64_t *p, uint64_t c, uint64_t s) +{ + + return (!OSAtomicCompareAndSwap64(c, s, (int64_t *)p)); +} + +JEMALLOC_INLINE void +atomic_write_uint64(uint64_t *p, uint64_t x) +{ + uint64_t o; + + /*The documented OSAtomic*() API does not expose an atomic exchange. */ + do { + o = atomic_read_uint64(p); + } while (atomic_cas_uint64(p, o, x)); +} +# elif (defined(_MSC_VER)) +JEMALLOC_INLINE uint64_t +atomic_add_uint64(uint64_t *p, uint64_t x) +{ + + return (InterlockedExchangeAdd64(p, x) + x); +} + +JEMALLOC_INLINE uint64_t +atomic_sub_uint64(uint64_t *p, uint64_t x) +{ + + return (InterlockedExchangeAdd64(p, -((int64_t)x)) - x); +} + +JEMALLOC_INLINE bool +atomic_cas_uint64(uint64_t *p, uint64_t c, uint64_t s) +{ + uint64_t o; + + o = InterlockedCompareExchange64(p, s, c); + return (o != c); +} + +JEMALLOC_INLINE void +atomic_write_uint64(uint64_t *p, uint64_t x) +{ + + InterlockedExchange64(p, x); +} +# elif (defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8) || \ + defined(JE_FORCE_SYNC_COMPARE_AND_SWAP_8)) +JEMALLOC_INLINE uint64_t +atomic_add_uint64(uint64_t *p, uint64_t x) +{ + + return (__sync_add_and_fetch(p, x)); +} + +JEMALLOC_INLINE uint64_t +atomic_sub_uint64(uint64_t *p, uint64_t x) +{ + + return (__sync_sub_and_fetch(p, x)); +} + +JEMALLOC_INLINE bool +atomic_cas_uint64(uint64_t *p, uint64_t c, uint64_t s) +{ + + return (!__sync_bool_compare_and_swap(p, c, s)); +} + +JEMALLOC_INLINE void +atomic_write_uint64(uint64_t *p, uint64_t x) +{ + + __sync_lock_test_and_set(p, x); +} +# else +# error "Missing implementation for 64-bit atomic operations" +# endif +#endif + +/******************************************************************************/ +/* 32-bit operations. */ +#if (defined(__i386__) || defined(__amd64__) || defined(__x86_64__)) +JEMALLOC_INLINE uint32_t +atomic_add_uint32(uint32_t *p, uint32_t x) +{ + uint32_t t = x; + + asm volatile ( + "lock; xaddl %0, %1;" + : "+r" (t), "=m" (*p) /* Outputs. */ + : "m" (*p) /* Inputs. */ + ); + + return (t + x); +} + +JEMALLOC_INLINE uint32_t +atomic_sub_uint32(uint32_t *p, uint32_t x) +{ + uint32_t t; + + x = (uint32_t)(-(int32_t)x); + t = x; + asm volatile ( + "lock; xaddl %0, %1;" + : "+r" (t), "=m" (*p) /* Outputs. */ + : "m" (*p) /* Inputs. */ + ); + + return (t + x); +} + +JEMALLOC_INLINE bool +atomic_cas_uint32(uint32_t *p, uint32_t c, uint32_t s) +{ + uint8_t success; + + asm volatile ( + "lock; cmpxchgl %4, %0;" + "sete %1;" + : "=m" (*p), "=a" (success) /* Outputs. */ + : "m" (*p), "a" (c), "r" (s) /* Inputs. */ + : "memory" + ); + + return (!(bool)success); +} + +JEMALLOC_INLINE void +atomic_write_uint32(uint32_t *p, uint32_t x) +{ + + asm volatile ( + "xchgl %1, %0;" /* Lock is implied by xchgl. */ + : "=m" (*p), "+r" (x) /* Outputs. */ + : "m" (*p) /* Inputs. */ + : "memory" /* Clobbers. */ + ); +} +# elif (defined(JEMALLOC_C11ATOMICS)) +JEMALLOC_INLINE uint32_t +atomic_add_uint32(uint32_t *p, uint32_t x) +{ + volatile atomic_uint_least32_t *a = (volatile atomic_uint_least32_t *)p; + return (atomic_fetch_add(a, x) + x); +} + +JEMALLOC_INLINE uint32_t +atomic_sub_uint32(uint32_t *p, uint32_t x) +{ + volatile atomic_uint_least32_t *a = (volatile atomic_uint_least32_t *)p; + return (atomic_fetch_sub(a, x) - x); +} + +JEMALLOC_INLINE bool +atomic_cas_uint32(uint32_t *p, uint32_t c, uint32_t s) +{ + volatile atomic_uint_least32_t *a = (volatile atomic_uint_least32_t *)p; + return (!atomic_compare_exchange_strong(a, &c, s)); +} + +JEMALLOC_INLINE void +atomic_write_uint32(uint32_t *p, uint32_t x) +{ + volatile atomic_uint_least32_t *a = (volatile atomic_uint_least32_t *)p; + atomic_store(a, x); +} +#elif (defined(JEMALLOC_ATOMIC9)) +JEMALLOC_INLINE uint32_t +atomic_add_uint32(uint32_t *p, uint32_t x) +{ + + return (atomic_fetchadd_32(p, x) + x); +} + +JEMALLOC_INLINE uint32_t +atomic_sub_uint32(uint32_t *p, uint32_t x) +{ + + return (atomic_fetchadd_32(p, (uint32_t)(-(int32_t)x)) - x); +} + +JEMALLOC_INLINE bool +atomic_cas_uint32(uint32_t *p, uint32_t c, uint32_t s) +{ + + return (!atomic_cmpset_32(p, c, s)); +} + +JEMALLOC_INLINE void +atomic_write_uint32(uint32_t *p, uint32_t x) +{ + + atomic_store_rel_32(p, x); +} +#elif (defined(JEMALLOC_OSATOMIC)) +JEMALLOC_INLINE uint32_t +atomic_add_uint32(uint32_t *p, uint32_t x) +{ + + return (OSAtomicAdd32((int32_t)x, (int32_t *)p)); +} + +JEMALLOC_INLINE uint32_t +atomic_sub_uint32(uint32_t *p, uint32_t x) +{ + + return (OSAtomicAdd32(-((int32_t)x), (int32_t *)p)); +} + +JEMALLOC_INLINE bool +atomic_cas_uint32(uint32_t *p, uint32_t c, uint32_t s) +{ + + return (!OSAtomicCompareAndSwap32(c, s, (int32_t *)p)); +} + +JEMALLOC_INLINE void +atomic_write_uint32(uint32_t *p, uint32_t x) +{ + uint32_t o; + + /*The documented OSAtomic*() API does not expose an atomic exchange. */ + do { + o = atomic_read_uint32(p); + } while (atomic_cas_uint32(p, o, x)); +} +#elif (defined(_MSC_VER)) +JEMALLOC_INLINE uint32_t +atomic_add_uint32(uint32_t *p, uint32_t x) +{ + + return (InterlockedExchangeAdd(p, x) + x); +} + +JEMALLOC_INLINE uint32_t +atomic_sub_uint32(uint32_t *p, uint32_t x) +{ + + return (InterlockedExchangeAdd(p, -((int32_t)x)) - x); +} + +JEMALLOC_INLINE bool +atomic_cas_uint32(uint32_t *p, uint32_t c, uint32_t s) +{ + uint32_t o; + + o = InterlockedCompareExchange(p, s, c); + return (o != c); +} + +JEMALLOC_INLINE void +atomic_write_uint32(uint32_t *p, uint32_t x) +{ + + InterlockedExchange(p, x); +} +#elif (defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) || \ + defined(JE_FORCE_SYNC_COMPARE_AND_SWAP_4)) +JEMALLOC_INLINE uint32_t +atomic_add_uint32(uint32_t *p, uint32_t x) +{ + + return (__sync_add_and_fetch(p, x)); +} + +JEMALLOC_INLINE uint32_t +atomic_sub_uint32(uint32_t *p, uint32_t x) +{ + + return (__sync_sub_and_fetch(p, x)); +} + +JEMALLOC_INLINE bool +atomic_cas_uint32(uint32_t *p, uint32_t c, uint32_t s) +{ + + return (!__sync_bool_compare_and_swap(p, c, s)); +} + +JEMALLOC_INLINE void +atomic_write_uint32(uint32_t *p, uint32_t x) +{ + + __sync_lock_test_and_set(p, x); +} +#else +# error "Missing implementation for 32-bit atomic operations" +#endif + +/******************************************************************************/ +/* Pointer operations. */ +JEMALLOC_INLINE void * +atomic_add_p(void **p, void *x) +{ + +#if (LG_SIZEOF_PTR == 3) + return ((void *)atomic_add_uint64((uint64_t *)p, (uint64_t)x)); +#elif (LG_SIZEOF_PTR == 2) + return ((void *)atomic_add_uint32((uint32_t *)p, (uint32_t)x)); +#endif +} + +JEMALLOC_INLINE void * +atomic_sub_p(void **p, void *x) +{ + +#if (LG_SIZEOF_PTR == 3) + return ((void *)atomic_add_uint64((uint64_t *)p, + (uint64_t)-((int64_t)x))); +#elif (LG_SIZEOF_PTR == 2) + return ((void *)atomic_add_uint32((uint32_t *)p, + (uint32_t)-((int32_t)x))); +#endif +} + +JEMALLOC_INLINE bool +atomic_cas_p(void **p, void *c, void *s) +{ + +#if (LG_SIZEOF_PTR == 3) + return (atomic_cas_uint64((uint64_t *)p, (uint64_t)c, (uint64_t)s)); +#elif (LG_SIZEOF_PTR == 2) + return (atomic_cas_uint32((uint32_t *)p, (uint32_t)c, (uint32_t)s)); +#endif +} + +JEMALLOC_INLINE void +atomic_write_p(void **p, const void *x) +{ + +#if (LG_SIZEOF_PTR == 3) + atomic_write_uint64((uint64_t *)p, (uint64_t)x); +#elif (LG_SIZEOF_PTR == 2) + atomic_write_uint32((uint32_t *)p, (uint32_t)x); +#endif +} + +/******************************************************************************/ +/* size_t operations. */ +JEMALLOC_INLINE size_t +atomic_add_z(size_t *p, size_t x) +{ + +#if (LG_SIZEOF_PTR == 3) + return ((size_t)atomic_add_uint64((uint64_t *)p, (uint64_t)x)); +#elif (LG_SIZEOF_PTR == 2) + return ((size_t)atomic_add_uint32((uint32_t *)p, (uint32_t)x)); +#endif +} + +JEMALLOC_INLINE size_t +atomic_sub_z(size_t *p, size_t x) +{ + +#if (LG_SIZEOF_PTR == 3) + return ((size_t)atomic_add_uint64((uint64_t *)p, + (uint64_t)-((int64_t)x))); +#elif (LG_SIZEOF_PTR == 2) + return ((size_t)atomic_add_uint32((uint32_t *)p, + (uint32_t)-((int32_t)x))); +#endif +} + +JEMALLOC_INLINE bool +atomic_cas_z(size_t *p, size_t c, size_t s) +{ + +#if (LG_SIZEOF_PTR == 3) + return (atomic_cas_uint64((uint64_t *)p, (uint64_t)c, (uint64_t)s)); +#elif (LG_SIZEOF_PTR == 2) + return (atomic_cas_uint32((uint32_t *)p, (uint32_t)c, (uint32_t)s)); +#endif +} + +JEMALLOC_INLINE void +atomic_write_z(size_t *p, size_t x) +{ + +#if (LG_SIZEOF_PTR == 3) + atomic_write_uint64((uint64_t *)p, (uint64_t)x); +#elif (LG_SIZEOF_PTR == 2) + atomic_write_uint32((uint32_t *)p, (uint32_t)x); +#endif +} + +/******************************************************************************/ +/* unsigned operations. */ +JEMALLOC_INLINE unsigned +atomic_add_u(unsigned *p, unsigned x) +{ + +#if (LG_SIZEOF_INT == 3) + return ((unsigned)atomic_add_uint64((uint64_t *)p, (uint64_t)x)); +#elif (LG_SIZEOF_INT == 2) + return ((unsigned)atomic_add_uint32((uint32_t *)p, (uint32_t)x)); +#endif +} + +JEMALLOC_INLINE unsigned +atomic_sub_u(unsigned *p, unsigned x) +{ + +#if (LG_SIZEOF_INT == 3) + return ((unsigned)atomic_add_uint64((uint64_t *)p, + (uint64_t)-((int64_t)x))); +#elif (LG_SIZEOF_INT == 2) + return ((unsigned)atomic_add_uint32((uint32_t *)p, + (uint32_t)-((int32_t)x))); +#endif +} + +JEMALLOC_INLINE bool +atomic_cas_u(unsigned *p, unsigned c, unsigned s) +{ + +#if (LG_SIZEOF_INT == 3) + return (atomic_cas_uint64((uint64_t *)p, (uint64_t)c, (uint64_t)s)); +#elif (LG_SIZEOF_INT == 2) + return (atomic_cas_uint32((uint32_t *)p, (uint32_t)c, (uint32_t)s)); +#endif +} + +JEMALLOC_INLINE void +atomic_write_u(unsigned *p, unsigned x) +{ + +#if (LG_SIZEOF_INT == 3) + atomic_write_uint64((uint64_t *)p, (uint64_t)x); +#elif (LG_SIZEOF_INT == 2) + atomic_write_uint32((uint32_t *)p, (uint32_t)x); +#endif +} + +/******************************************************************************/ +#endif + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/base.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/base.h new file mode 100644 index 0000000..39e46ee --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/base.h @@ -0,0 +1,24 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +void *base_alloc(size_t size); +void base_stats_get(size_t *allocated, size_t *resident, size_t *mapped); +bool base_boot(void); +void base_prefork(void); +void base_postfork_parent(void); +void base_postfork_child(void); + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/bitmap.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/bitmap.h new file mode 100644 index 0000000..fcc6005 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/bitmap.h @@ -0,0 +1,230 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +/* Maximum bitmap bit count is 2^LG_BITMAP_MAXBITS. */ +#define LG_BITMAP_MAXBITS LG_RUN_MAXREGS +#define BITMAP_MAXBITS (ZU(1) << LG_BITMAP_MAXBITS) + +typedef struct bitmap_level_s bitmap_level_t; +typedef struct bitmap_info_s bitmap_info_t; +typedef unsigned long bitmap_t; +#define LG_SIZEOF_BITMAP LG_SIZEOF_LONG + +/* Number of bits per group. */ +#define LG_BITMAP_GROUP_NBITS (LG_SIZEOF_BITMAP + 3) +#define BITMAP_GROUP_NBITS (ZU(1) << LG_BITMAP_GROUP_NBITS) +#define BITMAP_GROUP_NBITS_MASK (BITMAP_GROUP_NBITS-1) + +/* Number of groups required to store a given number of bits. */ +#define BITMAP_BITS2GROUPS(nbits) \ + ((nbits + BITMAP_GROUP_NBITS_MASK) >> LG_BITMAP_GROUP_NBITS) + +/* + * Number of groups required at a particular level for a given number of bits. + */ +#define BITMAP_GROUPS_L0(nbits) \ + BITMAP_BITS2GROUPS(nbits) +#define BITMAP_GROUPS_L1(nbits) \ + BITMAP_BITS2GROUPS(BITMAP_BITS2GROUPS(nbits)) +#define BITMAP_GROUPS_L2(nbits) \ + BITMAP_BITS2GROUPS(BITMAP_BITS2GROUPS(BITMAP_BITS2GROUPS((nbits)))) +#define BITMAP_GROUPS_L3(nbits) \ + BITMAP_BITS2GROUPS(BITMAP_BITS2GROUPS(BITMAP_BITS2GROUPS( \ + BITMAP_BITS2GROUPS((nbits))))) + +/* + * Assuming the number of levels, number of groups required for a given number + * of bits. + */ +#define BITMAP_GROUPS_1_LEVEL(nbits) \ + BITMAP_GROUPS_L0(nbits) +#define BITMAP_GROUPS_2_LEVEL(nbits) \ + (BITMAP_GROUPS_1_LEVEL(nbits) + BITMAP_GROUPS_L1(nbits)) +#define BITMAP_GROUPS_3_LEVEL(nbits) \ + (BITMAP_GROUPS_2_LEVEL(nbits) + BITMAP_GROUPS_L2(nbits)) +#define BITMAP_GROUPS_4_LEVEL(nbits) \ + (BITMAP_GROUPS_3_LEVEL(nbits) + BITMAP_GROUPS_L3(nbits)) + +/* + * Maximum number of groups required to support LG_BITMAP_MAXBITS. + */ +#if LG_BITMAP_MAXBITS <= LG_BITMAP_GROUP_NBITS +# define BITMAP_GROUPS_MAX BITMAP_GROUPS_1_LEVEL(BITMAP_MAXBITS) +#elif LG_BITMAP_MAXBITS <= LG_BITMAP_GROUP_NBITS * 2 +# define BITMAP_GROUPS_MAX BITMAP_GROUPS_2_LEVEL(BITMAP_MAXBITS) +#elif LG_BITMAP_MAXBITS <= LG_BITMAP_GROUP_NBITS * 3 +# define BITMAP_GROUPS_MAX BITMAP_GROUPS_3_LEVEL(BITMAP_MAXBITS) +#elif LG_BITMAP_MAXBITS <= LG_BITMAP_GROUP_NBITS * 4 +# define BITMAP_GROUPS_MAX BITMAP_GROUPS_4_LEVEL(BITMAP_MAXBITS) +#else +# error "Unsupported bitmap size" +#endif + +/* Maximum number of levels possible. */ +#define BITMAP_MAX_LEVELS \ + (LG_BITMAP_MAXBITS / LG_SIZEOF_BITMAP) \ + + !!(LG_BITMAP_MAXBITS % LG_SIZEOF_BITMAP) + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +struct bitmap_level_s { + /* Offset of this level's groups within the array of groups. */ + size_t group_offset; +}; + +struct bitmap_info_s { + /* Logical number of bits in bitmap (stored at bottom level). */ + size_t nbits; + + /* Number of levels necessary for nbits. */ + unsigned nlevels; + + /* + * Only the first (nlevels+1) elements are used, and levels are ordered + * bottom to top (e.g. the bottom level is stored in levels[0]). + */ + bitmap_level_t levels[BITMAP_MAX_LEVELS+1]; +}; + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +void bitmap_info_init(bitmap_info_t *binfo, size_t nbits); +size_t bitmap_info_ngroups(const bitmap_info_t *binfo); +size_t bitmap_size(size_t nbits); +void bitmap_init(bitmap_t *bitmap, const bitmap_info_t *binfo); + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#ifndef JEMALLOC_ENABLE_INLINE +bool bitmap_full(bitmap_t *bitmap, const bitmap_info_t *binfo); +bool bitmap_get(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit); +void bitmap_set(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit); +size_t bitmap_sfu(bitmap_t *bitmap, const bitmap_info_t *binfo); +void bitmap_unset(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit); +#endif + +#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_BITMAP_C_)) +JEMALLOC_INLINE bool +bitmap_full(bitmap_t *bitmap, const bitmap_info_t *binfo) +{ + unsigned rgoff = binfo->levels[binfo->nlevels].group_offset - 1; + bitmap_t rg = bitmap[rgoff]; + /* The bitmap is full iff the root group is 0. */ + return (rg == 0); +} + +JEMALLOC_INLINE bool +bitmap_get(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit) +{ + size_t goff; + bitmap_t g; + + assert(bit < binfo->nbits); + goff = bit >> LG_BITMAP_GROUP_NBITS; + g = bitmap[goff]; + return (!(g & (1LU << (bit & BITMAP_GROUP_NBITS_MASK)))); +} + +JEMALLOC_INLINE void +bitmap_set(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit) +{ + size_t goff; + bitmap_t *gp; + bitmap_t g; + + assert(bit < binfo->nbits); + assert(!bitmap_get(bitmap, binfo, bit)); + goff = bit >> LG_BITMAP_GROUP_NBITS; + gp = &bitmap[goff]; + g = *gp; + assert(g & (1LU << (bit & BITMAP_GROUP_NBITS_MASK))); + g ^= 1LU << (bit & BITMAP_GROUP_NBITS_MASK); + *gp = g; + assert(bitmap_get(bitmap, binfo, bit)); + /* Propagate group state transitions up the tree. */ + if (g == 0) { + unsigned i; + for (i = 1; i < binfo->nlevels; i++) { + bit = goff; + goff = bit >> LG_BITMAP_GROUP_NBITS; + gp = &bitmap[binfo->levels[i].group_offset + goff]; + g = *gp; + assert(g & (1LU << (bit & BITMAP_GROUP_NBITS_MASK))); + g ^= 1LU << (bit & BITMAP_GROUP_NBITS_MASK); + *gp = g; + if (g != 0) + break; + } + } +} + +/* sfu: set first unset. */ +JEMALLOC_INLINE size_t +bitmap_sfu(bitmap_t *bitmap, const bitmap_info_t *binfo) +{ + size_t bit; + bitmap_t g; + unsigned i; + + assert(!bitmap_full(bitmap, binfo)); + + i = binfo->nlevels - 1; + g = bitmap[binfo->levels[i].group_offset]; + bit = jemalloc_ffsl(g) - 1; + while (i > 0) { + i--; + g = bitmap[binfo->levels[i].group_offset + bit]; + bit = (bit << LG_BITMAP_GROUP_NBITS) + (jemalloc_ffsl(g) - 1); + } + + bitmap_set(bitmap, binfo, bit); + return (bit); +} + +JEMALLOC_INLINE void +bitmap_unset(bitmap_t *bitmap, const bitmap_info_t *binfo, size_t bit) +{ + size_t goff; + bitmap_t *gp; + bitmap_t g; + bool propagate; + + assert(bit < binfo->nbits); + assert(bitmap_get(bitmap, binfo, bit)); + goff = bit >> LG_BITMAP_GROUP_NBITS; + gp = &bitmap[goff]; + g = *gp; + propagate = (g == 0); + assert((g & (1LU << (bit & BITMAP_GROUP_NBITS_MASK))) == 0); + g ^= 1LU << (bit & BITMAP_GROUP_NBITS_MASK); + *gp = g; + assert(!bitmap_get(bitmap, binfo, bit)); + /* Propagate group state transitions up the tree. */ + if (propagate) { + unsigned i; + for (i = 1; i < binfo->nlevels; i++) { + bit = goff; + goff = bit >> LG_BITMAP_GROUP_NBITS; + gp = &bitmap[binfo->levels[i].group_offset + goff]; + g = *gp; + propagate = (g == 0); + assert((g & (1LU << (bit & BITMAP_GROUP_NBITS_MASK))) + == 0); + g ^= 1LU << (bit & BITMAP_GROUP_NBITS_MASK); + *gp = g; + if (!propagate) + break; + } + } +} + +#endif + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/chunk.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/chunk.h new file mode 100644 index 0000000..5d19383 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/chunk.h @@ -0,0 +1,99 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +/* + * Size and alignment of memory chunks that are allocated by the OS's virtual + * memory system. + */ +#define LG_CHUNK_DEFAULT 21 + +/* Return the chunk address for allocation address a. */ +#define CHUNK_ADDR2BASE(a) \ + ((void *)((uintptr_t)(a) & ~chunksize_mask)) + +/* Return the chunk offset of address a. */ +#define CHUNK_ADDR2OFFSET(a) \ + ((size_t)((uintptr_t)(a) & chunksize_mask)) + +/* Return the smallest chunk multiple that is >= s. */ +#define CHUNK_CEILING(s) \ + (((s) + chunksize_mask) & ~chunksize_mask) + +#define CHUNK_HOOKS_INITIALIZER { \ + NULL, \ + NULL, \ + NULL, \ + NULL, \ + NULL, \ + NULL, \ + NULL \ +} + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +extern size_t opt_lg_chunk; +extern const char *opt_dss; + +extern rtree_t chunks_rtree; + +extern size_t chunksize; +extern size_t chunksize_mask; /* (chunksize - 1). */ +extern size_t chunk_npages; + +extern const chunk_hooks_t chunk_hooks_default; + +chunk_hooks_t chunk_hooks_get(arena_t *arena); +chunk_hooks_t chunk_hooks_set(arena_t *arena, + const chunk_hooks_t *chunk_hooks); + +bool chunk_register(const void *chunk, const extent_node_t *node); +void chunk_deregister(const void *chunk, const extent_node_t *node); +void *chunk_alloc_base(size_t size); +void *chunk_alloc_cache(arena_t *arena, chunk_hooks_t *chunk_hooks, + void *new_addr, size_t size, size_t alignment, bool *zero, + bool dalloc_node); +void *chunk_alloc_wrapper(arena_t *arena, chunk_hooks_t *chunk_hooks, + void *new_addr, size_t size, size_t alignment, bool *zero, bool *commit); +void chunk_dalloc_cache(arena_t *arena, chunk_hooks_t *chunk_hooks, + void *chunk, size_t size, bool committed); +void chunk_dalloc_arena(arena_t *arena, chunk_hooks_t *chunk_hooks, + void *chunk, size_t size, bool zeroed, bool committed); +void chunk_dalloc_wrapper(arena_t *arena, chunk_hooks_t *chunk_hooks, + void *chunk, size_t size, bool committed); +bool chunk_purge_arena(arena_t *arena, void *chunk, size_t offset, + size_t length); +bool chunk_purge_wrapper(arena_t *arena, chunk_hooks_t *chunk_hooks, + void *chunk, size_t size, size_t offset, size_t length); +bool chunk_boot(void); +void chunk_prefork(void); +void chunk_postfork_parent(void); +void chunk_postfork_child(void); + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#ifndef JEMALLOC_ENABLE_INLINE +extent_node_t *chunk_lookup(const void *chunk, bool dependent); +#endif + +#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_CHUNK_C_)) +JEMALLOC_INLINE extent_node_t * +chunk_lookup(const void *ptr, bool dependent) +{ + + return (rtree_get(&chunks_rtree, (uintptr_t)ptr, dependent)); +} +#endif + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ + +#include "jemalloc/internal/chunk_dss.h" +#include "jemalloc/internal/chunk_mmap.h" diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/chunk_dss.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/chunk_dss.h new file mode 100644 index 0000000..388f46b --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/chunk_dss.h @@ -0,0 +1,39 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +typedef enum { + dss_prec_disabled = 0, + dss_prec_primary = 1, + dss_prec_secondary = 2, + + dss_prec_limit = 3 +} dss_prec_t; +#define DSS_PREC_DEFAULT dss_prec_secondary +#define DSS_DEFAULT "secondary" + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +extern const char *dss_prec_names[]; + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +dss_prec_t chunk_dss_prec_get(void); +bool chunk_dss_prec_set(dss_prec_t dss_prec); +void *chunk_alloc_dss(arena_t *arena, void *new_addr, size_t size, + size_t alignment, bool *zero, bool *commit); +bool chunk_in_dss(void *chunk); +bool chunk_dss_boot(void); +void chunk_dss_prefork(void); +void chunk_dss_postfork_parent(void); +void chunk_dss_postfork_child(void); + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/chunk_mmap.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/chunk_mmap.h new file mode 100644 index 0000000..7d8014c --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/chunk_mmap.h @@ -0,0 +1,21 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +void *chunk_alloc_mmap(size_t size, size_t alignment, bool *zero, + bool *commit); +bool chunk_dalloc_mmap(void *chunk, size_t size); + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/ckh.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/ckh.h new file mode 100644 index 0000000..75c1c97 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/ckh.h @@ -0,0 +1,88 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +typedef struct ckh_s ckh_t; +typedef struct ckhc_s ckhc_t; + +/* Typedefs to allow easy function pointer passing. */ +typedef void ckh_hash_t (const void *, size_t[2]); +typedef bool ckh_keycomp_t (const void *, const void *); + +/* Maintain counters used to get an idea of performance. */ +/* #define CKH_COUNT */ +/* Print counter values in ckh_delete() (requires CKH_COUNT). */ +/* #define CKH_VERBOSE */ + +/* + * There are 2^LG_CKH_BUCKET_CELLS cells in each hash table bucket. Try to fit + * one bucket per L1 cache line. + */ +#define LG_CKH_BUCKET_CELLS (LG_CACHELINE - LG_SIZEOF_PTR - 1) + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +/* Hash table cell. */ +struct ckhc_s { + const void *key; + const void *data; +}; + +struct ckh_s { +#ifdef CKH_COUNT + /* Counters used to get an idea of performance. */ + uint64_t ngrows; + uint64_t nshrinks; + uint64_t nshrinkfails; + uint64_t ninserts; + uint64_t nrelocs; +#endif + + /* Used for pseudo-random number generation. */ +#define CKH_A 1103515241 +#define CKH_C 12347 + uint32_t prng_state; + + /* Total number of items. */ + size_t count; + + /* + * Minimum and current number of hash table buckets. There are + * 2^LG_CKH_BUCKET_CELLS cells per bucket. + */ + unsigned lg_minbuckets; + unsigned lg_curbuckets; + + /* Hash and comparison functions. */ + ckh_hash_t *hash; + ckh_keycomp_t *keycomp; + + /* Hash table with 2^lg_curbuckets buckets. */ + ckhc_t *tab; +}; + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +bool ckh_new(tsd_t *tsd, ckh_t *ckh, size_t minitems, ckh_hash_t *hash, + ckh_keycomp_t *keycomp); +void ckh_delete(tsd_t *tsd, ckh_t *ckh); +size_t ckh_count(ckh_t *ckh); +bool ckh_iter(ckh_t *ckh, size_t *tabind, void **key, void **data); +bool ckh_insert(tsd_t *tsd, ckh_t *ckh, const void *key, const void *data); +bool ckh_remove(tsd_t *tsd, ckh_t *ckh, const void *searchkey, void **key, + void **data); +bool ckh_search(ckh_t *ckh, const void *seachkey, void **key, void **data); +void ckh_string_hash(const void *key, size_t r_hash[2]); +bool ckh_string_keycomp(const void *k1, const void *k2); +void ckh_pointer_hash(const void *key, size_t r_hash[2]); +bool ckh_pointer_keycomp(const void *k1, const void *k2); + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/ctl.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/ctl.h new file mode 100644 index 0000000..751c14b --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/ctl.h @@ -0,0 +1,111 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +typedef struct ctl_node_s ctl_node_t; +typedef struct ctl_named_node_s ctl_named_node_t; +typedef struct ctl_indexed_node_s ctl_indexed_node_t; +typedef struct ctl_arena_stats_s ctl_arena_stats_t; +typedef struct ctl_stats_s ctl_stats_t; + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +struct ctl_node_s { + bool named; +}; + +struct ctl_named_node_s { + struct ctl_node_s node; + const char *name; + /* If (nchildren == 0), this is a terminal node. */ + unsigned nchildren; + const ctl_node_t *children; + int (*ctl)(const size_t *, size_t, void *, size_t *, + void *, size_t); +}; + +struct ctl_indexed_node_s { + struct ctl_node_s node; + const ctl_named_node_t *(*index)(const size_t *, size_t, size_t); +}; + +struct ctl_arena_stats_s { + bool initialized; + unsigned nthreads; + const char *dss; + ssize_t lg_dirty_mult; + size_t pactive; + size_t pdirty; + arena_stats_t astats; + + /* Aggregate stats for small size classes, based on bin stats. */ + size_t allocated_small; + uint64_t nmalloc_small; + uint64_t ndalloc_small; + uint64_t nrequests_small; + + malloc_bin_stats_t bstats[NBINS]; + malloc_large_stats_t *lstats; /* nlclasses elements. */ + malloc_huge_stats_t *hstats; /* nhclasses elements. */ +}; + +struct ctl_stats_s { + size_t allocated; + size_t active; + size_t metadata; + size_t resident; + size_t mapped; + unsigned narenas; + ctl_arena_stats_t *arenas; /* (narenas + 1) elements. */ +}; + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +int ctl_byname(const char *name, void *oldp, size_t *oldlenp, void *newp, + size_t newlen); +int ctl_nametomib(const char *name, size_t *mibp, size_t *miblenp); + +int ctl_bymib(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, + void *newp, size_t newlen); +bool ctl_boot(void); +void ctl_prefork(void); +void ctl_postfork_parent(void); +void ctl_postfork_child(void); + +#define xmallctl(name, oldp, oldlenp, newp, newlen) do { \ + if (je_mallctl(name, oldp, oldlenp, newp, newlen) \ + != 0) { \ + malloc_printf( \ + ": Failure in xmallctl(\"%s\", ...)\n", \ + name); \ + abort(); \ + } \ +} while (0) + +#define xmallctlnametomib(name, mibp, miblenp) do { \ + if (je_mallctlnametomib(name, mibp, miblenp) != 0) { \ + malloc_printf(": Failure in " \ + "xmallctlnametomib(\"%s\", ...)\n", name); \ + abort(); \ + } \ +} while (0) + +#define xmallctlbymib(mib, miblen, oldp, oldlenp, newp, newlen) do { \ + if (je_mallctlbymib(mib, miblen, oldp, oldlenp, newp, \ + newlen) != 0) { \ + malloc_write( \ + ": Failure in xmallctlbymib()\n"); \ + abort(); \ + } \ +} while (0) + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ + diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/extent.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/extent.h new file mode 100644 index 0000000..386d50e --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/extent.h @@ -0,0 +1,239 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +typedef struct extent_node_s extent_node_t; + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +/* Tree of extents. Use accessor functions for en_* fields. */ +struct extent_node_s { + /* Arena from which this extent came, if any. */ + arena_t *en_arena; + + /* Pointer to the extent that this tree node is responsible for. */ + void *en_addr; + + /* Total region size. */ + size_t en_size; + + /* + * The zeroed flag is used by chunk recycling code to track whether + * memory is zero-filled. + */ + bool en_zeroed; + + /* + * True if physical memory is committed to the extent, whether + * explicitly or implicitly as on a system that overcommits and + * satisfies physical memory needs on demand via soft page faults. + */ + bool en_committed; + + /* + * The achunk flag is used to validate that huge allocation lookups + * don't return arena chunks. + */ + bool en_achunk; + + /* Profile counters, used for huge objects. */ + prof_tctx_t *en_prof_tctx; + + /* Linkage for arena's runs_dirty and chunks_cache rings. */ + arena_runs_dirty_link_t rd; + qr(extent_node_t) cc_link; + + union { + /* Linkage for the size/address-ordered tree. */ + rb_node(extent_node_t) szad_link; + + /* Linkage for arena's huge and node_cache lists. */ + ql_elm(extent_node_t) ql_link; + }; + + /* Linkage for the address-ordered tree. */ + rb_node(extent_node_t) ad_link; +}; +typedef rb_tree(extent_node_t) extent_tree_t; + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +rb_proto(, extent_tree_szad_, extent_tree_t, extent_node_t) + +rb_proto(, extent_tree_ad_, extent_tree_t, extent_node_t) + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#ifndef JEMALLOC_ENABLE_INLINE +arena_t *extent_node_arena_get(const extent_node_t *node); +void *extent_node_addr_get(const extent_node_t *node); +size_t extent_node_size_get(const extent_node_t *node); +bool extent_node_zeroed_get(const extent_node_t *node); +bool extent_node_committed_get(const extent_node_t *node); +bool extent_node_achunk_get(const extent_node_t *node); +prof_tctx_t *extent_node_prof_tctx_get(const extent_node_t *node); +void extent_node_arena_set(extent_node_t *node, arena_t *arena); +void extent_node_addr_set(extent_node_t *node, void *addr); +void extent_node_size_set(extent_node_t *node, size_t size); +void extent_node_zeroed_set(extent_node_t *node, bool zeroed); +void extent_node_committed_set(extent_node_t *node, bool committed); +void extent_node_achunk_set(extent_node_t *node, bool achunk); +void extent_node_prof_tctx_set(extent_node_t *node, prof_tctx_t *tctx); +void extent_node_init(extent_node_t *node, arena_t *arena, void *addr, + size_t size, bool zeroed, bool committed); +void extent_node_dirty_linkage_init(extent_node_t *node); +void extent_node_dirty_insert(extent_node_t *node, + arena_runs_dirty_link_t *runs_dirty, extent_node_t *chunks_dirty); +void extent_node_dirty_remove(extent_node_t *node); +#endif + +#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_EXTENT_C_)) +JEMALLOC_INLINE arena_t * +extent_node_arena_get(const extent_node_t *node) +{ + + return (node->en_arena); +} + +JEMALLOC_INLINE void * +extent_node_addr_get(const extent_node_t *node) +{ + + return (node->en_addr); +} + +JEMALLOC_INLINE size_t +extent_node_size_get(const extent_node_t *node) +{ + + return (node->en_size); +} + +JEMALLOC_INLINE bool +extent_node_zeroed_get(const extent_node_t *node) +{ + + return (node->en_zeroed); +} + +JEMALLOC_INLINE bool +extent_node_committed_get(const extent_node_t *node) +{ + + assert(!node->en_achunk); + return (node->en_committed); +} + +JEMALLOC_INLINE bool +extent_node_achunk_get(const extent_node_t *node) +{ + + return (node->en_achunk); +} + +JEMALLOC_INLINE prof_tctx_t * +extent_node_prof_tctx_get(const extent_node_t *node) +{ + + return (node->en_prof_tctx); +} + +JEMALLOC_INLINE void +extent_node_arena_set(extent_node_t *node, arena_t *arena) +{ + + node->en_arena = arena; +} + +JEMALLOC_INLINE void +extent_node_addr_set(extent_node_t *node, void *addr) +{ + + node->en_addr = addr; +} + +JEMALLOC_INLINE void +extent_node_size_set(extent_node_t *node, size_t size) +{ + + node->en_size = size; +} + +JEMALLOC_INLINE void +extent_node_zeroed_set(extent_node_t *node, bool zeroed) +{ + + node->en_zeroed = zeroed; +} + +JEMALLOC_INLINE void +extent_node_committed_set(extent_node_t *node, bool committed) +{ + + node->en_committed = committed; +} + +JEMALLOC_INLINE void +extent_node_achunk_set(extent_node_t *node, bool achunk) +{ + + node->en_achunk = achunk; +} + +JEMALLOC_INLINE void +extent_node_prof_tctx_set(extent_node_t *node, prof_tctx_t *tctx) +{ + + node->en_prof_tctx = tctx; +} + +JEMALLOC_INLINE void +extent_node_init(extent_node_t *node, arena_t *arena, void *addr, size_t size, + bool zeroed, bool committed) +{ + + extent_node_arena_set(node, arena); + extent_node_addr_set(node, addr); + extent_node_size_set(node, size); + extent_node_zeroed_set(node, zeroed); + extent_node_committed_set(node, committed); + extent_node_achunk_set(node, false); + if (config_prof) + extent_node_prof_tctx_set(node, NULL); +} + +JEMALLOC_INLINE void +extent_node_dirty_linkage_init(extent_node_t *node) +{ + + qr_new(&node->rd, rd_link); + qr_new(node, cc_link); +} + +JEMALLOC_INLINE void +extent_node_dirty_insert(extent_node_t *node, + arena_runs_dirty_link_t *runs_dirty, extent_node_t *chunks_dirty) +{ + + qr_meld(runs_dirty, &node->rd, rd_link); + qr_meld(chunks_dirty, node, cc_link); +} + +JEMALLOC_INLINE void +extent_node_dirty_remove(extent_node_t *node) +{ + + qr_remove(&node->rd, rd_link); + qr_remove(node, cc_link); +} + +#endif + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ + diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/hash.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/hash.h new file mode 100644 index 0000000..bcead33 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/hash.h @@ -0,0 +1,336 @@ +/* + * The following hash function is based on MurmurHash3, placed into the public + * domain by Austin Appleby. See http://code.google.com/p/smhasher/ for + * details. + */ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#ifndef JEMALLOC_ENABLE_INLINE +uint32_t hash_x86_32(const void *key, int len, uint32_t seed); +void hash_x86_128(const void *key, const int len, uint32_t seed, + uint64_t r_out[2]); +void hash_x64_128(const void *key, const int len, const uint32_t seed, + uint64_t r_out[2]); +void hash(const void *key, size_t len, const uint32_t seed, + size_t r_hash[2]); +#endif + +#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_HASH_C_)) +/******************************************************************************/ +/* Internal implementation. */ +JEMALLOC_INLINE uint32_t +hash_rotl_32(uint32_t x, int8_t r) +{ + + return ((x << r) | (x >> (32 - r))); +} + +JEMALLOC_INLINE uint64_t +hash_rotl_64(uint64_t x, int8_t r) +{ + + return ((x << r) | (x >> (64 - r))); +} + +JEMALLOC_INLINE uint32_t +hash_get_block_32(const uint32_t *p, int i) +{ + + return (p[i]); +} + +JEMALLOC_INLINE uint64_t +hash_get_block_64(const uint64_t *p, int i) +{ + + return (p[i]); +} + +JEMALLOC_INLINE uint32_t +hash_fmix_32(uint32_t h) +{ + + h ^= h >> 16; + h *= 0x85ebca6b; + h ^= h >> 13; + h *= 0xc2b2ae35; + h ^= h >> 16; + + return (h); +} + +JEMALLOC_INLINE uint64_t +hash_fmix_64(uint64_t k) +{ + + k ^= k >> 33; + k *= KQU(0xff51afd7ed558ccd); + k ^= k >> 33; + k *= KQU(0xc4ceb9fe1a85ec53); + k ^= k >> 33; + + return (k); +} + +JEMALLOC_INLINE uint32_t +hash_x86_32(const void *key, int len, uint32_t seed) +{ + const uint8_t *data = (const uint8_t *) key; + const int nblocks = len / 4; + + uint32_t h1 = seed; + + const uint32_t c1 = 0xcc9e2d51; + const uint32_t c2 = 0x1b873593; + + /* body */ + { + const uint32_t *blocks = (const uint32_t *) (data + nblocks*4); + int i; + + for (i = -nblocks; i; i++) { + uint32_t k1 = hash_get_block_32(blocks, i); + + k1 *= c1; + k1 = hash_rotl_32(k1, 15); + k1 *= c2; + + h1 ^= k1; + h1 = hash_rotl_32(h1, 13); + h1 = h1*5 + 0xe6546b64; + } + } + + /* tail */ + { + const uint8_t *tail = (const uint8_t *) (data + nblocks*4); + + uint32_t k1 = 0; + + switch (len & 3) { + case 3: k1 ^= tail[2] << 16; + case 2: k1 ^= tail[1] << 8; + case 1: k1 ^= tail[0]; k1 *= c1; k1 = hash_rotl_32(k1, 15); + k1 *= c2; h1 ^= k1; + } + } + + /* finalization */ + h1 ^= len; + + h1 = hash_fmix_32(h1); + + return (h1); +} + +UNUSED JEMALLOC_INLINE void +hash_x86_128(const void *key, const int len, uint32_t seed, + uint64_t r_out[2]) +{ + const uint8_t * data = (const uint8_t *) key; + const int nblocks = len / 16; + + uint32_t h1 = seed; + uint32_t h2 = seed; + uint32_t h3 = seed; + uint32_t h4 = seed; + + const uint32_t c1 = 0x239b961b; + const uint32_t c2 = 0xab0e9789; + const uint32_t c3 = 0x38b34ae5; + const uint32_t c4 = 0xa1e38b93; + + /* body */ + { + const uint32_t *blocks = (const uint32_t *) (data + nblocks*16); + int i; + + for (i = -nblocks; i; i++) { + uint32_t k1 = hash_get_block_32(blocks, i*4 + 0); + uint32_t k2 = hash_get_block_32(blocks, i*4 + 1); + uint32_t k3 = hash_get_block_32(blocks, i*4 + 2); + uint32_t k4 = hash_get_block_32(blocks, i*4 + 3); + + k1 *= c1; k1 = hash_rotl_32(k1, 15); k1 *= c2; h1 ^= k1; + + h1 = hash_rotl_32(h1, 19); h1 += h2; + h1 = h1*5 + 0x561ccd1b; + + k2 *= c2; k2 = hash_rotl_32(k2, 16); k2 *= c3; h2 ^= k2; + + h2 = hash_rotl_32(h2, 17); h2 += h3; + h2 = h2*5 + 0x0bcaa747; + + k3 *= c3; k3 = hash_rotl_32(k3, 17); k3 *= c4; h3 ^= k3; + + h3 = hash_rotl_32(h3, 15); h3 += h4; + h3 = h3*5 + 0x96cd1c35; + + k4 *= c4; k4 = hash_rotl_32(k4, 18); k4 *= c1; h4 ^= k4; + + h4 = hash_rotl_32(h4, 13); h4 += h1; + h4 = h4*5 + 0x32ac3b17; + } + } + + /* tail */ + { + const uint8_t *tail = (const uint8_t *) (data + nblocks*16); + uint32_t k1 = 0; + uint32_t k2 = 0; + uint32_t k3 = 0; + uint32_t k4 = 0; + + switch (len & 15) { + case 15: k4 ^= tail[14] << 16; + case 14: k4 ^= tail[13] << 8; + case 13: k4 ^= tail[12] << 0; + k4 *= c4; k4 = hash_rotl_32(k4, 18); k4 *= c1; h4 ^= k4; + + case 12: k3 ^= tail[11] << 24; + case 11: k3 ^= tail[10] << 16; + case 10: k3 ^= tail[ 9] << 8; + case 9: k3 ^= tail[ 8] << 0; + k3 *= c3; k3 = hash_rotl_32(k3, 17); k3 *= c4; h3 ^= k3; + + case 8: k2 ^= tail[ 7] << 24; + case 7: k2 ^= tail[ 6] << 16; + case 6: k2 ^= tail[ 5] << 8; + case 5: k2 ^= tail[ 4] << 0; + k2 *= c2; k2 = hash_rotl_32(k2, 16); k2 *= c3; h2 ^= k2; + + case 4: k1 ^= tail[ 3] << 24; + case 3: k1 ^= tail[ 2] << 16; + case 2: k1 ^= tail[ 1] << 8; + case 1: k1 ^= tail[ 0] << 0; + k1 *= c1; k1 = hash_rotl_32(k1, 15); k1 *= c2; h1 ^= k1; + } + } + + /* finalization */ + h1 ^= len; h2 ^= len; h3 ^= len; h4 ^= len; + + h1 += h2; h1 += h3; h1 += h4; + h2 += h1; h3 += h1; h4 += h1; + + h1 = hash_fmix_32(h1); + h2 = hash_fmix_32(h2); + h3 = hash_fmix_32(h3); + h4 = hash_fmix_32(h4); + + h1 += h2; h1 += h3; h1 += h4; + h2 += h1; h3 += h1; h4 += h1; + + r_out[0] = (((uint64_t) h2) << 32) | h1; + r_out[1] = (((uint64_t) h4) << 32) | h3; +} + +UNUSED JEMALLOC_INLINE void +hash_x64_128(const void *key, const int len, const uint32_t seed, + uint64_t r_out[2]) +{ + const uint8_t *data = (const uint8_t *) key; + const int nblocks = len / 16; + + uint64_t h1 = seed; + uint64_t h2 = seed; + + const uint64_t c1 = KQU(0x87c37b91114253d5); + const uint64_t c2 = KQU(0x4cf5ad432745937f); + + /* body */ + { + const uint64_t *blocks = (const uint64_t *) (data); + int i; + + for (i = 0; i < nblocks; i++) { + uint64_t k1 = hash_get_block_64(blocks, i*2 + 0); + uint64_t k2 = hash_get_block_64(blocks, i*2 + 1); + + k1 *= c1; k1 = hash_rotl_64(k1, 31); k1 *= c2; h1 ^= k1; + + h1 = hash_rotl_64(h1, 27); h1 += h2; + h1 = h1*5 + 0x52dce729; + + k2 *= c2; k2 = hash_rotl_64(k2, 33); k2 *= c1; h2 ^= k2; + + h2 = hash_rotl_64(h2, 31); h2 += h1; + h2 = h2*5 + 0x38495ab5; + } + } + + /* tail */ + { + const uint8_t *tail = (const uint8_t*)(data + nblocks*16); + uint64_t k1 = 0; + uint64_t k2 = 0; + + switch (len & 15) { + case 15: k2 ^= ((uint64_t)(tail[14])) << 48; + case 14: k2 ^= ((uint64_t)(tail[13])) << 40; + case 13: k2 ^= ((uint64_t)(tail[12])) << 32; + case 12: k2 ^= ((uint64_t)(tail[11])) << 24; + case 11: k2 ^= ((uint64_t)(tail[10])) << 16; + case 10: k2 ^= ((uint64_t)(tail[ 9])) << 8; + case 9: k2 ^= ((uint64_t)(tail[ 8])) << 0; + k2 *= c2; k2 = hash_rotl_64(k2, 33); k2 *= c1; h2 ^= k2; + + case 8: k1 ^= ((uint64_t)(tail[ 7])) << 56; + case 7: k1 ^= ((uint64_t)(tail[ 6])) << 48; + case 6: k1 ^= ((uint64_t)(tail[ 5])) << 40; + case 5: k1 ^= ((uint64_t)(tail[ 4])) << 32; + case 4: k1 ^= ((uint64_t)(tail[ 3])) << 24; + case 3: k1 ^= ((uint64_t)(tail[ 2])) << 16; + case 2: k1 ^= ((uint64_t)(tail[ 1])) << 8; + case 1: k1 ^= ((uint64_t)(tail[ 0])) << 0; + k1 *= c1; k1 = hash_rotl_64(k1, 31); k1 *= c2; h1 ^= k1; + } + } + + /* finalization */ + h1 ^= len; h2 ^= len; + + h1 += h2; + h2 += h1; + + h1 = hash_fmix_64(h1); + h2 = hash_fmix_64(h2); + + h1 += h2; + h2 += h1; + + r_out[0] = h1; + r_out[1] = h2; +} + +/******************************************************************************/ +/* API. */ +JEMALLOC_INLINE void +hash(const void *key, size_t len, const uint32_t seed, size_t r_hash[2]) +{ +#if (LG_SIZEOF_PTR == 3 && !defined(JEMALLOC_BIG_ENDIAN)) + hash_x64_128(key, len, seed, (uint64_t *)r_hash); +#else + uint64_t hashes[2]; + hash_x86_128(key, len, seed, hashes); + r_hash[0] = (size_t)hashes[0]; + r_hash[1] = (size_t)hashes[1]; +#endif +} +#endif + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/huge.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/huge.h new file mode 100644 index 0000000..ece7af9 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/huge.h @@ -0,0 +1,36 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +void *huge_malloc(tsd_t *tsd, arena_t *arena, size_t size, bool zero, + tcache_t *tcache); +void *huge_palloc(tsd_t *tsd, arena_t *arena, size_t size, size_t alignment, + bool zero, tcache_t *tcache); +bool huge_ralloc_no_move(void *ptr, size_t oldsize, size_t usize_min, + size_t usize_max, bool zero); +void *huge_ralloc(tsd_t *tsd, arena_t *arena, void *ptr, size_t oldsize, + size_t usize, size_t alignment, bool zero, tcache_t *tcache); +#ifdef JEMALLOC_JET +typedef void (huge_dalloc_junk_t)(void *, size_t); +extern huge_dalloc_junk_t *huge_dalloc_junk; +#endif +void huge_dalloc(tsd_t *tsd, void *ptr, tcache_t *tcache); +arena_t *huge_aalloc(const void *ptr); +size_t huge_salloc(const void *ptr); +prof_tctx_t *huge_prof_tctx_get(const void *ptr); +void huge_prof_tctx_set(const void *ptr, prof_tctx_t *tctx); +void huge_prof_tctx_reset(const void *ptr); + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/jemalloc_internal.h.in b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/jemalloc_internal.h.in new file mode 100644 index 0000000..8536a3e --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/jemalloc_internal.h.in @@ -0,0 +1,1134 @@ +#ifndef JEMALLOC_INTERNAL_H +#define JEMALLOC_INTERNAL_H + +#include "jemalloc_internal_defs.h" +#include "jemalloc/internal/jemalloc_internal_decls.h" + +#ifdef JEMALLOC_UTRACE +#include +#endif + +#define JEMALLOC_NO_DEMANGLE +#ifdef JEMALLOC_JET +# define JEMALLOC_N(n) jet_##n +# include "jemalloc/internal/public_namespace.h" +# define JEMALLOC_NO_RENAME +# include "../jemalloc@install_suffix@.h" +# undef JEMALLOC_NO_RENAME +#else +# define JEMALLOC_N(n) @private_namespace@##n +# include "../jemalloc@install_suffix@.h" +#endif +#include "jemalloc/internal/private_namespace.h" + +static const bool config_debug = +#ifdef JEMALLOC_DEBUG + true +#else + false +#endif + ; +static const bool have_dss = +#ifdef JEMALLOC_DSS + true +#else + false +#endif + ; +static const bool config_fill = +#ifdef JEMALLOC_FILL + true +#else + false +#endif + ; +static const bool config_lazy_lock = +#ifdef JEMALLOC_LAZY_LOCK + true +#else + false +#endif + ; +static const bool config_prof = +#ifdef JEMALLOC_PROF + true +#else + false +#endif + ; +static const bool config_prof_libgcc = +#ifdef JEMALLOC_PROF_LIBGCC + true +#else + false +#endif + ; +static const bool config_prof_libunwind = +#ifdef JEMALLOC_PROF_LIBUNWIND + true +#else + false +#endif + ; +static const bool maps_coalesce = +#ifdef JEMALLOC_MAPS_COALESCE + true +#else + false +#endif + ; +static const bool config_munmap = +#ifdef JEMALLOC_MUNMAP + true +#else + false +#endif + ; +static const bool config_stats = +#ifdef JEMALLOC_STATS + true +#else + false +#endif + ; +static const bool config_tcache = +#ifdef JEMALLOC_TCACHE + true +#else + false +#endif + ; +static const bool config_tls = +#ifdef JEMALLOC_TLS + true +#else + false +#endif + ; +static const bool config_utrace = +#ifdef JEMALLOC_UTRACE + true +#else + false +#endif + ; +static const bool config_valgrind = +#ifdef JEMALLOC_VALGRIND + true +#else + false +#endif + ; +static const bool config_xmalloc = +#ifdef JEMALLOC_XMALLOC + true +#else + false +#endif + ; +static const bool config_ivsalloc = +#ifdef JEMALLOC_IVSALLOC + true +#else + false +#endif + ; +static const bool config_cache_oblivious = +#ifdef JEMALLOC_CACHE_OBLIVIOUS + true +#else + false +#endif + ; + +#ifdef JEMALLOC_C11ATOMICS +#include +#endif + +#ifdef JEMALLOC_ATOMIC9 +#include +#endif + +#if (defined(JEMALLOC_OSATOMIC) || defined(JEMALLOC_OSSPIN)) +#include +#endif + +#ifdef JEMALLOC_ZONE +#include +#include +#include +#include +#endif + +#define RB_COMPACT +#include "jemalloc/internal/rb.h" +#include "jemalloc/internal/qr.h" +#include "jemalloc/internal/ql.h" + +/* + * jemalloc can conceptually be broken into components (arena, tcache, etc.), + * but there are circular dependencies that cannot be broken without + * substantial performance degradation. In order to reduce the effect on + * visual code flow, read the header files in multiple passes, with one of the + * following cpp variables defined during each pass: + * + * JEMALLOC_H_TYPES : Preprocessor-defined constants and psuedo-opaque data + * types. + * JEMALLOC_H_STRUCTS : Data structures. + * JEMALLOC_H_EXTERNS : Extern data declarations and function prototypes. + * JEMALLOC_H_INLINES : Inline functions. + */ +/******************************************************************************/ +#define JEMALLOC_H_TYPES + +#include "jemalloc/internal/jemalloc_internal_macros.h" + +/* Size class index type. */ +typedef unsigned szind_t; + +/* + * Flags bits: + * + * a: arena + * t: tcache + * 0: unused + * z: zero + * n: alignment + * + * aaaaaaaa aaaatttt tttttttt 0znnnnnn + */ +#define MALLOCX_ARENA_MASK ((int)~0xfffff) +#define MALLOCX_ARENA_MAX 0xffe +#define MALLOCX_TCACHE_MASK ((int)~0xfff000ffU) +#define MALLOCX_TCACHE_MAX 0xffd +#define MALLOCX_LG_ALIGN_MASK ((int)0x3f) +/* Use MALLOCX_ALIGN_GET() if alignment may not be specified in flags. */ +#define MALLOCX_ALIGN_GET_SPECIFIED(flags) \ + (ZU(1) << (flags & MALLOCX_LG_ALIGN_MASK)) +#define MALLOCX_ALIGN_GET(flags) \ + (MALLOCX_ALIGN_GET_SPECIFIED(flags) & (SIZE_T_MAX-1)) +#define MALLOCX_ZERO_GET(flags) \ + ((bool)(flags & MALLOCX_ZERO)) + +#define MALLOCX_TCACHE_GET(flags) \ + (((unsigned)((flags & MALLOCX_TCACHE_MASK) >> 8)) - 2) +#define MALLOCX_ARENA_GET(flags) \ + (((unsigned)(((unsigned)flags) >> 20)) - 1) + +/* Smallest size class to support. */ +#define TINY_MIN (1U << LG_TINY_MIN) + +/* + * Minimum allocation alignment is 2^LG_QUANTUM bytes (ignoring tiny size + * classes). + */ +#ifndef LG_QUANTUM +# if (defined(__i386__) || defined(_M_IX86)) +# define LG_QUANTUM 4 +# endif +# ifdef __ia64__ +# define LG_QUANTUM 4 +# endif +# ifdef __alpha__ +# define LG_QUANTUM 4 +# endif +# if (defined(__sparc64__) || defined(__sparcv9)) +# define LG_QUANTUM 4 +# endif +# if (defined(__amd64__) || defined(__x86_64__) || defined(_M_X64)) +# define LG_QUANTUM 4 +# endif +# ifdef __arm__ +# define LG_QUANTUM 3 +# endif +# ifdef __aarch64__ +# define LG_QUANTUM 4 +# endif +# ifdef __hppa__ +# define LG_QUANTUM 4 +# endif +# ifdef __mips__ +# define LG_QUANTUM 3 +# endif +# ifdef __or1k__ +# define LG_QUANTUM 3 +# endif +# ifdef __powerpc__ +# define LG_QUANTUM 4 +# endif +# ifdef __s390__ +# define LG_QUANTUM 4 +# endif +# ifdef __SH4__ +# define LG_QUANTUM 4 +# endif +# ifdef __tile__ +# define LG_QUANTUM 4 +# endif +# ifdef __le32__ +# define LG_QUANTUM 4 +# endif +# ifndef LG_QUANTUM +# error "Unknown minimum alignment for architecture; specify via " + "--with-lg-quantum" +# endif +#endif + +#define QUANTUM ((size_t)(1U << LG_QUANTUM)) +#define QUANTUM_MASK (QUANTUM - 1) + +/* Return the smallest quantum multiple that is >= a. */ +#define QUANTUM_CEILING(a) \ + (((a) + QUANTUM_MASK) & ~QUANTUM_MASK) + +#define LONG ((size_t)(1U << LG_SIZEOF_LONG)) +#define LONG_MASK (LONG - 1) + +/* Return the smallest long multiple that is >= a. */ +#define LONG_CEILING(a) \ + (((a) + LONG_MASK) & ~LONG_MASK) + +#define SIZEOF_PTR (1U << LG_SIZEOF_PTR) +#define PTR_MASK (SIZEOF_PTR - 1) + +/* Return the smallest (void *) multiple that is >= a. */ +#define PTR_CEILING(a) \ + (((a) + PTR_MASK) & ~PTR_MASK) + +/* + * Maximum size of L1 cache line. This is used to avoid cache line aliasing. + * In addition, this controls the spacing of cacheline-spaced size classes. + * + * CACHELINE cannot be based on LG_CACHELINE because __declspec(align()) can + * only handle raw constants. + */ +#define LG_CACHELINE 6 +#define CACHELINE 64 +#define CACHELINE_MASK (CACHELINE - 1) + +/* Return the smallest cacheline multiple that is >= s. */ +#define CACHELINE_CEILING(s) \ + (((s) + CACHELINE_MASK) & ~CACHELINE_MASK) + +/* Page size. LG_PAGE is determined by the configure script. */ +#ifdef PAGE_MASK +# undef PAGE_MASK +#endif +#define PAGE ((size_t)(1U << LG_PAGE)) +#define PAGE_MASK ((size_t)(PAGE - 1)) + +/* Return the smallest pagesize multiple that is >= s. */ +#define PAGE_CEILING(s) \ + (((s) + PAGE_MASK) & ~PAGE_MASK) + +/* Return the nearest aligned address at or below a. */ +#define ALIGNMENT_ADDR2BASE(a, alignment) \ + ((void *)((uintptr_t)(a) & (-(alignment)))) + +/* Return the offset between a and the nearest aligned address at or below a. */ +#define ALIGNMENT_ADDR2OFFSET(a, alignment) \ + ((size_t)((uintptr_t)(a) & (alignment - 1))) + +/* Return the smallest alignment multiple that is >= s. */ +#define ALIGNMENT_CEILING(s, alignment) \ + (((s) + (alignment - 1)) & (-(alignment))) + +/* Declare a variable-length array. */ +#if __STDC_VERSION__ < 199901L +# ifdef _MSC_VER +# include +# define alloca _alloca +# else +# ifdef JEMALLOC_HAS_ALLOCA_H +# include +# else +# include +# endif +# endif +# define VARIABLE_ARRAY(type, name, count) \ + type *name = alloca(sizeof(type) * (count)) +#else +# define VARIABLE_ARRAY(type, name, count) type name[(count)] +#endif + +#include "jemalloc/internal/valgrind.h" +#include "jemalloc/internal/util.h" +#include "jemalloc/internal/atomic.h" +#include "jemalloc/internal/prng.h" +#include "jemalloc/internal/ckh.h" +#include "jemalloc/internal/size_classes.h" +#include "jemalloc/internal/stats.h" +#include "jemalloc/internal/ctl.h" +#include "jemalloc/internal/mutex.h" +#include "jemalloc/internal/tsd.h" +#include "jemalloc/internal/mb.h" +#include "jemalloc/internal/extent.h" +#include "jemalloc/internal/arena.h" +#include "jemalloc/internal/bitmap.h" +#include "jemalloc/internal/base.h" +#include "jemalloc/internal/rtree.h" +#include "jemalloc/internal/pages.h" +#include "jemalloc/internal/chunk.h" +#include "jemalloc/internal/huge.h" +#include "jemalloc/internal/tcache.h" +#include "jemalloc/internal/hash.h" +#include "jemalloc/internal/quarantine.h" +#include "jemalloc/internal/prof.h" + +#undef JEMALLOC_H_TYPES +/******************************************************************************/ +#define JEMALLOC_H_STRUCTS + +#include "jemalloc/internal/valgrind.h" +#include "jemalloc/internal/util.h" +#include "jemalloc/internal/atomic.h" +#include "jemalloc/internal/prng.h" +#include "jemalloc/internal/ckh.h" +#include "jemalloc/internal/size_classes.h" +#include "jemalloc/internal/stats.h" +#include "jemalloc/internal/ctl.h" +#include "jemalloc/internal/mutex.h" +#include "jemalloc/internal/mb.h" +#include "jemalloc/internal/bitmap.h" +#define JEMALLOC_ARENA_STRUCTS_A +#include "jemalloc/internal/arena.h" +#undef JEMALLOC_ARENA_STRUCTS_A +#include "jemalloc/internal/extent.h" +#define JEMALLOC_ARENA_STRUCTS_B +#include "jemalloc/internal/arena.h" +#undef JEMALLOC_ARENA_STRUCTS_B +#include "jemalloc/internal/base.h" +#include "jemalloc/internal/rtree.h" +#include "jemalloc/internal/pages.h" +#include "jemalloc/internal/chunk.h" +#include "jemalloc/internal/huge.h" +#include "jemalloc/internal/tcache.h" +#include "jemalloc/internal/hash.h" +#include "jemalloc/internal/quarantine.h" +#include "jemalloc/internal/prof.h" + +#include "jemalloc/internal/tsd.h" + +#undef JEMALLOC_H_STRUCTS +/******************************************************************************/ +#define JEMALLOC_H_EXTERNS + +extern bool opt_abort; +extern const char *opt_junk; +extern bool opt_junk_alloc; +extern bool opt_junk_free; +extern size_t opt_quarantine; +extern bool opt_redzone; +extern bool opt_utrace; +extern bool opt_xmalloc; +extern bool opt_zero; +extern size_t opt_narenas; + +extern bool in_valgrind; + +/* Number of CPUs. */ +extern unsigned ncpus; + +/* + * index2size_tab encodes the same information as could be computed (at + * unacceptable cost in some code paths) by index2size_compute(). + */ +extern size_t const index2size_tab[NSIZES]; +/* + * size2index_tab is a compact lookup table that rounds request sizes up to + * size classes. In order to reduce cache footprint, the table is compressed, + * and all accesses are via size2index(). + */ +extern uint8_t const size2index_tab[]; + +arena_t *a0get(void); +void *a0malloc(size_t size); +void a0dalloc(void *ptr); +void *bootstrap_malloc(size_t size); +void *bootstrap_calloc(size_t num, size_t size); +void bootstrap_free(void *ptr); +arena_t *arenas_extend(unsigned ind); +arena_t *arena_init(unsigned ind); +unsigned narenas_total_get(void); +arena_t *arena_get_hard(tsd_t *tsd, unsigned ind, bool init_if_missing); +arena_t *arena_choose_hard(tsd_t *tsd); +void arena_migrate(tsd_t *tsd, unsigned oldind, unsigned newind); +unsigned arena_nbound(unsigned ind); +void thread_allocated_cleanup(tsd_t *tsd); +void thread_deallocated_cleanup(tsd_t *tsd); +void arena_cleanup(tsd_t *tsd); +void arenas_cache_cleanup(tsd_t *tsd); +void narenas_cache_cleanup(tsd_t *tsd); +void arenas_cache_bypass_cleanup(tsd_t *tsd); +void jemalloc_prefork(void); +void jemalloc_postfork_parent(void); +void jemalloc_postfork_child(void); + +#include "jemalloc/internal/valgrind.h" +#include "jemalloc/internal/util.h" +#include "jemalloc/internal/atomic.h" +#include "jemalloc/internal/prng.h" +#include "jemalloc/internal/ckh.h" +#include "jemalloc/internal/size_classes.h" +#include "jemalloc/internal/stats.h" +#include "jemalloc/internal/ctl.h" +#include "jemalloc/internal/mutex.h" +#include "jemalloc/internal/mb.h" +#include "jemalloc/internal/bitmap.h" +#include "jemalloc/internal/extent.h" +#include "jemalloc/internal/arena.h" +#include "jemalloc/internal/base.h" +#include "jemalloc/internal/rtree.h" +#include "jemalloc/internal/pages.h" +#include "jemalloc/internal/chunk.h" +#include "jemalloc/internal/huge.h" +#include "jemalloc/internal/tcache.h" +#include "jemalloc/internal/hash.h" +#include "jemalloc/internal/quarantine.h" +#include "jemalloc/internal/prof.h" +#include "jemalloc/internal/tsd.h" + +#undef JEMALLOC_H_EXTERNS +/******************************************************************************/ +#define JEMALLOC_H_INLINES + +#include "jemalloc/internal/valgrind.h" +#include "jemalloc/internal/util.h" +#include "jemalloc/internal/atomic.h" +#include "jemalloc/internal/prng.h" +#include "jemalloc/internal/ckh.h" +#include "jemalloc/internal/size_classes.h" +#include "jemalloc/internal/stats.h" +#include "jemalloc/internal/ctl.h" +#include "jemalloc/internal/mutex.h" +#include "jemalloc/internal/tsd.h" +#include "jemalloc/internal/mb.h" +#include "jemalloc/internal/extent.h" +#include "jemalloc/internal/base.h" +#include "jemalloc/internal/rtree.h" +#include "jemalloc/internal/pages.h" +#include "jemalloc/internal/chunk.h" +#include "jemalloc/internal/huge.h" + +#ifndef JEMALLOC_ENABLE_INLINE +szind_t size2index_compute(size_t size); +szind_t size2index_lookup(size_t size); +szind_t size2index(size_t size); +size_t index2size_compute(szind_t index); +size_t index2size_lookup(szind_t index); +size_t index2size(szind_t index); +size_t s2u_compute(size_t size); +size_t s2u_lookup(size_t size); +size_t s2u(size_t size); +size_t sa2u(size_t size, size_t alignment); +arena_t *arena_choose(tsd_t *tsd, arena_t *arena); +arena_t *arena_get(tsd_t *tsd, unsigned ind, bool init_if_missing, + bool refresh_if_missing); +#endif + +#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_C_)) +JEMALLOC_INLINE szind_t +size2index_compute(size_t size) +{ + +#if (NTBINS != 0) + if (size <= (ZU(1) << LG_TINY_MAXCLASS)) { + size_t lg_tmin = LG_TINY_MAXCLASS - NTBINS + 1; + size_t lg_ceil = lg_floor(pow2_ceil(size)); + return (lg_ceil < lg_tmin ? 0 : lg_ceil - lg_tmin); + } +#endif + { + size_t x = unlikely(ZI(size) < 0) ? ((size<<1) ? + (ZU(1)<<(LG_SIZEOF_PTR+3)) : ((ZU(1)<<(LG_SIZEOF_PTR+3))-1)) + : lg_floor((size<<1)-1); + size_t shift = (x < LG_SIZE_CLASS_GROUP + LG_QUANTUM) ? 0 : + x - (LG_SIZE_CLASS_GROUP + LG_QUANTUM); + size_t grp = shift << LG_SIZE_CLASS_GROUP; + + size_t lg_delta = (x < LG_SIZE_CLASS_GROUP + LG_QUANTUM + 1) + ? LG_QUANTUM : x - LG_SIZE_CLASS_GROUP - 1; + + size_t delta_inverse_mask = ZI(-1) << lg_delta; + size_t mod = ((((size-1) & delta_inverse_mask) >> lg_delta)) & + ((ZU(1) << LG_SIZE_CLASS_GROUP) - 1); + + size_t index = NTBINS + grp + mod; + return (index); + } +} + +JEMALLOC_ALWAYS_INLINE szind_t +size2index_lookup(size_t size) +{ + + assert(size <= LOOKUP_MAXCLASS); + { + size_t ret = ((size_t)(size2index_tab[(size-1) >> + LG_TINY_MIN])); + assert(ret == size2index_compute(size)); + return (ret); + } +} + +JEMALLOC_ALWAYS_INLINE szind_t +size2index(size_t size) +{ + + assert(size > 0); + if (likely(size <= LOOKUP_MAXCLASS)) + return (size2index_lookup(size)); + return (size2index_compute(size)); +} + +JEMALLOC_INLINE size_t +index2size_compute(szind_t index) +{ + +#if (NTBINS > 0) + if (index < NTBINS) + return (ZU(1) << (LG_TINY_MAXCLASS - NTBINS + 1 + index)); +#endif + { + size_t reduced_index = index - NTBINS; + size_t grp = reduced_index >> LG_SIZE_CLASS_GROUP; + size_t mod = reduced_index & ((ZU(1) << LG_SIZE_CLASS_GROUP) - + 1); + + size_t grp_size_mask = ~((!!grp)-1); + size_t grp_size = ((ZU(1) << (LG_QUANTUM + + (LG_SIZE_CLASS_GROUP-1))) << grp) & grp_size_mask; + + size_t shift = (grp == 0) ? 1 : grp; + size_t lg_delta = shift + (LG_QUANTUM-1); + size_t mod_size = (mod+1) << lg_delta; + + size_t usize = grp_size + mod_size; + return (usize); + } +} + +JEMALLOC_ALWAYS_INLINE size_t +index2size_lookup(szind_t index) +{ + size_t ret = (size_t)index2size_tab[index]; + assert(ret == index2size_compute(index)); + return (ret); +} + +JEMALLOC_ALWAYS_INLINE size_t +index2size(szind_t index) +{ + + assert(index < NSIZES); + return (index2size_lookup(index)); +} + +JEMALLOC_ALWAYS_INLINE size_t +s2u_compute(size_t size) +{ + +#if (NTBINS > 0) + if (size <= (ZU(1) << LG_TINY_MAXCLASS)) { + size_t lg_tmin = LG_TINY_MAXCLASS - NTBINS + 1; + size_t lg_ceil = lg_floor(pow2_ceil(size)); + return (lg_ceil < lg_tmin ? (ZU(1) << lg_tmin) : + (ZU(1) << lg_ceil)); + } +#endif + { + size_t x = unlikely(ZI(size) < 0) ? ((size<<1) ? + (ZU(1)<<(LG_SIZEOF_PTR+3)) : ((ZU(1)<<(LG_SIZEOF_PTR+3))-1)) + : lg_floor((size<<1)-1); + size_t lg_delta = (x < LG_SIZE_CLASS_GROUP + LG_QUANTUM + 1) + ? LG_QUANTUM : x - LG_SIZE_CLASS_GROUP - 1; + size_t delta = ZU(1) << lg_delta; + size_t delta_mask = delta - 1; + size_t usize = (size + delta_mask) & ~delta_mask; + return (usize); + } +} + +JEMALLOC_ALWAYS_INLINE size_t +s2u_lookup(size_t size) +{ + size_t ret = index2size_lookup(size2index_lookup(size)); + + assert(ret == s2u_compute(size)); + return (ret); +} + +/* + * Compute usable size that would result from allocating an object with the + * specified size. + */ +JEMALLOC_ALWAYS_INLINE size_t +s2u(size_t size) +{ + + assert(size > 0); + if (likely(size <= LOOKUP_MAXCLASS)) + return (s2u_lookup(size)); + return (s2u_compute(size)); +} + +/* + * Compute usable size that would result from allocating an object with the + * specified size and alignment. + */ +JEMALLOC_ALWAYS_INLINE size_t +sa2u(size_t size, size_t alignment) +{ + size_t usize; + + assert(alignment != 0 && ((alignment - 1) & alignment) == 0); + + /* Try for a small size class. */ + if (size <= SMALL_MAXCLASS && alignment < PAGE) { + /* + * Round size up to the nearest multiple of alignment. + * + * This done, we can take advantage of the fact that for each + * small size class, every object is aligned at the smallest + * power of two that is non-zero in the base two representation + * of the size. For example: + * + * Size | Base 2 | Minimum alignment + * -----+----------+------------------ + * 96 | 1100000 | 32 + * 144 | 10100000 | 32 + * 192 | 11000000 | 64 + */ + usize = s2u(ALIGNMENT_CEILING(size, alignment)); + if (usize < LARGE_MINCLASS) + return (usize); + } + + /* Try for a large size class. */ + if (likely(size <= large_maxclass) && likely(alignment < chunksize)) { + /* + * We can't achieve subpage alignment, so round up alignment + * to the minimum that can actually be supported. + */ + alignment = PAGE_CEILING(alignment); + + /* Make sure result is a large size class. */ + usize = (size <= LARGE_MINCLASS) ? LARGE_MINCLASS : s2u(size); + + /* + * Calculate the size of the over-size run that arena_palloc() + * would need to allocate in order to guarantee the alignment. + */ + if (usize + large_pad + alignment - PAGE <= arena_maxrun) + return (usize); + } + + /* Huge size class. Beware of size_t overflow. */ + + /* + * We can't achieve subchunk alignment, so round up alignment to the + * minimum that can actually be supported. + */ + alignment = CHUNK_CEILING(alignment); + if (alignment == 0) { + /* size_t overflow. */ + return (0); + } + + /* Make sure result is a huge size class. */ + if (size <= chunksize) + usize = chunksize; + else { + usize = s2u(size); + if (usize < size) { + /* size_t overflow. */ + return (0); + } + } + + /* + * Calculate the multi-chunk mapping that huge_palloc() would need in + * order to guarantee the alignment. + */ + if (usize + alignment - PAGE < usize) { + /* size_t overflow. */ + return (0); + } + return (usize); +} + +/* Choose an arena based on a per-thread value. */ +JEMALLOC_INLINE arena_t * +arena_choose(tsd_t *tsd, arena_t *arena) +{ + arena_t *ret; + + if (arena != NULL) + return (arena); + + if (unlikely((ret = tsd_arena_get(tsd)) == NULL)) + ret = arena_choose_hard(tsd); + + return (ret); +} + +JEMALLOC_INLINE arena_t * +arena_get(tsd_t *tsd, unsigned ind, bool init_if_missing, + bool refresh_if_missing) +{ + arena_t *arena; + arena_t **arenas_cache = tsd_arenas_cache_get(tsd); + + /* init_if_missing requires refresh_if_missing. */ + assert(!init_if_missing || refresh_if_missing); + + if (unlikely(arenas_cache == NULL)) { + /* arenas_cache hasn't been initialized yet. */ + return (arena_get_hard(tsd, ind, init_if_missing)); + } + if (unlikely(ind >= tsd_narenas_cache_get(tsd))) { + /* + * ind is invalid, cache is old (too small), or arena to be + * initialized. + */ + return (refresh_if_missing ? arena_get_hard(tsd, ind, + init_if_missing) : NULL); + } + arena = arenas_cache[ind]; + if (likely(arena != NULL) || !refresh_if_missing) + return (arena); + return (arena_get_hard(tsd, ind, init_if_missing)); +} +#endif + +#include "jemalloc/internal/bitmap.h" +/* + * Include portions of arena.h interleaved with tcache.h in order to resolve + * circular dependencies. + */ +#define JEMALLOC_ARENA_INLINE_A +#include "jemalloc/internal/arena.h" +#undef JEMALLOC_ARENA_INLINE_A +#include "jemalloc/internal/tcache.h" +#define JEMALLOC_ARENA_INLINE_B +#include "jemalloc/internal/arena.h" +#undef JEMALLOC_ARENA_INLINE_B +#include "jemalloc/internal/hash.h" +#include "jemalloc/internal/quarantine.h" + +#ifndef JEMALLOC_ENABLE_INLINE +arena_t *iaalloc(const void *ptr); +size_t isalloc(const void *ptr, bool demote); +void *iallocztm(tsd_t *tsd, size_t size, bool zero, tcache_t *tcache, + bool is_metadata, arena_t *arena); +void *imalloct(tsd_t *tsd, size_t size, tcache_t *tcache, arena_t *arena); +void *imalloc(tsd_t *tsd, size_t size); +void *icalloct(tsd_t *tsd, size_t size, tcache_t *tcache, arena_t *arena); +void *icalloc(tsd_t *tsd, size_t size); +void *ipallocztm(tsd_t *tsd, size_t usize, size_t alignment, bool zero, + tcache_t *tcache, bool is_metadata, arena_t *arena); +void *ipalloct(tsd_t *tsd, size_t usize, size_t alignment, bool zero, + tcache_t *tcache, arena_t *arena); +void *ipalloc(tsd_t *tsd, size_t usize, size_t alignment, bool zero); +size_t ivsalloc(const void *ptr, bool demote); +size_t u2rz(size_t usize); +size_t p2rz(const void *ptr); +void idalloctm(tsd_t *tsd, void *ptr, tcache_t *tcache, bool is_metadata); +void idalloct(tsd_t *tsd, void *ptr, tcache_t *tcache); +void idalloc(tsd_t *tsd, void *ptr); +void iqalloc(tsd_t *tsd, void *ptr, tcache_t *tcache); +void isdalloct(tsd_t *tsd, void *ptr, size_t size, tcache_t *tcache); +void isqalloc(tsd_t *tsd, void *ptr, size_t size, tcache_t *tcache); +void *iralloct_realign(tsd_t *tsd, void *ptr, size_t oldsize, size_t size, + size_t extra, size_t alignment, bool zero, tcache_t *tcache, + arena_t *arena); +void *iralloct(tsd_t *tsd, void *ptr, size_t oldsize, size_t size, + size_t alignment, bool zero, tcache_t *tcache, arena_t *arena); +void *iralloc(tsd_t *tsd, void *ptr, size_t oldsize, size_t size, + size_t alignment, bool zero); +bool ixalloc(void *ptr, size_t oldsize, size_t size, size_t extra, + size_t alignment, bool zero); +#endif + +#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_C_)) +JEMALLOC_ALWAYS_INLINE arena_t * +iaalloc(const void *ptr) +{ + + assert(ptr != NULL); + + return (arena_aalloc(ptr)); +} + +/* + * Typical usage: + * void *ptr = [...] + * size_t sz = isalloc(ptr, config_prof); + */ +JEMALLOC_ALWAYS_INLINE size_t +isalloc(const void *ptr, bool demote) +{ + + assert(ptr != NULL); + /* Demotion only makes sense if config_prof is true. */ + assert(config_prof || !demote); + + return (arena_salloc(ptr, demote)); +} + +JEMALLOC_ALWAYS_INLINE void * +iallocztm(tsd_t *tsd, size_t size, bool zero, tcache_t *tcache, bool is_metadata, + arena_t *arena) +{ + void *ret; + + assert(size != 0); + + ret = arena_malloc(tsd, arena, size, zero, tcache); + if (config_stats && is_metadata && likely(ret != NULL)) { + arena_metadata_allocated_add(iaalloc(ret), isalloc(ret, + config_prof)); + } + return (ret); +} + +JEMALLOC_ALWAYS_INLINE void * +imalloct(tsd_t *tsd, size_t size, tcache_t *tcache, arena_t *arena) +{ + + return (iallocztm(tsd, size, false, tcache, false, arena)); +} + +JEMALLOC_ALWAYS_INLINE void * +imalloc(tsd_t *tsd, size_t size) +{ + + return (iallocztm(tsd, size, false, tcache_get(tsd, true), false, NULL)); +} + +JEMALLOC_ALWAYS_INLINE void * +icalloct(tsd_t *tsd, size_t size, tcache_t *tcache, arena_t *arena) +{ + + return (iallocztm(tsd, size, true, tcache, false, arena)); +} + +JEMALLOC_ALWAYS_INLINE void * +icalloc(tsd_t *tsd, size_t size) +{ + + return (iallocztm(tsd, size, true, tcache_get(tsd, true), false, NULL)); +} + +JEMALLOC_ALWAYS_INLINE void * +ipallocztm(tsd_t *tsd, size_t usize, size_t alignment, bool zero, + tcache_t *tcache, bool is_metadata, arena_t *arena) +{ + void *ret; + + assert(usize != 0); + assert(usize == sa2u(usize, alignment)); + + ret = arena_palloc(tsd, arena, usize, alignment, zero, tcache); + assert(ALIGNMENT_ADDR2BASE(ret, alignment) == ret); + if (config_stats && is_metadata && likely(ret != NULL)) { + arena_metadata_allocated_add(iaalloc(ret), isalloc(ret, + config_prof)); + } + return (ret); +} + +JEMALLOC_ALWAYS_INLINE void * +ipalloct(tsd_t *tsd, size_t usize, size_t alignment, bool zero, + tcache_t *tcache, arena_t *arena) +{ + + return (ipallocztm(tsd, usize, alignment, zero, tcache, false, arena)); +} + +JEMALLOC_ALWAYS_INLINE void * +ipalloc(tsd_t *tsd, size_t usize, size_t alignment, bool zero) +{ + + return (ipallocztm(tsd, usize, alignment, zero, tcache_get(tsd, + NULL), false, NULL)); +} + +JEMALLOC_ALWAYS_INLINE size_t +ivsalloc(const void *ptr, bool demote) +{ + extent_node_t *node; + + /* Return 0 if ptr is not within a chunk managed by jemalloc. */ + node = chunk_lookup(ptr, false); + if (node == NULL) + return (0); + /* Only arena chunks should be looked up via interior pointers. */ + assert(extent_node_addr_get(node) == ptr || + extent_node_achunk_get(node)); + + return (isalloc(ptr, demote)); +} + +JEMALLOC_INLINE size_t +u2rz(size_t usize) +{ + size_t ret; + + if (usize <= SMALL_MAXCLASS) { + szind_t binind = size2index(usize); + ret = arena_bin_info[binind].redzone_size; + } else + ret = 0; + + return (ret); +} + +JEMALLOC_INLINE size_t +p2rz(const void *ptr) +{ + size_t usize = isalloc(ptr, false); + + return (u2rz(usize)); +} + +JEMALLOC_ALWAYS_INLINE void +idalloctm(tsd_t *tsd, void *ptr, tcache_t *tcache, bool is_metadata) +{ + + assert(ptr != NULL); + if (config_stats && is_metadata) { + arena_metadata_allocated_sub(iaalloc(ptr), isalloc(ptr, + config_prof)); + } + + arena_dalloc(tsd, ptr, tcache); +} + +JEMALLOC_ALWAYS_INLINE void +idalloct(tsd_t *tsd, void *ptr, tcache_t *tcache) +{ + + idalloctm(tsd, ptr, tcache, false); +} + +JEMALLOC_ALWAYS_INLINE void +idalloc(tsd_t *tsd, void *ptr) +{ + + idalloctm(tsd, ptr, tcache_get(tsd, false), false); +} + +JEMALLOC_ALWAYS_INLINE void +iqalloc(tsd_t *tsd, void *ptr, tcache_t *tcache) +{ + + if (config_fill && unlikely(opt_quarantine)) + quarantine(tsd, ptr); + else + idalloctm(tsd, ptr, tcache, false); +} + +JEMALLOC_ALWAYS_INLINE void +isdalloct(tsd_t *tsd, void *ptr, size_t size, tcache_t *tcache) +{ + + arena_sdalloc(tsd, ptr, size, tcache); +} + +JEMALLOC_ALWAYS_INLINE void +isqalloc(tsd_t *tsd, void *ptr, size_t size, tcache_t *tcache) +{ + + if (config_fill && unlikely(opt_quarantine)) + quarantine(tsd, ptr); + else + isdalloct(tsd, ptr, size, tcache); +} + +JEMALLOC_ALWAYS_INLINE void * +iralloct_realign(tsd_t *tsd, void *ptr, size_t oldsize, size_t size, + size_t extra, size_t alignment, bool zero, tcache_t *tcache, arena_t *arena) +{ + void *p; + size_t usize, copysize; + + usize = sa2u(size + extra, alignment); + if (usize == 0) + return (NULL); + p = ipalloct(tsd, usize, alignment, zero, tcache, arena); + if (p == NULL) { + if (extra == 0) + return (NULL); + /* Try again, without extra this time. */ + usize = sa2u(size, alignment); + if (usize == 0) + return (NULL); + p = ipalloct(tsd, usize, alignment, zero, tcache, arena); + if (p == NULL) + return (NULL); + } + /* + * Copy at most size bytes (not size+extra), since the caller has no + * expectation that the extra bytes will be reliably preserved. + */ + copysize = (size < oldsize) ? size : oldsize; + memcpy(p, ptr, copysize); + isqalloc(tsd, ptr, oldsize, tcache); + return (p); +} + +JEMALLOC_ALWAYS_INLINE void * +iralloct(tsd_t *tsd, void *ptr, size_t oldsize, size_t size, size_t alignment, + bool zero, tcache_t *tcache, arena_t *arena) +{ + + assert(ptr != NULL); + assert(size != 0); + + if (alignment != 0 && ((uintptr_t)ptr & ((uintptr_t)alignment-1)) + != 0) { + /* + * Existing object alignment is inadequate; allocate new space + * and copy. + */ + return (iralloct_realign(tsd, ptr, oldsize, size, 0, alignment, + zero, tcache, arena)); + } + + return (arena_ralloc(tsd, arena, ptr, oldsize, size, alignment, zero, + tcache)); +} + +JEMALLOC_ALWAYS_INLINE void * +iralloc(tsd_t *tsd, void *ptr, size_t oldsize, size_t size, size_t alignment, + bool zero) +{ + + return (iralloct(tsd, ptr, oldsize, size, alignment, zero, + tcache_get(tsd, true), NULL)); +} + +JEMALLOC_ALWAYS_INLINE bool +ixalloc(void *ptr, size_t oldsize, size_t size, size_t extra, size_t alignment, + bool zero) +{ + + assert(ptr != NULL); + assert(size != 0); + + if (alignment != 0 && ((uintptr_t)ptr & ((uintptr_t)alignment-1)) + != 0) { + /* Existing object alignment is inadequate. */ + return (true); + } + + return (arena_ralloc_no_move(ptr, oldsize, size, extra, zero)); +} +#endif + +#include "jemalloc/internal/prof.h" + +#undef JEMALLOC_H_INLINES +/******************************************************************************/ +#endif /* JEMALLOC_INTERNAL_H */ diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/jemalloc_internal_decls.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/jemalloc_internal_decls.h new file mode 100644 index 0000000..a601d6e --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/jemalloc_internal_decls.h @@ -0,0 +1,64 @@ +#ifndef JEMALLOC_INTERNAL_DECLS_H +#define JEMALLOC_INTERNAL_DECLS_H + +#include +#ifdef _WIN32 +# include +# include "msvc_compat/windows_extra.h" + +#else +# include +# include +# if !defined(__pnacl__) && !defined(__native_client__) +# include +# if !defined(SYS_write) && defined(__NR_write) +# define SYS_write __NR_write +# endif +# include +# endif +# include +# include +#endif +#include + +#include +#ifndef SIZE_T_MAX +# define SIZE_T_MAX SIZE_MAX +#endif +#include +#include +#include +#include +#include +#include +#ifndef offsetof +# define offsetof(type, member) ((size_t)&(((type *)NULL)->member)) +#endif +#include +#include +#include +#ifdef _MSC_VER +# include +typedef intptr_t ssize_t; +# define PATH_MAX 1024 +# define STDERR_FILENO 2 +# define __func__ __FUNCTION__ +# ifdef JEMALLOC_HAS_RESTRICT +# define restrict __restrict +# endif +/* Disable warnings about deprecated system functions. */ +# pragma warning(disable: 4996) +#if _MSC_VER < 1800 +static int +isblank(int c) +{ + + return (c == '\t' || c == ' '); +} +#endif +#else +# include +#endif +#include + +#endif /* JEMALLOC_INTERNAL_H */ diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/jemalloc_internal_defs.h.in b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/jemalloc_internal_defs.h.in new file mode 100644 index 0000000..b0f8caa --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/jemalloc_internal_defs.h.in @@ -0,0 +1,262 @@ +#ifndef JEMALLOC_INTERNAL_DEFS_H_ +#define JEMALLOC_INTERNAL_DEFS_H_ +/* + * If JEMALLOC_PREFIX is defined via --with-jemalloc-prefix, it will cause all + * public APIs to be prefixed. This makes it possible, with some care, to use + * multiple allocators simultaneously. + */ +#undef JEMALLOC_PREFIX +#undef JEMALLOC_CPREFIX + +/* + * JEMALLOC_PRIVATE_NAMESPACE is used as a prefix for all library-private APIs. + * For shared libraries, symbol visibility mechanisms prevent these symbols + * from being exported, but for static libraries, naming collisions are a real + * possibility. + */ +#undef JEMALLOC_PRIVATE_NAMESPACE + +/* + * Hyper-threaded CPUs may need a special instruction inside spin loops in + * order to yield to another virtual CPU. + */ +#undef CPU_SPINWAIT + +/* Defined if C11 atomics are available. */ +#undef JEMALLOC_C11ATOMICS + +/* Defined if the equivalent of FreeBSD's atomic(9) functions are available. */ +#undef JEMALLOC_ATOMIC9 + +/* + * Defined if OSAtomic*() functions are available, as provided by Darwin, and + * documented in the atomic(3) manual page. + */ +#undef JEMALLOC_OSATOMIC + +/* + * Defined if __sync_add_and_fetch(uint32_t *, uint32_t) and + * __sync_sub_and_fetch(uint32_t *, uint32_t) are available, despite + * __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 not being defined (which means the + * functions are defined in libgcc instead of being inlines). + */ +#undef JE_FORCE_SYNC_COMPARE_AND_SWAP_4 + +/* + * Defined if __sync_add_and_fetch(uint64_t *, uint64_t) and + * __sync_sub_and_fetch(uint64_t *, uint64_t) are available, despite + * __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 not being defined (which means the + * functions are defined in libgcc instead of being inlines). + */ +#undef JE_FORCE_SYNC_COMPARE_AND_SWAP_8 + +/* + * Defined if __builtin_clz() and __builtin_clzl() are available. + */ +#undef JEMALLOC_HAVE_BUILTIN_CLZ + +/* + * Defined if madvise(2) is available. + */ +#undef JEMALLOC_HAVE_MADVISE + +/* + * Defined if OSSpin*() functions are available, as provided by Darwin, and + * documented in the spinlock(3) manual page. + */ +#undef JEMALLOC_OSSPIN + +/* + * Defined if secure_getenv(3) is available. + */ +#undef JEMALLOC_HAVE_SECURE_GETENV + +/* + * Defined if issetugid(2) is available. + */ +#undef JEMALLOC_HAVE_ISSETUGID + +/* + * Defined if _malloc_thread_cleanup() exists. At least in the case of + * FreeBSD, pthread_key_create() allocates, which if used during malloc + * bootstrapping will cause recursion into the pthreads library. Therefore, if + * _malloc_thread_cleanup() exists, use it as the basis for thread cleanup in + * malloc_tsd. + */ +#undef JEMALLOC_MALLOC_THREAD_CLEANUP + +/* + * Defined if threaded initialization is known to be safe on this platform. + * Among other things, it must be possible to initialize a mutex without + * triggering allocation in order for threaded allocation to be safe. + */ +#undef JEMALLOC_THREADED_INIT + +/* + * Defined if the pthreads implementation defines + * _pthread_mutex_init_calloc_cb(), in which case the function is used in order + * to avoid recursive allocation during mutex initialization. + */ +#undef JEMALLOC_MUTEX_INIT_CB + +/* Non-empty if the tls_model attribute is supported. */ +#undef JEMALLOC_TLS_MODEL + +/* JEMALLOC_CC_SILENCE enables code that silences unuseful compiler warnings. */ +#undef JEMALLOC_CC_SILENCE + +/* JEMALLOC_CODE_COVERAGE enables test code coverage analysis. */ +#undef JEMALLOC_CODE_COVERAGE + +/* + * JEMALLOC_DEBUG enables assertions and other sanity checks, and disables + * inline functions. + */ +#undef JEMALLOC_DEBUG + +/* JEMALLOC_STATS enables statistics calculation. */ +#undef JEMALLOC_STATS + +/* JEMALLOC_PROF enables allocation profiling. */ +#undef JEMALLOC_PROF + +/* Use libunwind for profile backtracing if defined. */ +#undef JEMALLOC_PROF_LIBUNWIND + +/* Use libgcc for profile backtracing if defined. */ +#undef JEMALLOC_PROF_LIBGCC + +/* Use gcc intrinsics for profile backtracing if defined. */ +#undef JEMALLOC_PROF_GCC + +/* + * JEMALLOC_TCACHE enables a thread-specific caching layer for small objects. + * This makes it possible to allocate/deallocate objects without any locking + * when the cache is in the steady state. + */ +#undef JEMALLOC_TCACHE + +/* + * JEMALLOC_DSS enables use of sbrk(2) to allocate chunks from the data storage + * segment (DSS). + */ +#undef JEMALLOC_DSS + +/* Support memory filling (junk/zero/quarantine/redzone). */ +#undef JEMALLOC_FILL + +/* Support utrace(2)-based tracing. */ +#undef JEMALLOC_UTRACE + +/* Support Valgrind. */ +#undef JEMALLOC_VALGRIND + +/* Support optional abort() on OOM. */ +#undef JEMALLOC_XMALLOC + +/* Support lazy locking (avoid locking unless a second thread is launched). */ +#undef JEMALLOC_LAZY_LOCK + +/* Minimum size class to support is 2^LG_TINY_MIN bytes. */ +#undef LG_TINY_MIN + +/* + * Minimum allocation alignment is 2^LG_QUANTUM bytes (ignoring tiny size + * classes). + */ +#undef LG_QUANTUM + +/* One page is 2^LG_PAGE bytes. */ +#undef LG_PAGE + +/* + * If defined, adjacent virtual memory mappings with identical attributes + * automatically coalesce, and they fragment when changes are made to subranges. + * This is the normal order of things for mmap()/munmap(), but on Windows + * VirtualAlloc()/VirtualFree() operations must be precisely matched, i.e. + * mappings do *not* coalesce/fragment. + */ +#undef JEMALLOC_MAPS_COALESCE + +/* + * If defined, use munmap() to unmap freed chunks, rather than storing them for + * later reuse. This is disabled by default on Linux because common sequences + * of mmap()/munmap() calls will cause virtual memory map holes. + */ +#undef JEMALLOC_MUNMAP + +/* TLS is used to map arenas and magazine caches to threads. */ +#undef JEMALLOC_TLS + +/* + * ffs()/ffsl() functions to use for bitmapping. Don't use these directly; + * instead, use jemalloc_ffs() or jemalloc_ffsl() from util.h. + */ +#undef JEMALLOC_INTERNAL_FFSL +#undef JEMALLOC_INTERNAL_FFS + +/* + * JEMALLOC_IVSALLOC enables ivsalloc(), which verifies that pointers reside + * within jemalloc-owned chunks before dereferencing them. + */ +#undef JEMALLOC_IVSALLOC + +/* + * If defined, explicitly attempt to more uniformly distribute large allocation + * pointer alignments across all cache indices. + */ +#undef JEMALLOC_CACHE_OBLIVIOUS + +/* + * Darwin (OS X) uses zones to work around Mach-O symbol override shortcomings. + */ +#undef JEMALLOC_ZONE +#undef JEMALLOC_ZONE_VERSION + +/* + * Methods for purging unused pages differ between operating systems. + * + * madvise(..., MADV_DONTNEED) : On Linux, this immediately discards pages, + * such that new pages will be demand-zeroed if + * the address region is later touched. + * madvise(..., MADV_FREE) : On FreeBSD and Darwin, this marks pages as being + * unused, such that they will be discarded rather + * than swapped out. + */ +#undef JEMALLOC_PURGE_MADVISE_DONTNEED +#undef JEMALLOC_PURGE_MADVISE_FREE + +/* Define if operating system has alloca.h header. */ +#undef JEMALLOC_HAS_ALLOCA_H + +/* C99 restrict keyword supported. */ +#undef JEMALLOC_HAS_RESTRICT + +/* For use by hash code. */ +#undef JEMALLOC_BIG_ENDIAN + +/* sizeof(int) == 2^LG_SIZEOF_INT. */ +#undef LG_SIZEOF_INT + +/* sizeof(long) == 2^LG_SIZEOF_LONG. */ +#undef LG_SIZEOF_LONG + +/* sizeof(intmax_t) == 2^LG_SIZEOF_INTMAX_T. */ +#undef LG_SIZEOF_INTMAX_T + +/* glibc malloc hooks (__malloc_hook, __realloc_hook, __free_hook). */ +#undef JEMALLOC_GLIBC_MALLOC_HOOK + +/* glibc memalign hook. */ +#undef JEMALLOC_GLIBC_MEMALIGN_HOOK + +/* Adaptive mutex support in pthreads. */ +#undef JEMALLOC_HAVE_PTHREAD_MUTEX_ADAPTIVE_NP + +/* + * If defined, jemalloc symbols are not exported (doesn't work when + * JEMALLOC_PREFIX is not defined). + */ +#undef JEMALLOC_EXPORT + +#endif /* JEMALLOC_INTERNAL_DEFS_H_ */ diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/jemalloc_internal_macros.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/jemalloc_internal_macros.h new file mode 100644 index 0000000..a08ba77 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/jemalloc_internal_macros.h @@ -0,0 +1,57 @@ +/* + * JEMALLOC_ALWAYS_INLINE and JEMALLOC_INLINE are used within header files for + * functions that are static inline functions if inlining is enabled, and + * single-definition library-private functions if inlining is disabled. + * + * JEMALLOC_ALWAYS_INLINE_C and JEMALLOC_INLINE_C are for use in .c files, in + * which case the denoted functions are always static, regardless of whether + * inlining is enabled. + */ +#if defined(JEMALLOC_DEBUG) || defined(JEMALLOC_CODE_COVERAGE) + /* Disable inlining to make debugging/profiling easier. */ +# define JEMALLOC_ALWAYS_INLINE +# define JEMALLOC_ALWAYS_INLINE_C static +# define JEMALLOC_INLINE +# define JEMALLOC_INLINE_C static +# define inline +#else +# define JEMALLOC_ENABLE_INLINE +# ifdef JEMALLOC_HAVE_ATTR +# define JEMALLOC_ALWAYS_INLINE \ + static inline JEMALLOC_ATTR(unused) JEMALLOC_ATTR(always_inline) +# define JEMALLOC_ALWAYS_INLINE_C \ + static inline JEMALLOC_ATTR(always_inline) +# else +# define JEMALLOC_ALWAYS_INLINE static inline +# define JEMALLOC_ALWAYS_INLINE_C static inline +# endif +# define JEMALLOC_INLINE static inline +# define JEMALLOC_INLINE_C static inline +# ifdef _MSC_VER +# define inline _inline +# endif +#endif + +#ifdef JEMALLOC_CC_SILENCE +# define UNUSED JEMALLOC_ATTR(unused) +#else +# define UNUSED +#endif + +#define ZU(z) ((size_t)z) +#define ZI(z) ((ssize_t)z) +#define QU(q) ((uint64_t)q) +#define QI(q) ((int64_t)q) + +#define KZU(z) ZU(z##ULL) +#define KZI(z) ZI(z##LL) +#define KQU(q) QU(q##ULL) +#define KQI(q) QI(q##LL) + +#ifndef __DECONST +# define __DECONST(type, var) ((type)(uintptr_t)(const void *)(var)) +#endif + +#ifndef JEMALLOC_HAS_RESTRICT +# define restrict +#endif diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/mb.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/mb.h new file mode 100644 index 0000000..3cfa787 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/mb.h @@ -0,0 +1,115 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#ifndef JEMALLOC_ENABLE_INLINE +void mb_write(void); +#endif + +#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_MB_C_)) +#ifdef __i386__ +/* + * According to the Intel Architecture Software Developer's Manual, current + * processors execute instructions in order from the perspective of other + * processors in a multiprocessor system, but 1) Intel reserves the right to + * change that, and 2) the compiler's optimizer could re-order instructions if + * there weren't some form of barrier. Therefore, even if running on an + * architecture that does not need memory barriers (everything through at least + * i686), an "optimizer barrier" is necessary. + */ +JEMALLOC_INLINE void +mb_write(void) +{ + +# if 0 + /* This is a true memory barrier. */ + asm volatile ("pusha;" + "xor %%eax,%%eax;" + "cpuid;" + "popa;" + : /* Outputs. */ + : /* Inputs. */ + : "memory" /* Clobbers. */ + ); +#else + /* + * This is hopefully enough to keep the compiler from reordering + * instructions around this one. + */ + asm volatile ("nop;" + : /* Outputs. */ + : /* Inputs. */ + : "memory" /* Clobbers. */ + ); +#endif +} +#elif (defined(__amd64__) || defined(__x86_64__)) +JEMALLOC_INLINE void +mb_write(void) +{ + + asm volatile ("sfence" + : /* Outputs. */ + : /* Inputs. */ + : "memory" /* Clobbers. */ + ); +} +#elif defined(__powerpc__) +JEMALLOC_INLINE void +mb_write(void) +{ + + asm volatile ("eieio" + : /* Outputs. */ + : /* Inputs. */ + : "memory" /* Clobbers. */ + ); +} +#elif defined(__sparc64__) +JEMALLOC_INLINE void +mb_write(void) +{ + + asm volatile ("membar #StoreStore" + : /* Outputs. */ + : /* Inputs. */ + : "memory" /* Clobbers. */ + ); +} +#elif defined(__tile__) +JEMALLOC_INLINE void +mb_write(void) +{ + + __sync_synchronize(); +} +#else +/* + * This is much slower than a simple memory barrier, but the semantics of mutex + * unlock make this work. + */ +JEMALLOC_INLINE void +mb_write(void) +{ + malloc_mutex_t mtx; + + malloc_mutex_init(&mtx); + malloc_mutex_lock(&mtx); + malloc_mutex_unlock(&mtx); +} +#endif +#endif + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/mutex.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/mutex.h new file mode 100644 index 0000000..f051f29 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/mutex.h @@ -0,0 +1,111 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +typedef struct malloc_mutex_s malloc_mutex_t; + +#ifdef _WIN32 +# define MALLOC_MUTEX_INITIALIZER +#elif (defined(JEMALLOC_OSSPIN)) +# define MALLOC_MUTEX_INITIALIZER {0} +#elif (defined(JEMALLOC_MUTEX_INIT_CB)) +# define MALLOC_MUTEX_INITIALIZER {PTHREAD_MUTEX_INITIALIZER, NULL} +#else +# if (defined(JEMALLOC_HAVE_PTHREAD_MUTEX_ADAPTIVE_NP) && \ + defined(PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP)) +# define MALLOC_MUTEX_TYPE PTHREAD_MUTEX_ADAPTIVE_NP +# define MALLOC_MUTEX_INITIALIZER {PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP} +# else +# define MALLOC_MUTEX_TYPE PTHREAD_MUTEX_DEFAULT +# define MALLOC_MUTEX_INITIALIZER {PTHREAD_MUTEX_INITIALIZER} +# endif +#endif + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +struct malloc_mutex_s { +#ifdef _WIN32 +# if _WIN32_WINNT >= 0x0600 + SRWLOCK lock; +# else + CRITICAL_SECTION lock; +# endif +#elif (defined(JEMALLOC_OSSPIN)) + OSSpinLock lock; +#elif (defined(JEMALLOC_MUTEX_INIT_CB)) + pthread_mutex_t lock; + malloc_mutex_t *postponed_next; +#else + pthread_mutex_t lock; +#endif +}; + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +#ifdef JEMALLOC_LAZY_LOCK +extern bool isthreaded; +#else +# undef isthreaded /* Undo private_namespace.h definition. */ +# define isthreaded true +#endif + +bool malloc_mutex_init(malloc_mutex_t *mutex); +void malloc_mutex_prefork(malloc_mutex_t *mutex); +void malloc_mutex_postfork_parent(malloc_mutex_t *mutex); +void malloc_mutex_postfork_child(malloc_mutex_t *mutex); +bool mutex_boot(void); + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#ifndef JEMALLOC_ENABLE_INLINE +void malloc_mutex_lock(malloc_mutex_t *mutex); +void malloc_mutex_unlock(malloc_mutex_t *mutex); +#endif + +#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_MUTEX_C_)) +JEMALLOC_INLINE void +malloc_mutex_lock(malloc_mutex_t *mutex) +{ + + if (isthreaded) { +#ifdef _WIN32 +# if _WIN32_WINNT >= 0x0600 + AcquireSRWLockExclusive(&mutex->lock); +# else + EnterCriticalSection(&mutex->lock); +# endif +#elif (defined(JEMALLOC_OSSPIN)) + OSSpinLockLock(&mutex->lock); +#else + pthread_mutex_lock(&mutex->lock); +#endif + } +} + +JEMALLOC_INLINE void +malloc_mutex_unlock(malloc_mutex_t *mutex) +{ + + if (isthreaded) { +#ifdef _WIN32 +# if _WIN32_WINNT >= 0x0600 + ReleaseSRWLockExclusive(&mutex->lock); +# else + LeaveCriticalSection(&mutex->lock); +# endif +#elif (defined(JEMALLOC_OSSPIN)) + OSSpinLockUnlock(&mutex->lock); +#else + pthread_mutex_unlock(&mutex->lock); +#endif + } +} +#endif + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/pages.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/pages.h new file mode 100644 index 0000000..da7eb96 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/pages.h @@ -0,0 +1,26 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +void *pages_map(void *addr, size_t size); +void pages_unmap(void *addr, size_t size); +void *pages_trim(void *addr, size_t alloc_size, size_t leadsize, + size_t size); +bool pages_commit(void *addr, size_t size); +bool pages_decommit(void *addr, size_t size); +bool pages_purge(void *addr, size_t size); + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ + diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/private_namespace.sh b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/private_namespace.sh new file mode 100755 index 0000000..cd25eb3 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/private_namespace.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +for symbol in `cat $1` ; do + echo "#define ${symbol} JEMALLOC_N(${symbol})" +done diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/private_symbols.txt b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/private_symbols.txt new file mode 100644 index 0000000..a90021a --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/private_symbols.txt @@ -0,0 +1,499 @@ +a0dalloc +a0get +a0malloc +arena_aalloc +arena_alloc_junk_small +arena_bin_index +arena_bin_info +arena_bitselm_get +arena_boot +arena_choose +arena_choose_hard +arena_chunk_alloc_huge +arena_chunk_cache_maybe_insert +arena_chunk_cache_maybe_remove +arena_chunk_dalloc_huge +arena_chunk_ralloc_huge_expand +arena_chunk_ralloc_huge_shrink +arena_chunk_ralloc_huge_similar +arena_cleanup +arena_dalloc +arena_dalloc_bin +arena_dalloc_bin_junked_locked +arena_dalloc_junk_large +arena_dalloc_junk_small +arena_dalloc_large +arena_dalloc_large_junked_locked +arena_dalloc_small +arena_dss_prec_get +arena_dss_prec_set +arena_get +arena_get_hard +arena_init +arena_lg_dirty_mult_default_get +arena_lg_dirty_mult_default_set +arena_lg_dirty_mult_get +arena_lg_dirty_mult_set +arena_malloc +arena_malloc_large +arena_malloc_small +arena_mapbits_allocated_get +arena_mapbits_binind_get +arena_mapbits_decommitted_get +arena_mapbits_dirty_get +arena_mapbits_get +arena_mapbits_internal_set +arena_mapbits_large_binind_set +arena_mapbits_large_get +arena_mapbits_large_set +arena_mapbits_large_size_get +arena_mapbitsp_get +arena_mapbitsp_read +arena_mapbitsp_write +arena_mapbits_size_decode +arena_mapbits_size_encode +arena_mapbits_small_runind_get +arena_mapbits_small_set +arena_mapbits_unallocated_set +arena_mapbits_unallocated_size_get +arena_mapbits_unallocated_size_set +arena_mapbits_unzeroed_get +arena_maxrun +arena_maybe_purge +arena_metadata_allocated_add +arena_metadata_allocated_get +arena_metadata_allocated_sub +arena_migrate +arena_miscelm_get +arena_miscelm_to_pageind +arena_miscelm_to_rpages +arena_nbound +arena_new +arena_node_alloc +arena_node_dalloc +arena_palloc +arena_postfork_child +arena_postfork_parent +arena_prefork +arena_prof_accum +arena_prof_accum_impl +arena_prof_accum_locked +arena_prof_promoted +arena_prof_tctx_get +arena_prof_tctx_reset +arena_prof_tctx_set +arena_ptr_small_binind_get +arena_purge_all +arena_quarantine_junk_small +arena_ralloc +arena_ralloc_junk_large +arena_ralloc_no_move +arena_rd_to_miscelm +arena_redzone_corruption +arena_run_regind +arena_run_to_miscelm +arena_salloc +arenas_cache_bypass_cleanup +arenas_cache_cleanup +arena_sdalloc +arena_stats_merge +arena_tcache_fill_small +atomic_add_p +atomic_add_u +atomic_add_uint32 +atomic_add_uint64 +atomic_add_z +atomic_cas_p +atomic_cas_u +atomic_cas_uint32 +atomic_cas_uint64 +atomic_cas_z +atomic_sub_p +atomic_sub_u +atomic_sub_uint32 +atomic_sub_uint64 +atomic_sub_z +base_alloc +base_boot +base_postfork_child +base_postfork_parent +base_prefork +base_stats_get +bitmap_full +bitmap_get +bitmap_info_init +bitmap_info_ngroups +bitmap_init +bitmap_set +bitmap_sfu +bitmap_size +bitmap_unset +bootstrap_calloc +bootstrap_free +bootstrap_malloc +bt_init +buferror +chunk_alloc_base +chunk_alloc_cache +chunk_alloc_dss +chunk_alloc_mmap +chunk_alloc_wrapper +chunk_boot +chunk_dalloc_arena +chunk_dalloc_cache +chunk_dalloc_mmap +chunk_dalloc_wrapper +chunk_deregister +chunk_dss_boot +chunk_dss_postfork_child +chunk_dss_postfork_parent +chunk_dss_prec_get +chunk_dss_prec_set +chunk_dss_prefork +chunk_hooks_default +chunk_hooks_get +chunk_hooks_set +chunk_in_dss +chunk_lookup +chunk_npages +chunk_postfork_child +chunk_postfork_parent +chunk_prefork +chunk_purge_arena +chunk_purge_wrapper +chunk_register +chunksize +chunksize_mask +chunks_rtree +ckh_count +ckh_delete +ckh_insert +ckh_iter +ckh_new +ckh_pointer_hash +ckh_pointer_keycomp +ckh_remove +ckh_search +ckh_string_hash +ckh_string_keycomp +ctl_boot +ctl_bymib +ctl_byname +ctl_nametomib +ctl_postfork_child +ctl_postfork_parent +ctl_prefork +dss_prec_names +extent_node_achunk_get +extent_node_achunk_set +extent_node_addr_get +extent_node_addr_set +extent_node_arena_get +extent_node_arena_set +extent_node_dirty_insert +extent_node_dirty_linkage_init +extent_node_dirty_remove +extent_node_init +extent_node_prof_tctx_get +extent_node_prof_tctx_set +extent_node_size_get +extent_node_size_set +extent_node_zeroed_get +extent_node_zeroed_set +extent_tree_ad_empty +extent_tree_ad_first +extent_tree_ad_insert +extent_tree_ad_iter +extent_tree_ad_iter_recurse +extent_tree_ad_iter_start +extent_tree_ad_last +extent_tree_ad_new +extent_tree_ad_next +extent_tree_ad_nsearch +extent_tree_ad_prev +extent_tree_ad_psearch +extent_tree_ad_remove +extent_tree_ad_reverse_iter +extent_tree_ad_reverse_iter_recurse +extent_tree_ad_reverse_iter_start +extent_tree_ad_search +extent_tree_szad_empty +extent_tree_szad_first +extent_tree_szad_insert +extent_tree_szad_iter +extent_tree_szad_iter_recurse +extent_tree_szad_iter_start +extent_tree_szad_last +extent_tree_szad_new +extent_tree_szad_next +extent_tree_szad_nsearch +extent_tree_szad_prev +extent_tree_szad_psearch +extent_tree_szad_remove +extent_tree_szad_reverse_iter +extent_tree_szad_reverse_iter_recurse +extent_tree_szad_reverse_iter_start +extent_tree_szad_search +get_errno +hash +hash_fmix_32 +hash_fmix_64 +hash_get_block_32 +hash_get_block_64 +hash_rotl_32 +hash_rotl_64 +hash_x64_128 +hash_x86_128 +hash_x86_32 +huge_aalloc +huge_dalloc +huge_dalloc_junk +huge_malloc +huge_palloc +huge_prof_tctx_get +huge_prof_tctx_reset +huge_prof_tctx_set +huge_ralloc +huge_ralloc_no_move +huge_salloc +iaalloc +iallocztm +icalloc +icalloct +idalloc +idalloct +idalloctm +imalloc +imalloct +index2size +index2size_compute +index2size_lookup +index2size_tab +in_valgrind +ipalloc +ipalloct +ipallocztm +iqalloc +iralloc +iralloct +iralloct_realign +isalloc +isdalloct +isqalloc +isthreaded +ivsalloc +ixalloc +jemalloc_postfork_child +jemalloc_postfork_parent +jemalloc_prefork +large_maxclass +lg_floor +malloc_cprintf +malloc_mutex_init +malloc_mutex_lock +malloc_mutex_postfork_child +malloc_mutex_postfork_parent +malloc_mutex_prefork +malloc_mutex_unlock +malloc_printf +malloc_snprintf +malloc_strtoumax +malloc_tsd_boot0 +malloc_tsd_boot1 +malloc_tsd_cleanup_register +malloc_tsd_dalloc +malloc_tsd_malloc +malloc_tsd_no_cleanup +malloc_vcprintf +malloc_vsnprintf +malloc_write +map_bias +map_misc_offset +mb_write +mutex_boot +narenas_cache_cleanup +narenas_total_get +ncpus +nhbins +opt_abort +opt_dss +opt_junk +opt_junk_alloc +opt_junk_free +opt_lg_chunk +opt_lg_dirty_mult +opt_lg_prof_interval +opt_lg_prof_sample +opt_lg_tcache_max +opt_narenas +opt_prof +opt_prof_accum +opt_prof_active +opt_prof_final +opt_prof_gdump +opt_prof_leak +opt_prof_prefix +opt_prof_thread_active_init +opt_quarantine +opt_redzone +opt_stats_print +opt_tcache +opt_utrace +opt_xmalloc +opt_zero +p2rz +pages_commit +pages_decommit +pages_map +pages_purge +pages_trim +pages_unmap +pow2_ceil +prof_active_get +prof_active_get_unlocked +prof_active_set +prof_alloc_prep +prof_alloc_rollback +prof_backtrace +prof_boot0 +prof_boot1 +prof_boot2 +prof_dump_header +prof_dump_open +prof_free +prof_free_sampled_object +prof_gdump +prof_gdump_get +prof_gdump_get_unlocked +prof_gdump_set +prof_gdump_val +prof_idump +prof_interval +prof_lookup +prof_malloc +prof_malloc_sample_object +prof_mdump +prof_postfork_child +prof_postfork_parent +prof_prefork +prof_realloc +prof_reset +prof_sample_accum_update +prof_sample_threshold_update +prof_tctx_get +prof_tctx_reset +prof_tctx_set +prof_tdata_cleanup +prof_tdata_get +prof_tdata_init +prof_tdata_reinit +prof_thread_active_get +prof_thread_active_init_get +prof_thread_active_init_set +prof_thread_active_set +prof_thread_name_get +prof_thread_name_set +quarantine +quarantine_alloc_hook +quarantine_alloc_hook_work +quarantine_cleanup +register_zone +rtree_child_read +rtree_child_read_hard +rtree_child_tryread +rtree_delete +rtree_get +rtree_new +rtree_node_valid +rtree_set +rtree_start_level +rtree_subkey +rtree_subtree_read +rtree_subtree_read_hard +rtree_subtree_tryread +rtree_val_read +rtree_val_write +s2u +s2u_compute +s2u_lookup +sa2u +set_errno +size2index +size2index_compute +size2index_lookup +size2index_tab +stats_cactive +stats_cactive_add +stats_cactive_get +stats_cactive_sub +stats_print +tcache_alloc_easy +tcache_alloc_large +tcache_alloc_small +tcache_alloc_small_hard +tcache_arena_associate +tcache_arena_dissociate +tcache_arena_reassociate +tcache_bin_flush_large +tcache_bin_flush_small +tcache_bin_info +tcache_boot +tcache_cleanup +tcache_create +tcache_dalloc_large +tcache_dalloc_small +tcache_enabled_cleanup +tcache_enabled_get +tcache_enabled_set +tcache_event +tcache_event_hard +tcache_flush +tcache_get +tcache_get_hard +tcache_maxclass +tcaches +tcache_salloc +tcaches_create +tcaches_destroy +tcaches_flush +tcaches_get +tcache_stats_merge +thread_allocated_cleanup +thread_deallocated_cleanup +tsd_arena_get +tsd_arena_set +tsd_boot +tsd_boot0 +tsd_boot1 +tsd_booted +tsd_cleanup +tsd_cleanup_wrapper +tsd_fetch +tsd_get +tsd_wrapper_get +tsd_wrapper_set +tsd_initialized +tsd_init_check_recursion +tsd_init_finish +tsd_init_head +tsd_nominal +tsd_quarantine_get +tsd_quarantine_set +tsd_set +tsd_tcache_enabled_get +tsd_tcache_enabled_set +tsd_tcache_get +tsd_tcache_set +tsd_tls +tsd_tsd +tsd_prof_tdata_get +tsd_prof_tdata_set +tsd_thread_allocated_get +tsd_thread_allocated_set +tsd_thread_deallocated_get +tsd_thread_deallocated_set +u2rz +valgrind_freelike_block +valgrind_make_mem_defined +valgrind_make_mem_noaccess +valgrind_make_mem_undefined diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/private_unnamespace.sh b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/private_unnamespace.sh new file mode 100755 index 0000000..23fed8e --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/private_unnamespace.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +for symbol in `cat $1` ; do + echo "#undef ${symbol}" +done diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/prng.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/prng.h new file mode 100644 index 0000000..216d0ef --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/prng.h @@ -0,0 +1,60 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +/* + * Simple linear congruential pseudo-random number generator: + * + * prng(y) = (a*x + c) % m + * + * where the following constants ensure maximal period: + * + * a == Odd number (relatively prime to 2^n), and (a-1) is a multiple of 4. + * c == Odd number (relatively prime to 2^n). + * m == 2^32 + * + * See Knuth's TAOCP 3rd Ed., Vol. 2, pg. 17 for details on these constraints. + * + * This choice of m has the disadvantage that the quality of the bits is + * proportional to bit position. For example, the lowest bit has a cycle of 2, + * the next has a cycle of 4, etc. For this reason, we prefer to use the upper + * bits. + * + * Macro parameters: + * uint32_t r : Result. + * unsigned lg_range : (0..32], number of least significant bits to return. + * uint32_t state : Seed value. + * const uint32_t a, c : See above discussion. + */ +#define prng32(r, lg_range, state, a, c) do { \ + assert((lg_range) > 0); \ + assert((lg_range) <= 32); \ + \ + r = (state * (a)) + (c); \ + state = r; \ + r >>= (32 - (lg_range)); \ +} while (false) + +/* Same as prng32(), but 64 bits of pseudo-randomness, using uint64_t. */ +#define prng64(r, lg_range, state, a, c) do { \ + assert((lg_range) > 0); \ + assert((lg_range) <= 64); \ + \ + r = (state * (a)) + (c); \ + state = r; \ + r >>= (64 - (lg_range)); \ +} while (false) + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/prof.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/prof.h new file mode 100644 index 0000000..e5198c3 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/prof.h @@ -0,0 +1,545 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +typedef struct prof_bt_s prof_bt_t; +typedef struct prof_cnt_s prof_cnt_t; +typedef struct prof_tctx_s prof_tctx_t; +typedef struct prof_gctx_s prof_gctx_t; +typedef struct prof_tdata_s prof_tdata_t; + +/* Option defaults. */ +#ifdef JEMALLOC_PROF +# define PROF_PREFIX_DEFAULT "jeprof" +#else +# define PROF_PREFIX_DEFAULT "" +#endif +#define LG_PROF_SAMPLE_DEFAULT 19 +#define LG_PROF_INTERVAL_DEFAULT -1 + +/* + * Hard limit on stack backtrace depth. The version of prof_backtrace() that + * is based on __builtin_return_address() necessarily has a hard-coded number + * of backtrace frame handlers, and should be kept in sync with this setting. + */ +#define PROF_BT_MAX 128 + +/* Initial hash table size. */ +#define PROF_CKH_MINITEMS 64 + +/* Size of memory buffer to use when writing dump files. */ +#define PROF_DUMP_BUFSIZE 65536 + +/* Size of stack-allocated buffer used by prof_printf(). */ +#define PROF_PRINTF_BUFSIZE 128 + +/* + * Number of mutexes shared among all gctx's. No space is allocated for these + * unless profiling is enabled, so it's okay to over-provision. + */ +#define PROF_NCTX_LOCKS 1024 + +/* + * Number of mutexes shared among all tdata's. No space is allocated for these + * unless profiling is enabled, so it's okay to over-provision. + */ +#define PROF_NTDATA_LOCKS 256 + +/* + * prof_tdata pointers close to NULL are used to encode state information that + * is used for cleaning up during thread shutdown. + */ +#define PROF_TDATA_STATE_REINCARNATED ((prof_tdata_t *)(uintptr_t)1) +#define PROF_TDATA_STATE_PURGATORY ((prof_tdata_t *)(uintptr_t)2) +#define PROF_TDATA_STATE_MAX PROF_TDATA_STATE_PURGATORY + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +struct prof_bt_s { + /* Backtrace, stored as len program counters. */ + void **vec; + unsigned len; +}; + +#ifdef JEMALLOC_PROF_LIBGCC +/* Data structure passed to libgcc _Unwind_Backtrace() callback functions. */ +typedef struct { + prof_bt_t *bt; + unsigned max; +} prof_unwind_data_t; +#endif + +struct prof_cnt_s { + /* Profiling counters. */ + uint64_t curobjs; + uint64_t curbytes; + uint64_t accumobjs; + uint64_t accumbytes; +}; + +typedef enum { + prof_tctx_state_initializing, + prof_tctx_state_nominal, + prof_tctx_state_dumping, + prof_tctx_state_purgatory /* Dumper must finish destroying. */ +} prof_tctx_state_t; + +struct prof_tctx_s { + /* Thread data for thread that performed the allocation. */ + prof_tdata_t *tdata; + + /* + * Copy of tdata->thr_{uid,discrim}, necessary because tdata may be + * defunct during teardown. + */ + uint64_t thr_uid; + uint64_t thr_discrim; + + /* Profiling counters, protected by tdata->lock. */ + prof_cnt_t cnts; + + /* Associated global context. */ + prof_gctx_t *gctx; + + /* + * UID that distinguishes multiple tctx's created by the same thread, + * but coexisting in gctx->tctxs. There are two ways that such + * coexistence can occur: + * - A dumper thread can cause a tctx to be retained in the purgatory + * state. + * - Although a single "producer" thread must create all tctx's which + * share the same thr_uid, multiple "consumers" can each concurrently + * execute portions of prof_tctx_destroy(). prof_tctx_destroy() only + * gets called once each time cnts.cur{objs,bytes} drop to 0, but this + * threshold can be hit again before the first consumer finishes + * executing prof_tctx_destroy(). + */ + uint64_t tctx_uid; + + /* Linkage into gctx's tctxs. */ + rb_node(prof_tctx_t) tctx_link; + + /* + * True during prof_alloc_prep()..prof_malloc_sample_object(), prevents + * sample vs destroy race. + */ + bool prepared; + + /* Current dump-related state, protected by gctx->lock. */ + prof_tctx_state_t state; + + /* + * Copy of cnts snapshotted during early dump phase, protected by + * dump_mtx. + */ + prof_cnt_t dump_cnts; +}; +typedef rb_tree(prof_tctx_t) prof_tctx_tree_t; + +struct prof_gctx_s { + /* Protects nlimbo, cnt_summed, and tctxs. */ + malloc_mutex_t *lock; + + /* + * Number of threads that currently cause this gctx to be in a state of + * limbo due to one of: + * - Initializing this gctx. + * - Initializing per thread counters associated with this gctx. + * - Preparing to destroy this gctx. + * - Dumping a heap profile that includes this gctx. + * nlimbo must be 1 (single destroyer) in order to safely destroy the + * gctx. + */ + unsigned nlimbo; + + /* + * Tree of profile counters, one for each thread that has allocated in + * this context. + */ + prof_tctx_tree_t tctxs; + + /* Linkage for tree of contexts to be dumped. */ + rb_node(prof_gctx_t) dump_link; + + /* Temporary storage for summation during dump. */ + prof_cnt_t cnt_summed; + + /* Associated backtrace. */ + prof_bt_t bt; + + /* Backtrace vector, variable size, referred to by bt. */ + void *vec[1]; +}; +typedef rb_tree(prof_gctx_t) prof_gctx_tree_t; + +struct prof_tdata_s { + malloc_mutex_t *lock; + + /* Monotonically increasing unique thread identifier. */ + uint64_t thr_uid; + + /* + * Monotonically increasing discriminator among tdata structures + * associated with the same thr_uid. + */ + uint64_t thr_discrim; + + /* Included in heap profile dumps if non-NULL. */ + char *thread_name; + + bool attached; + bool expired; + + rb_node(prof_tdata_t) tdata_link; + + /* + * Counter used to initialize prof_tctx_t's tctx_uid. No locking is + * necessary when incrementing this field, because only one thread ever + * does so. + */ + uint64_t tctx_uid_next; + + /* + * Hash of (prof_bt_t *)-->(prof_tctx_t *). Each thread tracks + * backtraces for which it has non-zero allocation/deallocation counters + * associated with thread-specific prof_tctx_t objects. Other threads + * may write to prof_tctx_t contents when freeing associated objects. + */ + ckh_t bt2tctx; + + /* Sampling state. */ + uint64_t prng_state; + uint64_t bytes_until_sample; + + /* State used to avoid dumping while operating on prof internals. */ + bool enq; + bool enq_idump; + bool enq_gdump; + + /* + * Set to true during an early dump phase for tdata's which are + * currently being dumped. New threads' tdata's have this initialized + * to false so that they aren't accidentally included in later dump + * phases. + */ + bool dumping; + + /* + * True if profiling is active for this tdata's thread + * (thread.prof.active mallctl). + */ + bool active; + + /* Temporary storage for summation during dump. */ + prof_cnt_t cnt_summed; + + /* Backtrace vector, used for calls to prof_backtrace(). */ + void *vec[PROF_BT_MAX]; +}; +typedef rb_tree(prof_tdata_t) prof_tdata_tree_t; + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +extern bool opt_prof; +extern bool opt_prof_active; +extern bool opt_prof_thread_active_init; +extern size_t opt_lg_prof_sample; /* Mean bytes between samples. */ +extern ssize_t opt_lg_prof_interval; /* lg(prof_interval). */ +extern bool opt_prof_gdump; /* High-water memory dumping. */ +extern bool opt_prof_final; /* Final profile dumping. */ +extern bool opt_prof_leak; /* Dump leak summary at exit. */ +extern bool opt_prof_accum; /* Report cumulative bytes. */ +extern char opt_prof_prefix[ + /* Minimize memory bloat for non-prof builds. */ +#ifdef JEMALLOC_PROF + PATH_MAX + +#endif + 1]; + +/* Accessed via prof_active_[gs]et{_unlocked,}(). */ +extern bool prof_active; + +/* Accessed via prof_gdump_[gs]et{_unlocked,}(). */ +extern bool prof_gdump_val; + +/* + * Profile dump interval, measured in bytes allocated. Each arena triggers a + * profile dump when it reaches this threshold. The effect is that the + * interval between profile dumps averages prof_interval, though the actual + * interval between dumps will tend to be sporadic, and the interval will be a + * maximum of approximately (prof_interval * narenas). + */ +extern uint64_t prof_interval; + +/* + * Initialized as opt_lg_prof_sample, and potentially modified during profiling + * resets. + */ +extern size_t lg_prof_sample; + +void prof_alloc_rollback(tsd_t *tsd, prof_tctx_t *tctx, bool updated); +void prof_malloc_sample_object(const void *ptr, size_t usize, + prof_tctx_t *tctx); +void prof_free_sampled_object(tsd_t *tsd, size_t usize, prof_tctx_t *tctx); +void bt_init(prof_bt_t *bt, void **vec); +void prof_backtrace(prof_bt_t *bt); +prof_tctx_t *prof_lookup(tsd_t *tsd, prof_bt_t *bt); +#ifdef JEMALLOC_JET +size_t prof_tdata_count(void); +size_t prof_bt_count(void); +const prof_cnt_t *prof_cnt_all(void); +typedef int (prof_dump_open_t)(bool, const char *); +extern prof_dump_open_t *prof_dump_open; +typedef bool (prof_dump_header_t)(bool, const prof_cnt_t *); +extern prof_dump_header_t *prof_dump_header; +#endif +void prof_idump(void); +bool prof_mdump(const char *filename); +void prof_gdump(void); +prof_tdata_t *prof_tdata_init(tsd_t *tsd); +prof_tdata_t *prof_tdata_reinit(tsd_t *tsd, prof_tdata_t *tdata); +void prof_reset(tsd_t *tsd, size_t lg_sample); +void prof_tdata_cleanup(tsd_t *tsd); +const char *prof_thread_name_get(void); +bool prof_active_get(void); +bool prof_active_set(bool active); +int prof_thread_name_set(tsd_t *tsd, const char *thread_name); +bool prof_thread_active_get(void); +bool prof_thread_active_set(bool active); +bool prof_thread_active_init_get(void); +bool prof_thread_active_init_set(bool active_init); +bool prof_gdump_get(void); +bool prof_gdump_set(bool active); +void prof_boot0(void); +void prof_boot1(void); +bool prof_boot2(void); +void prof_prefork(void); +void prof_postfork_parent(void); +void prof_postfork_child(void); +void prof_sample_threshold_update(prof_tdata_t *tdata); + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#ifndef JEMALLOC_ENABLE_INLINE +bool prof_active_get_unlocked(void); +bool prof_gdump_get_unlocked(void); +prof_tdata_t *prof_tdata_get(tsd_t *tsd, bool create); +bool prof_sample_accum_update(tsd_t *tsd, size_t usize, bool commit, + prof_tdata_t **tdata_out); +prof_tctx_t *prof_alloc_prep(tsd_t *tsd, size_t usize, bool prof_active, + bool update); +prof_tctx_t *prof_tctx_get(const void *ptr); +void prof_tctx_set(const void *ptr, size_t usize, prof_tctx_t *tctx); +void prof_tctx_reset(const void *ptr, size_t usize, const void *old_ptr, + prof_tctx_t *tctx); +void prof_malloc_sample_object(const void *ptr, size_t usize, + prof_tctx_t *tctx); +void prof_malloc(const void *ptr, size_t usize, prof_tctx_t *tctx); +void prof_realloc(tsd_t *tsd, const void *ptr, size_t usize, + prof_tctx_t *tctx, bool prof_active, bool updated, const void *old_ptr, + size_t old_usize, prof_tctx_t *old_tctx); +void prof_free(tsd_t *tsd, const void *ptr, size_t usize); +#endif + +#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_PROF_C_)) +JEMALLOC_ALWAYS_INLINE bool +prof_active_get_unlocked(void) +{ + + /* + * Even if opt_prof is true, sampling can be temporarily disabled by + * setting prof_active to false. No locking is used when reading + * prof_active in the fast path, so there are no guarantees regarding + * how long it will take for all threads to notice state changes. + */ + return (prof_active); +} + +JEMALLOC_ALWAYS_INLINE bool +prof_gdump_get_unlocked(void) +{ + + /* + * No locking is used when reading prof_gdump_val in the fast path, so + * there are no guarantees regarding how long it will take for all + * threads to notice state changes. + */ + return (prof_gdump_val); +} + +JEMALLOC_ALWAYS_INLINE prof_tdata_t * +prof_tdata_get(tsd_t *tsd, bool create) +{ + prof_tdata_t *tdata; + + cassert(config_prof); + + tdata = tsd_prof_tdata_get(tsd); + if (create) { + if (unlikely(tdata == NULL)) { + if (tsd_nominal(tsd)) { + tdata = prof_tdata_init(tsd); + tsd_prof_tdata_set(tsd, tdata); + } + } else if (unlikely(tdata->expired)) { + tdata = prof_tdata_reinit(tsd, tdata); + tsd_prof_tdata_set(tsd, tdata); + } + assert(tdata == NULL || tdata->attached); + } + + return (tdata); +} + +JEMALLOC_ALWAYS_INLINE prof_tctx_t * +prof_tctx_get(const void *ptr) +{ + + cassert(config_prof); + assert(ptr != NULL); + + return (arena_prof_tctx_get(ptr)); +} + +JEMALLOC_ALWAYS_INLINE void +prof_tctx_set(const void *ptr, size_t usize, prof_tctx_t *tctx) +{ + + cassert(config_prof); + assert(ptr != NULL); + + arena_prof_tctx_set(ptr, usize, tctx); +} + +JEMALLOC_ALWAYS_INLINE void +prof_tctx_reset(const void *ptr, size_t usize, const void *old_ptr, + prof_tctx_t *old_tctx) +{ + + cassert(config_prof); + assert(ptr != NULL); + + arena_prof_tctx_reset(ptr, usize, old_ptr, old_tctx); +} + +JEMALLOC_ALWAYS_INLINE bool +prof_sample_accum_update(tsd_t *tsd, size_t usize, bool update, + prof_tdata_t **tdata_out) +{ + prof_tdata_t *tdata; + + cassert(config_prof); + + tdata = prof_tdata_get(tsd, true); + if ((uintptr_t)tdata <= (uintptr_t)PROF_TDATA_STATE_MAX) + tdata = NULL; + + if (tdata_out != NULL) + *tdata_out = tdata; + + if (tdata == NULL) + return (true); + + if (tdata->bytes_until_sample >= usize) { + if (update) + tdata->bytes_until_sample -= usize; + return (true); + } else { + /* Compute new sample threshold. */ + if (update) + prof_sample_threshold_update(tdata); + return (!tdata->active); + } +} + +JEMALLOC_ALWAYS_INLINE prof_tctx_t * +prof_alloc_prep(tsd_t *tsd, size_t usize, bool prof_active, bool update) +{ + prof_tctx_t *ret; + prof_tdata_t *tdata; + prof_bt_t bt; + + assert(usize == s2u(usize)); + + if (!prof_active || likely(prof_sample_accum_update(tsd, usize, update, + &tdata))) + ret = (prof_tctx_t *)(uintptr_t)1U; + else { + bt_init(&bt, tdata->vec); + prof_backtrace(&bt); + ret = prof_lookup(tsd, &bt); + } + + return (ret); +} + +JEMALLOC_ALWAYS_INLINE void +prof_malloc(const void *ptr, size_t usize, prof_tctx_t *tctx) +{ + + cassert(config_prof); + assert(ptr != NULL); + assert(usize == isalloc(ptr, true)); + + if (unlikely((uintptr_t)tctx > (uintptr_t)1U)) + prof_malloc_sample_object(ptr, usize, tctx); + else + prof_tctx_set(ptr, usize, (prof_tctx_t *)(uintptr_t)1U); +} + +JEMALLOC_ALWAYS_INLINE void +prof_realloc(tsd_t *tsd, const void *ptr, size_t usize, prof_tctx_t *tctx, + bool prof_active, bool updated, const void *old_ptr, size_t old_usize, + prof_tctx_t *old_tctx) +{ + bool sampled, old_sampled; + + cassert(config_prof); + assert(ptr != NULL || (uintptr_t)tctx <= (uintptr_t)1U); + + if (prof_active && !updated && ptr != NULL) { + assert(usize == isalloc(ptr, true)); + if (prof_sample_accum_update(tsd, usize, true, NULL)) { + /* + * Don't sample. The usize passed to prof_alloc_prep() + * was larger than what actually got allocated, so a + * backtrace was captured for this allocation, even + * though its actual usize was insufficient to cross the + * sample threshold. + */ + tctx = (prof_tctx_t *)(uintptr_t)1U; + } + } + + sampled = ((uintptr_t)tctx > (uintptr_t)1U); + old_sampled = ((uintptr_t)old_tctx > (uintptr_t)1U); + + if (unlikely(sampled)) + prof_malloc_sample_object(ptr, usize, tctx); + else + prof_tctx_reset(ptr, usize, old_ptr, old_tctx); + + if (unlikely(old_sampled)) + prof_free_sampled_object(tsd, old_usize, old_tctx); +} + +JEMALLOC_ALWAYS_INLINE void +prof_free(tsd_t *tsd, const void *ptr, size_t usize) +{ + prof_tctx_t *tctx = prof_tctx_get(ptr); + + cassert(config_prof); + assert(usize == isalloc(ptr, true)); + + if (unlikely((uintptr_t)tctx > (uintptr_t)1U)) + prof_free_sampled_object(tsd, usize, tctx); +} +#endif + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/public_namespace.sh b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/public_namespace.sh new file mode 100755 index 0000000..362109f --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/public_namespace.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +for nm in `cat $1` ; do + n=`echo ${nm} |tr ':' ' ' |awk '{print $1}'` + echo "#define je_${n} JEMALLOC_N(${n})" +done diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/public_unnamespace.sh b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/public_unnamespace.sh new file mode 100755 index 0000000..4239d17 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/public_unnamespace.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +for nm in `cat $1` ; do + n=`echo ${nm} |tr ':' ' ' |awk '{print $1}'` + echo "#undef je_${n}" +done diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/ql.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/ql.h new file mode 100644 index 0000000..1834bb8 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/ql.h @@ -0,0 +1,81 @@ +/* List definitions. */ +#define ql_head(a_type) \ +struct { \ + a_type *qlh_first; \ +} + +#define ql_head_initializer(a_head) {NULL} + +#define ql_elm(a_type) qr(a_type) + +/* List functions. */ +#define ql_new(a_head) do { \ + (a_head)->qlh_first = NULL; \ +} while (0) + +#define ql_elm_new(a_elm, a_field) qr_new((a_elm), a_field) + +#define ql_first(a_head) ((a_head)->qlh_first) + +#define ql_last(a_head, a_field) \ + ((ql_first(a_head) != NULL) \ + ? qr_prev(ql_first(a_head), a_field) : NULL) + +#define ql_next(a_head, a_elm, a_field) \ + ((ql_last(a_head, a_field) != (a_elm)) \ + ? qr_next((a_elm), a_field) : NULL) + +#define ql_prev(a_head, a_elm, a_field) \ + ((ql_first(a_head) != (a_elm)) ? qr_prev((a_elm), a_field) \ + : NULL) + +#define ql_before_insert(a_head, a_qlelm, a_elm, a_field) do { \ + qr_before_insert((a_qlelm), (a_elm), a_field); \ + if (ql_first(a_head) == (a_qlelm)) { \ + ql_first(a_head) = (a_elm); \ + } \ +} while (0) + +#define ql_after_insert(a_qlelm, a_elm, a_field) \ + qr_after_insert((a_qlelm), (a_elm), a_field) + +#define ql_head_insert(a_head, a_elm, a_field) do { \ + if (ql_first(a_head) != NULL) { \ + qr_before_insert(ql_first(a_head), (a_elm), a_field); \ + } \ + ql_first(a_head) = (a_elm); \ +} while (0) + +#define ql_tail_insert(a_head, a_elm, a_field) do { \ + if (ql_first(a_head) != NULL) { \ + qr_before_insert(ql_first(a_head), (a_elm), a_field); \ + } \ + ql_first(a_head) = qr_next((a_elm), a_field); \ +} while (0) + +#define ql_remove(a_head, a_elm, a_field) do { \ + if (ql_first(a_head) == (a_elm)) { \ + ql_first(a_head) = qr_next(ql_first(a_head), a_field); \ + } \ + if (ql_first(a_head) != (a_elm)) { \ + qr_remove((a_elm), a_field); \ + } else { \ + ql_first(a_head) = NULL; \ + } \ +} while (0) + +#define ql_head_remove(a_head, a_type, a_field) do { \ + a_type *t = ql_first(a_head); \ + ql_remove((a_head), t, a_field); \ +} while (0) + +#define ql_tail_remove(a_head, a_type, a_field) do { \ + a_type *t = ql_last(a_head, a_field); \ + ql_remove((a_head), t, a_field); \ +} while (0) + +#define ql_foreach(a_var, a_head, a_field) \ + qr_foreach((a_var), ql_first(a_head), a_field) + +#define ql_reverse_foreach(a_var, a_head, a_field) \ + qr_reverse_foreach((a_var), ql_first(a_head), a_field) diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/qr.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/qr.h new file mode 100644 index 0000000..0fbaec2 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/qr.h @@ -0,0 +1,69 @@ +/* Ring definitions. */ +#define qr(a_type) \ +struct { \ + a_type *qre_next; \ + a_type *qre_prev; \ +} + +/* Ring functions. */ +#define qr_new(a_qr, a_field) do { \ + (a_qr)->a_field.qre_next = (a_qr); \ + (a_qr)->a_field.qre_prev = (a_qr); \ +} while (0) + +#define qr_next(a_qr, a_field) ((a_qr)->a_field.qre_next) + +#define qr_prev(a_qr, a_field) ((a_qr)->a_field.qre_prev) + +#define qr_before_insert(a_qrelm, a_qr, a_field) do { \ + (a_qr)->a_field.qre_prev = (a_qrelm)->a_field.qre_prev; \ + (a_qr)->a_field.qre_next = (a_qrelm); \ + (a_qr)->a_field.qre_prev->a_field.qre_next = (a_qr); \ + (a_qrelm)->a_field.qre_prev = (a_qr); \ +} while (0) + +#define qr_after_insert(a_qrelm, a_qr, a_field) \ + do \ + { \ + (a_qr)->a_field.qre_next = (a_qrelm)->a_field.qre_next; \ + (a_qr)->a_field.qre_prev = (a_qrelm); \ + (a_qr)->a_field.qre_next->a_field.qre_prev = (a_qr); \ + (a_qrelm)->a_field.qre_next = (a_qr); \ + } while (0) + +#define qr_meld(a_qr_a, a_qr_b, a_field) do { \ + void *t; \ + (a_qr_a)->a_field.qre_prev->a_field.qre_next = (a_qr_b); \ + (a_qr_b)->a_field.qre_prev->a_field.qre_next = (a_qr_a); \ + t = (a_qr_a)->a_field.qre_prev; \ + (a_qr_a)->a_field.qre_prev = (a_qr_b)->a_field.qre_prev; \ + (a_qr_b)->a_field.qre_prev = t; \ +} while (0) + +/* + * qr_meld() and qr_split() are functionally equivalent, so there's no need to + * have two copies of the code. + */ +#define qr_split(a_qr_a, a_qr_b, a_field) \ + qr_meld((a_qr_a), (a_qr_b), a_field) + +#define qr_remove(a_qr, a_field) do { \ + (a_qr)->a_field.qre_prev->a_field.qre_next \ + = (a_qr)->a_field.qre_next; \ + (a_qr)->a_field.qre_next->a_field.qre_prev \ + = (a_qr)->a_field.qre_prev; \ + (a_qr)->a_field.qre_next = (a_qr); \ + (a_qr)->a_field.qre_prev = (a_qr); \ +} while (0) + +#define qr_foreach(var, a_qr, a_field) \ + for ((var) = (a_qr); \ + (var) != NULL; \ + (var) = (((var)->a_field.qre_next != (a_qr)) \ + ? (var)->a_field.qre_next : NULL)) + +#define qr_reverse_foreach(var, a_qr, a_field) \ + for ((var) = ((a_qr) != NULL) ? qr_prev(a_qr, a_field) : NULL; \ + (var) != NULL; \ + (var) = (((var) != (a_qr)) \ + ? (var)->a_field.qre_prev : NULL)) diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/quarantine.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/quarantine.h new file mode 100644 index 0000000..ae60739 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/quarantine.h @@ -0,0 +1,60 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +typedef struct quarantine_obj_s quarantine_obj_t; +typedef struct quarantine_s quarantine_t; + +/* Default per thread quarantine size if valgrind is enabled. */ +#define JEMALLOC_VALGRIND_QUARANTINE_DEFAULT (ZU(1) << 24) + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +struct quarantine_obj_s { + void *ptr; + size_t usize; +}; + +struct quarantine_s { + size_t curbytes; + size_t curobjs; + size_t first; +#define LG_MAXOBJS_INIT 10 + size_t lg_maxobjs; + quarantine_obj_t objs[1]; /* Dynamically sized ring buffer. */ +}; + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +void quarantine_alloc_hook_work(tsd_t *tsd); +void quarantine(tsd_t *tsd, void *ptr); +void quarantine_cleanup(tsd_t *tsd); + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#ifndef JEMALLOC_ENABLE_INLINE +void quarantine_alloc_hook(void); +#endif + +#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_QUARANTINE_C_)) +JEMALLOC_ALWAYS_INLINE void +quarantine_alloc_hook(void) +{ + tsd_t *tsd; + + assert(config_fill && opt_quarantine); + + tsd = tsd_fetch(); + if (tsd_quarantine_get(tsd) == NULL) + quarantine_alloc_hook_work(tsd); +} +#endif + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ + diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/rb.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/rb.h new file mode 100644 index 0000000..2ca8e59 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/rb.h @@ -0,0 +1,981 @@ +/*- + ******************************************************************************* + * + * cpp macro implementation of left-leaning 2-3 red-black trees. Parent + * pointers are not used, and color bits are stored in the least significant + * bit of right-child pointers (if RB_COMPACT is defined), thus making node + * linkage as compact as is possible for red-black trees. + * + * Usage: + * + * #include + * #include + * #define NDEBUG // (Optional, see assert(3).) + * #include + * #define RB_COMPACT // (Optional, embed color bits in right-child pointers.) + * #include + * ... + * + ******************************************************************************* + */ + +#ifndef RB_H_ +#define RB_H_ + +#ifdef RB_COMPACT +/* Node structure. */ +#define rb_node(a_type) \ +struct { \ + a_type *rbn_left; \ + a_type *rbn_right_red; \ +} +#else +#define rb_node(a_type) \ +struct { \ + a_type *rbn_left; \ + a_type *rbn_right; \ + bool rbn_red; \ +} +#endif + +/* Root structure. */ +#define rb_tree(a_type) \ +struct { \ + a_type *rbt_root; \ + a_type rbt_nil; \ +} + +/* Left accessors. */ +#define rbtn_left_get(a_type, a_field, a_node) \ + ((a_node)->a_field.rbn_left) +#define rbtn_left_set(a_type, a_field, a_node, a_left) do { \ + (a_node)->a_field.rbn_left = a_left; \ +} while (0) + +#ifdef RB_COMPACT +/* Right accessors. */ +#define rbtn_right_get(a_type, a_field, a_node) \ + ((a_type *) (((intptr_t) (a_node)->a_field.rbn_right_red) \ + & ((ssize_t)-2))) +#define rbtn_right_set(a_type, a_field, a_node, a_right) do { \ + (a_node)->a_field.rbn_right_red = (a_type *) (((uintptr_t) a_right) \ + | (((uintptr_t) (a_node)->a_field.rbn_right_red) & ((size_t)1))); \ +} while (0) + +/* Color accessors. */ +#define rbtn_red_get(a_type, a_field, a_node) \ + ((bool) (((uintptr_t) (a_node)->a_field.rbn_right_red) \ + & ((size_t)1))) +#define rbtn_color_set(a_type, a_field, a_node, a_red) do { \ + (a_node)->a_field.rbn_right_red = (a_type *) ((((intptr_t) \ + (a_node)->a_field.rbn_right_red) & ((ssize_t)-2)) \ + | ((ssize_t)a_red)); \ +} while (0) +#define rbtn_red_set(a_type, a_field, a_node) do { \ + (a_node)->a_field.rbn_right_red = (a_type *) (((uintptr_t) \ + (a_node)->a_field.rbn_right_red) | ((size_t)1)); \ +} while (0) +#define rbtn_black_set(a_type, a_field, a_node) do { \ + (a_node)->a_field.rbn_right_red = (a_type *) (((intptr_t) \ + (a_node)->a_field.rbn_right_red) & ((ssize_t)-2)); \ +} while (0) +#else +/* Right accessors. */ +#define rbtn_right_get(a_type, a_field, a_node) \ + ((a_node)->a_field.rbn_right) +#define rbtn_right_set(a_type, a_field, a_node, a_right) do { \ + (a_node)->a_field.rbn_right = a_right; \ +} while (0) + +/* Color accessors. */ +#define rbtn_red_get(a_type, a_field, a_node) \ + ((a_node)->a_field.rbn_red) +#define rbtn_color_set(a_type, a_field, a_node, a_red) do { \ + (a_node)->a_field.rbn_red = (a_red); \ +} while (0) +#define rbtn_red_set(a_type, a_field, a_node) do { \ + (a_node)->a_field.rbn_red = true; \ +} while (0) +#define rbtn_black_set(a_type, a_field, a_node) do { \ + (a_node)->a_field.rbn_red = false; \ +} while (0) +#endif + +/* Node initializer. */ +#define rbt_node_new(a_type, a_field, a_rbt, a_node) do { \ + rbtn_left_set(a_type, a_field, (a_node), &(a_rbt)->rbt_nil); \ + rbtn_right_set(a_type, a_field, (a_node), &(a_rbt)->rbt_nil); \ + rbtn_red_set(a_type, a_field, (a_node)); \ +} while (0) + +/* Tree initializer. */ +#define rb_new(a_type, a_field, a_rbt) do { \ + (a_rbt)->rbt_root = &(a_rbt)->rbt_nil; \ + rbt_node_new(a_type, a_field, a_rbt, &(a_rbt)->rbt_nil); \ + rbtn_black_set(a_type, a_field, &(a_rbt)->rbt_nil); \ +} while (0) + +/* Internal utility macros. */ +#define rbtn_first(a_type, a_field, a_rbt, a_root, r_node) do { \ + (r_node) = (a_root); \ + if ((r_node) != &(a_rbt)->rbt_nil) { \ + for (; \ + rbtn_left_get(a_type, a_field, (r_node)) != &(a_rbt)->rbt_nil;\ + (r_node) = rbtn_left_get(a_type, a_field, (r_node))) { \ + } \ + } \ +} while (0) + +#define rbtn_last(a_type, a_field, a_rbt, a_root, r_node) do { \ + (r_node) = (a_root); \ + if ((r_node) != &(a_rbt)->rbt_nil) { \ + for (; rbtn_right_get(a_type, a_field, (r_node)) != \ + &(a_rbt)->rbt_nil; (r_node) = rbtn_right_get(a_type, a_field, \ + (r_node))) { \ + } \ + } \ +} while (0) + +#define rbtn_rotate_left(a_type, a_field, a_node, r_node) do { \ + (r_node) = rbtn_right_get(a_type, a_field, (a_node)); \ + rbtn_right_set(a_type, a_field, (a_node), \ + rbtn_left_get(a_type, a_field, (r_node))); \ + rbtn_left_set(a_type, a_field, (r_node), (a_node)); \ +} while (0) + +#define rbtn_rotate_right(a_type, a_field, a_node, r_node) do { \ + (r_node) = rbtn_left_get(a_type, a_field, (a_node)); \ + rbtn_left_set(a_type, a_field, (a_node), \ + rbtn_right_get(a_type, a_field, (r_node))); \ + rbtn_right_set(a_type, a_field, (r_node), (a_node)); \ +} while (0) + +/* + * The rb_proto() macro generates function prototypes that correspond to the + * functions generated by an equivalently parameterized call to rb_gen(). + */ + +#define rb_proto(a_attr, a_prefix, a_rbt_type, a_type) \ +a_attr void \ +a_prefix##new(a_rbt_type *rbtree); \ +a_attr bool \ +a_prefix##empty(a_rbt_type *rbtree); \ +a_attr a_type * \ +a_prefix##first(a_rbt_type *rbtree); \ +a_attr a_type * \ +a_prefix##last(a_rbt_type *rbtree); \ +a_attr a_type * \ +a_prefix##next(a_rbt_type *rbtree, a_type *node); \ +a_attr a_type * \ +a_prefix##prev(a_rbt_type *rbtree, a_type *node); \ +a_attr a_type * \ +a_prefix##search(a_rbt_type *rbtree, a_type *key); \ +a_attr a_type * \ +a_prefix##nsearch(a_rbt_type *rbtree, a_type *key); \ +a_attr a_type * \ +a_prefix##psearch(a_rbt_type *rbtree, a_type *key); \ +a_attr void \ +a_prefix##insert(a_rbt_type *rbtree, a_type *node); \ +a_attr void \ +a_prefix##remove(a_rbt_type *rbtree, a_type *node); \ +a_attr a_type * \ +a_prefix##iter(a_rbt_type *rbtree, a_type *start, a_type *(*cb)( \ + a_rbt_type *, a_type *, void *), void *arg); \ +a_attr a_type * \ +a_prefix##reverse_iter(a_rbt_type *rbtree, a_type *start, \ + a_type *(*cb)(a_rbt_type *, a_type *, void *), void *arg); + +/* + * The rb_gen() macro generates a type-specific red-black tree implementation, + * based on the above cpp macros. + * + * Arguments: + * + * a_attr : Function attribute for generated functions (ex: static). + * a_prefix : Prefix for generated functions (ex: ex_). + * a_rb_type : Type for red-black tree data structure (ex: ex_t). + * a_type : Type for red-black tree node data structure (ex: ex_node_t). + * a_field : Name of red-black tree node linkage (ex: ex_link). + * a_cmp : Node comparison function name, with the following prototype: + * int (a_cmp *)(a_type *a_node, a_type *a_other); + * ^^^^^^ + * or a_key + * Interpretation of comparison function return values: + * -1 : a_node < a_other + * 0 : a_node == a_other + * 1 : a_node > a_other + * In all cases, the a_node or a_key macro argument is the first + * argument to the comparison function, which makes it possible + * to write comparison functions that treat the first argument + * specially. + * + * Assuming the following setup: + * + * typedef struct ex_node_s ex_node_t; + * struct ex_node_s { + * rb_node(ex_node_t) ex_link; + * }; + * typedef rb_tree(ex_node_t) ex_t; + * rb_gen(static, ex_, ex_t, ex_node_t, ex_link, ex_cmp) + * + * The following API is generated: + * + * static void + * ex_new(ex_t *tree); + * Description: Initialize a red-black tree structure. + * Args: + * tree: Pointer to an uninitialized red-black tree object. + * + * static bool + * ex_empty(ex_t *tree); + * Description: Determine whether tree is empty. + * Args: + * tree: Pointer to an initialized red-black tree object. + * Ret: True if tree is empty, false otherwise. + * + * static ex_node_t * + * ex_first(ex_t *tree); + * static ex_node_t * + * ex_last(ex_t *tree); + * Description: Get the first/last node in tree. + * Args: + * tree: Pointer to an initialized red-black tree object. + * Ret: First/last node in tree, or NULL if tree is empty. + * + * static ex_node_t * + * ex_next(ex_t *tree, ex_node_t *node); + * static ex_node_t * + * ex_prev(ex_t *tree, ex_node_t *node); + * Description: Get node's successor/predecessor. + * Args: + * tree: Pointer to an initialized red-black tree object. + * node: A node in tree. + * Ret: node's successor/predecessor in tree, or NULL if node is + * last/first. + * + * static ex_node_t * + * ex_search(ex_t *tree, ex_node_t *key); + * Description: Search for node that matches key. + * Args: + * tree: Pointer to an initialized red-black tree object. + * key : Search key. + * Ret: Node in tree that matches key, or NULL if no match. + * + * static ex_node_t * + * ex_nsearch(ex_t *tree, ex_node_t *key); + * static ex_node_t * + * ex_psearch(ex_t *tree, ex_node_t *key); + * Description: Search for node that matches key. If no match is found, + * return what would be key's successor/predecessor, were + * key in tree. + * Args: + * tree: Pointer to an initialized red-black tree object. + * key : Search key. + * Ret: Node in tree that matches key, or if no match, hypothetical node's + * successor/predecessor (NULL if no successor/predecessor). + * + * static void + * ex_insert(ex_t *tree, ex_node_t *node); + * Description: Insert node into tree. + * Args: + * tree: Pointer to an initialized red-black tree object. + * node: Node to be inserted into tree. + * + * static void + * ex_remove(ex_t *tree, ex_node_t *node); + * Description: Remove node from tree. + * Args: + * tree: Pointer to an initialized red-black tree object. + * node: Node in tree to be removed. + * + * static ex_node_t * + * ex_iter(ex_t *tree, ex_node_t *start, ex_node_t *(*cb)(ex_t *, + * ex_node_t *, void *), void *arg); + * static ex_node_t * + * ex_reverse_iter(ex_t *tree, ex_node_t *start, ex_node *(*cb)(ex_t *, + * ex_node_t *, void *), void *arg); + * Description: Iterate forward/backward over tree, starting at node. If + * tree is modified, iteration must be immediately + * terminated by the callback function that causes the + * modification. + * Args: + * tree : Pointer to an initialized red-black tree object. + * start: Node at which to start iteration, or NULL to start at + * first/last node. + * cb : Callback function, which is called for each node during + * iteration. Under normal circumstances the callback function + * should return NULL, which causes iteration to continue. If a + * callback function returns non-NULL, iteration is immediately + * terminated and the non-NULL return value is returned by the + * iterator. This is useful for re-starting iteration after + * modifying tree. + * arg : Opaque pointer passed to cb(). + * Ret: NULL if iteration completed, or the non-NULL callback return value + * that caused termination of the iteration. + */ +#define rb_gen(a_attr, a_prefix, a_rbt_type, a_type, a_field, a_cmp) \ +a_attr void \ +a_prefix##new(a_rbt_type *rbtree) { \ + rb_new(a_type, a_field, rbtree); \ +} \ +a_attr bool \ +a_prefix##empty(a_rbt_type *rbtree) { \ + return (rbtree->rbt_root == &rbtree->rbt_nil); \ +} \ +a_attr a_type * \ +a_prefix##first(a_rbt_type *rbtree) { \ + a_type *ret; \ + rbtn_first(a_type, a_field, rbtree, rbtree->rbt_root, ret); \ + if (ret == &rbtree->rbt_nil) { \ + ret = NULL; \ + } \ + return (ret); \ +} \ +a_attr a_type * \ +a_prefix##last(a_rbt_type *rbtree) { \ + a_type *ret; \ + rbtn_last(a_type, a_field, rbtree, rbtree->rbt_root, ret); \ + if (ret == &rbtree->rbt_nil) { \ + ret = NULL; \ + } \ + return (ret); \ +} \ +a_attr a_type * \ +a_prefix##next(a_rbt_type *rbtree, a_type *node) { \ + a_type *ret; \ + if (rbtn_right_get(a_type, a_field, node) != &rbtree->rbt_nil) { \ + rbtn_first(a_type, a_field, rbtree, rbtn_right_get(a_type, \ + a_field, node), ret); \ + } else { \ + a_type *tnode = rbtree->rbt_root; \ + assert(tnode != &rbtree->rbt_nil); \ + ret = &rbtree->rbt_nil; \ + while (true) { \ + int cmp = (a_cmp)(node, tnode); \ + if (cmp < 0) { \ + ret = tnode; \ + tnode = rbtn_left_get(a_type, a_field, tnode); \ + } else if (cmp > 0) { \ + tnode = rbtn_right_get(a_type, a_field, tnode); \ + } else { \ + break; \ + } \ + assert(tnode != &rbtree->rbt_nil); \ + } \ + } \ + if (ret == &rbtree->rbt_nil) { \ + ret = (NULL); \ + } \ + return (ret); \ +} \ +a_attr a_type * \ +a_prefix##prev(a_rbt_type *rbtree, a_type *node) { \ + a_type *ret; \ + if (rbtn_left_get(a_type, a_field, node) != &rbtree->rbt_nil) { \ + rbtn_last(a_type, a_field, rbtree, rbtn_left_get(a_type, \ + a_field, node), ret); \ + } else { \ + a_type *tnode = rbtree->rbt_root; \ + assert(tnode != &rbtree->rbt_nil); \ + ret = &rbtree->rbt_nil; \ + while (true) { \ + int cmp = (a_cmp)(node, tnode); \ + if (cmp < 0) { \ + tnode = rbtn_left_get(a_type, a_field, tnode); \ + } else if (cmp > 0) { \ + ret = tnode; \ + tnode = rbtn_right_get(a_type, a_field, tnode); \ + } else { \ + break; \ + } \ + assert(tnode != &rbtree->rbt_nil); \ + } \ + } \ + if (ret == &rbtree->rbt_nil) { \ + ret = (NULL); \ + } \ + return (ret); \ +} \ +a_attr a_type * \ +a_prefix##search(a_rbt_type *rbtree, a_type *key) { \ + a_type *ret; \ + int cmp; \ + ret = rbtree->rbt_root; \ + while (ret != &rbtree->rbt_nil \ + && (cmp = (a_cmp)(key, ret)) != 0) { \ + if (cmp < 0) { \ + ret = rbtn_left_get(a_type, a_field, ret); \ + } else { \ + ret = rbtn_right_get(a_type, a_field, ret); \ + } \ + } \ + if (ret == &rbtree->rbt_nil) { \ + ret = (NULL); \ + } \ + return (ret); \ +} \ +a_attr a_type * \ +a_prefix##nsearch(a_rbt_type *rbtree, a_type *key) { \ + a_type *ret; \ + a_type *tnode = rbtree->rbt_root; \ + ret = &rbtree->rbt_nil; \ + while (tnode != &rbtree->rbt_nil) { \ + int cmp = (a_cmp)(key, tnode); \ + if (cmp < 0) { \ + ret = tnode; \ + tnode = rbtn_left_get(a_type, a_field, tnode); \ + } else if (cmp > 0) { \ + tnode = rbtn_right_get(a_type, a_field, tnode); \ + } else { \ + ret = tnode; \ + break; \ + } \ + } \ + if (ret == &rbtree->rbt_nil) { \ + ret = (NULL); \ + } \ + return (ret); \ +} \ +a_attr a_type * \ +a_prefix##psearch(a_rbt_type *rbtree, a_type *key) { \ + a_type *ret; \ + a_type *tnode = rbtree->rbt_root; \ + ret = &rbtree->rbt_nil; \ + while (tnode != &rbtree->rbt_nil) { \ + int cmp = (a_cmp)(key, tnode); \ + if (cmp < 0) { \ + tnode = rbtn_left_get(a_type, a_field, tnode); \ + } else if (cmp > 0) { \ + ret = tnode; \ + tnode = rbtn_right_get(a_type, a_field, tnode); \ + } else { \ + ret = tnode; \ + break; \ + } \ + } \ + if (ret == &rbtree->rbt_nil) { \ + ret = (NULL); \ + } \ + return (ret); \ +} \ +a_attr void \ +a_prefix##insert(a_rbt_type *rbtree, a_type *node) { \ + struct { \ + a_type *node; \ + int cmp; \ + } path[sizeof(void *) << 4], *pathp; \ + rbt_node_new(a_type, a_field, rbtree, node); \ + /* Wind. */ \ + path->node = rbtree->rbt_root; \ + for (pathp = path; pathp->node != &rbtree->rbt_nil; pathp++) { \ + int cmp = pathp->cmp = a_cmp(node, pathp->node); \ + assert(cmp != 0); \ + if (cmp < 0) { \ + pathp[1].node = rbtn_left_get(a_type, a_field, \ + pathp->node); \ + } else { \ + pathp[1].node = rbtn_right_get(a_type, a_field, \ + pathp->node); \ + } \ + } \ + pathp->node = node; \ + /* Unwind. */ \ + for (pathp--; (uintptr_t)pathp >= (uintptr_t)path; pathp--) { \ + a_type *cnode = pathp->node; \ + if (pathp->cmp < 0) { \ + a_type *left = pathp[1].node; \ + rbtn_left_set(a_type, a_field, cnode, left); \ + if (rbtn_red_get(a_type, a_field, left)) { \ + a_type *leftleft = rbtn_left_get(a_type, a_field, left);\ + if (rbtn_red_get(a_type, a_field, leftleft)) { \ + /* Fix up 4-node. */ \ + a_type *tnode; \ + rbtn_black_set(a_type, a_field, leftleft); \ + rbtn_rotate_right(a_type, a_field, cnode, tnode); \ + cnode = tnode; \ + } \ + } else { \ + return; \ + } \ + } else { \ + a_type *right = pathp[1].node; \ + rbtn_right_set(a_type, a_field, cnode, right); \ + if (rbtn_red_get(a_type, a_field, right)) { \ + a_type *left = rbtn_left_get(a_type, a_field, cnode); \ + if (rbtn_red_get(a_type, a_field, left)) { \ + /* Split 4-node. */ \ + rbtn_black_set(a_type, a_field, left); \ + rbtn_black_set(a_type, a_field, right); \ + rbtn_red_set(a_type, a_field, cnode); \ + } else { \ + /* Lean left. */ \ + a_type *tnode; \ + bool tred = rbtn_red_get(a_type, a_field, cnode); \ + rbtn_rotate_left(a_type, a_field, cnode, tnode); \ + rbtn_color_set(a_type, a_field, tnode, tred); \ + rbtn_red_set(a_type, a_field, cnode); \ + cnode = tnode; \ + } \ + } else { \ + return; \ + } \ + } \ + pathp->node = cnode; \ + } \ + /* Set root, and make it black. */ \ + rbtree->rbt_root = path->node; \ + rbtn_black_set(a_type, a_field, rbtree->rbt_root); \ +} \ +a_attr void \ +a_prefix##remove(a_rbt_type *rbtree, a_type *node) { \ + struct { \ + a_type *node; \ + int cmp; \ + } *pathp, *nodep, path[sizeof(void *) << 4]; \ + /* Wind. */ \ + nodep = NULL; /* Silence compiler warning. */ \ + path->node = rbtree->rbt_root; \ + for (pathp = path; pathp->node != &rbtree->rbt_nil; pathp++) { \ + int cmp = pathp->cmp = a_cmp(node, pathp->node); \ + if (cmp < 0) { \ + pathp[1].node = rbtn_left_get(a_type, a_field, \ + pathp->node); \ + } else { \ + pathp[1].node = rbtn_right_get(a_type, a_field, \ + pathp->node); \ + if (cmp == 0) { \ + /* Find node's successor, in preparation for swap. */ \ + pathp->cmp = 1; \ + nodep = pathp; \ + for (pathp++; pathp->node != &rbtree->rbt_nil; \ + pathp++) { \ + pathp->cmp = -1; \ + pathp[1].node = rbtn_left_get(a_type, a_field, \ + pathp->node); \ + } \ + break; \ + } \ + } \ + } \ + assert(nodep->node == node); \ + pathp--; \ + if (pathp->node != node) { \ + /* Swap node with its successor. */ \ + bool tred = rbtn_red_get(a_type, a_field, pathp->node); \ + rbtn_color_set(a_type, a_field, pathp->node, \ + rbtn_red_get(a_type, a_field, node)); \ + rbtn_left_set(a_type, a_field, pathp->node, \ + rbtn_left_get(a_type, a_field, node)); \ + /* If node's successor is its right child, the following code */\ + /* will do the wrong thing for the right child pointer. */\ + /* However, it doesn't matter, because the pointer will be */\ + /* properly set when the successor is pruned. */\ + rbtn_right_set(a_type, a_field, pathp->node, \ + rbtn_right_get(a_type, a_field, node)); \ + rbtn_color_set(a_type, a_field, node, tred); \ + /* The pruned leaf node's child pointers are never accessed */\ + /* again, so don't bother setting them to nil. */\ + nodep->node = pathp->node; \ + pathp->node = node; \ + if (nodep == path) { \ + rbtree->rbt_root = nodep->node; \ + } else { \ + if (nodep[-1].cmp < 0) { \ + rbtn_left_set(a_type, a_field, nodep[-1].node, \ + nodep->node); \ + } else { \ + rbtn_right_set(a_type, a_field, nodep[-1].node, \ + nodep->node); \ + } \ + } \ + } else { \ + a_type *left = rbtn_left_get(a_type, a_field, node); \ + if (left != &rbtree->rbt_nil) { \ + /* node has no successor, but it has a left child. */\ + /* Splice node out, without losing the left child. */\ + assert(!rbtn_red_get(a_type, a_field, node)); \ + assert(rbtn_red_get(a_type, a_field, left)); \ + rbtn_black_set(a_type, a_field, left); \ + if (pathp == path) { \ + rbtree->rbt_root = left; \ + } else { \ + if (pathp[-1].cmp < 0) { \ + rbtn_left_set(a_type, a_field, pathp[-1].node, \ + left); \ + } else { \ + rbtn_right_set(a_type, a_field, pathp[-1].node, \ + left); \ + } \ + } \ + return; \ + } else if (pathp == path) { \ + /* The tree only contained one node. */ \ + rbtree->rbt_root = &rbtree->rbt_nil; \ + return; \ + } \ + } \ + if (rbtn_red_get(a_type, a_field, pathp->node)) { \ + /* Prune red node, which requires no fixup. */ \ + assert(pathp[-1].cmp < 0); \ + rbtn_left_set(a_type, a_field, pathp[-1].node, \ + &rbtree->rbt_nil); \ + return; \ + } \ + /* The node to be pruned is black, so unwind until balance is */\ + /* restored. */\ + pathp->node = &rbtree->rbt_nil; \ + for (pathp--; (uintptr_t)pathp >= (uintptr_t)path; pathp--) { \ + assert(pathp->cmp != 0); \ + if (pathp->cmp < 0) { \ + rbtn_left_set(a_type, a_field, pathp->node, \ + pathp[1].node); \ + assert(!rbtn_red_get(a_type, a_field, pathp[1].node)); \ + if (rbtn_red_get(a_type, a_field, pathp->node)) { \ + a_type *right = rbtn_right_get(a_type, a_field, \ + pathp->node); \ + a_type *rightleft = rbtn_left_get(a_type, a_field, \ + right); \ + a_type *tnode; \ + if (rbtn_red_get(a_type, a_field, rightleft)) { \ + /* In the following diagrams, ||, //, and \\ */\ + /* indicate the path to the removed node. */\ + /* */\ + /* || */\ + /* pathp(r) */\ + /* // \ */\ + /* (b) (b) */\ + /* / */\ + /* (r) */\ + /* */\ + rbtn_black_set(a_type, a_field, pathp->node); \ + rbtn_rotate_right(a_type, a_field, right, tnode); \ + rbtn_right_set(a_type, a_field, pathp->node, tnode);\ + rbtn_rotate_left(a_type, a_field, pathp->node, \ + tnode); \ + } else { \ + /* || */\ + /* pathp(r) */\ + /* // \ */\ + /* (b) (b) */\ + /* / */\ + /* (b) */\ + /* */\ + rbtn_rotate_left(a_type, a_field, pathp->node, \ + tnode); \ + } \ + /* Balance restored, but rotation modified subtree */\ + /* root. */\ + assert((uintptr_t)pathp > (uintptr_t)path); \ + if (pathp[-1].cmp < 0) { \ + rbtn_left_set(a_type, a_field, pathp[-1].node, \ + tnode); \ + } else { \ + rbtn_right_set(a_type, a_field, pathp[-1].node, \ + tnode); \ + } \ + return; \ + } else { \ + a_type *right = rbtn_right_get(a_type, a_field, \ + pathp->node); \ + a_type *rightleft = rbtn_left_get(a_type, a_field, \ + right); \ + if (rbtn_red_get(a_type, a_field, rightleft)) { \ + /* || */\ + /* pathp(b) */\ + /* // \ */\ + /* (b) (b) */\ + /* / */\ + /* (r) */\ + a_type *tnode; \ + rbtn_black_set(a_type, a_field, rightleft); \ + rbtn_rotate_right(a_type, a_field, right, tnode); \ + rbtn_right_set(a_type, a_field, pathp->node, tnode);\ + rbtn_rotate_left(a_type, a_field, pathp->node, \ + tnode); \ + /* Balance restored, but rotation modified */\ + /* subtree root, which may actually be the tree */\ + /* root. */\ + if (pathp == path) { \ + /* Set root. */ \ + rbtree->rbt_root = tnode; \ + } else { \ + if (pathp[-1].cmp < 0) { \ + rbtn_left_set(a_type, a_field, \ + pathp[-1].node, tnode); \ + } else { \ + rbtn_right_set(a_type, a_field, \ + pathp[-1].node, tnode); \ + } \ + } \ + return; \ + } else { \ + /* || */\ + /* pathp(b) */\ + /* // \ */\ + /* (b) (b) */\ + /* / */\ + /* (b) */\ + a_type *tnode; \ + rbtn_red_set(a_type, a_field, pathp->node); \ + rbtn_rotate_left(a_type, a_field, pathp->node, \ + tnode); \ + pathp->node = tnode; \ + } \ + } \ + } else { \ + a_type *left; \ + rbtn_right_set(a_type, a_field, pathp->node, \ + pathp[1].node); \ + left = rbtn_left_get(a_type, a_field, pathp->node); \ + if (rbtn_red_get(a_type, a_field, left)) { \ + a_type *tnode; \ + a_type *leftright = rbtn_right_get(a_type, a_field, \ + left); \ + a_type *leftrightleft = rbtn_left_get(a_type, a_field, \ + leftright); \ + if (rbtn_red_get(a_type, a_field, leftrightleft)) { \ + /* || */\ + /* pathp(b) */\ + /* / \\ */\ + /* (r) (b) */\ + /* \ */\ + /* (b) */\ + /* / */\ + /* (r) */\ + a_type *unode; \ + rbtn_black_set(a_type, a_field, leftrightleft); \ + rbtn_rotate_right(a_type, a_field, pathp->node, \ + unode); \ + rbtn_rotate_right(a_type, a_field, pathp->node, \ + tnode); \ + rbtn_right_set(a_type, a_field, unode, tnode); \ + rbtn_rotate_left(a_type, a_field, unode, tnode); \ + } else { \ + /* || */\ + /* pathp(b) */\ + /* / \\ */\ + /* (r) (b) */\ + /* \ */\ + /* (b) */\ + /* / */\ + /* (b) */\ + assert(leftright != &rbtree->rbt_nil); \ + rbtn_red_set(a_type, a_field, leftright); \ + rbtn_rotate_right(a_type, a_field, pathp->node, \ + tnode); \ + rbtn_black_set(a_type, a_field, tnode); \ + } \ + /* Balance restored, but rotation modified subtree */\ + /* root, which may actually be the tree root. */\ + if (pathp == path) { \ + /* Set root. */ \ + rbtree->rbt_root = tnode; \ + } else { \ + if (pathp[-1].cmp < 0) { \ + rbtn_left_set(a_type, a_field, pathp[-1].node, \ + tnode); \ + } else { \ + rbtn_right_set(a_type, a_field, pathp[-1].node, \ + tnode); \ + } \ + } \ + return; \ + } else if (rbtn_red_get(a_type, a_field, pathp->node)) { \ + a_type *leftleft = rbtn_left_get(a_type, a_field, left);\ + if (rbtn_red_get(a_type, a_field, leftleft)) { \ + /* || */\ + /* pathp(r) */\ + /* / \\ */\ + /* (b) (b) */\ + /* / */\ + /* (r) */\ + a_type *tnode; \ + rbtn_black_set(a_type, a_field, pathp->node); \ + rbtn_red_set(a_type, a_field, left); \ + rbtn_black_set(a_type, a_field, leftleft); \ + rbtn_rotate_right(a_type, a_field, pathp->node, \ + tnode); \ + /* Balance restored, but rotation modified */\ + /* subtree root. */\ + assert((uintptr_t)pathp > (uintptr_t)path); \ + if (pathp[-1].cmp < 0) { \ + rbtn_left_set(a_type, a_field, pathp[-1].node, \ + tnode); \ + } else { \ + rbtn_right_set(a_type, a_field, pathp[-1].node, \ + tnode); \ + } \ + return; \ + } else { \ + /* || */\ + /* pathp(r) */\ + /* / \\ */\ + /* (b) (b) */\ + /* / */\ + /* (b) */\ + rbtn_red_set(a_type, a_field, left); \ + rbtn_black_set(a_type, a_field, pathp->node); \ + /* Balance restored. */ \ + return; \ + } \ + } else { \ + a_type *leftleft = rbtn_left_get(a_type, a_field, left);\ + if (rbtn_red_get(a_type, a_field, leftleft)) { \ + /* || */\ + /* pathp(b) */\ + /* / \\ */\ + /* (b) (b) */\ + /* / */\ + /* (r) */\ + a_type *tnode; \ + rbtn_black_set(a_type, a_field, leftleft); \ + rbtn_rotate_right(a_type, a_field, pathp->node, \ + tnode); \ + /* Balance restored, but rotation modified */\ + /* subtree root, which may actually be the tree */\ + /* root. */\ + if (pathp == path) { \ + /* Set root. */ \ + rbtree->rbt_root = tnode; \ + } else { \ + if (pathp[-1].cmp < 0) { \ + rbtn_left_set(a_type, a_field, \ + pathp[-1].node, tnode); \ + } else { \ + rbtn_right_set(a_type, a_field, \ + pathp[-1].node, tnode); \ + } \ + } \ + return; \ + } else { \ + /* || */\ + /* pathp(b) */\ + /* / \\ */\ + /* (b) (b) */\ + /* / */\ + /* (b) */\ + rbtn_red_set(a_type, a_field, left); \ + } \ + } \ + } \ + } \ + /* Set root. */ \ + rbtree->rbt_root = path->node; \ + assert(!rbtn_red_get(a_type, a_field, rbtree->rbt_root)); \ +} \ +a_attr a_type * \ +a_prefix##iter_recurse(a_rbt_type *rbtree, a_type *node, \ + a_type *(*cb)(a_rbt_type *, a_type *, void *), void *arg) { \ + if (node == &rbtree->rbt_nil) { \ + return (&rbtree->rbt_nil); \ + } else { \ + a_type *ret; \ + if ((ret = a_prefix##iter_recurse(rbtree, rbtn_left_get(a_type, \ + a_field, node), cb, arg)) != &rbtree->rbt_nil \ + || (ret = cb(rbtree, node, arg)) != NULL) { \ + return (ret); \ + } \ + return (a_prefix##iter_recurse(rbtree, rbtn_right_get(a_type, \ + a_field, node), cb, arg)); \ + } \ +} \ +a_attr a_type * \ +a_prefix##iter_start(a_rbt_type *rbtree, a_type *start, a_type *node, \ + a_type *(*cb)(a_rbt_type *, a_type *, void *), void *arg) { \ + int cmp = a_cmp(start, node); \ + if (cmp < 0) { \ + a_type *ret; \ + if ((ret = a_prefix##iter_start(rbtree, start, \ + rbtn_left_get(a_type, a_field, node), cb, arg)) != \ + &rbtree->rbt_nil || (ret = cb(rbtree, node, arg)) != NULL) { \ + return (ret); \ + } \ + return (a_prefix##iter_recurse(rbtree, rbtn_right_get(a_type, \ + a_field, node), cb, arg)); \ + } else if (cmp > 0) { \ + return (a_prefix##iter_start(rbtree, start, \ + rbtn_right_get(a_type, a_field, node), cb, arg)); \ + } else { \ + a_type *ret; \ + if ((ret = cb(rbtree, node, arg)) != NULL) { \ + return (ret); \ + } \ + return (a_prefix##iter_recurse(rbtree, rbtn_right_get(a_type, \ + a_field, node), cb, arg)); \ + } \ +} \ +a_attr a_type * \ +a_prefix##iter(a_rbt_type *rbtree, a_type *start, a_type *(*cb)( \ + a_rbt_type *, a_type *, void *), void *arg) { \ + a_type *ret; \ + if (start != NULL) { \ + ret = a_prefix##iter_start(rbtree, start, rbtree->rbt_root, \ + cb, arg); \ + } else { \ + ret = a_prefix##iter_recurse(rbtree, rbtree->rbt_root, cb, arg);\ + } \ + if (ret == &rbtree->rbt_nil) { \ + ret = NULL; \ + } \ + return (ret); \ +} \ +a_attr a_type * \ +a_prefix##reverse_iter_recurse(a_rbt_type *rbtree, a_type *node, \ + a_type *(*cb)(a_rbt_type *, a_type *, void *), void *arg) { \ + if (node == &rbtree->rbt_nil) { \ + return (&rbtree->rbt_nil); \ + } else { \ + a_type *ret; \ + if ((ret = a_prefix##reverse_iter_recurse(rbtree, \ + rbtn_right_get(a_type, a_field, node), cb, arg)) != \ + &rbtree->rbt_nil || (ret = cb(rbtree, node, arg)) != NULL) { \ + return (ret); \ + } \ + return (a_prefix##reverse_iter_recurse(rbtree, \ + rbtn_left_get(a_type, a_field, node), cb, arg)); \ + } \ +} \ +a_attr a_type * \ +a_prefix##reverse_iter_start(a_rbt_type *rbtree, a_type *start, \ + a_type *node, a_type *(*cb)(a_rbt_type *, a_type *, void *), \ + void *arg) { \ + int cmp = a_cmp(start, node); \ + if (cmp > 0) { \ + a_type *ret; \ + if ((ret = a_prefix##reverse_iter_start(rbtree, start, \ + rbtn_right_get(a_type, a_field, node), cb, arg)) != \ + &rbtree->rbt_nil || (ret = cb(rbtree, node, arg)) != NULL) { \ + return (ret); \ + } \ + return (a_prefix##reverse_iter_recurse(rbtree, \ + rbtn_left_get(a_type, a_field, node), cb, arg)); \ + } else if (cmp < 0) { \ + return (a_prefix##reverse_iter_start(rbtree, start, \ + rbtn_left_get(a_type, a_field, node), cb, arg)); \ + } else { \ + a_type *ret; \ + if ((ret = cb(rbtree, node, arg)) != NULL) { \ + return (ret); \ + } \ + return (a_prefix##reverse_iter_recurse(rbtree, \ + rbtn_left_get(a_type, a_field, node), cb, arg)); \ + } \ +} \ +a_attr a_type * \ +a_prefix##reverse_iter(a_rbt_type *rbtree, a_type *start, \ + a_type *(*cb)(a_rbt_type *, a_type *, void *), void *arg) { \ + a_type *ret; \ + if (start != NULL) { \ + ret = a_prefix##reverse_iter_start(rbtree, start, \ + rbtree->rbt_root, cb, arg); \ + } else { \ + ret = a_prefix##reverse_iter_recurse(rbtree, rbtree->rbt_root, \ + cb, arg); \ + } \ + if (ret == &rbtree->rbt_nil) { \ + ret = NULL; \ + } \ + return (ret); \ +} + +#endif /* RB_H_ */ diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/rtree.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/rtree.h new file mode 100644 index 0000000..28ae9d1 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/rtree.h @@ -0,0 +1,294 @@ +/* + * This radix tree implementation is tailored to the singular purpose of + * associating metadata with chunks that are currently owned by jemalloc. + * + ******************************************************************************* + */ +#ifdef JEMALLOC_H_TYPES + +typedef struct rtree_node_elm_s rtree_node_elm_t; +typedef struct rtree_level_s rtree_level_t; +typedef struct rtree_s rtree_t; + +/* + * RTREE_BITS_PER_LEVEL must be a power of two that is no larger than the + * machine address width. + */ +#define LG_RTREE_BITS_PER_LEVEL 4 +#define RTREE_BITS_PER_LEVEL (ZU(1) << LG_RTREE_BITS_PER_LEVEL) +#define RTREE_HEIGHT_MAX \ + ((ZU(1) << (LG_SIZEOF_PTR+3)) / RTREE_BITS_PER_LEVEL) + +/* Used for two-stage lock-free node initialization. */ +#define RTREE_NODE_INITIALIZING ((rtree_node_elm_t *)0x1) + +/* + * The node allocation callback function's argument is the number of contiguous + * rtree_node_elm_t structures to allocate, and the resulting memory must be + * zeroed. + */ +typedef rtree_node_elm_t *(rtree_node_alloc_t)(size_t); +typedef void (rtree_node_dalloc_t)(rtree_node_elm_t *); + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +struct rtree_node_elm_s { + union { + void *pun; + rtree_node_elm_t *child; + extent_node_t *val; + }; +}; + +struct rtree_level_s { + /* + * A non-NULL subtree points to a subtree rooted along the hypothetical + * path to the leaf node corresponding to key 0. Depending on what keys + * have been used to store to the tree, an arbitrary combination of + * subtree pointers may remain NULL. + * + * Suppose keys comprise 48 bits, and LG_RTREE_BITS_PER_LEVEL is 4. + * This results in a 3-level tree, and the leftmost leaf can be directly + * accessed via subtrees[2], the subtree prefixed by 0x0000 (excluding + * 0x00000000) can be accessed via subtrees[1], and the remainder of the + * tree can be accessed via subtrees[0]. + * + * levels[0] : [ | 0x0001******** | 0x0002******** | ...] + * + * levels[1] : [ | 0x00000001**** | 0x00000002**** | ... ] + * + * levels[2] : [val(0x000000000000) | val(0x000000000001) | ...] + * + * This has practical implications on x64, which currently uses only the + * lower 47 bits of virtual address space in userland, thus leaving + * subtrees[0] unused and avoiding a level of tree traversal. + */ + union { + void *subtree_pun; + rtree_node_elm_t *subtree; + }; + /* Number of key bits distinguished by this level. */ + unsigned bits; + /* + * Cumulative number of key bits distinguished by traversing to + * corresponding tree level. + */ + unsigned cumbits; +}; + +struct rtree_s { + rtree_node_alloc_t *alloc; + rtree_node_dalloc_t *dalloc; + unsigned height; + /* + * Precomputed table used to convert from the number of leading 0 key + * bits to which subtree level to start at. + */ + unsigned start_level[RTREE_HEIGHT_MAX]; + rtree_level_t levels[RTREE_HEIGHT_MAX]; +}; + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +bool rtree_new(rtree_t *rtree, unsigned bits, rtree_node_alloc_t *alloc, + rtree_node_dalloc_t *dalloc); +void rtree_delete(rtree_t *rtree); +rtree_node_elm_t *rtree_subtree_read_hard(rtree_t *rtree, + unsigned level); +rtree_node_elm_t *rtree_child_read_hard(rtree_t *rtree, + rtree_node_elm_t *elm, unsigned level); + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#ifndef JEMALLOC_ENABLE_INLINE +unsigned rtree_start_level(rtree_t *rtree, uintptr_t key); +uintptr_t rtree_subkey(rtree_t *rtree, uintptr_t key, unsigned level); + +bool rtree_node_valid(rtree_node_elm_t *node); +rtree_node_elm_t *rtree_child_tryread(rtree_node_elm_t *elm); +rtree_node_elm_t *rtree_child_read(rtree_t *rtree, rtree_node_elm_t *elm, + unsigned level); +extent_node_t *rtree_val_read(rtree_t *rtree, rtree_node_elm_t *elm, + bool dependent); +void rtree_val_write(rtree_t *rtree, rtree_node_elm_t *elm, + const extent_node_t *val); +rtree_node_elm_t *rtree_subtree_tryread(rtree_t *rtree, unsigned level); +rtree_node_elm_t *rtree_subtree_read(rtree_t *rtree, unsigned level); + +extent_node_t *rtree_get(rtree_t *rtree, uintptr_t key, bool dependent); +bool rtree_set(rtree_t *rtree, uintptr_t key, const extent_node_t *val); +#endif + +#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_RTREE_C_)) +JEMALLOC_INLINE unsigned +rtree_start_level(rtree_t *rtree, uintptr_t key) +{ + unsigned start_level; + + if (unlikely(key == 0)) + return (rtree->height - 1); + + start_level = rtree->start_level[lg_floor(key) >> + LG_RTREE_BITS_PER_LEVEL]; + assert(start_level < rtree->height); + return (start_level); +} + +JEMALLOC_INLINE uintptr_t +rtree_subkey(rtree_t *rtree, uintptr_t key, unsigned level) +{ + + return ((key >> ((ZU(1) << (LG_SIZEOF_PTR+3)) - + rtree->levels[level].cumbits)) & ((ZU(1) << + rtree->levels[level].bits) - 1)); +} + +JEMALLOC_INLINE bool +rtree_node_valid(rtree_node_elm_t *node) +{ + + return ((uintptr_t)node > (uintptr_t)RTREE_NODE_INITIALIZING); +} + +JEMALLOC_INLINE rtree_node_elm_t * +rtree_child_tryread(rtree_node_elm_t *elm) +{ + rtree_node_elm_t *child; + + /* Double-checked read (first read may be stale. */ + child = elm->child; + if (!rtree_node_valid(child)) + child = atomic_read_p(&elm->pun); + return (child); +} + +JEMALLOC_INLINE rtree_node_elm_t * +rtree_child_read(rtree_t *rtree, rtree_node_elm_t *elm, unsigned level) +{ + rtree_node_elm_t *child; + + child = rtree_child_tryread(elm); + if (unlikely(!rtree_node_valid(child))) + child = rtree_child_read_hard(rtree, elm, level); + return (child); +} + +JEMALLOC_INLINE extent_node_t * +rtree_val_read(rtree_t *rtree, rtree_node_elm_t *elm, bool dependent) +{ + + if (dependent) { + /* + * Reading a val on behalf of a pointer to a valid allocation is + * guaranteed to be a clean read even without synchronization, + * because the rtree update became visible in memory before the + * pointer came into existence. + */ + return (elm->val); + } else { + /* + * An arbitrary read, e.g. on behalf of ivsalloc(), may not be + * dependent on a previous rtree write, which means a stale read + * could result if synchronization were omitted here. + */ + return (atomic_read_p(&elm->pun)); + } +} + +JEMALLOC_INLINE void +rtree_val_write(rtree_t *rtree, rtree_node_elm_t *elm, const extent_node_t *val) +{ + + atomic_write_p(&elm->pun, val); +} + +JEMALLOC_INLINE rtree_node_elm_t * +rtree_subtree_tryread(rtree_t *rtree, unsigned level) +{ + rtree_node_elm_t *subtree; + + /* Double-checked read (first read may be stale. */ + subtree = rtree->levels[level].subtree; + if (!rtree_node_valid(subtree)) + subtree = atomic_read_p(&rtree->levels[level].subtree_pun); + return (subtree); +} + +JEMALLOC_INLINE rtree_node_elm_t * +rtree_subtree_read(rtree_t *rtree, unsigned level) +{ + rtree_node_elm_t *subtree; + + subtree = rtree_subtree_tryread(rtree, level); + if (unlikely(!rtree_node_valid(subtree))) + subtree = rtree_subtree_read_hard(rtree, level); + return (subtree); +} + +JEMALLOC_INLINE extent_node_t * +rtree_get(rtree_t *rtree, uintptr_t key, bool dependent) +{ + uintptr_t subkey; + unsigned i, start_level; + rtree_node_elm_t *node, *child; + + start_level = rtree_start_level(rtree, key); + + for (i = start_level, node = rtree_subtree_tryread(rtree, start_level); + /**/; i++, node = child) { + if (!dependent && unlikely(!rtree_node_valid(node))) + return (NULL); + subkey = rtree_subkey(rtree, key, i); + if (i == rtree->height - 1) { + /* + * node is a leaf, so it contains values rather than + * child pointers. + */ + return (rtree_val_read(rtree, &node[subkey], + dependent)); + } + assert(i < rtree->height - 1); + child = rtree_child_tryread(&node[subkey]); + } + not_reached(); +} + +JEMALLOC_INLINE bool +rtree_set(rtree_t *rtree, uintptr_t key, const extent_node_t *val) +{ + uintptr_t subkey; + unsigned i, start_level; + rtree_node_elm_t *node, *child; + + start_level = rtree_start_level(rtree, key); + + node = rtree_subtree_read(rtree, start_level); + if (node == NULL) + return (true); + for (i = start_level; /**/; i++, node = child) { + subkey = rtree_subkey(rtree, key, i); + if (i == rtree->height - 1) { + /* + * node is a leaf, so it contains values rather than + * child pointers. + */ + rtree_val_write(rtree, &node[subkey], val); + return (false); + } + assert(i + 1 < rtree->height); + child = rtree_child_read(rtree, &node[subkey], i); + if (child == NULL) + return (true); + } + not_reached(); +} +#endif + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/size_classes.sh b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/size_classes.sh new file mode 100755 index 0000000..fc82036 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/size_classes.sh @@ -0,0 +1,286 @@ +#!/bin/sh +# +# Usage: size_classes.sh + +# The following limits are chosen such that they cover all supported platforms. + +# Pointer sizes. +lg_zarr="2 3" + +# Quanta. +lg_qarr=$1 + +# The range of tiny size classes is [2^lg_tmin..2^(lg_q-1)]. +lg_tmin=$2 + +# Maximum lookup size. +lg_kmax=12 + +# Page sizes. +lg_parr=`echo $3 | tr ',' ' '` + +# Size class group size (number of size classes for each size doubling). +lg_g=$4 + +pow2() { + e=$1 + pow2_result=1 + while [ ${e} -gt 0 ] ; do + pow2_result=$((${pow2_result} + ${pow2_result})) + e=$((${e} - 1)) + done +} + +lg() { + x=$1 + lg_result=0 + while [ ${x} -gt 1 ] ; do + lg_result=$((${lg_result} + 1)) + x=$((${x} / 2)) + done +} + +size_class() { + index=$1 + lg_grp=$2 + lg_delta=$3 + ndelta=$4 + lg_p=$5 + lg_kmax=$6 + + lg ${ndelta}; lg_ndelta=${lg_result}; pow2 ${lg_ndelta} + if [ ${pow2_result} -lt ${ndelta} ] ; then + rem="yes" + else + rem="no" + fi + + lg_size=${lg_grp} + if [ $((${lg_delta} + ${lg_ndelta})) -eq ${lg_grp} ] ; then + lg_size=$((${lg_grp} + 1)) + else + lg_size=${lg_grp} + rem="yes" + fi + + if [ ${lg_size} -lt $((${lg_p} + ${lg_g})) ] ; then + bin="yes" + else + bin="no" + fi + if [ ${lg_size} -lt ${lg_kmax} \ + -o ${lg_size} -eq ${lg_kmax} -a ${rem} = "no" ] ; then + lg_delta_lookup=${lg_delta} + else + lg_delta_lookup="no" + fi + printf ' SC(%3d, %6d, %8d, %6d, %3s, %2s) \\\n' ${index} ${lg_grp} ${lg_delta} ${ndelta} ${bin} ${lg_delta_lookup} + # Defined upon return: + # - lg_delta_lookup (${lg_delta} or "no") + # - bin ("yes" or "no") +} + +sep_line() { + echo " \\" +} + +size_classes() { + lg_z=$1 + lg_q=$2 + lg_t=$3 + lg_p=$4 + lg_g=$5 + + pow2 $((${lg_z} + 3)); ptr_bits=${pow2_result} + pow2 ${lg_g}; g=${pow2_result} + + echo "#define SIZE_CLASSES \\" + echo " /* index, lg_grp, lg_delta, ndelta, bin, lg_delta_lookup */ \\" + + ntbins=0 + nlbins=0 + lg_tiny_maxclass='"NA"' + nbins=0 + + # Tiny size classes. + ndelta=0 + index=0 + lg_grp=${lg_t} + lg_delta=${lg_grp} + while [ ${lg_grp} -lt ${lg_q} ] ; do + size_class ${index} ${lg_grp} ${lg_delta} ${ndelta} ${lg_p} ${lg_kmax} + if [ ${lg_delta_lookup} != "no" ] ; then + nlbins=$((${index} + 1)) + fi + if [ ${bin} != "no" ] ; then + nbins=$((${index} + 1)) + fi + ntbins=$((${ntbins} + 1)) + lg_tiny_maxclass=${lg_grp} # Final written value is correct. + index=$((${index} + 1)) + lg_delta=${lg_grp} + lg_grp=$((${lg_grp} + 1)) + done + + # First non-tiny group. + if [ ${ntbins} -gt 0 ] ; then + sep_line + # The first size class has an unusual encoding, because the size has to be + # split between grp and delta*ndelta. + lg_grp=$((${lg_grp} - 1)) + ndelta=1 + size_class ${index} ${lg_grp} ${lg_delta} ${ndelta} ${lg_p} ${lg_kmax} + index=$((${index} + 1)) + lg_grp=$((${lg_grp} + 1)) + lg_delta=$((${lg_delta} + 1)) + fi + while [ ${ndelta} -lt ${g} ] ; do + size_class ${index} ${lg_grp} ${lg_delta} ${ndelta} ${lg_p} ${lg_kmax} + index=$((${index} + 1)) + ndelta=$((${ndelta} + 1)) + done + + # All remaining groups. + lg_grp=$((${lg_grp} + ${lg_g})) + while [ ${lg_grp} -lt ${ptr_bits} ] ; do + sep_line + ndelta=1 + if [ ${lg_grp} -eq $((${ptr_bits} - 1)) ] ; then + ndelta_limit=$((${g} - 1)) + else + ndelta_limit=${g} + fi + while [ ${ndelta} -le ${ndelta_limit} ] ; do + size_class ${index} ${lg_grp} ${lg_delta} ${ndelta} ${lg_p} ${lg_kmax} + if [ ${lg_delta_lookup} != "no" ] ; then + nlbins=$((${index} + 1)) + # Final written value is correct: + lookup_maxclass="((((size_t)1) << ${lg_grp}) + (((size_t)${ndelta}) << ${lg_delta}))" + fi + if [ ${bin} != "no" ] ; then + nbins=$((${index} + 1)) + # Final written value is correct: + small_maxclass="((((size_t)1) << ${lg_grp}) + (((size_t)${ndelta}) << ${lg_delta}))" + if [ ${lg_g} -gt 0 ] ; then + lg_large_minclass=$((${lg_grp} + 1)) + else + lg_large_minclass=$((${lg_grp} + 2)) + fi + fi + # Final written value is correct: + huge_maxclass="((((size_t)1) << ${lg_grp}) + (((size_t)${ndelta}) << ${lg_delta}))" + index=$((${index} + 1)) + ndelta=$((${ndelta} + 1)) + done + lg_grp=$((${lg_grp} + 1)) + lg_delta=$((${lg_delta} + 1)) + done + echo + nsizes=${index} + + # Defined upon completion: + # - ntbins + # - nlbins + # - nbins + # - nsizes + # - lg_tiny_maxclass + # - lookup_maxclass + # - small_maxclass + # - lg_large_minclass + # - huge_maxclass +} + +cat < 255) +# error "Too many small size classes" +#endif + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ +EOF diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/stats.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/stats.h new file mode 100644 index 0000000..c91dba9 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/stats.h @@ -0,0 +1,183 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +typedef struct tcache_bin_stats_s tcache_bin_stats_t; +typedef struct malloc_bin_stats_s malloc_bin_stats_t; +typedef struct malloc_large_stats_s malloc_large_stats_t; +typedef struct malloc_huge_stats_s malloc_huge_stats_t; +typedef struct arena_stats_s arena_stats_t; +typedef struct chunk_stats_s chunk_stats_t; + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +struct tcache_bin_stats_s { + /* + * Number of allocation requests that corresponded to the size of this + * bin. + */ + uint64_t nrequests; +}; + +struct malloc_bin_stats_s { + /* + * Total number of allocation/deallocation requests served directly by + * the bin. Note that tcache may allocate an object, then recycle it + * many times, resulting many increments to nrequests, but only one + * each to nmalloc and ndalloc. + */ + uint64_t nmalloc; + uint64_t ndalloc; + + /* + * Number of allocation requests that correspond to the size of this + * bin. This includes requests served by tcache, though tcache only + * periodically merges into this counter. + */ + uint64_t nrequests; + + /* + * Current number of regions of this size class, including regions + * currently cached by tcache. + */ + size_t curregs; + + /* Number of tcache fills from this bin. */ + uint64_t nfills; + + /* Number of tcache flushes to this bin. */ + uint64_t nflushes; + + /* Total number of runs created for this bin's size class. */ + uint64_t nruns; + + /* + * Total number of runs reused by extracting them from the runs tree for + * this bin's size class. + */ + uint64_t reruns; + + /* Current number of runs in this bin. */ + size_t curruns; +}; + +struct malloc_large_stats_s { + /* + * Total number of allocation/deallocation requests served directly by + * the arena. Note that tcache may allocate an object, then recycle it + * many times, resulting many increments to nrequests, but only one + * each to nmalloc and ndalloc. + */ + uint64_t nmalloc; + uint64_t ndalloc; + + /* + * Number of allocation requests that correspond to this size class. + * This includes requests served by tcache, though tcache only + * periodically merges into this counter. + */ + uint64_t nrequests; + + /* + * Current number of runs of this size class, including runs currently + * cached by tcache. + */ + size_t curruns; +}; + +struct malloc_huge_stats_s { + /* + * Total number of allocation/deallocation requests served directly by + * the arena. + */ + uint64_t nmalloc; + uint64_t ndalloc; + + /* Current number of (multi-)chunk allocations of this size class. */ + size_t curhchunks; +}; + +struct arena_stats_s { + /* Number of bytes currently mapped. */ + size_t mapped; + + /* + * Total number of purge sweeps, total number of madvise calls made, + * and total pages purged in order to keep dirty unused memory under + * control. + */ + uint64_t npurge; + uint64_t nmadvise; + uint64_t purged; + + /* + * Number of bytes currently mapped purely for metadata purposes, and + * number of bytes currently allocated for internal metadata. + */ + size_t metadata_mapped; + size_t metadata_allocated; /* Protected via atomic_*_z(). */ + + /* Per-size-category statistics. */ + size_t allocated_large; + uint64_t nmalloc_large; + uint64_t ndalloc_large; + uint64_t nrequests_large; + + size_t allocated_huge; + uint64_t nmalloc_huge; + uint64_t ndalloc_huge; + + /* One element for each large size class. */ + malloc_large_stats_t *lstats; + + /* One element for each huge size class. */ + malloc_huge_stats_t *hstats; +}; + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +extern bool opt_stats_print; + +extern size_t stats_cactive; + +void stats_print(void (*write)(void *, const char *), void *cbopaque, + const char *opts); + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#ifndef JEMALLOC_ENABLE_INLINE +size_t stats_cactive_get(void); +void stats_cactive_add(size_t size); +void stats_cactive_sub(size_t size); +#endif + +#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_STATS_C_)) +JEMALLOC_INLINE size_t +stats_cactive_get(void) +{ + + return (atomic_read_z(&stats_cactive)); +} + +JEMALLOC_INLINE void +stats_cactive_add(size_t size) +{ + + atomic_add_z(&stats_cactive, size); +} + +JEMALLOC_INLINE void +stats_cactive_sub(size_t size) +{ + + atomic_sub_z(&stats_cactive, size); +} +#endif + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/tcache.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/tcache.h new file mode 100644 index 0000000..5079cd2 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/tcache.h @@ -0,0 +1,426 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +typedef struct tcache_bin_info_s tcache_bin_info_t; +typedef struct tcache_bin_s tcache_bin_t; +typedef struct tcache_s tcache_t; +typedef struct tcaches_s tcaches_t; + +/* + * tcache pointers close to NULL are used to encode state information that is + * used for two purposes: preventing thread caching on a per thread basis and + * cleaning up during thread shutdown. + */ +#define TCACHE_STATE_DISABLED ((tcache_t *)(uintptr_t)1) +#define TCACHE_STATE_REINCARNATED ((tcache_t *)(uintptr_t)2) +#define TCACHE_STATE_PURGATORY ((tcache_t *)(uintptr_t)3) +#define TCACHE_STATE_MAX TCACHE_STATE_PURGATORY + +/* + * Absolute minimum number of cache slots for each small bin. + */ +#define TCACHE_NSLOTS_SMALL_MIN 20 + +/* + * Absolute maximum number of cache slots for each small bin in the thread + * cache. This is an additional constraint beyond that imposed as: twice the + * number of regions per run for this size class. + * + * This constant must be an even number. + */ +#define TCACHE_NSLOTS_SMALL_MAX 200 + +/* Number of cache slots for large size classes. */ +#define TCACHE_NSLOTS_LARGE 20 + +/* (1U << opt_lg_tcache_max) is used to compute tcache_maxclass. */ +#define LG_TCACHE_MAXCLASS_DEFAULT 15 + +/* + * TCACHE_GC_SWEEP is the approximate number of allocation events between + * full GC sweeps. Integer rounding may cause the actual number to be + * slightly higher, since GC is performed incrementally. + */ +#define TCACHE_GC_SWEEP 8192 + +/* Number of tcache allocation/deallocation events between incremental GCs. */ +#define TCACHE_GC_INCR \ + ((TCACHE_GC_SWEEP / NBINS) + ((TCACHE_GC_SWEEP / NBINS == 0) ? 0 : 1)) + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +typedef enum { + tcache_enabled_false = 0, /* Enable cast to/from bool. */ + tcache_enabled_true = 1, + tcache_enabled_default = 2 +} tcache_enabled_t; + +/* + * Read-only information associated with each element of tcache_t's tbins array + * is stored separately, mainly to reduce memory usage. + */ +struct tcache_bin_info_s { + unsigned ncached_max; /* Upper limit on ncached. */ +}; + +struct tcache_bin_s { + tcache_bin_stats_t tstats; + int low_water; /* Min # cached since last GC. */ + unsigned lg_fill_div; /* Fill (ncached_max >> lg_fill_div). */ + unsigned ncached; /* # of cached objects. */ + void **avail; /* Stack of available objects. */ +}; + +struct tcache_s { + ql_elm(tcache_t) link; /* Used for aggregating stats. */ + uint64_t prof_accumbytes;/* Cleared after arena_prof_accum(). */ + unsigned ev_cnt; /* Event count since incremental GC. */ + szind_t next_gc_bin; /* Next bin to GC. */ + tcache_bin_t tbins[1]; /* Dynamically sized. */ + /* + * The pointer stacks associated with tbins follow as a contiguous + * array. During tcache initialization, the avail pointer in each + * element of tbins is initialized to point to the proper offset within + * this array. + */ +}; + +/* Linkage for list of available (previously used) explicit tcache IDs. */ +struct tcaches_s { + union { + tcache_t *tcache; + tcaches_t *next; + }; +}; + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +extern bool opt_tcache; +extern ssize_t opt_lg_tcache_max; + +extern tcache_bin_info_t *tcache_bin_info; + +/* + * Number of tcache bins. There are NBINS small-object bins, plus 0 or more + * large-object bins. + */ +extern size_t nhbins; + +/* Maximum cached size class. */ +extern size_t tcache_maxclass; + +/* + * Explicit tcaches, managed via the tcache.{create,flush,destroy} mallctls and + * usable via the MALLOCX_TCACHE() flag. The automatic per thread tcaches are + * completely disjoint from this data structure. tcaches starts off as a sparse + * array, so it has no physical memory footprint until individual pages are + * touched. This allows the entire array to be allocated the first time an + * explicit tcache is created without a disproportionate impact on memory usage. + */ +extern tcaches_t *tcaches; + +size_t tcache_salloc(const void *ptr); +void tcache_event_hard(tsd_t *tsd, tcache_t *tcache); +void *tcache_alloc_small_hard(tsd_t *tsd, arena_t *arena, tcache_t *tcache, + tcache_bin_t *tbin, szind_t binind); +void tcache_bin_flush_small(tsd_t *tsd, tcache_t *tcache, tcache_bin_t *tbin, + szind_t binind, unsigned rem); +void tcache_bin_flush_large(tsd_t *tsd, tcache_bin_t *tbin, szind_t binind, + unsigned rem, tcache_t *tcache); +void tcache_arena_associate(tcache_t *tcache, arena_t *arena); +void tcache_arena_reassociate(tcache_t *tcache, arena_t *oldarena, + arena_t *newarena); +void tcache_arena_dissociate(tcache_t *tcache, arena_t *arena); +tcache_t *tcache_get_hard(tsd_t *tsd); +tcache_t *tcache_create(tsd_t *tsd, arena_t *arena); +void tcache_cleanup(tsd_t *tsd); +void tcache_enabled_cleanup(tsd_t *tsd); +void tcache_stats_merge(tcache_t *tcache, arena_t *arena); +bool tcaches_create(tsd_t *tsd, unsigned *r_ind); +void tcaches_flush(tsd_t *tsd, unsigned ind); +void tcaches_destroy(tsd_t *tsd, unsigned ind); +bool tcache_boot(void); + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#ifndef JEMALLOC_ENABLE_INLINE +void tcache_event(tsd_t *tsd, tcache_t *tcache); +void tcache_flush(void); +bool tcache_enabled_get(void); +tcache_t *tcache_get(tsd_t *tsd, bool create); +void tcache_enabled_set(bool enabled); +void *tcache_alloc_easy(tcache_bin_t *tbin); +void *tcache_alloc_small(tsd_t *tsd, arena_t *arena, tcache_t *tcache, + size_t size, bool zero); +void *tcache_alloc_large(tsd_t *tsd, arena_t *arena, tcache_t *tcache, + size_t size, bool zero); +void tcache_dalloc_small(tsd_t *tsd, tcache_t *tcache, void *ptr, + szind_t binind); +void tcache_dalloc_large(tsd_t *tsd, tcache_t *tcache, void *ptr, + size_t size); +tcache_t *tcaches_get(tsd_t *tsd, unsigned ind); +#endif + +#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_TCACHE_C_)) +JEMALLOC_INLINE void +tcache_flush(void) +{ + tsd_t *tsd; + + cassert(config_tcache); + + tsd = tsd_fetch(); + tcache_cleanup(tsd); +} + +JEMALLOC_INLINE bool +tcache_enabled_get(void) +{ + tsd_t *tsd; + tcache_enabled_t tcache_enabled; + + cassert(config_tcache); + + tsd = tsd_fetch(); + tcache_enabled = tsd_tcache_enabled_get(tsd); + if (tcache_enabled == tcache_enabled_default) { + tcache_enabled = (tcache_enabled_t)opt_tcache; + tsd_tcache_enabled_set(tsd, tcache_enabled); + } + + return ((bool)tcache_enabled); +} + +JEMALLOC_INLINE void +tcache_enabled_set(bool enabled) +{ + tsd_t *tsd; + tcache_enabled_t tcache_enabled; + + cassert(config_tcache); + + tsd = tsd_fetch(); + + tcache_enabled = (tcache_enabled_t)enabled; + tsd_tcache_enabled_set(tsd, tcache_enabled); + + if (!enabled) + tcache_cleanup(tsd); +} + +JEMALLOC_ALWAYS_INLINE tcache_t * +tcache_get(tsd_t *tsd, bool create) +{ + tcache_t *tcache; + + if (!config_tcache) + return (NULL); + + tcache = tsd_tcache_get(tsd); + if (!create) + return (tcache); + if (unlikely(tcache == NULL) && tsd_nominal(tsd)) { + tcache = tcache_get_hard(tsd); + tsd_tcache_set(tsd, tcache); + } + + return (tcache); +} + +JEMALLOC_ALWAYS_INLINE void +tcache_event(tsd_t *tsd, tcache_t *tcache) +{ + + if (TCACHE_GC_INCR == 0) + return; + + tcache->ev_cnt++; + assert(tcache->ev_cnt <= TCACHE_GC_INCR); + if (unlikely(tcache->ev_cnt == TCACHE_GC_INCR)) + tcache_event_hard(tsd, tcache); +} + +JEMALLOC_ALWAYS_INLINE void * +tcache_alloc_easy(tcache_bin_t *tbin) +{ + void *ret; + + if (unlikely(tbin->ncached == 0)) { + tbin->low_water = -1; + return (NULL); + } + tbin->ncached--; + if (unlikely((int)tbin->ncached < tbin->low_water)) + tbin->low_water = tbin->ncached; + ret = tbin->avail[tbin->ncached]; + return (ret); +} + +JEMALLOC_ALWAYS_INLINE void * +tcache_alloc_small(tsd_t *tsd, arena_t *arena, tcache_t *tcache, size_t size, + bool zero) +{ + void *ret; + szind_t binind; + size_t usize; + tcache_bin_t *tbin; + + binind = size2index(size); + assert(binind < NBINS); + tbin = &tcache->tbins[binind]; + usize = index2size(binind); + ret = tcache_alloc_easy(tbin); + if (unlikely(ret == NULL)) { + ret = tcache_alloc_small_hard(tsd, arena, tcache, tbin, binind); + if (ret == NULL) + return (NULL); + } + assert(tcache_salloc(ret) == usize); + + if (likely(!zero)) { + if (config_fill) { + if (unlikely(opt_junk_alloc)) { + arena_alloc_junk_small(ret, + &arena_bin_info[binind], false); + } else if (unlikely(opt_zero)) + memset(ret, 0, usize); + } + } else { + if (config_fill && unlikely(opt_junk_alloc)) { + arena_alloc_junk_small(ret, &arena_bin_info[binind], + true); + } + memset(ret, 0, usize); + } + + if (config_stats) + tbin->tstats.nrequests++; + if (config_prof) + tcache->prof_accumbytes += usize; + tcache_event(tsd, tcache); + return (ret); +} + +JEMALLOC_ALWAYS_INLINE void * +tcache_alloc_large(tsd_t *tsd, arena_t *arena, tcache_t *tcache, size_t size, + bool zero) +{ + void *ret; + szind_t binind; + size_t usize; + tcache_bin_t *tbin; + + binind = size2index(size); + usize = index2size(binind); + assert(usize <= tcache_maxclass); + assert(binind < nhbins); + tbin = &tcache->tbins[binind]; + ret = tcache_alloc_easy(tbin); + if (unlikely(ret == NULL)) { + /* + * Only allocate one large object at a time, because it's quite + * expensive to create one and not use it. + */ + ret = arena_malloc_large(arena, usize, zero); + if (ret == NULL) + return (NULL); + } else { + if (config_prof && usize == LARGE_MINCLASS) { + arena_chunk_t *chunk = + (arena_chunk_t *)CHUNK_ADDR2BASE(ret); + size_t pageind = (((uintptr_t)ret - (uintptr_t)chunk) >> + LG_PAGE); + arena_mapbits_large_binind_set(chunk, pageind, + BININD_INVALID); + } + if (likely(!zero)) { + if (config_fill) { + if (unlikely(opt_junk_alloc)) + memset(ret, 0xa5, usize); + else if (unlikely(opt_zero)) + memset(ret, 0, usize); + } + } else + memset(ret, 0, usize); + + if (config_stats) + tbin->tstats.nrequests++; + if (config_prof) + tcache->prof_accumbytes += usize; + } + + tcache_event(tsd, tcache); + return (ret); +} + +JEMALLOC_ALWAYS_INLINE void +tcache_dalloc_small(tsd_t *tsd, tcache_t *tcache, void *ptr, szind_t binind) +{ + tcache_bin_t *tbin; + tcache_bin_info_t *tbin_info; + + assert(tcache_salloc(ptr) <= SMALL_MAXCLASS); + + if (config_fill && unlikely(opt_junk_free)) + arena_dalloc_junk_small(ptr, &arena_bin_info[binind]); + + tbin = &tcache->tbins[binind]; + tbin_info = &tcache_bin_info[binind]; + if (unlikely(tbin->ncached == tbin_info->ncached_max)) { + tcache_bin_flush_small(tsd, tcache, tbin, binind, + (tbin_info->ncached_max >> 1)); + } + assert(tbin->ncached < tbin_info->ncached_max); + tbin->avail[tbin->ncached] = ptr; + tbin->ncached++; + + tcache_event(tsd, tcache); +} + +JEMALLOC_ALWAYS_INLINE void +tcache_dalloc_large(tsd_t *tsd, tcache_t *tcache, void *ptr, size_t size) +{ + szind_t binind; + tcache_bin_t *tbin; + tcache_bin_info_t *tbin_info; + + assert((size & PAGE_MASK) == 0); + assert(tcache_salloc(ptr) > SMALL_MAXCLASS); + assert(tcache_salloc(ptr) <= tcache_maxclass); + + binind = size2index(size); + + if (config_fill && unlikely(opt_junk_free)) + arena_dalloc_junk_large(ptr, size); + + tbin = &tcache->tbins[binind]; + tbin_info = &tcache_bin_info[binind]; + if (unlikely(tbin->ncached == tbin_info->ncached_max)) { + tcache_bin_flush_large(tsd, tbin, binind, + (tbin_info->ncached_max >> 1), tcache); + } + assert(tbin->ncached < tbin_info->ncached_max); + tbin->avail[tbin->ncached] = ptr; + tbin->ncached++; + + tcache_event(tsd, tcache); +} + +JEMALLOC_ALWAYS_INLINE tcache_t * +tcaches_get(tsd_t *tsd, unsigned ind) +{ + tcaches_t *elm = &tcaches[ind]; + if (unlikely(elm->tcache == NULL)) + elm->tcache = tcache_create(tsd, arena_choose(tsd, NULL)); + return (elm->tcache); +} +#endif + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/tsd.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/tsd.h new file mode 100644 index 0000000..eed7aa0 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/tsd.h @@ -0,0 +1,665 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +/* Maximum number of malloc_tsd users with cleanup functions. */ +#define MALLOC_TSD_CLEANUPS_MAX 2 + +typedef bool (*malloc_tsd_cleanup_t)(void); + +#if (!defined(JEMALLOC_MALLOC_THREAD_CLEANUP) && !defined(JEMALLOC_TLS) && \ + !defined(_WIN32)) +typedef struct tsd_init_block_s tsd_init_block_t; +typedef struct tsd_init_head_s tsd_init_head_t; +#endif + +typedef struct tsd_s tsd_t; + +typedef enum { + tsd_state_uninitialized, + tsd_state_nominal, + tsd_state_purgatory, + tsd_state_reincarnated +} tsd_state_t; + +/* + * TLS/TSD-agnostic macro-based implementation of thread-specific data. There + * are five macros that support (at least) three use cases: file-private, + * library-private, and library-private inlined. Following is an example + * library-private tsd variable: + * + * In example.h: + * typedef struct { + * int x; + * int y; + * } example_t; + * #define EX_INITIALIZER JEMALLOC_CONCAT({0, 0}) + * malloc_tsd_types(example_, example_t) + * malloc_tsd_protos(, example_, example_t) + * malloc_tsd_externs(example_, example_t) + * In example.c: + * malloc_tsd_data(, example_, example_t, EX_INITIALIZER) + * malloc_tsd_funcs(, example_, example_t, EX_INITIALIZER, + * example_tsd_cleanup) + * + * The result is a set of generated functions, e.g.: + * + * bool example_tsd_boot(void) {...} + * example_t *example_tsd_get() {...} + * void example_tsd_set(example_t *val) {...} + * + * Note that all of the functions deal in terms of (a_type *) rather than + * (a_type) so that it is possible to support non-pointer types (unlike + * pthreads TSD). example_tsd_cleanup() is passed an (a_type *) pointer that is + * cast to (void *). This means that the cleanup function needs to cast the + * function argument to (a_type *), then dereference the resulting pointer to + * access fields, e.g. + * + * void + * example_tsd_cleanup(void *arg) + * { + * example_t *example = (example_t *)arg; + * + * example->x = 42; + * [...] + * if ([want the cleanup function to be called again]) + * example_tsd_set(example); + * } + * + * If example_tsd_set() is called within example_tsd_cleanup(), it will be + * called again. This is similar to how pthreads TSD destruction works, except + * that pthreads only calls the cleanup function again if the value was set to + * non-NULL. + */ + +/* malloc_tsd_types(). */ +#ifdef JEMALLOC_MALLOC_THREAD_CLEANUP +#define malloc_tsd_types(a_name, a_type) +#elif (defined(JEMALLOC_TLS)) +#define malloc_tsd_types(a_name, a_type) +#elif (defined(_WIN32)) +#define malloc_tsd_types(a_name, a_type) \ +typedef struct { \ + bool initialized; \ + a_type val; \ +} a_name##tsd_wrapper_t; +#else +#define malloc_tsd_types(a_name, a_type) \ +typedef struct { \ + bool initialized; \ + a_type val; \ +} a_name##tsd_wrapper_t; +#endif + +/* malloc_tsd_protos(). */ +#define malloc_tsd_protos(a_attr, a_name, a_type) \ +a_attr bool \ +a_name##tsd_boot0(void); \ +a_attr void \ +a_name##tsd_boot1(void); \ +a_attr bool \ +a_name##tsd_boot(void); \ +a_attr a_type * \ +a_name##tsd_get(void); \ +a_attr void \ +a_name##tsd_set(a_type *val); + +/* malloc_tsd_externs(). */ +#ifdef JEMALLOC_MALLOC_THREAD_CLEANUP +#define malloc_tsd_externs(a_name, a_type) \ +extern __thread a_type a_name##tsd_tls; \ +extern __thread bool a_name##tsd_initialized; \ +extern bool a_name##tsd_booted; +#elif (defined(JEMALLOC_TLS)) +#define malloc_tsd_externs(a_name, a_type) \ +extern __thread a_type a_name##tsd_tls; \ +extern pthread_key_t a_name##tsd_tsd; \ +extern bool a_name##tsd_booted; +#elif (defined(_WIN32)) +#define malloc_tsd_externs(a_name, a_type) \ +extern DWORD a_name##tsd_tsd; \ +extern a_name##tsd_wrapper_t a_name##tsd_boot_wrapper; \ +extern bool a_name##tsd_booted; +#else +#define malloc_tsd_externs(a_name, a_type) \ +extern pthread_key_t a_name##tsd_tsd; \ +extern tsd_init_head_t a_name##tsd_init_head; \ +extern a_name##tsd_wrapper_t a_name##tsd_boot_wrapper; \ +extern bool a_name##tsd_booted; +#endif + +/* malloc_tsd_data(). */ +#ifdef JEMALLOC_MALLOC_THREAD_CLEANUP +#define malloc_tsd_data(a_attr, a_name, a_type, a_initializer) \ +a_attr __thread a_type JEMALLOC_TLS_MODEL \ + a_name##tsd_tls = a_initializer; \ +a_attr __thread bool JEMALLOC_TLS_MODEL \ + a_name##tsd_initialized = false; \ +a_attr bool a_name##tsd_booted = false; +#elif (defined(JEMALLOC_TLS)) +#define malloc_tsd_data(a_attr, a_name, a_type, a_initializer) \ +a_attr __thread a_type JEMALLOC_TLS_MODEL \ + a_name##tsd_tls = a_initializer; \ +a_attr pthread_key_t a_name##tsd_tsd; \ +a_attr bool a_name##tsd_booted = false; +#elif (defined(_WIN32)) +#define malloc_tsd_data(a_attr, a_name, a_type, a_initializer) \ +a_attr DWORD a_name##tsd_tsd; \ +a_attr a_name##tsd_wrapper_t a_name##tsd_boot_wrapper = { \ + false, \ + a_initializer \ +}; \ +a_attr bool a_name##tsd_booted = false; +#else +#define malloc_tsd_data(a_attr, a_name, a_type, a_initializer) \ +a_attr pthread_key_t a_name##tsd_tsd; \ +a_attr tsd_init_head_t a_name##tsd_init_head = { \ + ql_head_initializer(blocks), \ + MALLOC_MUTEX_INITIALIZER \ +}; \ +a_attr a_name##tsd_wrapper_t a_name##tsd_boot_wrapper = { \ + false, \ + a_initializer \ +}; \ +a_attr bool a_name##tsd_booted = false; +#endif + +/* malloc_tsd_funcs(). */ +#ifdef JEMALLOC_MALLOC_THREAD_CLEANUP +#define malloc_tsd_funcs(a_attr, a_name, a_type, a_initializer, \ + a_cleanup) \ +/* Initialization/cleanup. */ \ +a_attr bool \ +a_name##tsd_cleanup_wrapper(void) \ +{ \ + \ + if (a_name##tsd_initialized) { \ + a_name##tsd_initialized = false; \ + a_cleanup(&a_name##tsd_tls); \ + } \ + return (a_name##tsd_initialized); \ +} \ +a_attr bool \ +a_name##tsd_boot0(void) \ +{ \ + \ + if (a_cleanup != malloc_tsd_no_cleanup) { \ + malloc_tsd_cleanup_register( \ + &a_name##tsd_cleanup_wrapper); \ + } \ + a_name##tsd_booted = true; \ + return (false); \ +} \ +a_attr void \ +a_name##tsd_boot1(void) \ +{ \ + \ + /* Do nothing. */ \ +} \ +a_attr bool \ +a_name##tsd_boot(void) \ +{ \ + \ + return (a_name##tsd_boot0()); \ +} \ +/* Get/set. */ \ +a_attr a_type * \ +a_name##tsd_get(void) \ +{ \ + \ + assert(a_name##tsd_booted); \ + return (&a_name##tsd_tls); \ +} \ +a_attr void \ +a_name##tsd_set(a_type *val) \ +{ \ + \ + assert(a_name##tsd_booted); \ + a_name##tsd_tls = (*val); \ + if (a_cleanup != malloc_tsd_no_cleanup) \ + a_name##tsd_initialized = true; \ +} +#elif (defined(JEMALLOC_TLS)) +#define malloc_tsd_funcs(a_attr, a_name, a_type, a_initializer, \ + a_cleanup) \ +/* Initialization/cleanup. */ \ +a_attr bool \ +a_name##tsd_boot0(void) \ +{ \ + \ + if (a_cleanup != malloc_tsd_no_cleanup) { \ + if (pthread_key_create(&a_name##tsd_tsd, a_cleanup) != \ + 0) \ + return (true); \ + } \ + a_name##tsd_booted = true; \ + return (false); \ +} \ +a_attr void \ +a_name##tsd_boot1(void) \ +{ \ + \ + /* Do nothing. */ \ +} \ +a_attr bool \ +a_name##tsd_boot(void) \ +{ \ + \ + return (a_name##tsd_boot0()); \ +} \ +/* Get/set. */ \ +a_attr a_type * \ +a_name##tsd_get(void) \ +{ \ + \ + assert(a_name##tsd_booted); \ + return (&a_name##tsd_tls); \ +} \ +a_attr void \ +a_name##tsd_set(a_type *val) \ +{ \ + \ + assert(a_name##tsd_booted); \ + a_name##tsd_tls = (*val); \ + if (a_cleanup != malloc_tsd_no_cleanup) { \ + if (pthread_setspecific(a_name##tsd_tsd, \ + (void *)(&a_name##tsd_tls))) { \ + malloc_write(": Error" \ + " setting TSD for "#a_name"\n"); \ + if (opt_abort) \ + abort(); \ + } \ + } \ +} +#elif (defined(_WIN32)) +#define malloc_tsd_funcs(a_attr, a_name, a_type, a_initializer, \ + a_cleanup) \ +/* Initialization/cleanup. */ \ +a_attr bool \ +a_name##tsd_cleanup_wrapper(void) \ +{ \ + DWORD error = GetLastError(); \ + a_name##tsd_wrapper_t *wrapper = (a_name##tsd_wrapper_t *) \ + TlsGetValue(a_name##tsd_tsd); \ + SetLastError(error); \ + \ + if (wrapper == NULL) \ + return (false); \ + if (a_cleanup != malloc_tsd_no_cleanup && \ + wrapper->initialized) { \ + wrapper->initialized = false; \ + a_cleanup(&wrapper->val); \ + if (wrapper->initialized) { \ + /* Trigger another cleanup round. */ \ + return (true); \ + } \ + } \ + malloc_tsd_dalloc(wrapper); \ + return (false); \ +} \ +a_attr void \ +a_name##tsd_wrapper_set(a_name##tsd_wrapper_t *wrapper) \ +{ \ + \ + if (!TlsSetValue(a_name##tsd_tsd, (void *)wrapper)) { \ + malloc_write(": Error setting" \ + " TSD for "#a_name"\n"); \ + abort(); \ + } \ +} \ +a_attr a_name##tsd_wrapper_t * \ +a_name##tsd_wrapper_get(void) \ +{ \ + DWORD error = GetLastError(); \ + a_name##tsd_wrapper_t *wrapper = (a_name##tsd_wrapper_t *) \ + TlsGetValue(a_name##tsd_tsd); \ + SetLastError(error); \ + \ + if (unlikely(wrapper == NULL)) { \ + wrapper = (a_name##tsd_wrapper_t *) \ + malloc_tsd_malloc(sizeof(a_name##tsd_wrapper_t)); \ + if (wrapper == NULL) { \ + malloc_write(": Error allocating" \ + " TSD for "#a_name"\n"); \ + abort(); \ + } else { \ + wrapper->initialized = false; \ + wrapper->val = a_initializer; \ + } \ + a_name##tsd_wrapper_set(wrapper); \ + } \ + return (wrapper); \ +} \ +a_attr bool \ +a_name##tsd_boot0(void) \ +{ \ + \ + a_name##tsd_tsd = TlsAlloc(); \ + if (a_name##tsd_tsd == TLS_OUT_OF_INDEXES) \ + return (true); \ + if (a_cleanup != malloc_tsd_no_cleanup) { \ + malloc_tsd_cleanup_register( \ + &a_name##tsd_cleanup_wrapper); \ + } \ + a_name##tsd_wrapper_set(&a_name##tsd_boot_wrapper); \ + a_name##tsd_booted = true; \ + return (false); \ +} \ +a_attr void \ +a_name##tsd_boot1(void) \ +{ \ + a_name##tsd_wrapper_t *wrapper; \ + wrapper = (a_name##tsd_wrapper_t *) \ + malloc_tsd_malloc(sizeof(a_name##tsd_wrapper_t)); \ + if (wrapper == NULL) { \ + malloc_write(": Error allocating" \ + " TSD for "#a_name"\n"); \ + abort(); \ + } \ + memcpy(wrapper, &a_name##tsd_boot_wrapper, \ + sizeof(a_name##tsd_wrapper_t)); \ + a_name##tsd_wrapper_set(wrapper); \ +} \ +a_attr bool \ +a_name##tsd_boot(void) \ +{ \ + \ + if (a_name##tsd_boot0()) \ + return (true); \ + a_name##tsd_boot1(); \ + return (false); \ +} \ +/* Get/set. */ \ +a_attr a_type * \ +a_name##tsd_get(void) \ +{ \ + a_name##tsd_wrapper_t *wrapper; \ + \ + assert(a_name##tsd_booted); \ + wrapper = a_name##tsd_wrapper_get(); \ + return (&wrapper->val); \ +} \ +a_attr void \ +a_name##tsd_set(a_type *val) \ +{ \ + a_name##tsd_wrapper_t *wrapper; \ + \ + assert(a_name##tsd_booted); \ + wrapper = a_name##tsd_wrapper_get(); \ + wrapper->val = *(val); \ + if (a_cleanup != malloc_tsd_no_cleanup) \ + wrapper->initialized = true; \ +} +#else +#define malloc_tsd_funcs(a_attr, a_name, a_type, a_initializer, \ + a_cleanup) \ +/* Initialization/cleanup. */ \ +a_attr void \ +a_name##tsd_cleanup_wrapper(void *arg) \ +{ \ + a_name##tsd_wrapper_t *wrapper = (a_name##tsd_wrapper_t *)arg; \ + \ + if (a_cleanup != malloc_tsd_no_cleanup && \ + wrapper->initialized) { \ + wrapper->initialized = false; \ + a_cleanup(&wrapper->val); \ + if (wrapper->initialized) { \ + /* Trigger another cleanup round. */ \ + if (pthread_setspecific(a_name##tsd_tsd, \ + (void *)wrapper)) { \ + malloc_write(": Error" \ + " setting TSD for "#a_name"\n"); \ + if (opt_abort) \ + abort(); \ + } \ + return; \ + } \ + } \ + malloc_tsd_dalloc(wrapper); \ +} \ +a_attr void \ +a_name##tsd_wrapper_set(a_name##tsd_wrapper_t *wrapper) \ +{ \ + \ + if (pthread_setspecific(a_name##tsd_tsd, \ + (void *)wrapper)) { \ + malloc_write(": Error setting" \ + " TSD for "#a_name"\n"); \ + abort(); \ + } \ +} \ +a_attr a_name##tsd_wrapper_t * \ +a_name##tsd_wrapper_get(void) \ +{ \ + a_name##tsd_wrapper_t *wrapper = (a_name##tsd_wrapper_t *) \ + pthread_getspecific(a_name##tsd_tsd); \ + \ + if (unlikely(wrapper == NULL)) { \ + tsd_init_block_t block; \ + wrapper = tsd_init_check_recursion( \ + &a_name##tsd_init_head, &block); \ + if (wrapper) \ + return (wrapper); \ + wrapper = (a_name##tsd_wrapper_t *) \ + malloc_tsd_malloc(sizeof(a_name##tsd_wrapper_t)); \ + block.data = wrapper; \ + if (wrapper == NULL) { \ + malloc_write(": Error allocating" \ + " TSD for "#a_name"\n"); \ + abort(); \ + } else { \ + wrapper->initialized = false; \ + wrapper->val = a_initializer; \ + } \ + a_name##tsd_wrapper_set(wrapper); \ + tsd_init_finish(&a_name##tsd_init_head, &block); \ + } \ + return (wrapper); \ +} \ +a_attr bool \ +a_name##tsd_boot0(void) \ +{ \ + \ + if (pthread_key_create(&a_name##tsd_tsd, \ + a_name##tsd_cleanup_wrapper) != 0) \ + return (true); \ + a_name##tsd_wrapper_set(&a_name##tsd_boot_wrapper); \ + a_name##tsd_booted = true; \ + return (false); \ +} \ +a_attr void \ +a_name##tsd_boot1(void) \ +{ \ + a_name##tsd_wrapper_t *wrapper; \ + wrapper = (a_name##tsd_wrapper_t *) \ + malloc_tsd_malloc(sizeof(a_name##tsd_wrapper_t)); \ + if (wrapper == NULL) { \ + malloc_write(": Error allocating" \ + " TSD for "#a_name"\n"); \ + abort(); \ + } \ + memcpy(wrapper, &a_name##tsd_boot_wrapper, \ + sizeof(a_name##tsd_wrapper_t)); \ + a_name##tsd_wrapper_set(wrapper); \ +} \ +a_attr bool \ +a_name##tsd_boot(void) \ +{ \ + \ + if (a_name##tsd_boot0()) \ + return (true); \ + a_name##tsd_boot1(); \ + return (false); \ +} \ +/* Get/set. */ \ +a_attr a_type * \ +a_name##tsd_get(void) \ +{ \ + a_name##tsd_wrapper_t *wrapper; \ + \ + assert(a_name##tsd_booted); \ + wrapper = a_name##tsd_wrapper_get(); \ + return (&wrapper->val); \ +} \ +a_attr void \ +a_name##tsd_set(a_type *val) \ +{ \ + a_name##tsd_wrapper_t *wrapper; \ + \ + assert(a_name##tsd_booted); \ + wrapper = a_name##tsd_wrapper_get(); \ + wrapper->val = *(val); \ + if (a_cleanup != malloc_tsd_no_cleanup) \ + wrapper->initialized = true; \ +} +#endif + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +#if (!defined(JEMALLOC_MALLOC_THREAD_CLEANUP) && !defined(JEMALLOC_TLS) && \ + !defined(_WIN32)) +struct tsd_init_block_s { + ql_elm(tsd_init_block_t) link; + pthread_t thread; + void *data; +}; +struct tsd_init_head_s { + ql_head(tsd_init_block_t) blocks; + malloc_mutex_t lock; +}; +#endif + +#define MALLOC_TSD \ +/* O(name, type) */ \ + O(tcache, tcache_t *) \ + O(thread_allocated, uint64_t) \ + O(thread_deallocated, uint64_t) \ + O(prof_tdata, prof_tdata_t *) \ + O(arena, arena_t *) \ + O(arenas_cache, arena_t **) \ + O(narenas_cache, unsigned) \ + O(arenas_cache_bypass, bool) \ + O(tcache_enabled, tcache_enabled_t) \ + O(quarantine, quarantine_t *) \ + +#define TSD_INITIALIZER { \ + tsd_state_uninitialized, \ + NULL, \ + 0, \ + 0, \ + NULL, \ + NULL, \ + NULL, \ + 0, \ + false, \ + tcache_enabled_default, \ + NULL \ +} + +struct tsd_s { + tsd_state_t state; +#define O(n, t) \ + t n; +MALLOC_TSD +#undef O +}; + +static const tsd_t tsd_initializer = TSD_INITIALIZER; + +malloc_tsd_types(, tsd_t) + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +void *malloc_tsd_malloc(size_t size); +void malloc_tsd_dalloc(void *wrapper); +void malloc_tsd_no_cleanup(void *arg); +void malloc_tsd_cleanup_register(bool (*f)(void)); +bool malloc_tsd_boot0(void); +void malloc_tsd_boot1(void); +#if (!defined(JEMALLOC_MALLOC_THREAD_CLEANUP) && !defined(JEMALLOC_TLS) && \ + !defined(_WIN32)) +void *tsd_init_check_recursion(tsd_init_head_t *head, + tsd_init_block_t *block); +void tsd_init_finish(tsd_init_head_t *head, tsd_init_block_t *block); +#endif +void tsd_cleanup(void *arg); + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#ifndef JEMALLOC_ENABLE_INLINE +malloc_tsd_protos(JEMALLOC_ATTR(unused), , tsd_t) + +tsd_t *tsd_fetch(void); +bool tsd_nominal(tsd_t *tsd); +#define O(n, t) \ +t *tsd_##n##p_get(tsd_t *tsd); \ +t tsd_##n##_get(tsd_t *tsd); \ +void tsd_##n##_set(tsd_t *tsd, t n); +MALLOC_TSD +#undef O +#endif + +#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_TSD_C_)) +malloc_tsd_externs(, tsd_t) +malloc_tsd_funcs(JEMALLOC_ALWAYS_INLINE, , tsd_t, tsd_initializer, tsd_cleanup) + +JEMALLOC_ALWAYS_INLINE tsd_t * +tsd_fetch(void) +{ + tsd_t *tsd = tsd_get(); + + if (unlikely(tsd->state != tsd_state_nominal)) { + if (tsd->state == tsd_state_uninitialized) { + tsd->state = tsd_state_nominal; + /* Trigger cleanup handler registration. */ + tsd_set(tsd); + } else if (tsd->state == tsd_state_purgatory) { + tsd->state = tsd_state_reincarnated; + tsd_set(tsd); + } else + assert(tsd->state == tsd_state_reincarnated); + } + + return (tsd); +} + +JEMALLOC_INLINE bool +tsd_nominal(tsd_t *tsd) +{ + + return (tsd->state == tsd_state_nominal); +} + +#define O(n, t) \ +JEMALLOC_ALWAYS_INLINE t * \ +tsd_##n##p_get(tsd_t *tsd) \ +{ \ + \ + return (&tsd->n); \ +} \ + \ +JEMALLOC_ALWAYS_INLINE t \ +tsd_##n##_get(tsd_t *tsd) \ +{ \ + \ + return (*tsd_##n##p_get(tsd)); \ +} \ + \ +JEMALLOC_ALWAYS_INLINE void \ +tsd_##n##_set(tsd_t *tsd, t n) \ +{ \ + \ + assert(tsd->state == tsd_state_nominal); \ + tsd->n = n; \ +} +MALLOC_TSD +#undef O +#endif + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/util.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/util.h new file mode 100644 index 0000000..b2ea740 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/util.h @@ -0,0 +1,314 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +#ifdef _WIN32 +# ifdef _WIN64 +# define FMT64_PREFIX "ll" +# define FMTPTR_PREFIX "ll" +# else +# define FMT64_PREFIX "ll" +# define FMTPTR_PREFIX "" +# endif +# define FMTd32 "d" +# define FMTu32 "u" +# define FMTx32 "x" +# define FMTd64 FMT64_PREFIX "d" +# define FMTu64 FMT64_PREFIX "u" +# define FMTx64 FMT64_PREFIX "x" +# define FMTdPTR FMTPTR_PREFIX "d" +# define FMTuPTR FMTPTR_PREFIX "u" +# define FMTxPTR FMTPTR_PREFIX "x" +#else +# include +# define FMTd32 PRId32 +# define FMTu32 PRIu32 +# define FMTx32 PRIx32 +# define FMTd64 PRId64 +# define FMTu64 PRIu64 +# define FMTx64 PRIx64 +# define FMTdPTR PRIdPTR +# define FMTuPTR PRIuPTR +# define FMTxPTR PRIxPTR +#endif + +/* Size of stack-allocated buffer passed to buferror(). */ +#define BUFERROR_BUF 64 + +/* + * Size of stack-allocated buffer used by malloc_{,v,vc}printf(). This must be + * large enough for all possible uses within jemalloc. + */ +#define MALLOC_PRINTF_BUFSIZE 4096 + +/* + * Wrap a cpp argument that contains commas such that it isn't broken up into + * multiple arguments. + */ +#define JEMALLOC_ARG_CONCAT(...) __VA_ARGS__ + +/* + * Silence compiler warnings due to uninitialized values. This is used + * wherever the compiler fails to recognize that the variable is never used + * uninitialized. + */ +#ifdef JEMALLOC_CC_SILENCE +# define JEMALLOC_CC_SILENCE_INIT(v) = v +#else +# define JEMALLOC_CC_SILENCE_INIT(v) +#endif + +#define JEMALLOC_GNUC_PREREQ(major, minor) \ + (!defined(__clang__) && \ + (__GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)))) +#ifndef __has_builtin +# define __has_builtin(builtin) (0) +#endif +#define JEMALLOC_CLANG_HAS_BUILTIN(builtin) \ + (defined(__clang__) && __has_builtin(builtin)) + +#ifdef __GNUC__ +# define likely(x) __builtin_expect(!!(x), 1) +# define unlikely(x) __builtin_expect(!!(x), 0) +# if JEMALLOC_GNUC_PREREQ(4, 6) || \ + JEMALLOC_CLANG_HAS_BUILTIN(__builtin_unreachable) +# define unreachable() __builtin_unreachable() +# else +# define unreachable() +# endif +#else +# define likely(x) !!(x) +# define unlikely(x) !!(x) +# define unreachable() +#endif + +/* + * Define a custom assert() in order to reduce the chances of deadlock during + * assertion failure. + */ +#ifndef assert +#define assert(e) do { \ + if (unlikely(config_debug && !(e))) { \ + malloc_printf( \ + ": %s:%d: Failed assertion: \"%s\"\n", \ + __FILE__, __LINE__, #e); \ + abort(); \ + } \ +} while (0) +#endif + +#ifndef not_reached +#define not_reached() do { \ + if (config_debug) { \ + malloc_printf( \ + ": %s:%d: Unreachable code reached\n", \ + __FILE__, __LINE__); \ + abort(); \ + } \ + unreachable(); \ +} while (0) +#endif + +#ifndef not_implemented +#define not_implemented() do { \ + if (config_debug) { \ + malloc_printf(": %s:%d: Not implemented\n", \ + __FILE__, __LINE__); \ + abort(); \ + } \ +} while (0) +#endif + +#ifndef assert_not_implemented +#define assert_not_implemented(e) do { \ + if (unlikely(config_debug && !(e))) \ + not_implemented(); \ +} while (0) +#endif + +/* Use to assert a particular configuration, e.g., cassert(config_debug). */ +#define cassert(c) do { \ + if (unlikely(!(c))) \ + not_reached(); \ +} while (0) + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +int buferror(int err, char *buf, size_t buflen); +uintmax_t malloc_strtoumax(const char *restrict nptr, + char **restrict endptr, int base); +void malloc_write(const char *s); + +/* + * malloc_vsnprintf() supports a subset of snprintf(3) that avoids floating + * point math. + */ +int malloc_vsnprintf(char *str, size_t size, const char *format, + va_list ap); +int malloc_snprintf(char *str, size_t size, const char *format, ...) + JEMALLOC_FORMAT_PRINTF(3, 4); +void malloc_vcprintf(void (*write_cb)(void *, const char *), void *cbopaque, + const char *format, va_list ap); +void malloc_cprintf(void (*write)(void *, const char *), void *cbopaque, + const char *format, ...) JEMALLOC_FORMAT_PRINTF(3, 4); +void malloc_printf(const char *format, ...) JEMALLOC_FORMAT_PRINTF(1, 2); + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#ifndef JEMALLOC_ENABLE_INLINE +int jemalloc_ffsl(long bitmap); +int jemalloc_ffs(int bitmap); +size_t pow2_ceil(size_t x); +size_t lg_floor(size_t x); +void set_errno(int errnum); +int get_errno(void); +#endif + +#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_UTIL_C_)) + +/* Sanity check. */ +#if !defined(JEMALLOC_INTERNAL_FFSL) || !defined(JEMALLOC_INTERNAL_FFS) +# error Both JEMALLOC_INTERNAL_FFSL && JEMALLOC_INTERNAL_FFS should have been defined by configure +#endif + +JEMALLOC_ALWAYS_INLINE int +jemalloc_ffsl(long bitmap) +{ + + return (JEMALLOC_INTERNAL_FFSL(bitmap)); +} + +JEMALLOC_ALWAYS_INLINE int +jemalloc_ffs(int bitmap) +{ + + return (JEMALLOC_INTERNAL_FFS(bitmap)); +} + +/* Compute the smallest power of 2 that is >= x. */ +JEMALLOC_INLINE size_t +pow2_ceil(size_t x) +{ + + x--; + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; +#if (LG_SIZEOF_PTR == 3) + x |= x >> 32; +#endif + x++; + return (x); +} + +#if (defined(__i386__) || defined(__amd64__) || defined(__x86_64__)) +JEMALLOC_INLINE size_t +lg_floor(size_t x) +{ + size_t ret; + + assert(x != 0); + + asm ("bsr %1, %0" + : "=r"(ret) // Outputs. + : "r"(x) // Inputs. + ); + return (ret); +} +#elif (defined(_MSC_VER)) +JEMALLOC_INLINE size_t +lg_floor(size_t x) +{ + unsigned long ret; + + assert(x != 0); + +#if (LG_SIZEOF_PTR == 3) + _BitScanReverse64(&ret, x); +#elif (LG_SIZEOF_PTR == 2) + _BitScanReverse(&ret, x); +#else +# error "Unsupported type sizes for lg_floor()" +#endif + return (ret); +} +#elif (defined(JEMALLOC_HAVE_BUILTIN_CLZ)) +JEMALLOC_INLINE size_t +lg_floor(size_t x) +{ + + assert(x != 0); + +#if (LG_SIZEOF_PTR == LG_SIZEOF_INT) + return (((8 << LG_SIZEOF_PTR) - 1) - __builtin_clz(x)); +#elif (LG_SIZEOF_PTR == LG_SIZEOF_LONG) + return (((8 << LG_SIZEOF_PTR) - 1) - __builtin_clzl(x)); +#else +# error "Unsupported type sizes for lg_floor()" +#endif +} +#else +JEMALLOC_INLINE size_t +lg_floor(size_t x) +{ + + assert(x != 0); + + x |= (x >> 1); + x |= (x >> 2); + x |= (x >> 4); + x |= (x >> 8); + x |= (x >> 16); +#if (LG_SIZEOF_PTR == 3 && LG_SIZEOF_PTR == LG_SIZEOF_LONG) + x |= (x >> 32); + if (x == KZU(0xffffffffffffffff)) + return (63); + x++; + return (jemalloc_ffsl(x) - 2); +#elif (LG_SIZEOF_PTR == 2) + if (x == KZU(0xffffffff)) + return (31); + x++; + return (jemalloc_ffs(x) - 2); +#else +# error "Unsupported type sizes for lg_floor()" +#endif +} +#endif + +/* Set error code. */ +JEMALLOC_INLINE void +set_errno(int errnum) +{ + +#ifdef _WIN32 + SetLastError(errnum); +#else + errno = errnum; +#endif +} + +/* Get last error code. */ +JEMALLOC_INLINE int +get_errno(void) +{ + +#ifdef _WIN32 + return (GetLastError()); +#else + return (errno); +#endif +} +#endif + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/valgrind.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/valgrind.h new file mode 100644 index 0000000..a3380df --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/internal/valgrind.h @@ -0,0 +1,112 @@ +/******************************************************************************/ +#ifdef JEMALLOC_H_TYPES + +#ifdef JEMALLOC_VALGRIND +#include + +/* + * The size that is reported to Valgrind must be consistent through a chain of + * malloc..realloc..realloc calls. Request size isn't recorded anywhere in + * jemalloc, so it is critical that all callers of these macros provide usize + * rather than request size. As a result, buffer overflow detection is + * technically weakened for the standard API, though it is generally accepted + * practice to consider any extra bytes reported by malloc_usable_size() as + * usable space. + */ +#define JEMALLOC_VALGRIND_MAKE_MEM_NOACCESS(ptr, usize) do { \ + if (unlikely(in_valgrind)) \ + valgrind_make_mem_noaccess(ptr, usize); \ +} while (0) +#define JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(ptr, usize) do { \ + if (unlikely(in_valgrind)) \ + valgrind_make_mem_undefined(ptr, usize); \ +} while (0) +#define JEMALLOC_VALGRIND_MAKE_MEM_DEFINED(ptr, usize) do { \ + if (unlikely(in_valgrind)) \ + valgrind_make_mem_defined(ptr, usize); \ +} while (0) +/* + * The VALGRIND_MALLOCLIKE_BLOCK() and VALGRIND_RESIZEINPLACE_BLOCK() macro + * calls must be embedded in macros rather than in functions so that when + * Valgrind reports errors, there are no extra stack frames in the backtraces. + */ +#define JEMALLOC_VALGRIND_MALLOC(cond, ptr, usize, zero) do { \ + if (unlikely(in_valgrind && cond)) \ + VALGRIND_MALLOCLIKE_BLOCK(ptr, usize, p2rz(ptr), zero); \ +} while (0) +#define JEMALLOC_VALGRIND_REALLOC(maybe_moved, ptr, usize, \ + ptr_maybe_null, old_ptr, old_usize, old_rzsize, old_ptr_maybe_null, \ + zero) do { \ + if (unlikely(in_valgrind)) { \ + size_t rzsize = p2rz(ptr); \ + \ + if (!maybe_moved || ptr == old_ptr) { \ + VALGRIND_RESIZEINPLACE_BLOCK(ptr, old_usize, \ + usize, rzsize); \ + if (zero && old_usize < usize) { \ + valgrind_make_mem_defined( \ + (void *)((uintptr_t)ptr + \ + old_usize), usize - old_usize); \ + } \ + } else { \ + if (!old_ptr_maybe_null || old_ptr != NULL) { \ + valgrind_freelike_block(old_ptr, \ + old_rzsize); \ + } \ + if (!ptr_maybe_null || ptr != NULL) { \ + size_t copy_size = (old_usize < usize) \ + ? old_usize : usize; \ + size_t tail_size = usize - copy_size; \ + VALGRIND_MALLOCLIKE_BLOCK(ptr, usize, \ + rzsize, false); \ + if (copy_size > 0) { \ + valgrind_make_mem_defined(ptr, \ + copy_size); \ + } \ + if (zero && tail_size > 0) { \ + valgrind_make_mem_defined( \ + (void *)((uintptr_t)ptr + \ + copy_size), tail_size); \ + } \ + } \ + } \ + } \ +} while (0) +#define JEMALLOC_VALGRIND_FREE(ptr, rzsize) do { \ + if (unlikely(in_valgrind)) \ + valgrind_freelike_block(ptr, rzsize); \ +} while (0) +#else +#define RUNNING_ON_VALGRIND ((unsigned)0) +#define JEMALLOC_VALGRIND_MAKE_MEM_NOACCESS(ptr, usize) do {} while (0) +#define JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(ptr, usize) do {} while (0) +#define JEMALLOC_VALGRIND_MAKE_MEM_DEFINED(ptr, usize) do {} while (0) +#define JEMALLOC_VALGRIND_MALLOC(cond, ptr, usize, zero) do {} while (0) +#define JEMALLOC_VALGRIND_REALLOC(maybe_moved, ptr, usize, \ + ptr_maybe_null, old_ptr, old_usize, old_rzsize, old_ptr_maybe_null, \ + zero) do {} while (0) +#define JEMALLOC_VALGRIND_FREE(ptr, rzsize) do {} while (0) +#endif + +#endif /* JEMALLOC_H_TYPES */ +/******************************************************************************/ +#ifdef JEMALLOC_H_STRUCTS + +#endif /* JEMALLOC_H_STRUCTS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_EXTERNS + +#ifdef JEMALLOC_VALGRIND +void valgrind_make_mem_noaccess(void *ptr, size_t usize); +void valgrind_make_mem_undefined(void *ptr, size_t usize); +void valgrind_make_mem_defined(void *ptr, size_t usize); +void valgrind_freelike_block(void *ptr, size_t usize); +#endif + +#endif /* JEMALLOC_H_EXTERNS */ +/******************************************************************************/ +#ifdef JEMALLOC_H_INLINES + +#endif /* JEMALLOC_H_INLINES */ +/******************************************************************************/ + diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/jemalloc.sh b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/jemalloc.sh new file mode 100755 index 0000000..c085814 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/jemalloc.sh @@ -0,0 +1,28 @@ +#!/bin/sh + +objroot=$1 + +cat < +#include +#include +#include +#include + +#define JEMALLOC_VERSION "@jemalloc_version@" +#define JEMALLOC_VERSION_MAJOR @jemalloc_version_major@ +#define JEMALLOC_VERSION_MINOR @jemalloc_version_minor@ +#define JEMALLOC_VERSION_BUGFIX @jemalloc_version_bugfix@ +#define JEMALLOC_VERSION_NREV @jemalloc_version_nrev@ +#define JEMALLOC_VERSION_GID "@jemalloc_version_gid@" + +# define MALLOCX_LG_ALIGN(la) (la) +# if LG_SIZEOF_PTR == 2 +# define MALLOCX_ALIGN(a) (ffs(a)-1) +# else +# define MALLOCX_ALIGN(a) \ + ((a < (size_t)INT_MAX) ? ffs(a)-1 : ffs(a>>32)+31) +# endif +# define MALLOCX_ZERO ((int)0x40) +/* + * Bias tcache index bits so that 0 encodes "automatic tcache management", and 1 + * encodes MALLOCX_TCACHE_NONE. + */ +# define MALLOCX_TCACHE(tc) ((int)(((tc)+2) << 8)) +# define MALLOCX_TCACHE_NONE MALLOCX_TCACHE(-1) +/* + * Bias arena index bits so that 0 encodes "use an automatically chosen arena". + */ +# define MALLOCX_ARENA(a) ((int)(((a)+1) << 20)) + +#if defined(__cplusplus) && defined(JEMALLOC_USE_CXX_THROW) +# define JEMALLOC_CXX_THROW throw() +#else +# define JEMALLOC_CXX_THROW +#endif + +#ifdef JEMALLOC_HAVE_ATTR +# define JEMALLOC_ATTR(s) __attribute__((s)) +# define JEMALLOC_ALIGNED(s) JEMALLOC_ATTR(aligned(s)) +# ifdef JEMALLOC_HAVE_ATTR_ALLOC_SIZE +# define JEMALLOC_ALLOC_SIZE(s) JEMALLOC_ATTR(alloc_size(s)) +# define JEMALLOC_ALLOC_SIZE2(s1, s2) JEMALLOC_ATTR(alloc_size(s1, s2)) +# else +# define JEMALLOC_ALLOC_SIZE(s) +# define JEMALLOC_ALLOC_SIZE2(s1, s2) +# endif +# ifndef JEMALLOC_EXPORT +# define JEMALLOC_EXPORT JEMALLOC_ATTR(visibility("default")) +# endif +# ifdef JEMALLOC_HAVE_ATTR_FORMAT_GNU_PRINTF +# define JEMALLOC_FORMAT_PRINTF(s, i) JEMALLOC_ATTR(format(gnu_printf, s, i)) +# elif defined(JEMALLOC_HAVE_ATTR_FORMAT_PRINTF) +# define JEMALLOC_FORMAT_PRINTF(s, i) JEMALLOC_ATTR(format(printf, s, i)) +# else +# define JEMALLOC_FORMAT_PRINTF(s, i) +# endif +# define JEMALLOC_NOINLINE JEMALLOC_ATTR(noinline) +# define JEMALLOC_NOTHROW JEMALLOC_ATTR(nothrow) +# define JEMALLOC_SECTION(s) JEMALLOC_ATTR(section(s)) +# define JEMALLOC_RESTRICT_RETURN +# define JEMALLOC_ALLOCATOR +#elif _MSC_VER +# define JEMALLOC_ATTR(s) +# define JEMALLOC_ALIGNED(s) __declspec(align(s)) +# define JEMALLOC_ALLOC_SIZE(s) +# define JEMALLOC_ALLOC_SIZE2(s1, s2) +# ifndef JEMALLOC_EXPORT +# ifdef DLLEXPORT +# define JEMALLOC_EXPORT __declspec(dllexport) +# else +# define JEMALLOC_EXPORT __declspec(dllimport) +# endif +# endif +# define JEMALLOC_FORMAT_PRINTF(s, i) +# define JEMALLOC_NOINLINE __declspec(noinline) +# ifdef __cplusplus +# define JEMALLOC_NOTHROW __declspec(nothrow) +# else +# define JEMALLOC_NOTHROW +# endif +# define JEMALLOC_SECTION(s) __declspec(allocate(s)) +# define JEMALLOC_RESTRICT_RETURN __declspec(restrict) +# if _MSC_VER >= 1900 && !defined(__EDG__) +# define JEMALLOC_ALLOCATOR __declspec(allocator) +# else +# define JEMALLOC_ALLOCATOR +# endif +#else +# define JEMALLOC_ATTR(s) +# define JEMALLOC_ALIGNED(s) +# define JEMALLOC_ALLOC_SIZE(s) +# define JEMALLOC_ALLOC_SIZE2(s1, s2) +# define JEMALLOC_EXPORT +# define JEMALLOC_FORMAT_PRINTF(s, i) +# define JEMALLOC_NOINLINE +# define JEMALLOC_NOTHROW +# define JEMALLOC_SECTION(s) +# define JEMALLOC_RESTRICT_RETURN +# define JEMALLOC_ALLOCATOR +#endif + +/* This version of Jemalloc, modified for Redis, has the je_get_defrag_hint() + * function. */ +#define JEMALLOC_FRAG_HINT diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/jemalloc_mangle.sh b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/jemalloc_mangle.sh new file mode 100755 index 0000000..df328b7 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/jemalloc/jemalloc_mangle.sh @@ -0,0 +1,45 @@ +#!/bin/sh + +public_symbols_txt=$1 +symbol_prefix=$2 + +cat < + +/* MSVC doesn't define _Bool or bool in C, but does have BOOL */ +/* Note this doesn't pass autoconf's test because (bool) 0.5 != true */ +/* Clang-cl uses MSVC headers, so needs msvc_compat, but has _Bool as + * a built-in type. */ +#ifndef __clang__ +typedef BOOL _Bool; +#endif + +#define bool _Bool +#define true 1 +#define false 0 + +#define __bool_true_false_are_defined 1 + +#endif /* stdbool_h */ diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/msvc_compat/C99/stdint.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/msvc_compat/C99/stdint.h new file mode 100644 index 0000000..d02608a --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/msvc_compat/C99/stdint.h @@ -0,0 +1,247 @@ +// ISO C9x compliant stdint.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006-2008 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. The name of the author may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_STDINT_H_ // [ +#define _MSC_STDINT_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#include + +// For Visual Studio 6 in C++ mode and for many Visual Studio versions when +// compiling for ARM we should wrap include with 'extern "C++" {}' +// or compiler give many errors like this: +// error C2733: second C linkage of overloaded function 'wmemchr' not allowed +#ifdef __cplusplus +extern "C" { +#endif +# include +#ifdef __cplusplus +} +#endif + +// Define _W64 macros to mark types changing their size, like intptr_t. +#ifndef _W64 +# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 +# define _W64 __w64 +# else +# define _W64 +# endif +#endif + + +// 7.18.1 Integer types + +// 7.18.1.1 Exact-width integer types + +// Visual Studio 6 and Embedded Visual C++ 4 doesn't +// realize that, e.g. char has the same size as __int8 +// so we give up on __intX for them. +#if (_MSC_VER < 1300) + typedef signed char int8_t; + typedef signed short int16_t; + typedef signed int int32_t; + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; +#else + typedef signed __int8 int8_t; + typedef signed __int16 int16_t; + typedef signed __int32 int32_t; + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; +#endif +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; + + +// 7.18.1.2 Minimum-width integer types +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +typedef int64_t int_least64_t; +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +typedef uint64_t uint_least64_t; + +// 7.18.1.3 Fastest minimum-width integer types +typedef int8_t int_fast8_t; +typedef int16_t int_fast16_t; +typedef int32_t int_fast32_t; +typedef int64_t int_fast64_t; +typedef uint8_t uint_fast8_t; +typedef uint16_t uint_fast16_t; +typedef uint32_t uint_fast32_t; +typedef uint64_t uint_fast64_t; + +// 7.18.1.4 Integer types capable of holding object pointers +#ifdef _WIN64 // [ + typedef signed __int64 intptr_t; + typedef unsigned __int64 uintptr_t; +#else // _WIN64 ][ + typedef _W64 signed int intptr_t; + typedef _W64 unsigned int uintptr_t; +#endif // _WIN64 ] + +// 7.18.1.5 Greatest-width integer types +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; + + +// 7.18.2 Limits of specified-width integer types + +#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 + +// 7.18.2.1 Limits of exact-width integer types +#define INT8_MIN ((int8_t)_I8_MIN) +#define INT8_MAX _I8_MAX +#define INT16_MIN ((int16_t)_I16_MIN) +#define INT16_MAX _I16_MAX +#define INT32_MIN ((int32_t)_I32_MIN) +#define INT32_MAX _I32_MAX +#define INT64_MIN ((int64_t)_I64_MIN) +#define INT64_MAX _I64_MAX +#define UINT8_MAX _UI8_MAX +#define UINT16_MAX _UI16_MAX +#define UINT32_MAX _UI32_MAX +#define UINT64_MAX _UI64_MAX + +// 7.18.2.2 Limits of minimum-width integer types +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MIN INT64_MIN +#define INT_LEAST64_MAX INT64_MAX +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +// 7.18.2.3 Limits of fastest minimum-width integer types +#define INT_FAST8_MIN INT8_MIN +#define INT_FAST8_MAX INT8_MAX +#define INT_FAST16_MIN INT16_MIN +#define INT_FAST16_MAX INT16_MAX +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST32_MAX INT32_MAX +#define INT_FAST64_MIN INT64_MIN +#define INT_FAST64_MAX INT64_MAX +#define UINT_FAST8_MAX UINT8_MAX +#define UINT_FAST16_MAX UINT16_MAX +#define UINT_FAST32_MAX UINT32_MAX +#define UINT_FAST64_MAX UINT64_MAX + +// 7.18.2.4 Limits of integer types capable of holding object pointers +#ifdef _WIN64 // [ +# define INTPTR_MIN INT64_MIN +# define INTPTR_MAX INT64_MAX +# define UINTPTR_MAX UINT64_MAX +#else // _WIN64 ][ +# define INTPTR_MIN INT32_MIN +# define INTPTR_MAX INT32_MAX +# define UINTPTR_MAX UINT32_MAX +#endif // _WIN64 ] + +// 7.18.2.5 Limits of greatest-width integer types +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +// 7.18.3 Limits of other integer types + +#ifdef _WIN64 // [ +# define PTRDIFF_MIN _I64_MIN +# define PTRDIFF_MAX _I64_MAX +#else // _WIN64 ][ +# define PTRDIFF_MIN _I32_MIN +# define PTRDIFF_MAX _I32_MAX +#endif // _WIN64 ] + +#define SIG_ATOMIC_MIN INT_MIN +#define SIG_ATOMIC_MAX INT_MAX + +#ifndef SIZE_MAX // [ +# ifdef _WIN64 // [ +# define SIZE_MAX _UI64_MAX +# else // _WIN64 ][ +# define SIZE_MAX _UI32_MAX +# endif // _WIN64 ] +#endif // SIZE_MAX ] + +// WCHAR_MIN and WCHAR_MAX are also defined in +#ifndef WCHAR_MIN // [ +# define WCHAR_MIN 0 +#endif // WCHAR_MIN ] +#ifndef WCHAR_MAX // [ +# define WCHAR_MAX _UI16_MAX +#endif // WCHAR_MAX ] + +#define WINT_MIN 0 +#define WINT_MAX _UI16_MAX + +#endif // __STDC_LIMIT_MACROS ] + + +// 7.18.4 Limits of other integer types + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 + +// 7.18.4.1 Macros for minimum-width integer constants + +#define INT8_C(val) val##i8 +#define INT16_C(val) val##i16 +#define INT32_C(val) val##i32 +#define INT64_C(val) val##i64 + +#define UINT8_C(val) val##ui8 +#define UINT16_C(val) val##ui16 +#define UINT32_C(val) val##ui32 +#define UINT64_C(val) val##ui64 + +// 7.18.4.2 Macros for greatest-width integer constants +#define INTMAX_C INT64_C +#define UINTMAX_C UINT64_C + +#endif // __STDC_CONSTANT_MACROS ] + + +#endif // _MSC_STDINT_H_ ] diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/msvc_compat/strings.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/msvc_compat/strings.h new file mode 100644 index 0000000..f01ffdd --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/msvc_compat/strings.h @@ -0,0 +1,29 @@ +#ifndef strings_h +#define strings_h + +/* MSVC doesn't define ffs/ffsl. This dummy strings.h header is provided + * for both */ +#ifdef _MSC_VER +# include +# pragma intrinsic(_BitScanForward) +static __forceinline int ffsl(long x) +{ + unsigned long i; + + if (_BitScanForward(&i, x)) + return (i + 1); + return (0); +} + +static __forceinline int ffs(int x) +{ + + return (ffsl(x)); +} + +#else +# define ffsl(x) __builtin_ffsl(x) +# define ffs(x) __builtin_ffs(x) +#endif + +#endif /* strings_h */ diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/msvc_compat/windows_extra.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/msvc_compat/windows_extra.h new file mode 100644 index 0000000..0c5e323 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/include/msvc_compat/windows_extra.h @@ -0,0 +1,26 @@ +#ifndef MSVC_COMPAT_WINDOWS_EXTRA_H +#define MSVC_COMPAT_WINDOWS_EXTRA_H + +#ifndef ENOENT +# define ENOENT ERROR_PATH_NOT_FOUND +#endif +#ifndef EINVAL +# define EINVAL ERROR_BAD_ARGUMENTS +#endif +#ifndef EAGAIN +# define EAGAIN ERROR_OUTOFMEMORY +#endif +#ifndef EPERM +# define EPERM ERROR_WRITE_FAULT +#endif +#ifndef EFAULT +# define EFAULT ERROR_INVALID_ADDRESS +#endif +#ifndef ENOMEM +# define ENOMEM ERROR_NOT_ENOUGH_MEMORY +#endif +#ifndef ERANGE +# define ERANGE ERROR_INVALID_DATA +#endif + +#endif /* MSVC_COMPAT_WINDOWS_EXTRA_H */ diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/install-sh b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/install-sh new file mode 100755 index 0000000..ebc6691 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/install-sh @@ -0,0 +1,250 @@ +#! /bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/jemalloc.pc.in b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/jemalloc.pc.in new file mode 100644 index 0000000..1a3ad9b --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/jemalloc.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ +install_suffix=@install_suffix@ + +Name: jemalloc +Description: A general purpose malloc(3) implementation that emphasizes fragmentation avoidance and scalable concurrency support. +URL: http://www.canonware.com/jemalloc +Version: @jemalloc_version@ +Cflags: -I${includedir} +Libs: -L${libdir} -ljemalloc${install_suffix} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/arena.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/arena.c new file mode 100644 index 0000000..3081519 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/arena.c @@ -0,0 +1,3318 @@ +#define JEMALLOC_ARENA_C_ +#include "jemalloc/internal/jemalloc_internal.h" + +/******************************************************************************/ +/* Data. */ + +ssize_t opt_lg_dirty_mult = LG_DIRTY_MULT_DEFAULT; +static ssize_t lg_dirty_mult_default; +arena_bin_info_t arena_bin_info[NBINS]; + +size_t map_bias; +size_t map_misc_offset; +size_t arena_maxrun; /* Max run size for arenas. */ +size_t large_maxclass; /* Max large size class. */ +static size_t small_maxrun; /* Max run size used for small size classes. */ +static bool *small_run_tab; /* Valid small run page multiples. */ +unsigned nlclasses; /* Number of large size classes. */ +unsigned nhclasses; /* Number of huge size classes. */ + +/******************************************************************************/ +/* + * Function prototypes for static functions that are referenced prior to + * definition. + */ + +static void arena_purge(arena_t *arena, bool all); +static void arena_run_dalloc(arena_t *arena, arena_run_t *run, bool dirty, + bool cleaned, bool decommitted); +static void arena_dalloc_bin_run(arena_t *arena, arena_chunk_t *chunk, + arena_run_t *run, arena_bin_t *bin); +static void arena_bin_lower_run(arena_t *arena, arena_chunk_t *chunk, + arena_run_t *run, arena_bin_t *bin); + +/******************************************************************************/ + +#define CHUNK_MAP_KEY ((uintptr_t)0x1U) + +JEMALLOC_INLINE_C arena_chunk_map_misc_t * +arena_miscelm_key_create(size_t size) +{ + + return ((arena_chunk_map_misc_t *)(arena_mapbits_size_encode(size) | + CHUNK_MAP_KEY)); +} + +JEMALLOC_INLINE_C bool +arena_miscelm_is_key(const arena_chunk_map_misc_t *miscelm) +{ + + return (((uintptr_t)miscelm & CHUNK_MAP_KEY) != 0); +} + +#undef CHUNK_MAP_KEY + +JEMALLOC_INLINE_C size_t +arena_miscelm_key_size_get(const arena_chunk_map_misc_t *miscelm) +{ + + assert(arena_miscelm_is_key(miscelm)); + + return (arena_mapbits_size_decode((uintptr_t)miscelm)); +} + +JEMALLOC_INLINE_C size_t +arena_miscelm_size_get(arena_chunk_map_misc_t *miscelm) +{ + arena_chunk_t *chunk; + size_t pageind, mapbits; + + assert(!arena_miscelm_is_key(miscelm)); + + chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(miscelm); + pageind = arena_miscelm_to_pageind(miscelm); + mapbits = arena_mapbits_get(chunk, pageind); + return (arena_mapbits_size_decode(mapbits)); +} + +JEMALLOC_INLINE_C int +arena_run_comp(arena_chunk_map_misc_t *a, arena_chunk_map_misc_t *b) +{ + uintptr_t a_miscelm = (uintptr_t)a; + uintptr_t b_miscelm = (uintptr_t)b; + + assert(a != NULL); + assert(b != NULL); + + return ((a_miscelm > b_miscelm) - (a_miscelm < b_miscelm)); +} + +/* Generate red-black tree functions. */ +rb_gen(static UNUSED, arena_run_tree_, arena_run_tree_t, arena_chunk_map_misc_t, + rb_link, arena_run_comp) + +static size_t +run_quantize(size_t size) +{ + size_t qsize; + + assert(size != 0); + assert(size == PAGE_CEILING(size)); + + /* Don't change sizes that are valid small run sizes. */ + if (size <= small_maxrun && small_run_tab[size >> LG_PAGE]) + return (size); + + /* + * Round down to the nearest run size that can actually be requested + * during normal large allocation. Add large_pad so that cache index + * randomization can offset the allocation from the page boundary. + */ + qsize = index2size(size2index(size - large_pad + 1) - 1) + large_pad; + if (qsize <= SMALL_MAXCLASS + large_pad) + return (run_quantize(size - large_pad)); + assert(qsize <= size); + return (qsize); +} + +static size_t +run_quantize_next(size_t size) +{ + size_t large_run_size_next; + + assert(size != 0); + assert(size == PAGE_CEILING(size)); + + /* + * Return the next quantized size greater than the input size. + * Quantized sizes comprise the union of run sizes that back small + * region runs, and run sizes that back large regions with no explicit + * alignment constraints. + */ + + if (size > SMALL_MAXCLASS) { + large_run_size_next = PAGE_CEILING(index2size(size2index(size - + large_pad) + 1) + large_pad); + } else + large_run_size_next = SIZE_T_MAX; + if (size >= small_maxrun) + return (large_run_size_next); + + while (true) { + size += PAGE; + assert(size <= small_maxrun); + if (small_run_tab[size >> LG_PAGE]) { + if (large_run_size_next < size) + return (large_run_size_next); + return (size); + } + } +} + +static size_t +run_quantize_first(size_t size) +{ + size_t qsize = run_quantize(size); + + if (qsize < size) { + /* + * Skip a quantization that may have an adequately large run, + * because under-sized runs may be mixed in. This only happens + * when an unusual size is requested, i.e. for aligned + * allocation, and is just one of several places where linear + * search would potentially find sufficiently aligned available + * memory somewhere lower. + */ + qsize = run_quantize_next(size); + } + return (qsize); +} + +JEMALLOC_INLINE_C int +arena_avail_comp(arena_chunk_map_misc_t *a, arena_chunk_map_misc_t *b) +{ + int ret; + uintptr_t a_miscelm = (uintptr_t)a; + size_t a_qsize = run_quantize(arena_miscelm_is_key(a) ? + arena_miscelm_key_size_get(a) : arena_miscelm_size_get(a)); + size_t b_qsize = run_quantize(arena_miscelm_size_get(b)); + + /* + * Compare based on quantized size rather than size, in order to sort + * equally useful runs only by address. + */ + ret = (a_qsize > b_qsize) - (a_qsize < b_qsize); + if (ret == 0) { + if (!arena_miscelm_is_key(a)) { + uintptr_t b_miscelm = (uintptr_t)b; + + ret = (a_miscelm > b_miscelm) - (a_miscelm < b_miscelm); + } else { + /* + * Treat keys as if they are lower than anything else. + */ + ret = -1; + } + } + + return (ret); +} + +/* Generate red-black tree functions. */ +rb_gen(static UNUSED, arena_avail_tree_, arena_avail_tree_t, + arena_chunk_map_misc_t, rb_link, arena_avail_comp) + +static void +arena_avail_insert(arena_t *arena, arena_chunk_t *chunk, size_t pageind, + size_t npages) +{ + + assert(npages == (arena_mapbits_unallocated_size_get(chunk, pageind) >> + LG_PAGE)); + arena_avail_tree_insert(&arena->runs_avail, arena_miscelm_get(chunk, + pageind)); +} + +static void +arena_avail_remove(arena_t *arena, arena_chunk_t *chunk, size_t pageind, + size_t npages) +{ + + assert(npages == (arena_mapbits_unallocated_size_get(chunk, pageind) >> + LG_PAGE)); + arena_avail_tree_remove(&arena->runs_avail, arena_miscelm_get(chunk, + pageind)); +} + +static void +arena_run_dirty_insert(arena_t *arena, arena_chunk_t *chunk, size_t pageind, + size_t npages) +{ + arena_chunk_map_misc_t *miscelm = arena_miscelm_get(chunk, pageind); + + assert(npages == (arena_mapbits_unallocated_size_get(chunk, pageind) >> + LG_PAGE)); + assert(arena_mapbits_dirty_get(chunk, pageind) == CHUNK_MAP_DIRTY); + assert(arena_mapbits_dirty_get(chunk, pageind+npages-1) == + CHUNK_MAP_DIRTY); + + qr_new(&miscelm->rd, rd_link); + qr_meld(&arena->runs_dirty, &miscelm->rd, rd_link); + arena->ndirty += npages; +} + +static void +arena_run_dirty_remove(arena_t *arena, arena_chunk_t *chunk, size_t pageind, + size_t npages) +{ + arena_chunk_map_misc_t *miscelm = arena_miscelm_get(chunk, pageind); + + assert(npages == (arena_mapbits_unallocated_size_get(chunk, pageind) >> + LG_PAGE)); + assert(arena_mapbits_dirty_get(chunk, pageind) == CHUNK_MAP_DIRTY); + assert(arena_mapbits_dirty_get(chunk, pageind+npages-1) == + CHUNK_MAP_DIRTY); + + qr_remove(&miscelm->rd, rd_link); + assert(arena->ndirty >= npages); + arena->ndirty -= npages; +} + +static size_t +arena_chunk_dirty_npages(const extent_node_t *node) +{ + + return (extent_node_size_get(node) >> LG_PAGE); +} + +void +arena_chunk_cache_maybe_insert(arena_t *arena, extent_node_t *node, bool cache) +{ + + if (cache) { + extent_node_dirty_linkage_init(node); + extent_node_dirty_insert(node, &arena->runs_dirty, + &arena->chunks_cache); + arena->ndirty += arena_chunk_dirty_npages(node); + } +} + +void +arena_chunk_cache_maybe_remove(arena_t *arena, extent_node_t *node, bool dirty) +{ + + if (dirty) { + extent_node_dirty_remove(node); + assert(arena->ndirty >= arena_chunk_dirty_npages(node)); + arena->ndirty -= arena_chunk_dirty_npages(node); + } +} + +JEMALLOC_INLINE_C void * +arena_run_reg_alloc(arena_run_t *run, arena_bin_info_t *bin_info) +{ + void *ret; + unsigned regind; + arena_chunk_map_misc_t *miscelm; + void *rpages; + + assert(run->nfree > 0); + assert(!bitmap_full(run->bitmap, &bin_info->bitmap_info)); + + regind = bitmap_sfu(run->bitmap, &bin_info->bitmap_info); + miscelm = arena_run_to_miscelm(run); + rpages = arena_miscelm_to_rpages(miscelm); + ret = (void *)((uintptr_t)rpages + (uintptr_t)bin_info->reg0_offset + + (uintptr_t)(bin_info->reg_interval * regind)); + run->nfree--; + return (ret); +} + +JEMALLOC_INLINE_C void +arena_run_reg_dalloc(arena_run_t *run, void *ptr) +{ + arena_chunk_t *chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(run); + size_t pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE; + size_t mapbits = arena_mapbits_get(chunk, pageind); + szind_t binind = arena_ptr_small_binind_get(ptr, mapbits); + arena_bin_info_t *bin_info = &arena_bin_info[binind]; + unsigned regind = arena_run_regind(run, bin_info, ptr); + + assert(run->nfree < bin_info->nregs); + /* Freeing an interior pointer can cause assertion failure. */ + assert(((uintptr_t)ptr - + ((uintptr_t)arena_miscelm_to_rpages(arena_run_to_miscelm(run)) + + (uintptr_t)bin_info->reg0_offset)) % + (uintptr_t)bin_info->reg_interval == 0); + assert((uintptr_t)ptr >= + (uintptr_t)arena_miscelm_to_rpages(arena_run_to_miscelm(run)) + + (uintptr_t)bin_info->reg0_offset); + /* Freeing an unallocated pointer can cause assertion failure. */ + assert(bitmap_get(run->bitmap, &bin_info->bitmap_info, regind)); + + bitmap_unset(run->bitmap, &bin_info->bitmap_info, regind); + run->nfree++; +} + +JEMALLOC_INLINE_C void +arena_run_zero(arena_chunk_t *chunk, size_t run_ind, size_t npages) +{ + + JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED((void *)((uintptr_t)chunk + + (run_ind << LG_PAGE)), (npages << LG_PAGE)); + memset((void *)((uintptr_t)chunk + (run_ind << LG_PAGE)), 0, + (npages << LG_PAGE)); +} + +JEMALLOC_INLINE_C void +arena_run_page_mark_zeroed(arena_chunk_t *chunk, size_t run_ind) +{ + + JEMALLOC_VALGRIND_MAKE_MEM_DEFINED((void *)((uintptr_t)chunk + (run_ind + << LG_PAGE)), PAGE); +} + +JEMALLOC_INLINE_C void +arena_run_page_validate_zeroed(arena_chunk_t *chunk, size_t run_ind) +{ + size_t i; + UNUSED size_t *p = (size_t *)((uintptr_t)chunk + (run_ind << LG_PAGE)); + + arena_run_page_mark_zeroed(chunk, run_ind); + for (i = 0; i < PAGE / sizeof(size_t); i++) + assert(p[i] == 0); +} + +static void +arena_cactive_update(arena_t *arena, size_t add_pages, size_t sub_pages) +{ + + if (config_stats) { + ssize_t cactive_diff = CHUNK_CEILING((arena->nactive + add_pages + - sub_pages) << LG_PAGE) - CHUNK_CEILING(arena->nactive << + LG_PAGE); + if (cactive_diff != 0) + stats_cactive_add(cactive_diff); + } +} + +static void +arena_run_split_remove(arena_t *arena, arena_chunk_t *chunk, size_t run_ind, + size_t flag_dirty, size_t flag_decommitted, size_t need_pages) +{ + size_t total_pages, rem_pages; + + assert(flag_dirty == 0 || flag_decommitted == 0); + + total_pages = arena_mapbits_unallocated_size_get(chunk, run_ind) >> + LG_PAGE; + assert(arena_mapbits_dirty_get(chunk, run_ind+total_pages-1) == + flag_dirty); + assert(need_pages <= total_pages); + rem_pages = total_pages - need_pages; + + arena_avail_remove(arena, chunk, run_ind, total_pages); + if (flag_dirty != 0) + arena_run_dirty_remove(arena, chunk, run_ind, total_pages); + arena_cactive_update(arena, need_pages, 0); + arena->nactive += need_pages; + + /* Keep track of trailing unused pages for later use. */ + if (rem_pages > 0) { + size_t flags = flag_dirty | flag_decommitted; + size_t flag_unzeroed_mask = (flags == 0) ? CHUNK_MAP_UNZEROED : + 0; + + arena_mapbits_unallocated_set(chunk, run_ind+need_pages, + (rem_pages << LG_PAGE), flags | + (arena_mapbits_unzeroed_get(chunk, run_ind+need_pages) & + flag_unzeroed_mask)); + arena_mapbits_unallocated_set(chunk, run_ind+total_pages-1, + (rem_pages << LG_PAGE), flags | + (arena_mapbits_unzeroed_get(chunk, run_ind+total_pages-1) & + flag_unzeroed_mask)); + if (flag_dirty != 0) { + arena_run_dirty_insert(arena, chunk, run_ind+need_pages, + rem_pages); + } + arena_avail_insert(arena, chunk, run_ind+need_pages, rem_pages); + } +} + +static bool +arena_run_split_large_helper(arena_t *arena, arena_run_t *run, size_t size, + bool remove, bool zero) +{ + arena_chunk_t *chunk; + arena_chunk_map_misc_t *miscelm; + size_t flag_dirty, flag_decommitted, run_ind, need_pages; + size_t flag_unzeroed_mask; + + chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(run); + miscelm = arena_run_to_miscelm(run); + run_ind = arena_miscelm_to_pageind(miscelm); + flag_dirty = arena_mapbits_dirty_get(chunk, run_ind); + flag_decommitted = arena_mapbits_decommitted_get(chunk, run_ind); + need_pages = (size >> LG_PAGE); + assert(need_pages > 0); + + if (flag_decommitted != 0 && arena->chunk_hooks.commit(chunk, chunksize, + run_ind << LG_PAGE, size, arena->ind)) + return (true); + + if (remove) { + arena_run_split_remove(arena, chunk, run_ind, flag_dirty, + flag_decommitted, need_pages); + } + + if (zero) { + if (flag_decommitted != 0) { + /* The run is untouched, and therefore zeroed. */ + JEMALLOC_VALGRIND_MAKE_MEM_DEFINED((void + *)((uintptr_t)chunk + (run_ind << LG_PAGE)), + (need_pages << LG_PAGE)); + } else if (flag_dirty != 0) { + /* The run is dirty, so all pages must be zeroed. */ + arena_run_zero(chunk, run_ind, need_pages); + } else { + /* + * The run is clean, so some pages may be zeroed (i.e. + * never before touched). + */ + size_t i; + for (i = 0; i < need_pages; i++) { + if (arena_mapbits_unzeroed_get(chunk, run_ind+i) + != 0) + arena_run_zero(chunk, run_ind+i, 1); + else if (config_debug) { + arena_run_page_validate_zeroed(chunk, + run_ind+i); + } else { + arena_run_page_mark_zeroed(chunk, + run_ind+i); + } + } + } + } else { + JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED((void *)((uintptr_t)chunk + + (run_ind << LG_PAGE)), (need_pages << LG_PAGE)); + } + + /* + * Set the last element first, in case the run only contains one page + * (i.e. both statements set the same element). + */ + flag_unzeroed_mask = (flag_dirty | flag_decommitted) == 0 ? + CHUNK_MAP_UNZEROED : 0; + arena_mapbits_large_set(chunk, run_ind+need_pages-1, 0, flag_dirty | + (flag_unzeroed_mask & arena_mapbits_unzeroed_get(chunk, + run_ind+need_pages-1))); + arena_mapbits_large_set(chunk, run_ind, size, flag_dirty | + (flag_unzeroed_mask & arena_mapbits_unzeroed_get(chunk, run_ind))); + return (false); +} + +static bool +arena_run_split_large(arena_t *arena, arena_run_t *run, size_t size, bool zero) +{ + + return (arena_run_split_large_helper(arena, run, size, true, zero)); +} + +static bool +arena_run_init_large(arena_t *arena, arena_run_t *run, size_t size, bool zero) +{ + + return (arena_run_split_large_helper(arena, run, size, false, zero)); +} + +static bool +arena_run_split_small(arena_t *arena, arena_run_t *run, size_t size, + szind_t binind) +{ + arena_chunk_t *chunk; + arena_chunk_map_misc_t *miscelm; + size_t flag_dirty, flag_decommitted, run_ind, need_pages, i; + + assert(binind != BININD_INVALID); + + chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(run); + miscelm = arena_run_to_miscelm(run); + run_ind = arena_miscelm_to_pageind(miscelm); + flag_dirty = arena_mapbits_dirty_get(chunk, run_ind); + flag_decommitted = arena_mapbits_decommitted_get(chunk, run_ind); + need_pages = (size >> LG_PAGE); + assert(need_pages > 0); + + if (flag_decommitted != 0 && arena->chunk_hooks.commit(chunk, chunksize, + run_ind << LG_PAGE, size, arena->ind)) + return (true); + + arena_run_split_remove(arena, chunk, run_ind, flag_dirty, + flag_decommitted, need_pages); + + for (i = 0; i < need_pages; i++) { + size_t flag_unzeroed = arena_mapbits_unzeroed_get(chunk, + run_ind+i); + arena_mapbits_small_set(chunk, run_ind+i, i, binind, + flag_unzeroed); + if (config_debug && flag_dirty == 0 && flag_unzeroed == 0) + arena_run_page_validate_zeroed(chunk, run_ind+i); + } + JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED((void *)((uintptr_t)chunk + + (run_ind << LG_PAGE)), (need_pages << LG_PAGE)); + return (false); +} + +static arena_chunk_t * +arena_chunk_init_spare(arena_t *arena) +{ + arena_chunk_t *chunk; + + assert(arena->spare != NULL); + + chunk = arena->spare; + arena->spare = NULL; + + assert(arena_mapbits_allocated_get(chunk, map_bias) == 0); + assert(arena_mapbits_allocated_get(chunk, chunk_npages-1) == 0); + assert(arena_mapbits_unallocated_size_get(chunk, map_bias) == + arena_maxrun); + assert(arena_mapbits_unallocated_size_get(chunk, chunk_npages-1) == + arena_maxrun); + assert(arena_mapbits_dirty_get(chunk, map_bias) == + arena_mapbits_dirty_get(chunk, chunk_npages-1)); + + return (chunk); +} + +static bool +arena_chunk_register(arena_t *arena, arena_chunk_t *chunk, bool zero) +{ + + /* + * The extent node notion of "committed" doesn't directly apply to + * arena chunks. Arbitrarily mark them as committed. The commit state + * of runs is tracked individually, and upon chunk deallocation the + * entire chunk is in a consistent commit state. + */ + extent_node_init(&chunk->node, arena, chunk, chunksize, zero, true); + extent_node_achunk_set(&chunk->node, true); + return (chunk_register(chunk, &chunk->node)); +} + +static arena_chunk_t * +arena_chunk_alloc_internal_hard(arena_t *arena, chunk_hooks_t *chunk_hooks, + bool *zero, bool *commit) +{ + arena_chunk_t *chunk; + + malloc_mutex_unlock(&arena->lock); + + chunk = (arena_chunk_t *)chunk_alloc_wrapper(arena, chunk_hooks, NULL, + chunksize, chunksize, zero, commit); + if (chunk != NULL && !*commit) { + /* Commit header. */ + if (chunk_hooks->commit(chunk, chunksize, 0, map_bias << + LG_PAGE, arena->ind)) { + chunk_dalloc_wrapper(arena, chunk_hooks, + (void *)chunk, chunksize, *commit); + chunk = NULL; + } + } + if (chunk != NULL && arena_chunk_register(arena, chunk, *zero)) { + if (!*commit) { + /* Undo commit of header. */ + chunk_hooks->decommit(chunk, chunksize, 0, map_bias << + LG_PAGE, arena->ind); + } + chunk_dalloc_wrapper(arena, chunk_hooks, (void *)chunk, + chunksize, *commit); + chunk = NULL; + } + + malloc_mutex_lock(&arena->lock); + return (chunk); +} + +static arena_chunk_t * +arena_chunk_alloc_internal(arena_t *arena, bool *zero, bool *commit) +{ + arena_chunk_t *chunk; + chunk_hooks_t chunk_hooks = CHUNK_HOOKS_INITIALIZER; + + chunk = chunk_alloc_cache(arena, &chunk_hooks, NULL, chunksize, + chunksize, zero, true); + if (chunk != NULL) { + if (arena_chunk_register(arena, chunk, *zero)) { + chunk_dalloc_cache(arena, &chunk_hooks, chunk, + chunksize, true); + return (NULL); + } + *commit = true; + } + if (chunk == NULL) { + chunk = arena_chunk_alloc_internal_hard(arena, &chunk_hooks, + zero, commit); + } + + if (config_stats && chunk != NULL) { + arena->stats.mapped += chunksize; + arena->stats.metadata_mapped += (map_bias << LG_PAGE); + } + + return (chunk); +} + +static arena_chunk_t * +arena_chunk_init_hard(arena_t *arena) +{ + arena_chunk_t *chunk; + bool zero, commit; + size_t flag_unzeroed, flag_decommitted, i; + + assert(arena->spare == NULL); + + zero = false; + commit = false; + chunk = arena_chunk_alloc_internal(arena, &zero, &commit); + if (chunk == NULL) + return (NULL); + + /* + * Initialize the map to contain one maximal free untouched run. Mark + * the pages as zeroed if chunk_alloc() returned a zeroed or decommitted + * chunk. + */ + flag_unzeroed = (zero || !commit) ? 0 : CHUNK_MAP_UNZEROED; + flag_decommitted = commit ? 0 : CHUNK_MAP_DECOMMITTED; + arena_mapbits_unallocated_set(chunk, map_bias, arena_maxrun, + flag_unzeroed | flag_decommitted); + /* + * There is no need to initialize the internal page map entries unless + * the chunk is not zeroed. + */ + if (!zero) { + JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED( + (void *)arena_bitselm_get(chunk, map_bias+1), + (size_t)((uintptr_t) arena_bitselm_get(chunk, + chunk_npages-1) - (uintptr_t)arena_bitselm_get(chunk, + map_bias+1))); + for (i = map_bias+1; i < chunk_npages-1; i++) + arena_mapbits_internal_set(chunk, i, flag_unzeroed); + } else { + JEMALLOC_VALGRIND_MAKE_MEM_DEFINED((void + *)arena_bitselm_get(chunk, map_bias+1), (size_t)((uintptr_t) + arena_bitselm_get(chunk, chunk_npages-1) - + (uintptr_t)arena_bitselm_get(chunk, map_bias+1))); + if (config_debug) { + for (i = map_bias+1; i < chunk_npages-1; i++) { + assert(arena_mapbits_unzeroed_get(chunk, i) == + flag_unzeroed); + } + } + } + arena_mapbits_unallocated_set(chunk, chunk_npages-1, arena_maxrun, + flag_unzeroed); + + return (chunk); +} + +static arena_chunk_t * +arena_chunk_alloc(arena_t *arena) +{ + arena_chunk_t *chunk; + + if (arena->spare != NULL) + chunk = arena_chunk_init_spare(arena); + else { + chunk = arena_chunk_init_hard(arena); + if (chunk == NULL) + return (NULL); + } + + /* Insert the run into the runs_avail tree. */ + arena_avail_insert(arena, chunk, map_bias, chunk_npages-map_bias); + + return (chunk); +} + +static void +arena_chunk_dalloc(arena_t *arena, arena_chunk_t *chunk) +{ + + assert(arena_mapbits_allocated_get(chunk, map_bias) == 0); + assert(arena_mapbits_allocated_get(chunk, chunk_npages-1) == 0); + assert(arena_mapbits_unallocated_size_get(chunk, map_bias) == + arena_maxrun); + assert(arena_mapbits_unallocated_size_get(chunk, chunk_npages-1) == + arena_maxrun); + assert(arena_mapbits_dirty_get(chunk, map_bias) == + arena_mapbits_dirty_get(chunk, chunk_npages-1)); + assert(arena_mapbits_decommitted_get(chunk, map_bias) == + arena_mapbits_decommitted_get(chunk, chunk_npages-1)); + + /* + * Remove run from the runs_avail tree, so that the arena does not use + * it. + */ + arena_avail_remove(arena, chunk, map_bias, chunk_npages-map_bias); + + if (arena->spare != NULL) { + arena_chunk_t *spare = arena->spare; + chunk_hooks_t chunk_hooks = CHUNK_HOOKS_INITIALIZER; + bool committed; + + arena->spare = chunk; + if (arena_mapbits_dirty_get(spare, map_bias) != 0) { + arena_run_dirty_remove(arena, spare, map_bias, + chunk_npages-map_bias); + } + + chunk_deregister(spare, &spare->node); + + committed = (arena_mapbits_decommitted_get(spare, map_bias) == + 0); + if (!committed) { + /* + * Decommit the header. Mark the chunk as decommitted + * even if header decommit fails, since treating a + * partially committed chunk as committed has a high + * potential for causing later access of decommitted + * memory. + */ + chunk_hooks = chunk_hooks_get(arena); + chunk_hooks.decommit(spare, chunksize, 0, map_bias << + LG_PAGE, arena->ind); + } + + chunk_dalloc_cache(arena, &chunk_hooks, (void *)spare, + chunksize, committed); + + if (config_stats) { + arena->stats.mapped -= chunksize; + arena->stats.metadata_mapped -= (map_bias << LG_PAGE); + } + } else + arena->spare = chunk; +} + +static void +arena_huge_malloc_stats_update(arena_t *arena, size_t usize) +{ + szind_t index = size2index(usize) - nlclasses - NBINS; + + cassert(config_stats); + + arena->stats.nmalloc_huge++; + arena->stats.allocated_huge += usize; + arena->stats.hstats[index].nmalloc++; + arena->stats.hstats[index].curhchunks++; +} + +static void +arena_huge_malloc_stats_update_undo(arena_t *arena, size_t usize) +{ + szind_t index = size2index(usize) - nlclasses - NBINS; + + cassert(config_stats); + + arena->stats.nmalloc_huge--; + arena->stats.allocated_huge -= usize; + arena->stats.hstats[index].nmalloc--; + arena->stats.hstats[index].curhchunks--; +} + +static void +arena_huge_dalloc_stats_update(arena_t *arena, size_t usize) +{ + szind_t index = size2index(usize) - nlclasses - NBINS; + + cassert(config_stats); + + arena->stats.ndalloc_huge++; + arena->stats.allocated_huge -= usize; + arena->stats.hstats[index].ndalloc++; + arena->stats.hstats[index].curhchunks--; +} + +static void +arena_huge_dalloc_stats_update_undo(arena_t *arena, size_t usize) +{ + szind_t index = size2index(usize) - nlclasses - NBINS; + + cassert(config_stats); + + arena->stats.ndalloc_huge--; + arena->stats.allocated_huge += usize; + arena->stats.hstats[index].ndalloc--; + arena->stats.hstats[index].curhchunks++; +} + +static void +arena_huge_ralloc_stats_update(arena_t *arena, size_t oldsize, size_t usize) +{ + + arena_huge_dalloc_stats_update(arena, oldsize); + arena_huge_malloc_stats_update(arena, usize); +} + +static void +arena_huge_ralloc_stats_update_undo(arena_t *arena, size_t oldsize, + size_t usize) +{ + + arena_huge_dalloc_stats_update_undo(arena, oldsize); + arena_huge_malloc_stats_update_undo(arena, usize); +} + +extent_node_t * +arena_node_alloc(arena_t *arena) +{ + extent_node_t *node; + + malloc_mutex_lock(&arena->node_cache_mtx); + node = ql_last(&arena->node_cache, ql_link); + if (node == NULL) { + malloc_mutex_unlock(&arena->node_cache_mtx); + return (base_alloc(sizeof(extent_node_t))); + } + ql_tail_remove(&arena->node_cache, extent_node_t, ql_link); + malloc_mutex_unlock(&arena->node_cache_mtx); + return (node); +} + +void +arena_node_dalloc(arena_t *arena, extent_node_t *node) +{ + + malloc_mutex_lock(&arena->node_cache_mtx); + ql_elm_new(node, ql_link); + ql_tail_insert(&arena->node_cache, node, ql_link); + malloc_mutex_unlock(&arena->node_cache_mtx); +} + +static void * +arena_chunk_alloc_huge_hard(arena_t *arena, chunk_hooks_t *chunk_hooks, + size_t usize, size_t alignment, bool *zero, size_t csize) +{ + void *ret; + bool commit = true; + + ret = chunk_alloc_wrapper(arena, chunk_hooks, NULL, csize, alignment, + zero, &commit); + if (ret == NULL) { + /* Revert optimistic stats updates. */ + malloc_mutex_lock(&arena->lock); + if (config_stats) { + arena_huge_malloc_stats_update_undo(arena, usize); + arena->stats.mapped -= usize; + } + arena->nactive -= (usize >> LG_PAGE); + malloc_mutex_unlock(&arena->lock); + } + + return (ret); +} + +void * +arena_chunk_alloc_huge(arena_t *arena, size_t usize, size_t alignment, + bool *zero) +{ + void *ret; + chunk_hooks_t chunk_hooks = CHUNK_HOOKS_INITIALIZER; + size_t csize = CHUNK_CEILING(usize); + + malloc_mutex_lock(&arena->lock); + + /* Optimistically update stats. */ + if (config_stats) { + arena_huge_malloc_stats_update(arena, usize); + arena->stats.mapped += usize; + } + arena->nactive += (usize >> LG_PAGE); + + ret = chunk_alloc_cache(arena, &chunk_hooks, NULL, csize, alignment, + zero, true); + malloc_mutex_unlock(&arena->lock); + if (ret == NULL) { + ret = arena_chunk_alloc_huge_hard(arena, &chunk_hooks, usize, + alignment, zero, csize); + } + + if (config_stats && ret != NULL) + stats_cactive_add(usize); + return (ret); +} + +void +arena_chunk_dalloc_huge(arena_t *arena, void *chunk, size_t usize) +{ + chunk_hooks_t chunk_hooks = CHUNK_HOOKS_INITIALIZER; + size_t csize; + + csize = CHUNK_CEILING(usize); + malloc_mutex_lock(&arena->lock); + if (config_stats) { + arena_huge_dalloc_stats_update(arena, usize); + arena->stats.mapped -= usize; + stats_cactive_sub(usize); + } + arena->nactive -= (usize >> LG_PAGE); + + chunk_dalloc_cache(arena, &chunk_hooks, chunk, csize, true); + malloc_mutex_unlock(&arena->lock); +} + +void +arena_chunk_ralloc_huge_similar(arena_t *arena, void *chunk, size_t oldsize, + size_t usize) +{ + + assert(CHUNK_CEILING(oldsize) == CHUNK_CEILING(usize)); + assert(oldsize != usize); + + malloc_mutex_lock(&arena->lock); + if (config_stats) + arena_huge_ralloc_stats_update(arena, oldsize, usize); + if (oldsize < usize) { + size_t udiff = usize - oldsize; + arena->nactive += udiff >> LG_PAGE; + if (config_stats) + stats_cactive_add(udiff); + } else { + size_t udiff = oldsize - usize; + arena->nactive -= udiff >> LG_PAGE; + if (config_stats) + stats_cactive_sub(udiff); + } + malloc_mutex_unlock(&arena->lock); +} + +void +arena_chunk_ralloc_huge_shrink(arena_t *arena, void *chunk, size_t oldsize, + size_t usize) +{ + size_t udiff = oldsize - usize; + size_t cdiff = CHUNK_CEILING(oldsize) - CHUNK_CEILING(usize); + + malloc_mutex_lock(&arena->lock); + if (config_stats) { + arena_huge_ralloc_stats_update(arena, oldsize, usize); + if (cdiff != 0) { + arena->stats.mapped -= cdiff; + stats_cactive_sub(udiff); + } + } + arena->nactive -= udiff >> LG_PAGE; + + if (cdiff != 0) { + chunk_hooks_t chunk_hooks = CHUNK_HOOKS_INITIALIZER; + void *nchunk = (void *)((uintptr_t)chunk + + CHUNK_CEILING(usize)); + + chunk_dalloc_cache(arena, &chunk_hooks, nchunk, cdiff, true); + } + malloc_mutex_unlock(&arena->lock); +} + +static bool +arena_chunk_ralloc_huge_expand_hard(arena_t *arena, chunk_hooks_t *chunk_hooks, + void *chunk, size_t oldsize, size_t usize, bool *zero, void *nchunk, + size_t udiff, size_t cdiff) +{ + bool err; + bool commit = true; + + err = (chunk_alloc_wrapper(arena, chunk_hooks, nchunk, cdiff, chunksize, + zero, &commit) == NULL); + if (err) { + /* Revert optimistic stats updates. */ + malloc_mutex_lock(&arena->lock); + if (config_stats) { + arena_huge_ralloc_stats_update_undo(arena, oldsize, + usize); + arena->stats.mapped -= cdiff; + } + arena->nactive -= (udiff >> LG_PAGE); + malloc_mutex_unlock(&arena->lock); + } else if (chunk_hooks->merge(chunk, CHUNK_CEILING(oldsize), nchunk, + cdiff, true, arena->ind)) { + chunk_dalloc_arena(arena, chunk_hooks, nchunk, cdiff, *zero, + true); + err = true; + } + return (err); +} + +bool +arena_chunk_ralloc_huge_expand(arena_t *arena, void *chunk, size_t oldsize, + size_t usize, bool *zero) +{ + bool err; + chunk_hooks_t chunk_hooks = chunk_hooks_get(arena); + void *nchunk = (void *)((uintptr_t)chunk + CHUNK_CEILING(oldsize)); + size_t udiff = usize - oldsize; + size_t cdiff = CHUNK_CEILING(usize) - CHUNK_CEILING(oldsize); + + malloc_mutex_lock(&arena->lock); + + /* Optimistically update stats. */ + if (config_stats) { + arena_huge_ralloc_stats_update(arena, oldsize, usize); + arena->stats.mapped += cdiff; + } + arena->nactive += (udiff >> LG_PAGE); + + err = (chunk_alloc_cache(arena, &arena->chunk_hooks, nchunk, cdiff, + chunksize, zero, true) == NULL); + malloc_mutex_unlock(&arena->lock); + if (err) { + err = arena_chunk_ralloc_huge_expand_hard(arena, &chunk_hooks, + chunk, oldsize, usize, zero, nchunk, udiff, + cdiff); + } else if (chunk_hooks.merge(chunk, CHUNK_CEILING(oldsize), nchunk, + cdiff, true, arena->ind)) { + chunk_dalloc_arena(arena, &chunk_hooks, nchunk, cdiff, *zero, + true); + err = true; + } + + if (config_stats && !err) + stats_cactive_add(udiff); + return (err); +} + +/* + * Do first-best-fit run selection, i.e. select the lowest run that best fits. + * Run sizes are quantized, so not all candidate runs are necessarily exactly + * the same size. + */ +static arena_run_t * +arena_run_first_best_fit(arena_t *arena, size_t size) +{ + size_t search_size = run_quantize_first(size); + arena_chunk_map_misc_t *key = arena_miscelm_key_create(search_size); + arena_chunk_map_misc_t *miscelm = + arena_avail_tree_nsearch(&arena->runs_avail, key); + if (miscelm == NULL) + return (NULL); + return (&miscelm->run); +} + +static arena_run_t * +arena_run_alloc_large_helper(arena_t *arena, size_t size, bool zero) +{ + arena_run_t *run = arena_run_first_best_fit(arena, s2u(size)); + if (run != NULL) { + if (arena_run_split_large(arena, run, size, zero)) + run = NULL; + } + return (run); +} + +static arena_run_t * +arena_run_alloc_large(arena_t *arena, size_t size, bool zero) +{ + arena_chunk_t *chunk; + arena_run_t *run; + + assert(size <= arena_maxrun); + assert(size == PAGE_CEILING(size)); + + /* Search the arena's chunks for the lowest best fit. */ + run = arena_run_alloc_large_helper(arena, size, zero); + if (run != NULL) + return (run); + + /* + * No usable runs. Create a new chunk from which to allocate the run. + */ + chunk = arena_chunk_alloc(arena); + if (chunk != NULL) { + run = &arena_miscelm_get(chunk, map_bias)->run; + if (arena_run_split_large(arena, run, size, zero)) + run = NULL; + return (run); + } + + /* + * arena_chunk_alloc() failed, but another thread may have made + * sufficient memory available while this one dropped arena->lock in + * arena_chunk_alloc(), so search one more time. + */ + return (arena_run_alloc_large_helper(arena, size, zero)); +} + +static arena_run_t * +arena_run_alloc_small_helper(arena_t *arena, size_t size, szind_t binind) +{ + arena_run_t *run = arena_run_first_best_fit(arena, size); + if (run != NULL) { + if (arena_run_split_small(arena, run, size, binind)) + run = NULL; + } + return (run); +} + +static arena_run_t * +arena_run_alloc_small(arena_t *arena, size_t size, szind_t binind) +{ + arena_chunk_t *chunk; + arena_run_t *run; + + assert(size <= arena_maxrun); + assert(size == PAGE_CEILING(size)); + assert(binind != BININD_INVALID); + + /* Search the arena's chunks for the lowest best fit. */ + run = arena_run_alloc_small_helper(arena, size, binind); + if (run != NULL) + return (run); + + /* + * No usable runs. Create a new chunk from which to allocate the run. + */ + chunk = arena_chunk_alloc(arena); + if (chunk != NULL) { + run = &arena_miscelm_get(chunk, map_bias)->run; + if (arena_run_split_small(arena, run, size, binind)) + run = NULL; + return (run); + } + + /* + * arena_chunk_alloc() failed, but another thread may have made + * sufficient memory available while this one dropped arena->lock in + * arena_chunk_alloc(), so search one more time. + */ + return (arena_run_alloc_small_helper(arena, size, binind)); +} + +static bool +arena_lg_dirty_mult_valid(ssize_t lg_dirty_mult) +{ + + return (lg_dirty_mult >= -1 && lg_dirty_mult < (ssize_t)(sizeof(size_t) + << 3)); +} + +ssize_t +arena_lg_dirty_mult_get(arena_t *arena) +{ + ssize_t lg_dirty_mult; + + malloc_mutex_lock(&arena->lock); + lg_dirty_mult = arena->lg_dirty_mult; + malloc_mutex_unlock(&arena->lock); + + return (lg_dirty_mult); +} + +bool +arena_lg_dirty_mult_set(arena_t *arena, ssize_t lg_dirty_mult) +{ + + if (!arena_lg_dirty_mult_valid(lg_dirty_mult)) + return (true); + + malloc_mutex_lock(&arena->lock); + arena->lg_dirty_mult = lg_dirty_mult; + arena_maybe_purge(arena); + malloc_mutex_unlock(&arena->lock); + + return (false); +} + +void +arena_maybe_purge(arena_t *arena) +{ + + /* Don't purge if the option is disabled. */ + if (arena->lg_dirty_mult < 0) + return; + /* Don't recursively purge. */ + if (arena->purging) + return; + /* + * Iterate, since preventing recursive purging could otherwise leave too + * many dirty pages. + */ + while (true) { + size_t threshold = (arena->nactive >> arena->lg_dirty_mult); + if (threshold < chunk_npages) + threshold = chunk_npages; + /* + * Don't purge unless the number of purgeable pages exceeds the + * threshold. + */ + if (arena->ndirty <= threshold) + return; + arena_purge(arena, false); + } +} + +static size_t +arena_dirty_count(arena_t *arena) +{ + size_t ndirty = 0; + arena_runs_dirty_link_t *rdelm; + extent_node_t *chunkselm; + + for (rdelm = qr_next(&arena->runs_dirty, rd_link), + chunkselm = qr_next(&arena->chunks_cache, cc_link); + rdelm != &arena->runs_dirty; rdelm = qr_next(rdelm, rd_link)) { + size_t npages; + + if (rdelm == &chunkselm->rd) { + npages = extent_node_size_get(chunkselm) >> LG_PAGE; + chunkselm = qr_next(chunkselm, cc_link); + } else { + arena_chunk_t *chunk = (arena_chunk_t *)CHUNK_ADDR2BASE( + rdelm); + arena_chunk_map_misc_t *miscelm = + arena_rd_to_miscelm(rdelm); + size_t pageind = arena_miscelm_to_pageind(miscelm); + assert(arena_mapbits_allocated_get(chunk, pageind) == + 0); + assert(arena_mapbits_large_get(chunk, pageind) == 0); + assert(arena_mapbits_dirty_get(chunk, pageind) != 0); + npages = arena_mapbits_unallocated_size_get(chunk, + pageind) >> LG_PAGE; + } + ndirty += npages; + } + + return (ndirty); +} + +static size_t +arena_compute_npurge(arena_t *arena, bool all) +{ + size_t npurge; + + /* + * Compute the minimum number of pages that this thread should try to + * purge. + */ + if (!all) { + size_t threshold = (arena->nactive >> arena->lg_dirty_mult); + threshold = threshold < chunk_npages ? chunk_npages : threshold; + + npurge = arena->ndirty - threshold; + } else + npurge = arena->ndirty; + + return (npurge); +} + +static size_t +arena_stash_dirty(arena_t *arena, chunk_hooks_t *chunk_hooks, bool all, + size_t npurge, arena_runs_dirty_link_t *purge_runs_sentinel, + extent_node_t *purge_chunks_sentinel) +{ + arena_runs_dirty_link_t *rdelm, *rdelm_next; + extent_node_t *chunkselm; + size_t nstashed = 0; + + /* Stash at least npurge pages. */ + for (rdelm = qr_next(&arena->runs_dirty, rd_link), + chunkselm = qr_next(&arena->chunks_cache, cc_link); + rdelm != &arena->runs_dirty; rdelm = rdelm_next) { + size_t npages; + rdelm_next = qr_next(rdelm, rd_link); + + if (rdelm == &chunkselm->rd) { + extent_node_t *chunkselm_next; + bool zero; + UNUSED void *chunk; + + chunkselm_next = qr_next(chunkselm, cc_link); + /* + * Allocate. chunkselm remains valid due to the + * dalloc_node=false argument to chunk_alloc_cache(). + */ + zero = false; + chunk = chunk_alloc_cache(arena, chunk_hooks, + extent_node_addr_get(chunkselm), + extent_node_size_get(chunkselm), chunksize, &zero, + false); + assert(chunk == extent_node_addr_get(chunkselm)); + assert(zero == extent_node_zeroed_get(chunkselm)); + extent_node_dirty_insert(chunkselm, purge_runs_sentinel, + purge_chunks_sentinel); + npages = extent_node_size_get(chunkselm) >> LG_PAGE; + chunkselm = chunkselm_next; + } else { + arena_chunk_t *chunk = + (arena_chunk_t *)CHUNK_ADDR2BASE(rdelm); + arena_chunk_map_misc_t *miscelm = + arena_rd_to_miscelm(rdelm); + size_t pageind = arena_miscelm_to_pageind(miscelm); + arena_run_t *run = &miscelm->run; + size_t run_size = + arena_mapbits_unallocated_size_get(chunk, pageind); + + npages = run_size >> LG_PAGE; + + assert(pageind + npages <= chunk_npages); + assert(arena_mapbits_dirty_get(chunk, pageind) == + arena_mapbits_dirty_get(chunk, pageind+npages-1)); + + /* + * If purging the spare chunk's run, make it available + * prior to allocation. + */ + if (chunk == arena->spare) + arena_chunk_alloc(arena); + + /* Temporarily allocate the free dirty run. */ + arena_run_split_large(arena, run, run_size, false); + /* Stash. */ + if (false) + qr_new(rdelm, rd_link); /* Redundant. */ + else { + assert(qr_next(rdelm, rd_link) == rdelm); + assert(qr_prev(rdelm, rd_link) == rdelm); + } + qr_meld(purge_runs_sentinel, rdelm, rd_link); + } + + nstashed += npages; + if (!all && nstashed >= npurge) + break; + } + + return (nstashed); +} + +static size_t +arena_purge_stashed(arena_t *arena, chunk_hooks_t *chunk_hooks, + arena_runs_dirty_link_t *purge_runs_sentinel, + extent_node_t *purge_chunks_sentinel) +{ + size_t npurged, nmadvise; + arena_runs_dirty_link_t *rdelm; + extent_node_t *chunkselm; + + if (config_stats) + nmadvise = 0; + npurged = 0; + + malloc_mutex_unlock(&arena->lock); + for (rdelm = qr_next(purge_runs_sentinel, rd_link), + chunkselm = qr_next(purge_chunks_sentinel, cc_link); + rdelm != purge_runs_sentinel; rdelm = qr_next(rdelm, rd_link)) { + size_t npages; + + if (rdelm == &chunkselm->rd) { + /* + * Don't actually purge the chunk here because 1) + * chunkselm is embedded in the chunk and must remain + * valid, and 2) we deallocate the chunk in + * arena_unstash_purged(), where it is destroyed, + * decommitted, or purged, depending on chunk + * deallocation policy. + */ + size_t size = extent_node_size_get(chunkselm); + npages = size >> LG_PAGE; + chunkselm = qr_next(chunkselm, cc_link); + } else { + size_t pageind, run_size, flag_unzeroed, flags, i; + bool decommitted; + arena_chunk_t *chunk = + (arena_chunk_t *)CHUNK_ADDR2BASE(rdelm); + arena_chunk_map_misc_t *miscelm = + arena_rd_to_miscelm(rdelm); + pageind = arena_miscelm_to_pageind(miscelm); + run_size = arena_mapbits_large_size_get(chunk, pageind); + npages = run_size >> LG_PAGE; + + assert(pageind + npages <= chunk_npages); + assert(!arena_mapbits_decommitted_get(chunk, pageind)); + assert(!arena_mapbits_decommitted_get(chunk, + pageind+npages-1)); + decommitted = !chunk_hooks->decommit(chunk, chunksize, + pageind << LG_PAGE, npages << LG_PAGE, arena->ind); + if (decommitted) { + flag_unzeroed = 0; + flags = CHUNK_MAP_DECOMMITTED; + } else { + flag_unzeroed = chunk_purge_wrapper(arena, + chunk_hooks, chunk, chunksize, pageind << + LG_PAGE, run_size) ? CHUNK_MAP_UNZEROED : 0; + flags = flag_unzeroed; + } + arena_mapbits_large_set(chunk, pageind+npages-1, 0, + flags); + arena_mapbits_large_set(chunk, pageind, run_size, + flags); + + /* + * Set the unzeroed flag for internal pages, now that + * chunk_purge_wrapper() has returned whether the pages + * were zeroed as a side effect of purging. This chunk + * map modification is safe even though the arena mutex + * isn't currently owned by this thread, because the run + * is marked as allocated, thus protecting it from being + * modified by any other thread. As long as these + * writes don't perturb the first and last elements' + * CHUNK_MAP_ALLOCATED bits, behavior is well defined. + */ + for (i = 1; i < npages-1; i++) { + arena_mapbits_internal_set(chunk, pageind+i, + flag_unzeroed); + } + } + + npurged += npages; + if (config_stats) + nmadvise++; + } + malloc_mutex_lock(&arena->lock); + + if (config_stats) { + arena->stats.nmadvise += nmadvise; + arena->stats.purged += npurged; + } + + return (npurged); +} + +static void +arena_unstash_purged(arena_t *arena, chunk_hooks_t *chunk_hooks, + arena_runs_dirty_link_t *purge_runs_sentinel, + extent_node_t *purge_chunks_sentinel) +{ + arena_runs_dirty_link_t *rdelm, *rdelm_next; + extent_node_t *chunkselm; + + /* Deallocate chunks/runs. */ + for (rdelm = qr_next(purge_runs_sentinel, rd_link), + chunkselm = qr_next(purge_chunks_sentinel, cc_link); + rdelm != purge_runs_sentinel; rdelm = rdelm_next) { + rdelm_next = qr_next(rdelm, rd_link); + if (rdelm == &chunkselm->rd) { + extent_node_t *chunkselm_next = qr_next(chunkselm, + cc_link); + void *addr = extent_node_addr_get(chunkselm); + size_t size = extent_node_size_get(chunkselm); + bool zeroed = extent_node_zeroed_get(chunkselm); + bool committed = extent_node_committed_get(chunkselm); + extent_node_dirty_remove(chunkselm); + arena_node_dalloc(arena, chunkselm); + chunkselm = chunkselm_next; + chunk_dalloc_arena(arena, chunk_hooks, addr, size, + zeroed, committed); + } else { + arena_chunk_t *chunk = + (arena_chunk_t *)CHUNK_ADDR2BASE(rdelm); + arena_chunk_map_misc_t *miscelm = + arena_rd_to_miscelm(rdelm); + size_t pageind = arena_miscelm_to_pageind(miscelm); + bool decommitted = (arena_mapbits_decommitted_get(chunk, + pageind) != 0); + arena_run_t *run = &miscelm->run; + qr_remove(rdelm, rd_link); + arena_run_dalloc(arena, run, false, true, decommitted); + } + } +} + +static void +arena_purge(arena_t *arena, bool all) +{ + chunk_hooks_t chunk_hooks = chunk_hooks_get(arena); + size_t npurge, npurgeable, npurged; + arena_runs_dirty_link_t purge_runs_sentinel; + extent_node_t purge_chunks_sentinel; + + arena->purging = true; + + /* + * Calls to arena_dirty_count() are disabled even for debug builds + * because overhead grows nonlinearly as memory usage increases. + */ + if (false && config_debug) { + size_t ndirty = arena_dirty_count(arena); + assert(ndirty == arena->ndirty); + } + assert((arena->nactive >> arena->lg_dirty_mult) < arena->ndirty || all); + + if (config_stats) + arena->stats.npurge++; + + npurge = arena_compute_npurge(arena, all); + qr_new(&purge_runs_sentinel, rd_link); + extent_node_dirty_linkage_init(&purge_chunks_sentinel); + + npurgeable = arena_stash_dirty(arena, &chunk_hooks, all, npurge, + &purge_runs_sentinel, &purge_chunks_sentinel); + assert(npurgeable >= npurge); + npurged = arena_purge_stashed(arena, &chunk_hooks, &purge_runs_sentinel, + &purge_chunks_sentinel); + assert(npurged == npurgeable); + arena_unstash_purged(arena, &chunk_hooks, &purge_runs_sentinel, + &purge_chunks_sentinel); + + arena->purging = false; +} + +void +arena_purge_all(arena_t *arena) +{ + + malloc_mutex_lock(&arena->lock); + arena_purge(arena, true); + malloc_mutex_unlock(&arena->lock); +} + +static void +arena_run_coalesce(arena_t *arena, arena_chunk_t *chunk, size_t *p_size, + size_t *p_run_ind, size_t *p_run_pages, size_t flag_dirty, + size_t flag_decommitted) +{ + size_t size = *p_size; + size_t run_ind = *p_run_ind; + size_t run_pages = *p_run_pages; + + /* Try to coalesce forward. */ + if (run_ind + run_pages < chunk_npages && + arena_mapbits_allocated_get(chunk, run_ind+run_pages) == 0 && + arena_mapbits_dirty_get(chunk, run_ind+run_pages) == flag_dirty && + arena_mapbits_decommitted_get(chunk, run_ind+run_pages) == + flag_decommitted) { + size_t nrun_size = arena_mapbits_unallocated_size_get(chunk, + run_ind+run_pages); + size_t nrun_pages = nrun_size >> LG_PAGE; + + /* + * Remove successor from runs_avail; the coalesced run is + * inserted later. + */ + assert(arena_mapbits_unallocated_size_get(chunk, + run_ind+run_pages+nrun_pages-1) == nrun_size); + assert(arena_mapbits_dirty_get(chunk, + run_ind+run_pages+nrun_pages-1) == flag_dirty); + assert(arena_mapbits_decommitted_get(chunk, + run_ind+run_pages+nrun_pages-1) == flag_decommitted); + arena_avail_remove(arena, chunk, run_ind+run_pages, nrun_pages); + + /* + * If the successor is dirty, remove it from the set of dirty + * pages. + */ + if (flag_dirty != 0) { + arena_run_dirty_remove(arena, chunk, run_ind+run_pages, + nrun_pages); + } + + size += nrun_size; + run_pages += nrun_pages; + + arena_mapbits_unallocated_size_set(chunk, run_ind, size); + arena_mapbits_unallocated_size_set(chunk, run_ind+run_pages-1, + size); + } + + /* Try to coalesce backward. */ + if (run_ind > map_bias && arena_mapbits_allocated_get(chunk, + run_ind-1) == 0 && arena_mapbits_dirty_get(chunk, run_ind-1) == + flag_dirty && arena_mapbits_decommitted_get(chunk, run_ind-1) == + flag_decommitted) { + size_t prun_size = arena_mapbits_unallocated_size_get(chunk, + run_ind-1); + size_t prun_pages = prun_size >> LG_PAGE; + + run_ind -= prun_pages; + + /* + * Remove predecessor from runs_avail; the coalesced run is + * inserted later. + */ + assert(arena_mapbits_unallocated_size_get(chunk, run_ind) == + prun_size); + assert(arena_mapbits_dirty_get(chunk, run_ind) == flag_dirty); + assert(arena_mapbits_decommitted_get(chunk, run_ind) == + flag_decommitted); + arena_avail_remove(arena, chunk, run_ind, prun_pages); + + /* + * If the predecessor is dirty, remove it from the set of dirty + * pages. + */ + if (flag_dirty != 0) { + arena_run_dirty_remove(arena, chunk, run_ind, + prun_pages); + } + + size += prun_size; + run_pages += prun_pages; + + arena_mapbits_unallocated_size_set(chunk, run_ind, size); + arena_mapbits_unallocated_size_set(chunk, run_ind+run_pages-1, + size); + } + + *p_size = size; + *p_run_ind = run_ind; + *p_run_pages = run_pages; +} + +static size_t +arena_run_size_get(arena_t *arena, arena_chunk_t *chunk, arena_run_t *run, + size_t run_ind) +{ + size_t size; + + assert(run_ind >= map_bias); + assert(run_ind < chunk_npages); + + if (arena_mapbits_large_get(chunk, run_ind) != 0) { + size = arena_mapbits_large_size_get(chunk, run_ind); + assert(size == PAGE || arena_mapbits_large_size_get(chunk, + run_ind+(size>>LG_PAGE)-1) == 0); + } else { + arena_bin_info_t *bin_info = &arena_bin_info[run->binind]; + size = bin_info->run_size; + } + + return (size); +} + +static bool +arena_run_decommit(arena_t *arena, arena_chunk_t *chunk, arena_run_t *run) +{ + arena_chunk_map_misc_t *miscelm = arena_run_to_miscelm(run); + size_t run_ind = arena_miscelm_to_pageind(miscelm); + size_t offset = run_ind << LG_PAGE; + size_t length = arena_run_size_get(arena, chunk, run, run_ind); + + return (arena->chunk_hooks.decommit(chunk, chunksize, offset, length, + arena->ind)); +} + +static void +arena_run_dalloc(arena_t *arena, arena_run_t *run, bool dirty, bool cleaned, + bool decommitted) +{ + arena_chunk_t *chunk; + arena_chunk_map_misc_t *miscelm; + size_t size, run_ind, run_pages, flag_dirty, flag_decommitted; + + chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(run); + miscelm = arena_run_to_miscelm(run); + run_ind = arena_miscelm_to_pageind(miscelm); + assert(run_ind >= map_bias); + assert(run_ind < chunk_npages); + size = arena_run_size_get(arena, chunk, run, run_ind); + run_pages = (size >> LG_PAGE); + arena_cactive_update(arena, 0, run_pages); + arena->nactive -= run_pages; + + /* + * The run is dirty if the caller claims to have dirtied it, as well as + * if it was already dirty before being allocated and the caller + * doesn't claim to have cleaned it. + */ + assert(arena_mapbits_dirty_get(chunk, run_ind) == + arena_mapbits_dirty_get(chunk, run_ind+run_pages-1)); + if (!cleaned && !decommitted && arena_mapbits_dirty_get(chunk, run_ind) + != 0) + dirty = true; + flag_dirty = dirty ? CHUNK_MAP_DIRTY : 0; + flag_decommitted = decommitted ? CHUNK_MAP_DECOMMITTED : 0; + + /* Mark pages as unallocated in the chunk map. */ + if (dirty || decommitted) { + size_t flags = flag_dirty | flag_decommitted; + arena_mapbits_unallocated_set(chunk, run_ind, size, flags); + arena_mapbits_unallocated_set(chunk, run_ind+run_pages-1, size, + flags); + } else { + arena_mapbits_unallocated_set(chunk, run_ind, size, + arena_mapbits_unzeroed_get(chunk, run_ind)); + arena_mapbits_unallocated_set(chunk, run_ind+run_pages-1, size, + arena_mapbits_unzeroed_get(chunk, run_ind+run_pages-1)); + } + + arena_run_coalesce(arena, chunk, &size, &run_ind, &run_pages, + flag_dirty, flag_decommitted); + + /* Insert into runs_avail, now that coalescing is complete. */ + assert(arena_mapbits_unallocated_size_get(chunk, run_ind) == + arena_mapbits_unallocated_size_get(chunk, run_ind+run_pages-1)); + assert(arena_mapbits_dirty_get(chunk, run_ind) == + arena_mapbits_dirty_get(chunk, run_ind+run_pages-1)); + assert(arena_mapbits_decommitted_get(chunk, run_ind) == + arena_mapbits_decommitted_get(chunk, run_ind+run_pages-1)); + arena_avail_insert(arena, chunk, run_ind, run_pages); + + if (dirty) + arena_run_dirty_insert(arena, chunk, run_ind, run_pages); + + /* Deallocate chunk if it is now completely unused. */ + if (size == arena_maxrun) { + assert(run_ind == map_bias); + assert(run_pages == (arena_maxrun >> LG_PAGE)); + arena_chunk_dalloc(arena, chunk); + } + + /* + * It is okay to do dirty page processing here even if the chunk was + * deallocated above, since in that case it is the spare. Waiting + * until after possible chunk deallocation to do dirty processing + * allows for an old spare to be fully deallocated, thus decreasing the + * chances of spuriously crossing the dirty page purging threshold. + */ + if (dirty) + arena_maybe_purge(arena); +} + +static void +arena_run_dalloc_decommit(arena_t *arena, arena_chunk_t *chunk, + arena_run_t *run) +{ + bool committed = arena_run_decommit(arena, chunk, run); + + arena_run_dalloc(arena, run, committed, false, !committed); +} + +static void +arena_run_trim_head(arena_t *arena, arena_chunk_t *chunk, arena_run_t *run, + size_t oldsize, size_t newsize) +{ + arena_chunk_map_misc_t *miscelm = arena_run_to_miscelm(run); + size_t pageind = arena_miscelm_to_pageind(miscelm); + size_t head_npages = (oldsize - newsize) >> LG_PAGE; + size_t flag_dirty = arena_mapbits_dirty_get(chunk, pageind); + size_t flag_decommitted = arena_mapbits_decommitted_get(chunk, pageind); + size_t flag_unzeroed_mask = (flag_dirty | flag_decommitted) == 0 ? + CHUNK_MAP_UNZEROED : 0; + + assert(oldsize > newsize); + + /* + * Update the chunk map so that arena_run_dalloc() can treat the + * leading run as separately allocated. Set the last element of each + * run first, in case of single-page runs. + */ + assert(arena_mapbits_large_size_get(chunk, pageind) == oldsize); + arena_mapbits_large_set(chunk, pageind+head_npages-1, 0, flag_dirty | + (flag_unzeroed_mask & arena_mapbits_unzeroed_get(chunk, + pageind+head_npages-1))); + arena_mapbits_large_set(chunk, pageind, oldsize-newsize, flag_dirty | + (flag_unzeroed_mask & arena_mapbits_unzeroed_get(chunk, pageind))); + + if (config_debug) { + UNUSED size_t tail_npages = newsize >> LG_PAGE; + assert(arena_mapbits_large_size_get(chunk, + pageind+head_npages+tail_npages-1) == 0); + assert(arena_mapbits_dirty_get(chunk, + pageind+head_npages+tail_npages-1) == flag_dirty); + } + arena_mapbits_large_set(chunk, pageind+head_npages, newsize, + flag_dirty | (flag_unzeroed_mask & arena_mapbits_unzeroed_get(chunk, + pageind+head_npages))); + + arena_run_dalloc(arena, run, false, false, (flag_decommitted != 0)); +} + +static void +arena_run_trim_tail(arena_t *arena, arena_chunk_t *chunk, arena_run_t *run, + size_t oldsize, size_t newsize, bool dirty) +{ + arena_chunk_map_misc_t *miscelm = arena_run_to_miscelm(run); + size_t pageind = arena_miscelm_to_pageind(miscelm); + size_t head_npages = newsize >> LG_PAGE; + size_t flag_dirty = arena_mapbits_dirty_get(chunk, pageind); + size_t flag_decommitted = arena_mapbits_decommitted_get(chunk, pageind); + size_t flag_unzeroed_mask = (flag_dirty | flag_decommitted) == 0 ? + CHUNK_MAP_UNZEROED : 0; + arena_chunk_map_misc_t *tail_miscelm; + arena_run_t *tail_run; + + assert(oldsize > newsize); + + /* + * Update the chunk map so that arena_run_dalloc() can treat the + * trailing run as separately allocated. Set the last element of each + * run first, in case of single-page runs. + */ + assert(arena_mapbits_large_size_get(chunk, pageind) == oldsize); + arena_mapbits_large_set(chunk, pageind+head_npages-1, 0, flag_dirty | + (flag_unzeroed_mask & arena_mapbits_unzeroed_get(chunk, + pageind+head_npages-1))); + arena_mapbits_large_set(chunk, pageind, newsize, flag_dirty | + (flag_unzeroed_mask & arena_mapbits_unzeroed_get(chunk, pageind))); + + if (config_debug) { + UNUSED size_t tail_npages = (oldsize - newsize) >> LG_PAGE; + assert(arena_mapbits_large_size_get(chunk, + pageind+head_npages+tail_npages-1) == 0); + assert(arena_mapbits_dirty_get(chunk, + pageind+head_npages+tail_npages-1) == flag_dirty); + } + arena_mapbits_large_set(chunk, pageind+head_npages, oldsize-newsize, + flag_dirty | (flag_unzeroed_mask & arena_mapbits_unzeroed_get(chunk, + pageind+head_npages))); + + tail_miscelm = arena_miscelm_get(chunk, pageind + head_npages); + tail_run = &tail_miscelm->run; + arena_run_dalloc(arena, tail_run, dirty, false, (flag_decommitted != + 0)); +} + +static arena_run_t * +arena_bin_runs_first(arena_bin_t *bin) +{ + arena_chunk_map_misc_t *miscelm = arena_run_tree_first(&bin->runs); + if (miscelm != NULL) + return (&miscelm->run); + + return (NULL); +} + +static void +arena_bin_runs_insert(arena_bin_t *bin, arena_run_t *run) +{ + arena_chunk_map_misc_t *miscelm = arena_run_to_miscelm(run); + + assert(arena_run_tree_search(&bin->runs, miscelm) == NULL); + + arena_run_tree_insert(&bin->runs, miscelm); +} + +static void +arena_bin_runs_remove(arena_bin_t *bin, arena_run_t *run) +{ + arena_chunk_map_misc_t *miscelm = arena_run_to_miscelm(run); + + assert(arena_run_tree_search(&bin->runs, miscelm) != NULL); + + arena_run_tree_remove(&bin->runs, miscelm); +} + +static arena_run_t * +arena_bin_nonfull_run_tryget(arena_bin_t *bin) +{ + arena_run_t *run = arena_bin_runs_first(bin); + if (run != NULL) { + arena_bin_runs_remove(bin, run); + if (config_stats) + bin->stats.reruns++; + } + return (run); +} + +static arena_run_t * +arena_bin_nonfull_run_get(arena_t *arena, arena_bin_t *bin) +{ + arena_run_t *run; + szind_t binind; + arena_bin_info_t *bin_info; + + /* Look for a usable run. */ + run = arena_bin_nonfull_run_tryget(bin); + if (run != NULL) + return (run); + /* No existing runs have any space available. */ + + binind = arena_bin_index(arena, bin); + bin_info = &arena_bin_info[binind]; + + /* Allocate a new run. */ + malloc_mutex_unlock(&bin->lock); + /******************************/ + malloc_mutex_lock(&arena->lock); + run = arena_run_alloc_small(arena, bin_info->run_size, binind); + if (run != NULL) { + /* Initialize run internals. */ + run->binind = binind; + run->nfree = bin_info->nregs; + bitmap_init(run->bitmap, &bin_info->bitmap_info); + } + malloc_mutex_unlock(&arena->lock); + /********************************/ + malloc_mutex_lock(&bin->lock); + if (run != NULL) { + if (config_stats) { + bin->stats.nruns++; + bin->stats.curruns++; + } + return (run); + } + + /* + * arena_run_alloc_small() failed, but another thread may have made + * sufficient memory available while this one dropped bin->lock above, + * so search one more time. + */ + run = arena_bin_nonfull_run_tryget(bin); + if (run != NULL) + return (run); + + return (NULL); +} + +/* Re-fill bin->runcur, then call arena_run_reg_alloc(). */ +static void * +arena_bin_malloc_hard(arena_t *arena, arena_bin_t *bin) +{ + szind_t binind; + arena_bin_info_t *bin_info; + arena_run_t *run; + + binind = arena_bin_index(arena, bin); + bin_info = &arena_bin_info[binind]; + bin->runcur = NULL; + run = arena_bin_nonfull_run_get(arena, bin); + if (bin->runcur != NULL && bin->runcur->nfree > 0) { + /* + * Another thread updated runcur while this one ran without the + * bin lock in arena_bin_nonfull_run_get(). + */ + void *ret; + assert(bin->runcur->nfree > 0); + ret = arena_run_reg_alloc(bin->runcur, bin_info); + if (run != NULL) { + arena_chunk_t *chunk; + + /* + * arena_run_alloc_small() may have allocated run, or + * it may have pulled run from the bin's run tree. + * Therefore it is unsafe to make any assumptions about + * how run has previously been used, and + * arena_bin_lower_run() must be called, as if a region + * were just deallocated from the run. + */ + chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(run); + if (run->nfree == bin_info->nregs) + arena_dalloc_bin_run(arena, chunk, run, bin); + else + arena_bin_lower_run(arena, chunk, run, bin); + } + return (ret); + } + + if (run == NULL) + return (NULL); + + bin->runcur = run; + + assert(bin->runcur->nfree > 0); + + return (arena_run_reg_alloc(bin->runcur, bin_info)); +} + +void +arena_tcache_fill_small(arena_t *arena, tcache_bin_t *tbin, szind_t binind, + uint64_t prof_accumbytes) +{ + unsigned i, nfill; + arena_bin_t *bin; + + assert(tbin->ncached == 0); + + if (config_prof && arena_prof_accum(arena, prof_accumbytes)) + prof_idump(); + bin = &arena->bins[binind]; + malloc_mutex_lock(&bin->lock); + for (i = 0, nfill = (tcache_bin_info[binind].ncached_max >> + tbin->lg_fill_div); i < nfill; i++) { + arena_run_t *run; + void *ptr; + if ((run = bin->runcur) != NULL && run->nfree > 0) + ptr = arena_run_reg_alloc(run, &arena_bin_info[binind]); + else + ptr = arena_bin_malloc_hard(arena, bin); + if (ptr == NULL) { + /* + * OOM. tbin->avail isn't yet filled down to its first + * element, so the successful allocations (if any) must + * be moved to the base of tbin->avail before bailing + * out. + */ + if (i > 0) { + memmove(tbin->avail, &tbin->avail[nfill - i], + i * sizeof(void *)); + } + break; + } + if (config_fill && unlikely(opt_junk_alloc)) { + arena_alloc_junk_small(ptr, &arena_bin_info[binind], + true); + } + /* Insert such that low regions get used first. */ + tbin->avail[nfill - 1 - i] = ptr; + } + if (config_stats) { + bin->stats.nmalloc += i; + bin->stats.nrequests += tbin->tstats.nrequests; + bin->stats.curregs += i; + bin->stats.nfills++; + tbin->tstats.nrequests = 0; + } + malloc_mutex_unlock(&bin->lock); + tbin->ncached = i; +} + +void +arena_alloc_junk_small(void *ptr, arena_bin_info_t *bin_info, bool zero) +{ + + if (zero) { + size_t redzone_size = bin_info->redzone_size; + memset((void *)((uintptr_t)ptr - redzone_size), 0xa5, + redzone_size); + memset((void *)((uintptr_t)ptr + bin_info->reg_size), 0xa5, + redzone_size); + } else { + memset((void *)((uintptr_t)ptr - bin_info->redzone_size), 0xa5, + bin_info->reg_interval); + } +} + +#ifdef JEMALLOC_JET +#undef arena_redzone_corruption +#define arena_redzone_corruption JEMALLOC_N(arena_redzone_corruption_impl) +#endif +static void +arena_redzone_corruption(void *ptr, size_t usize, bool after, + size_t offset, uint8_t byte) +{ + + malloc_printf(": Corrupt redzone %zu byte%s %s %p " + "(size %zu), byte=%#x\n", offset, (offset == 1) ? "" : "s", + after ? "after" : "before", ptr, usize, byte); +} +#ifdef JEMALLOC_JET +#undef arena_redzone_corruption +#define arena_redzone_corruption JEMALLOC_N(arena_redzone_corruption) +arena_redzone_corruption_t *arena_redzone_corruption = + JEMALLOC_N(arena_redzone_corruption_impl); +#endif + +static void +arena_redzones_validate(void *ptr, arena_bin_info_t *bin_info, bool reset) +{ + bool error = false; + + if (opt_junk_alloc) { + size_t size = bin_info->reg_size; + size_t redzone_size = bin_info->redzone_size; + size_t i; + + for (i = 1; i <= redzone_size; i++) { + uint8_t *byte = (uint8_t *)((uintptr_t)ptr - i); + if (*byte != 0xa5) { + error = true; + arena_redzone_corruption(ptr, size, false, i, + *byte); + if (reset) + *byte = 0xa5; + } + } + for (i = 0; i < redzone_size; i++) { + uint8_t *byte = (uint8_t *)((uintptr_t)ptr + size + i); + if (*byte != 0xa5) { + error = true; + arena_redzone_corruption(ptr, size, true, i, + *byte); + if (reset) + *byte = 0xa5; + } + } + } + + if (opt_abort && error) + abort(); +} + +#ifdef JEMALLOC_JET +#undef arena_dalloc_junk_small +#define arena_dalloc_junk_small JEMALLOC_N(arena_dalloc_junk_small_impl) +#endif +void +arena_dalloc_junk_small(void *ptr, arena_bin_info_t *bin_info) +{ + size_t redzone_size = bin_info->redzone_size; + + arena_redzones_validate(ptr, bin_info, false); + memset((void *)((uintptr_t)ptr - redzone_size), 0x5a, + bin_info->reg_interval); +} +#ifdef JEMALLOC_JET +#undef arena_dalloc_junk_small +#define arena_dalloc_junk_small JEMALLOC_N(arena_dalloc_junk_small) +arena_dalloc_junk_small_t *arena_dalloc_junk_small = + JEMALLOC_N(arena_dalloc_junk_small_impl); +#endif + +void +arena_quarantine_junk_small(void *ptr, size_t usize) +{ + szind_t binind; + arena_bin_info_t *bin_info; + cassert(config_fill); + assert(opt_junk_free); + assert(opt_quarantine); + assert(usize <= SMALL_MAXCLASS); + + binind = size2index(usize); + bin_info = &arena_bin_info[binind]; + arena_redzones_validate(ptr, bin_info, true); +} + +void * +arena_malloc_small(arena_t *arena, size_t size, bool zero) +{ + void *ret; + arena_bin_t *bin; + arena_run_t *run; + szind_t binind; + + binind = size2index(size); + assert(binind < NBINS); + bin = &arena->bins[binind]; + size = index2size(binind); + + malloc_mutex_lock(&bin->lock); + if ((run = bin->runcur) != NULL && run->nfree > 0) + ret = arena_run_reg_alloc(run, &arena_bin_info[binind]); + else + ret = arena_bin_malloc_hard(arena, bin); + + if (ret == NULL) { + malloc_mutex_unlock(&bin->lock); + return (NULL); + } + + if (config_stats) { + bin->stats.nmalloc++; + bin->stats.nrequests++; + bin->stats.curregs++; + } + malloc_mutex_unlock(&bin->lock); + if (config_prof && !isthreaded && arena_prof_accum(arena, size)) + prof_idump(); + + if (!zero) { + if (config_fill) { + if (unlikely(opt_junk_alloc)) { + arena_alloc_junk_small(ret, + &arena_bin_info[binind], false); + } else if (unlikely(opt_zero)) + memset(ret, 0, size); + } + JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(ret, size); + } else { + if (config_fill && unlikely(opt_junk_alloc)) { + arena_alloc_junk_small(ret, &arena_bin_info[binind], + true); + } + JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(ret, size); + memset(ret, 0, size); + } + + return (ret); +} + +void * +arena_malloc_large(arena_t *arena, size_t size, bool zero) +{ + void *ret; + size_t usize; + uintptr_t random_offset; + arena_run_t *run; + arena_chunk_map_misc_t *miscelm; + UNUSED bool idump; + + /* Large allocation. */ + usize = s2u(size); + malloc_mutex_lock(&arena->lock); + if (config_cache_oblivious) { + uint64_t r; + + /* + * Compute a uniformly distributed offset within the first page + * that is a multiple of the cacheline size, e.g. [0 .. 63) * 64 + * for 4 KiB pages and 64-byte cachelines. + */ + prng64(r, LG_PAGE - LG_CACHELINE, arena->offset_state, + UINT64_C(6364136223846793009), + UINT64_C(1442695040888963409)); + random_offset = ((uintptr_t)r) << LG_CACHELINE; + } else + random_offset = 0; + run = arena_run_alloc_large(arena, usize + large_pad, zero); + if (run == NULL) { + malloc_mutex_unlock(&arena->lock); + return (NULL); + } + miscelm = arena_run_to_miscelm(run); + ret = (void *)((uintptr_t)arena_miscelm_to_rpages(miscelm) + + random_offset); + if (config_stats) { + szind_t index = size2index(usize) - NBINS; + + arena->stats.nmalloc_large++; + arena->stats.nrequests_large++; + arena->stats.allocated_large += usize; + arena->stats.lstats[index].nmalloc++; + arena->stats.lstats[index].nrequests++; + arena->stats.lstats[index].curruns++; + } + if (config_prof) + idump = arena_prof_accum_locked(arena, usize); + malloc_mutex_unlock(&arena->lock); + if (config_prof && idump) + prof_idump(); + + if (!zero) { + if (config_fill) { + if (unlikely(opt_junk_alloc)) + memset(ret, 0xa5, usize); + else if (unlikely(opt_zero)) + memset(ret, 0, usize); + } + } + + return (ret); +} + +/* Only handles large allocations that require more than page alignment. */ +static void * +arena_palloc_large(tsd_t *tsd, arena_t *arena, size_t usize, size_t alignment, + bool zero) +{ + void *ret; + size_t alloc_size, leadsize, trailsize; + arena_run_t *run; + arena_chunk_t *chunk; + arena_chunk_map_misc_t *miscelm; + void *rpages; + + assert(usize == PAGE_CEILING(usize)); + + arena = arena_choose(tsd, arena); + if (unlikely(arena == NULL)) + return (NULL); + + alignment = PAGE_CEILING(alignment); + alloc_size = usize + large_pad + alignment - PAGE; + + malloc_mutex_lock(&arena->lock); + run = arena_run_alloc_large(arena, alloc_size, false); + if (run == NULL) { + malloc_mutex_unlock(&arena->lock); + return (NULL); + } + chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(run); + miscelm = arena_run_to_miscelm(run); + rpages = arena_miscelm_to_rpages(miscelm); + + leadsize = ALIGNMENT_CEILING((uintptr_t)rpages, alignment) - + (uintptr_t)rpages; + assert(alloc_size >= leadsize + usize); + trailsize = alloc_size - leadsize - usize - large_pad; + if (leadsize != 0) { + arena_chunk_map_misc_t *head_miscelm = miscelm; + arena_run_t *head_run = run; + + miscelm = arena_miscelm_get(chunk, + arena_miscelm_to_pageind(head_miscelm) + (leadsize >> + LG_PAGE)); + run = &miscelm->run; + + arena_run_trim_head(arena, chunk, head_run, alloc_size, + alloc_size - leadsize); + } + if (trailsize != 0) { + arena_run_trim_tail(arena, chunk, run, usize + large_pad + + trailsize, usize + large_pad, false); + } + if (arena_run_init_large(arena, run, usize + large_pad, zero)) { + size_t run_ind = + arena_miscelm_to_pageind(arena_run_to_miscelm(run)); + bool dirty = (arena_mapbits_dirty_get(chunk, run_ind) != 0); + bool decommitted = (arena_mapbits_decommitted_get(chunk, + run_ind) != 0); + + assert(decommitted); /* Cause of OOM. */ + arena_run_dalloc(arena, run, dirty, false, decommitted); + malloc_mutex_unlock(&arena->lock); + return (NULL); + } + ret = arena_miscelm_to_rpages(miscelm); + + if (config_stats) { + szind_t index = size2index(usize) - NBINS; + + arena->stats.nmalloc_large++; + arena->stats.nrequests_large++; + arena->stats.allocated_large += usize; + arena->stats.lstats[index].nmalloc++; + arena->stats.lstats[index].nrequests++; + arena->stats.lstats[index].curruns++; + } + malloc_mutex_unlock(&arena->lock); + + if (config_fill && !zero) { + if (unlikely(opt_junk_alloc)) + memset(ret, 0xa5, usize); + else if (unlikely(opt_zero)) + memset(ret, 0, usize); + } + return (ret); +} + +void * +arena_palloc(tsd_t *tsd, arena_t *arena, size_t usize, size_t alignment, + bool zero, tcache_t *tcache) +{ + void *ret; + + if (usize <= SMALL_MAXCLASS && (alignment < PAGE || (alignment == PAGE + && (usize & PAGE_MASK) == 0))) { + /* Small; alignment doesn't require special run placement. */ + ret = arena_malloc(tsd, arena, usize, zero, tcache); + } else if (usize <= large_maxclass && alignment <= PAGE) { + /* + * Large; alignment doesn't require special run placement. + * However, the cached pointer may be at a random offset from + * the base of the run, so do some bit manipulation to retrieve + * the base. + */ + ret = arena_malloc(tsd, arena, usize, zero, tcache); + if (config_cache_oblivious) + ret = (void *)((uintptr_t)ret & ~PAGE_MASK); + } else { + if (likely(usize <= large_maxclass)) { + ret = arena_palloc_large(tsd, arena, usize, alignment, + zero); + } else if (likely(alignment <= chunksize)) + ret = huge_malloc(tsd, arena, usize, zero, tcache); + else { + ret = huge_palloc(tsd, arena, usize, alignment, zero, + tcache); + } + } + return (ret); +} + +void +arena_prof_promoted(const void *ptr, size_t size) +{ + arena_chunk_t *chunk; + size_t pageind; + szind_t binind; + + cassert(config_prof); + assert(ptr != NULL); + assert(CHUNK_ADDR2BASE(ptr) != ptr); + assert(isalloc(ptr, false) == LARGE_MINCLASS); + assert(isalloc(ptr, true) == LARGE_MINCLASS); + assert(size <= SMALL_MAXCLASS); + + chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr); + pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE; + binind = size2index(size); + assert(binind < NBINS); + arena_mapbits_large_binind_set(chunk, pageind, binind); + + assert(isalloc(ptr, false) == LARGE_MINCLASS); + assert(isalloc(ptr, true) == size); +} + +static void +arena_dissociate_bin_run(arena_chunk_t *chunk, arena_run_t *run, + arena_bin_t *bin) +{ + + /* Dissociate run from bin. */ + if (run == bin->runcur) + bin->runcur = NULL; + else { + szind_t binind = arena_bin_index(extent_node_arena_get( + &chunk->node), bin); + arena_bin_info_t *bin_info = &arena_bin_info[binind]; + + if (bin_info->nregs != 1) { + /* + * This block's conditional is necessary because if the + * run only contains one region, then it never gets + * inserted into the non-full runs tree. + */ + arena_bin_runs_remove(bin, run); + } + } +} + +static void +arena_dalloc_bin_run(arena_t *arena, arena_chunk_t *chunk, arena_run_t *run, + arena_bin_t *bin) +{ + + assert(run != bin->runcur); + assert(arena_run_tree_search(&bin->runs, arena_run_to_miscelm(run)) == + NULL); + + malloc_mutex_unlock(&bin->lock); + /******************************/ + malloc_mutex_lock(&arena->lock); + arena_run_dalloc_decommit(arena, chunk, run); + malloc_mutex_unlock(&arena->lock); + /****************************/ + malloc_mutex_lock(&bin->lock); + if (config_stats) + bin->stats.curruns--; +} + +static void +arena_bin_lower_run(arena_t *arena, arena_chunk_t *chunk, arena_run_t *run, + arena_bin_t *bin) +{ + + /* + * Make sure that if bin->runcur is non-NULL, it refers to the lowest + * non-full run. It is okay to NULL runcur out rather than proactively + * keeping it pointing at the lowest non-full run. + */ + if ((uintptr_t)run < (uintptr_t)bin->runcur) { + /* Switch runcur. */ + if (bin->runcur->nfree > 0) + arena_bin_runs_insert(bin, bin->runcur); + bin->runcur = run; + if (config_stats) + bin->stats.reruns++; + } else + arena_bin_runs_insert(bin, run); +} + +static void +arena_dalloc_bin_locked_impl(arena_t *arena, arena_chunk_t *chunk, void *ptr, + arena_chunk_map_bits_t *bitselm, bool junked) +{ + size_t pageind, rpages_ind; + arena_run_t *run; + arena_bin_t *bin; + arena_bin_info_t *bin_info; + szind_t binind; + + pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE; + rpages_ind = pageind - arena_mapbits_small_runind_get(chunk, pageind); + run = &arena_miscelm_get(chunk, rpages_ind)->run; + binind = run->binind; + bin = &arena->bins[binind]; + bin_info = &arena_bin_info[binind]; + + if (!junked && config_fill && unlikely(opt_junk_free)) + arena_dalloc_junk_small(ptr, bin_info); + + arena_run_reg_dalloc(run, ptr); + if (run->nfree == bin_info->nregs) { + arena_dissociate_bin_run(chunk, run, bin); + arena_dalloc_bin_run(arena, chunk, run, bin); + } else if (run->nfree == 1 && run != bin->runcur) + arena_bin_lower_run(arena, chunk, run, bin); + + if (config_stats) { + bin->stats.ndalloc++; + bin->stats.curregs--; + } +} + +void +arena_dalloc_bin_junked_locked(arena_t *arena, arena_chunk_t *chunk, void *ptr, + arena_chunk_map_bits_t *bitselm) +{ + + arena_dalloc_bin_locked_impl(arena, chunk, ptr, bitselm, true); +} + +void +arena_dalloc_bin(arena_t *arena, arena_chunk_t *chunk, void *ptr, + size_t pageind, arena_chunk_map_bits_t *bitselm) +{ + arena_run_t *run; + arena_bin_t *bin; + size_t rpages_ind; + + rpages_ind = pageind - arena_mapbits_small_runind_get(chunk, pageind); + run = &arena_miscelm_get(chunk, rpages_ind)->run; + bin = &arena->bins[run->binind]; + malloc_mutex_lock(&bin->lock); + arena_dalloc_bin_locked_impl(arena, chunk, ptr, bitselm, false); + malloc_mutex_unlock(&bin->lock); +} + +void +arena_dalloc_small(arena_t *arena, arena_chunk_t *chunk, void *ptr, + size_t pageind) +{ + arena_chunk_map_bits_t *bitselm; + + if (config_debug) { + /* arena_ptr_small_binind_get() does extra sanity checking. */ + assert(arena_ptr_small_binind_get(ptr, arena_mapbits_get(chunk, + pageind)) != BININD_INVALID); + } + bitselm = arena_bitselm_get(chunk, pageind); + arena_dalloc_bin(arena, chunk, ptr, pageind, bitselm); +} + +#ifdef JEMALLOC_JET +#undef arena_dalloc_junk_large +#define arena_dalloc_junk_large JEMALLOC_N(arena_dalloc_junk_large_impl) +#endif +void +arena_dalloc_junk_large(void *ptr, size_t usize) +{ + + if (config_fill && unlikely(opt_junk_free)) + memset(ptr, 0x5a, usize); +} +#ifdef JEMALLOC_JET +#undef arena_dalloc_junk_large +#define arena_dalloc_junk_large JEMALLOC_N(arena_dalloc_junk_large) +arena_dalloc_junk_large_t *arena_dalloc_junk_large = + JEMALLOC_N(arena_dalloc_junk_large_impl); +#endif + +static void +arena_dalloc_large_locked_impl(arena_t *arena, arena_chunk_t *chunk, + void *ptr, bool junked) +{ + size_t pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE; + arena_chunk_map_misc_t *miscelm = arena_miscelm_get(chunk, pageind); + arena_run_t *run = &miscelm->run; + + if (config_fill || config_stats) { + size_t usize = arena_mapbits_large_size_get(chunk, pageind) - + large_pad; + + if (!junked) + arena_dalloc_junk_large(ptr, usize); + if (config_stats) { + szind_t index = size2index(usize) - NBINS; + + arena->stats.ndalloc_large++; + arena->stats.allocated_large -= usize; + arena->stats.lstats[index].ndalloc++; + arena->stats.lstats[index].curruns--; + } + } + + arena_run_dalloc_decommit(arena, chunk, run); +} + +void +arena_dalloc_large_junked_locked(arena_t *arena, arena_chunk_t *chunk, + void *ptr) +{ + + arena_dalloc_large_locked_impl(arena, chunk, ptr, true); +} + +void +arena_dalloc_large(arena_t *arena, arena_chunk_t *chunk, void *ptr) +{ + + malloc_mutex_lock(&arena->lock); + arena_dalloc_large_locked_impl(arena, chunk, ptr, false); + malloc_mutex_unlock(&arena->lock); +} + +static void +arena_ralloc_large_shrink(arena_t *arena, arena_chunk_t *chunk, void *ptr, + size_t oldsize, size_t size) +{ + size_t pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE; + arena_chunk_map_misc_t *miscelm = arena_miscelm_get(chunk, pageind); + arena_run_t *run = &miscelm->run; + + assert(size < oldsize); + + /* + * Shrink the run, and make trailing pages available for other + * allocations. + */ + malloc_mutex_lock(&arena->lock); + arena_run_trim_tail(arena, chunk, run, oldsize + large_pad, size + + large_pad, true); + if (config_stats) { + szind_t oldindex = size2index(oldsize) - NBINS; + szind_t index = size2index(size) - NBINS; + + arena->stats.ndalloc_large++; + arena->stats.allocated_large -= oldsize; + arena->stats.lstats[oldindex].ndalloc++; + arena->stats.lstats[oldindex].curruns--; + + arena->stats.nmalloc_large++; + arena->stats.nrequests_large++; + arena->stats.allocated_large += size; + arena->stats.lstats[index].nmalloc++; + arena->stats.lstats[index].nrequests++; + arena->stats.lstats[index].curruns++; + } + malloc_mutex_unlock(&arena->lock); +} + +static bool +arena_ralloc_large_grow(arena_t *arena, arena_chunk_t *chunk, void *ptr, + size_t oldsize, size_t usize_min, size_t usize_max, bool zero) +{ + size_t pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE; + size_t npages = (oldsize + large_pad) >> LG_PAGE; + size_t followsize; + + assert(oldsize == arena_mapbits_large_size_get(chunk, pageind) - + large_pad); + + /* Try to extend the run. */ + malloc_mutex_lock(&arena->lock); + if (pageind+npages >= chunk_npages || arena_mapbits_allocated_get(chunk, + pageind+npages) != 0) + goto label_fail; + followsize = arena_mapbits_unallocated_size_get(chunk, pageind+npages); + if (oldsize + followsize >= usize_min) { + /* + * The next run is available and sufficiently large. Split the + * following run, then merge the first part with the existing + * allocation. + */ + arena_run_t *run; + size_t usize, splitsize, size, flag_dirty, flag_unzeroed_mask; + + usize = usize_max; + while (oldsize + followsize < usize) + usize = index2size(size2index(usize)-1); + assert(usize >= usize_min); + assert(usize >= oldsize); + splitsize = usize - oldsize; + if (splitsize == 0) + goto label_fail; + + run = &arena_miscelm_get(chunk, pageind+npages)->run; + if (arena_run_split_large(arena, run, splitsize, zero)) + goto label_fail; + + if (config_cache_oblivious && zero) { + /* + * Zero the trailing bytes of the original allocation's + * last page, since they are in an indeterminate state. + */ + assert(PAGE_CEILING(oldsize) == oldsize); + memset((void *)((uintptr_t)ptr + oldsize), 0, + PAGE_CEILING((uintptr_t)ptr) - (uintptr_t)ptr); + } + + size = oldsize + splitsize; + npages = (size + large_pad) >> LG_PAGE; + + /* + * Mark the extended run as dirty if either portion of the run + * was dirty before allocation. This is rather pedantic, + * because there's not actually any sequence of events that + * could cause the resulting run to be passed to + * arena_run_dalloc() with the dirty argument set to false + * (which is when dirty flag consistency would really matter). + */ + flag_dirty = arena_mapbits_dirty_get(chunk, pageind) | + arena_mapbits_dirty_get(chunk, pageind+npages-1); + flag_unzeroed_mask = flag_dirty == 0 ? CHUNK_MAP_UNZEROED : 0; + arena_mapbits_large_set(chunk, pageind, size + large_pad, + flag_dirty | (flag_unzeroed_mask & + arena_mapbits_unzeroed_get(chunk, pageind))); + arena_mapbits_large_set(chunk, pageind+npages-1, 0, flag_dirty | + (flag_unzeroed_mask & arena_mapbits_unzeroed_get(chunk, + pageind+npages-1))); + + if (config_stats) { + szind_t oldindex = size2index(oldsize) - NBINS; + szind_t index = size2index(size) - NBINS; + + arena->stats.ndalloc_large++; + arena->stats.allocated_large -= oldsize; + arena->stats.lstats[oldindex].ndalloc++; + arena->stats.lstats[oldindex].curruns--; + + arena->stats.nmalloc_large++; + arena->stats.nrequests_large++; + arena->stats.allocated_large += size; + arena->stats.lstats[index].nmalloc++; + arena->stats.lstats[index].nrequests++; + arena->stats.lstats[index].curruns++; + } + malloc_mutex_unlock(&arena->lock); + return (false); + } +label_fail: + malloc_mutex_unlock(&arena->lock); + return (true); +} + +#ifdef JEMALLOC_JET +#undef arena_ralloc_junk_large +#define arena_ralloc_junk_large JEMALLOC_N(arena_ralloc_junk_large_impl) +#endif +static void +arena_ralloc_junk_large(void *ptr, size_t old_usize, size_t usize) +{ + + if (config_fill && unlikely(opt_junk_free)) { + memset((void *)((uintptr_t)ptr + usize), 0x5a, + old_usize - usize); + } +} +#ifdef JEMALLOC_JET +#undef arena_ralloc_junk_large +#define arena_ralloc_junk_large JEMALLOC_N(arena_ralloc_junk_large) +arena_ralloc_junk_large_t *arena_ralloc_junk_large = + JEMALLOC_N(arena_ralloc_junk_large_impl); +#endif + +/* + * Try to resize a large allocation, in order to avoid copying. This will + * always fail if growing an object, and the following run is already in use. + */ +static bool +arena_ralloc_large(void *ptr, size_t oldsize, size_t usize_min, + size_t usize_max, bool zero) +{ + arena_chunk_t *chunk; + arena_t *arena; + + if (oldsize == usize_max) { + /* Current size class is compatible and maximal. */ + return (false); + } + + chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr); + arena = extent_node_arena_get(&chunk->node); + + if (oldsize < usize_max) { + bool ret = arena_ralloc_large_grow(arena, chunk, ptr, oldsize, + usize_min, usize_max, zero); + if (config_fill && !ret && !zero) { + if (unlikely(opt_junk_alloc)) { + memset((void *)((uintptr_t)ptr + oldsize), 0xa5, + isalloc(ptr, config_prof) - oldsize); + } else if (unlikely(opt_zero)) { + memset((void *)((uintptr_t)ptr + oldsize), 0, + isalloc(ptr, config_prof) - oldsize); + } + } + return (ret); + } + + assert(oldsize > usize_max); + /* Fill before shrinking in order avoid a race. */ + arena_ralloc_junk_large(ptr, oldsize, usize_max); + arena_ralloc_large_shrink(arena, chunk, ptr, oldsize, usize_max); + return (false); +} + +bool +arena_ralloc_no_move(void *ptr, size_t oldsize, size_t size, size_t extra, + bool zero) +{ + size_t usize_min, usize_max; + + usize_min = s2u(size); + usize_max = s2u(size + extra); + if (likely(oldsize <= large_maxclass && usize_min <= large_maxclass)) { + /* + * Avoid moving the allocation if the size class can be left the + * same. + */ + if (oldsize <= SMALL_MAXCLASS) { + assert(arena_bin_info[size2index(oldsize)].reg_size == + oldsize); + if ((usize_max <= SMALL_MAXCLASS && + size2index(usize_max) == size2index(oldsize)) || + (size <= oldsize && usize_max >= oldsize)) + return (false); + } else { + if (usize_max > SMALL_MAXCLASS) { + if (!arena_ralloc_large(ptr, oldsize, usize_min, + usize_max, zero)) + return (false); + } + } + + /* Reallocation would require a move. */ + return (true); + } else { + return (huge_ralloc_no_move(ptr, oldsize, usize_min, usize_max, + zero)); + } +} + +static void * +arena_ralloc_move_helper(tsd_t *tsd, arena_t *arena, size_t usize, + size_t alignment, bool zero, tcache_t *tcache) +{ + + if (alignment == 0) + return (arena_malloc(tsd, arena, usize, zero, tcache)); + usize = sa2u(usize, alignment); + if (usize == 0) + return (NULL); + return (ipalloct(tsd, usize, alignment, zero, tcache, arena)); +} + +void * +arena_ralloc(tsd_t *tsd, arena_t *arena, void *ptr, size_t oldsize, size_t size, + size_t alignment, bool zero, tcache_t *tcache) +{ + void *ret; + size_t usize; + + usize = s2u(size); + if (usize == 0) + return (NULL); + + if (likely(usize <= large_maxclass)) { + size_t copysize; + + /* Try to avoid moving the allocation. */ + if (!arena_ralloc_no_move(ptr, oldsize, usize, 0, zero)) + return (ptr); + + /* + * size and oldsize are different enough that we need to move + * the object. In that case, fall back to allocating new space + * and copying. + */ + ret = arena_ralloc_move_helper(tsd, arena, usize, alignment, + zero, tcache); + if (ret == NULL) + return (NULL); + + /* + * Junk/zero-filling were already done by + * ipalloc()/arena_malloc(). + */ + + copysize = (usize < oldsize) ? usize : oldsize; + JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(ret, copysize); + memcpy(ret, ptr, copysize); + isqalloc(tsd, ptr, oldsize, tcache); + } else { + ret = huge_ralloc(tsd, arena, ptr, oldsize, usize, alignment, + zero, tcache); + } + return (ret); +} + +dss_prec_t +arena_dss_prec_get(arena_t *arena) +{ + dss_prec_t ret; + + malloc_mutex_lock(&arena->lock); + ret = arena->dss_prec; + malloc_mutex_unlock(&arena->lock); + return (ret); +} + +bool +arena_dss_prec_set(arena_t *arena, dss_prec_t dss_prec) +{ + + if (!have_dss) + return (dss_prec != dss_prec_disabled); + malloc_mutex_lock(&arena->lock); + arena->dss_prec = dss_prec; + malloc_mutex_unlock(&arena->lock); + return (false); +} + +ssize_t +arena_lg_dirty_mult_default_get(void) +{ + + return ((ssize_t)atomic_read_z((size_t *)&lg_dirty_mult_default)); +} + +bool +arena_lg_dirty_mult_default_set(ssize_t lg_dirty_mult) +{ + + if (!arena_lg_dirty_mult_valid(lg_dirty_mult)) + return (true); + atomic_write_z((size_t *)&lg_dirty_mult_default, (size_t)lg_dirty_mult); + return (false); +} + +void +arena_stats_merge(arena_t *arena, const char **dss, ssize_t *lg_dirty_mult, + size_t *nactive, size_t *ndirty, arena_stats_t *astats, + malloc_bin_stats_t *bstats, malloc_large_stats_t *lstats, + malloc_huge_stats_t *hstats) +{ + unsigned i; + + malloc_mutex_lock(&arena->lock); + *dss = dss_prec_names[arena->dss_prec]; + *lg_dirty_mult = arena->lg_dirty_mult; + *nactive += arena->nactive; + *ndirty += arena->ndirty; + + astats->mapped += arena->stats.mapped; + astats->npurge += arena->stats.npurge; + astats->nmadvise += arena->stats.nmadvise; + astats->purged += arena->stats.purged; + astats->metadata_mapped += arena->stats.metadata_mapped; + astats->metadata_allocated += arena_metadata_allocated_get(arena); + astats->allocated_large += arena->stats.allocated_large; + astats->nmalloc_large += arena->stats.nmalloc_large; + astats->ndalloc_large += arena->stats.ndalloc_large; + astats->nrequests_large += arena->stats.nrequests_large; + astats->allocated_huge += arena->stats.allocated_huge; + astats->nmalloc_huge += arena->stats.nmalloc_huge; + astats->ndalloc_huge += arena->stats.ndalloc_huge; + + for (i = 0; i < nlclasses; i++) { + lstats[i].nmalloc += arena->stats.lstats[i].nmalloc; + lstats[i].ndalloc += arena->stats.lstats[i].ndalloc; + lstats[i].nrequests += arena->stats.lstats[i].nrequests; + lstats[i].curruns += arena->stats.lstats[i].curruns; + } + + for (i = 0; i < nhclasses; i++) { + hstats[i].nmalloc += arena->stats.hstats[i].nmalloc; + hstats[i].ndalloc += arena->stats.hstats[i].ndalloc; + hstats[i].curhchunks += arena->stats.hstats[i].curhchunks; + } + malloc_mutex_unlock(&arena->lock); + + for (i = 0; i < NBINS; i++) { + arena_bin_t *bin = &arena->bins[i]; + + malloc_mutex_lock(&bin->lock); + bstats[i].nmalloc += bin->stats.nmalloc; + bstats[i].ndalloc += bin->stats.ndalloc; + bstats[i].nrequests += bin->stats.nrequests; + bstats[i].curregs += bin->stats.curregs; + if (config_tcache) { + bstats[i].nfills += bin->stats.nfills; + bstats[i].nflushes += bin->stats.nflushes; + } + bstats[i].nruns += bin->stats.nruns; + bstats[i].reruns += bin->stats.reruns; + bstats[i].curruns += bin->stats.curruns; + malloc_mutex_unlock(&bin->lock); + } +} + +arena_t * +arena_new(unsigned ind) +{ + arena_t *arena; + unsigned i; + arena_bin_t *bin; + + /* + * Allocate arena, arena->lstats, and arena->hstats contiguously, mainly + * because there is no way to clean up if base_alloc() OOMs. + */ + if (config_stats) { + arena = (arena_t *)base_alloc(CACHELINE_CEILING(sizeof(arena_t)) + + QUANTUM_CEILING(nlclasses * sizeof(malloc_large_stats_t) + + nhclasses) * sizeof(malloc_huge_stats_t)); + } else + arena = (arena_t *)base_alloc(sizeof(arena_t)); + if (arena == NULL) + return (NULL); + + arena->ind = ind; + arena->nthreads = 0; + if (malloc_mutex_init(&arena->lock)) + return (NULL); + + if (config_stats) { + memset(&arena->stats, 0, sizeof(arena_stats_t)); + arena->stats.lstats = (malloc_large_stats_t *)((uintptr_t)arena + + CACHELINE_CEILING(sizeof(arena_t))); + memset(arena->stats.lstats, 0, nlclasses * + sizeof(malloc_large_stats_t)); + arena->stats.hstats = (malloc_huge_stats_t *)((uintptr_t)arena + + CACHELINE_CEILING(sizeof(arena_t)) + + QUANTUM_CEILING(nlclasses * sizeof(malloc_large_stats_t))); + memset(arena->stats.hstats, 0, nhclasses * + sizeof(malloc_huge_stats_t)); + if (config_tcache) + ql_new(&arena->tcache_ql); + } + + if (config_prof) + arena->prof_accumbytes = 0; + + if (config_cache_oblivious) { + /* + * A nondeterministic seed based on the address of arena reduces + * the likelihood of lockstep non-uniform cache index + * utilization among identical concurrent processes, but at the + * cost of test repeatability. For debug builds, instead use a + * deterministic seed. + */ + arena->offset_state = config_debug ? ind : + (uint64_t)(uintptr_t)arena; + } + + arena->dss_prec = chunk_dss_prec_get(); + + arena->spare = NULL; + + arena->lg_dirty_mult = arena_lg_dirty_mult_default_get(); + arena->purging = false; + arena->nactive = 0; + arena->ndirty = 0; + + arena_avail_tree_new(&arena->runs_avail); + qr_new(&arena->runs_dirty, rd_link); + qr_new(&arena->chunks_cache, cc_link); + + ql_new(&arena->huge); + if (malloc_mutex_init(&arena->huge_mtx)) + return (NULL); + + extent_tree_szad_new(&arena->chunks_szad_cached); + extent_tree_ad_new(&arena->chunks_ad_cached); + extent_tree_szad_new(&arena->chunks_szad_retained); + extent_tree_ad_new(&arena->chunks_ad_retained); + if (malloc_mutex_init(&arena->chunks_mtx)) + return (NULL); + ql_new(&arena->node_cache); + if (malloc_mutex_init(&arena->node_cache_mtx)) + return (NULL); + + arena->chunk_hooks = chunk_hooks_default; + + /* Initialize bins. */ + for (i = 0; i < NBINS; i++) { + bin = &arena->bins[i]; + if (malloc_mutex_init(&bin->lock)) + return (NULL); + bin->runcur = NULL; + arena_run_tree_new(&bin->runs); + if (config_stats) + memset(&bin->stats, 0, sizeof(malloc_bin_stats_t)); + } + + return (arena); +} + +/* + * Calculate bin_info->run_size such that it meets the following constraints: + * + * *) bin_info->run_size <= arena_maxrun + * *) bin_info->nregs <= RUN_MAXREGS + * + * bin_info->nregs and bin_info->reg0_offset are also calculated here, since + * these settings are all interdependent. + */ +static void +bin_info_run_size_calc(arena_bin_info_t *bin_info) +{ + size_t pad_size; + size_t try_run_size, perfect_run_size, actual_run_size; + uint32_t try_nregs, perfect_nregs, actual_nregs; + + /* + * Determine redzone size based on minimum alignment and minimum + * redzone size. Add padding to the end of the run if it is needed to + * align the regions. The padding allows each redzone to be half the + * minimum alignment; without the padding, each redzone would have to + * be twice as large in order to maintain alignment. + */ + if (config_fill && unlikely(opt_redzone)) { + size_t align_min = ZU(1) << (jemalloc_ffs(bin_info->reg_size) - + 1); + if (align_min <= REDZONE_MINSIZE) { + bin_info->redzone_size = REDZONE_MINSIZE; + pad_size = 0; + } else { + bin_info->redzone_size = align_min >> 1; + pad_size = bin_info->redzone_size; + } + } else { + bin_info->redzone_size = 0; + pad_size = 0; + } + bin_info->reg_interval = bin_info->reg_size + + (bin_info->redzone_size << 1); + + /* + * Compute run size under ideal conditions (no redzones, no limit on run + * size). + */ + try_run_size = PAGE; + try_nregs = try_run_size / bin_info->reg_size; + do { + perfect_run_size = try_run_size; + perfect_nregs = try_nregs; + + try_run_size += PAGE; + try_nregs = try_run_size / bin_info->reg_size; + } while (perfect_run_size != perfect_nregs * bin_info->reg_size); + assert(perfect_nregs <= RUN_MAXREGS); + + actual_run_size = perfect_run_size; + actual_nregs = (actual_run_size - pad_size) / bin_info->reg_interval; + + /* + * Redzones can require enough padding that not even a single region can + * fit within the number of pages that would normally be dedicated to a + * run for this size class. Increase the run size until at least one + * region fits. + */ + while (actual_nregs == 0) { + assert(config_fill && unlikely(opt_redzone)); + + actual_run_size += PAGE; + actual_nregs = (actual_run_size - pad_size) / + bin_info->reg_interval; + } + + /* + * Make sure that the run will fit within an arena chunk. + */ + while (actual_run_size > arena_maxrun) { + actual_run_size -= PAGE; + actual_nregs = (actual_run_size - pad_size) / + bin_info->reg_interval; + } + assert(actual_nregs > 0); + assert(actual_run_size == s2u(actual_run_size)); + + /* Copy final settings. */ + bin_info->run_size = actual_run_size; + bin_info->nregs = actual_nregs; + bin_info->reg0_offset = actual_run_size - (actual_nregs * + bin_info->reg_interval) - pad_size + bin_info->redzone_size; + + if (actual_run_size > small_maxrun) + small_maxrun = actual_run_size; + + assert(bin_info->reg0_offset - bin_info->redzone_size + (bin_info->nregs + * bin_info->reg_interval) + pad_size == bin_info->run_size); +} + +static void +bin_info_init(void) +{ + arena_bin_info_t *bin_info; + +#define BIN_INFO_INIT_bin_yes(index, size) \ + bin_info = &arena_bin_info[index]; \ + bin_info->reg_size = size; \ + bin_info_run_size_calc(bin_info); \ + bitmap_info_init(&bin_info->bitmap_info, bin_info->nregs); +#define BIN_INFO_INIT_bin_no(index, size) +#define SC(index, lg_grp, lg_delta, ndelta, bin, lg_delta_lookup) \ + BIN_INFO_INIT_bin_##bin(index, (ZU(1)<> + LG_PAGE)); + if (small_run_tab == NULL) + return (true); + +#define TAB_INIT_bin_yes(index, size) { \ + arena_bin_info_t *bin_info = &arena_bin_info[index]; \ + small_run_tab[bin_info->run_size >> LG_PAGE] = true; \ + } +#define TAB_INIT_bin_no(index, size) +#define SC(index, lg_grp, lg_delta, ndelta, bin, lg_delta_lookup) \ + TAB_INIT_bin_##bin(index, (ZU(1)<= the result + * from (2), and will always be correct. + */ + map_bias = 0; + for (i = 0; i < 3; i++) { + size_t header_size = offsetof(arena_chunk_t, map_bits) + + ((sizeof(arena_chunk_map_bits_t) + + sizeof(arena_chunk_map_misc_t)) * (chunk_npages-map_bias)); + map_bias = (header_size + PAGE_MASK) >> LG_PAGE; + } + assert(map_bias > 0); + + map_misc_offset = offsetof(arena_chunk_t, map_bits) + + sizeof(arena_chunk_map_bits_t) * (chunk_npages-map_bias); + + arena_maxrun = chunksize - (map_bias << LG_PAGE); + assert(arena_maxrun > 0); + large_maxclass = index2size(size2index(chunksize)-1); + if (large_maxclass > arena_maxrun) { + /* + * For small chunk sizes it's possible for there to be fewer + * non-header pages available than are necessary to serve the + * size classes just below chunksize. + */ + large_maxclass = arena_maxrun; + } + assert(large_maxclass > 0); + nlclasses = size2index(large_maxclass) - size2index(SMALL_MAXCLASS); + nhclasses = NSIZES - nlclasses - NBINS; + + bin_info_init(); + return (small_run_size_init()); +} + +void +arena_prefork(arena_t *arena) +{ + unsigned i; + + malloc_mutex_prefork(&arena->lock); + malloc_mutex_prefork(&arena->huge_mtx); + malloc_mutex_prefork(&arena->chunks_mtx); + malloc_mutex_prefork(&arena->node_cache_mtx); + for (i = 0; i < NBINS; i++) + malloc_mutex_prefork(&arena->bins[i].lock); +} + +void +arena_postfork_parent(arena_t *arena) +{ + unsigned i; + + for (i = 0; i < NBINS; i++) + malloc_mutex_postfork_parent(&arena->bins[i].lock); + malloc_mutex_postfork_parent(&arena->node_cache_mtx); + malloc_mutex_postfork_parent(&arena->chunks_mtx); + malloc_mutex_postfork_parent(&arena->huge_mtx); + malloc_mutex_postfork_parent(&arena->lock); +} + +void +arena_postfork_child(arena_t *arena) +{ + unsigned i; + + for (i = 0; i < NBINS; i++) + malloc_mutex_postfork_child(&arena->bins[i].lock); + malloc_mutex_postfork_child(&arena->node_cache_mtx); + malloc_mutex_postfork_child(&arena->chunks_mtx); + malloc_mutex_postfork_child(&arena->huge_mtx); + malloc_mutex_postfork_child(&arena->lock); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/atomic.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/atomic.c new file mode 100644 index 0000000..77ee313 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/atomic.c @@ -0,0 +1,2 @@ +#define JEMALLOC_ATOMIC_C_ +#include "jemalloc/internal/jemalloc_internal.h" diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/base.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/base.c new file mode 100644 index 0000000..7cdcfed --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/base.c @@ -0,0 +1,174 @@ +#define JEMALLOC_BASE_C_ +#include "jemalloc/internal/jemalloc_internal.h" + +/******************************************************************************/ +/* Data. */ + +static malloc_mutex_t base_mtx; +static extent_tree_t base_avail_szad; +static extent_node_t *base_nodes; +static size_t base_allocated; +static size_t base_resident; +static size_t base_mapped; + +/******************************************************************************/ + +/* base_mtx must be held. */ +static extent_node_t * +base_node_try_alloc(void) +{ + extent_node_t *node; + + if (base_nodes == NULL) + return (NULL); + node = base_nodes; + base_nodes = *(extent_node_t **)node; + JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(node, sizeof(extent_node_t)); + return (node); +} + +/* base_mtx must be held. */ +static void +base_node_dalloc(extent_node_t *node) +{ + + JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(node, sizeof(extent_node_t)); + *(extent_node_t **)node = base_nodes; + base_nodes = node; +} + +/* base_mtx must be held. */ +static extent_node_t * +base_chunk_alloc(size_t minsize) +{ + extent_node_t *node; + size_t csize, nsize; + void *addr; + + assert(minsize != 0); + node = base_node_try_alloc(); + /* Allocate enough space to also carve a node out if necessary. */ + nsize = (node == NULL) ? CACHELINE_CEILING(sizeof(extent_node_t)) : 0; + csize = CHUNK_CEILING(minsize + nsize); + addr = chunk_alloc_base(csize); + if (addr == NULL) { + if (node != NULL) + base_node_dalloc(node); + return (NULL); + } + base_mapped += csize; + if (node == NULL) { + node = (extent_node_t *)addr; + addr = (void *)((uintptr_t)addr + nsize); + csize -= nsize; + if (config_stats) { + base_allocated += nsize; + base_resident += PAGE_CEILING(nsize); + } + } + extent_node_init(node, NULL, addr, csize, true, true); + return (node); +} + +/* + * base_alloc() guarantees demand-zeroed memory, in order to make multi-page + * sparse data structures such as radix tree nodes efficient with respect to + * physical memory usage. + */ +void * +base_alloc(size_t size) +{ + void *ret; + size_t csize, usize; + extent_node_t *node; + extent_node_t key; + + /* + * Round size up to nearest multiple of the cacheline size, so that + * there is no chance of false cache line sharing. + */ + csize = CACHELINE_CEILING(size); + + usize = s2u(csize); + extent_node_init(&key, NULL, NULL, usize, false, false); + malloc_mutex_lock(&base_mtx); + node = extent_tree_szad_nsearch(&base_avail_szad, &key); + if (node != NULL) { + /* Use existing space. */ + extent_tree_szad_remove(&base_avail_szad, node); + } else { + /* Try to allocate more space. */ + node = base_chunk_alloc(csize); + } + if (node == NULL) { + ret = NULL; + goto label_return; + } + + ret = extent_node_addr_get(node); + if (extent_node_size_get(node) > csize) { + extent_node_addr_set(node, (void *)((uintptr_t)ret + csize)); + extent_node_size_set(node, extent_node_size_get(node) - csize); + extent_tree_szad_insert(&base_avail_szad, node); + } else + base_node_dalloc(node); + if (config_stats) { + base_allocated += csize; + /* + * Add one PAGE to base_resident for every page boundary that is + * crossed by the new allocation. + */ + base_resident += PAGE_CEILING((uintptr_t)ret + csize) - + PAGE_CEILING((uintptr_t)ret); + } + JEMALLOC_VALGRIND_MAKE_MEM_DEFINED(ret, csize); +label_return: + malloc_mutex_unlock(&base_mtx); + return (ret); +} + +void +base_stats_get(size_t *allocated, size_t *resident, size_t *mapped) +{ + + malloc_mutex_lock(&base_mtx); + assert(base_allocated <= base_resident); + assert(base_resident <= base_mapped); + *allocated = base_allocated; + *resident = base_resident; + *mapped = base_mapped; + malloc_mutex_unlock(&base_mtx); +} + +bool +base_boot(void) +{ + + if (malloc_mutex_init(&base_mtx)) + return (true); + extent_tree_szad_new(&base_avail_szad); + base_nodes = NULL; + + return (false); +} + +void +base_prefork(void) +{ + + malloc_mutex_prefork(&base_mtx); +} + +void +base_postfork_parent(void) +{ + + malloc_mutex_postfork_parent(&base_mtx); +} + +void +base_postfork_child(void) +{ + + malloc_mutex_postfork_child(&base_mtx); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/bitmap.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/bitmap.c new file mode 100644 index 0000000..c733372 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/bitmap.c @@ -0,0 +1,78 @@ +#define JEMALLOC_BITMAP_C_ +#include "jemalloc/internal/jemalloc_internal.h" + +/******************************************************************************/ + +void +bitmap_info_init(bitmap_info_t *binfo, size_t nbits) +{ + unsigned i; + size_t group_count; + + assert(nbits > 0); + assert(nbits <= (ZU(1) << LG_BITMAP_MAXBITS)); + + /* + * Compute the number of groups necessary to store nbits bits, and + * progressively work upward through the levels until reaching a level + * that requires only one group. + */ + binfo->levels[0].group_offset = 0; + group_count = BITMAP_BITS2GROUPS(nbits); + for (i = 1; group_count > 1; i++) { + assert(i < BITMAP_MAX_LEVELS); + binfo->levels[i].group_offset = binfo->levels[i-1].group_offset + + group_count; + group_count = BITMAP_BITS2GROUPS(group_count); + } + binfo->levels[i].group_offset = binfo->levels[i-1].group_offset + + group_count; + assert(binfo->levels[i].group_offset <= BITMAP_GROUPS_MAX); + binfo->nlevels = i; + binfo->nbits = nbits; +} + +size_t +bitmap_info_ngroups(const bitmap_info_t *binfo) +{ + + return (binfo->levels[binfo->nlevels].group_offset << LG_SIZEOF_BITMAP); +} + +size_t +bitmap_size(size_t nbits) +{ + bitmap_info_t binfo; + + bitmap_info_init(&binfo, nbits); + return (bitmap_info_ngroups(&binfo)); +} + +void +bitmap_init(bitmap_t *bitmap, const bitmap_info_t *binfo) +{ + size_t extra; + unsigned i; + + /* + * Bits are actually inverted with regard to the external bitmap + * interface, so the bitmap starts out with all 1 bits, except for + * trailing unused bits (if any). Note that each group uses bit 0 to + * correspond to the first logical bit in the group, so extra bits + * are the most significant bits of the last group. + */ + memset(bitmap, 0xffU, binfo->levels[binfo->nlevels].group_offset << + LG_SIZEOF_BITMAP); + extra = (BITMAP_GROUP_NBITS - (binfo->nbits & BITMAP_GROUP_NBITS_MASK)) + & BITMAP_GROUP_NBITS_MASK; + if (extra != 0) + bitmap[binfo->levels[1].group_offset - 1] >>= extra; + for (i = 1; i < binfo->nlevels; i++) { + size_t group_count = binfo->levels[i].group_offset - + binfo->levels[i-1].group_offset; + extra = (BITMAP_GROUP_NBITS - (group_count & + BITMAP_GROUP_NBITS_MASK)) & BITMAP_GROUP_NBITS_MASK; + if (extra != 0) + bitmap[binfo->levels[i+1].group_offset - 1] >>= extra; + } +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/chunk.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/chunk.c new file mode 100644 index 0000000..6ba1ca7 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/chunk.c @@ -0,0 +1,761 @@ +#define JEMALLOC_CHUNK_C_ +#include "jemalloc/internal/jemalloc_internal.h" + +/******************************************************************************/ +/* Data. */ + +const char *opt_dss = DSS_DEFAULT; +size_t opt_lg_chunk = 0; + +/* Used exclusively for gdump triggering. */ +static size_t curchunks; +static size_t highchunks; + +rtree_t chunks_rtree; + +/* Various chunk-related settings. */ +size_t chunksize; +size_t chunksize_mask; /* (chunksize - 1). */ +size_t chunk_npages; + +static void *chunk_alloc_default(void *new_addr, size_t size, + size_t alignment, bool *zero, bool *commit, unsigned arena_ind); +static bool chunk_dalloc_default(void *chunk, size_t size, bool committed, + unsigned arena_ind); +static bool chunk_commit_default(void *chunk, size_t size, size_t offset, + size_t length, unsigned arena_ind); +static bool chunk_decommit_default(void *chunk, size_t size, size_t offset, + size_t length, unsigned arena_ind); +static bool chunk_purge_default(void *chunk, size_t size, size_t offset, + size_t length, unsigned arena_ind); +static bool chunk_split_default(void *chunk, size_t size, size_t size_a, + size_t size_b, bool committed, unsigned arena_ind); +static bool chunk_merge_default(void *chunk_a, size_t size_a, void *chunk_b, + size_t size_b, bool committed, unsigned arena_ind); + +const chunk_hooks_t chunk_hooks_default = { + chunk_alloc_default, + chunk_dalloc_default, + chunk_commit_default, + chunk_decommit_default, + chunk_purge_default, + chunk_split_default, + chunk_merge_default +}; + +/******************************************************************************/ +/* + * Function prototypes for static functions that are referenced prior to + * definition. + */ + +static void chunk_record(arena_t *arena, chunk_hooks_t *chunk_hooks, + extent_tree_t *chunks_szad, extent_tree_t *chunks_ad, bool cache, + void *chunk, size_t size, bool zeroed, bool committed); + +/******************************************************************************/ + +static chunk_hooks_t +chunk_hooks_get_locked(arena_t *arena) +{ + + return (arena->chunk_hooks); +} + +chunk_hooks_t +chunk_hooks_get(arena_t *arena) +{ + chunk_hooks_t chunk_hooks; + + malloc_mutex_lock(&arena->chunks_mtx); + chunk_hooks = chunk_hooks_get_locked(arena); + malloc_mutex_unlock(&arena->chunks_mtx); + + return (chunk_hooks); +} + +chunk_hooks_t +chunk_hooks_set(arena_t *arena, const chunk_hooks_t *chunk_hooks) +{ + chunk_hooks_t old_chunk_hooks; + + malloc_mutex_lock(&arena->chunks_mtx); + old_chunk_hooks = arena->chunk_hooks; + /* + * Copy each field atomically so that it is impossible for readers to + * see partially updated pointers. There are places where readers only + * need one hook function pointer (therefore no need to copy the + * entirety of arena->chunk_hooks), and stale reads do not affect + * correctness, so they perform unlocked reads. + */ +#define ATOMIC_COPY_HOOK(n) do { \ + union { \ + chunk_##n##_t **n; \ + void **v; \ + } u; \ + u.n = &arena->chunk_hooks.n; \ + atomic_write_p(u.v, chunk_hooks->n); \ +} while (0) + ATOMIC_COPY_HOOK(alloc); + ATOMIC_COPY_HOOK(dalloc); + ATOMIC_COPY_HOOK(commit); + ATOMIC_COPY_HOOK(decommit); + ATOMIC_COPY_HOOK(purge); + ATOMIC_COPY_HOOK(split); + ATOMIC_COPY_HOOK(merge); +#undef ATOMIC_COPY_HOOK + malloc_mutex_unlock(&arena->chunks_mtx); + + return (old_chunk_hooks); +} + +static void +chunk_hooks_assure_initialized_impl(arena_t *arena, chunk_hooks_t *chunk_hooks, + bool locked) +{ + static const chunk_hooks_t uninitialized_hooks = + CHUNK_HOOKS_INITIALIZER; + + if (memcmp(chunk_hooks, &uninitialized_hooks, sizeof(chunk_hooks_t)) == + 0) { + *chunk_hooks = locked ? chunk_hooks_get_locked(arena) : + chunk_hooks_get(arena); + } +} + +static void +chunk_hooks_assure_initialized_locked(arena_t *arena, + chunk_hooks_t *chunk_hooks) +{ + + chunk_hooks_assure_initialized_impl(arena, chunk_hooks, true); +} + +static void +chunk_hooks_assure_initialized(arena_t *arena, chunk_hooks_t *chunk_hooks) +{ + + chunk_hooks_assure_initialized_impl(arena, chunk_hooks, false); +} + +bool +chunk_register(const void *chunk, const extent_node_t *node) +{ + + assert(extent_node_addr_get(node) == chunk); + + if (rtree_set(&chunks_rtree, (uintptr_t)chunk, node)) + return (true); + if (config_prof && opt_prof) { + size_t size = extent_node_size_get(node); + size_t nadd = (size == 0) ? 1 : size / chunksize; + size_t cur = atomic_add_z(&curchunks, nadd); + size_t high = atomic_read_z(&highchunks); + while (cur > high && atomic_cas_z(&highchunks, high, cur)) { + /* + * Don't refresh cur, because it may have decreased + * since this thread lost the highchunks update race. + */ + high = atomic_read_z(&highchunks); + } + if (cur > high && prof_gdump_get_unlocked()) + prof_gdump(); + } + + return (false); +} + +void +chunk_deregister(const void *chunk, const extent_node_t *node) +{ + bool err; + + err = rtree_set(&chunks_rtree, (uintptr_t)chunk, NULL); + assert(!err); + if (config_prof && opt_prof) { + size_t size = extent_node_size_get(node); + size_t nsub = (size == 0) ? 1 : size / chunksize; + assert(atomic_read_z(&curchunks) >= nsub); + atomic_sub_z(&curchunks, nsub); + } +} + +/* + * Do first-best-fit chunk selection, i.e. select the lowest chunk that best + * fits. + */ +static extent_node_t * +chunk_first_best_fit(arena_t *arena, extent_tree_t *chunks_szad, + extent_tree_t *chunks_ad, size_t size) +{ + extent_node_t key; + + assert(size == CHUNK_CEILING(size)); + + extent_node_init(&key, arena, NULL, size, false, false); + return (extent_tree_szad_nsearch(chunks_szad, &key)); +} + +static void * +chunk_recycle(arena_t *arena, chunk_hooks_t *chunk_hooks, + extent_tree_t *chunks_szad, extent_tree_t *chunks_ad, bool cache, + void *new_addr, size_t size, size_t alignment, bool *zero, bool *commit, + bool dalloc_node) +{ + void *ret; + extent_node_t *node; + size_t alloc_size, leadsize, trailsize; + bool zeroed, committed; + + assert(new_addr == NULL || alignment == chunksize); + /* + * Cached chunks use the node linkage embedded in their headers, in + * which case dalloc_node is true, and new_addr is non-NULL because + * we're operating on a specific chunk. + */ + assert(dalloc_node || new_addr != NULL); + + alloc_size = CHUNK_CEILING(s2u(size + alignment - chunksize)); + /* Beware size_t wrap-around. */ + if (alloc_size < size) + return (NULL); + malloc_mutex_lock(&arena->chunks_mtx); + chunk_hooks_assure_initialized_locked(arena, chunk_hooks); + if (new_addr != NULL) { + extent_node_t key; + extent_node_init(&key, arena, new_addr, alloc_size, false, + false); + node = extent_tree_ad_search(chunks_ad, &key); + } else { + node = chunk_first_best_fit(arena, chunks_szad, chunks_ad, + alloc_size); + } + if (node == NULL || (new_addr != NULL && extent_node_size_get(node) < + size)) { + malloc_mutex_unlock(&arena->chunks_mtx); + return (NULL); + } + leadsize = ALIGNMENT_CEILING((uintptr_t)extent_node_addr_get(node), + alignment) - (uintptr_t)extent_node_addr_get(node); + assert(new_addr == NULL || leadsize == 0); + assert(extent_node_size_get(node) >= leadsize + size); + trailsize = extent_node_size_get(node) - leadsize - size; + ret = (void *)((uintptr_t)extent_node_addr_get(node) + leadsize); + zeroed = extent_node_zeroed_get(node); + if (zeroed) + *zero = true; + committed = extent_node_committed_get(node); + if (committed) + *commit = true; + /* Split the lead. */ + if (leadsize != 0 && + chunk_hooks->split(extent_node_addr_get(node), + extent_node_size_get(node), leadsize, size, false, arena->ind)) { + malloc_mutex_unlock(&arena->chunks_mtx); + return (NULL); + } + /* Remove node from the tree. */ + extent_tree_szad_remove(chunks_szad, node); + extent_tree_ad_remove(chunks_ad, node); + arena_chunk_cache_maybe_remove(arena, node, cache); + if (leadsize != 0) { + /* Insert the leading space as a smaller chunk. */ + extent_node_size_set(node, leadsize); + extent_tree_szad_insert(chunks_szad, node); + extent_tree_ad_insert(chunks_ad, node); + arena_chunk_cache_maybe_insert(arena, node, cache); + node = NULL; + } + if (trailsize != 0) { + /* Split the trail. */ + if (chunk_hooks->split(ret, size + trailsize, size, + trailsize, false, arena->ind)) { + if (dalloc_node && node != NULL) + arena_node_dalloc(arena, node); + malloc_mutex_unlock(&arena->chunks_mtx); + chunk_record(arena, chunk_hooks, chunks_szad, chunks_ad, + cache, ret, size + trailsize, zeroed, committed); + return (NULL); + } + /* Insert the trailing space as a smaller chunk. */ + if (node == NULL) { + node = arena_node_alloc(arena); + if (node == NULL) { + malloc_mutex_unlock(&arena->chunks_mtx); + chunk_record(arena, chunk_hooks, chunks_szad, + chunks_ad, cache, ret, size + trailsize, + zeroed, committed); + return (NULL); + } + } + extent_node_init(node, arena, (void *)((uintptr_t)(ret) + size), + trailsize, zeroed, committed); + extent_tree_szad_insert(chunks_szad, node); + extent_tree_ad_insert(chunks_ad, node); + arena_chunk_cache_maybe_insert(arena, node, cache); + node = NULL; + } + if (!committed && chunk_hooks->commit(ret, size, 0, size, arena->ind)) { + malloc_mutex_unlock(&arena->chunks_mtx); + chunk_record(arena, chunk_hooks, chunks_szad, chunks_ad, cache, + ret, size, zeroed, committed); + return (NULL); + } + malloc_mutex_unlock(&arena->chunks_mtx); + + assert(dalloc_node || node != NULL); + if (dalloc_node && node != NULL) + arena_node_dalloc(arena, node); + if (*zero) { + if (!zeroed) + memset(ret, 0, size); + else if (config_debug) { + size_t i; + size_t *p = (size_t *)(uintptr_t)ret; + + JEMALLOC_VALGRIND_MAKE_MEM_DEFINED(ret, size); + for (i = 0; i < size / sizeof(size_t); i++) + assert(p[i] == 0); + } + } + return (ret); +} + +/* + * If the caller specifies (!*zero), it is still possible to receive zeroed + * memory, in which case *zero is toggled to true. arena_chunk_alloc() takes + * advantage of this to avoid demanding zeroed chunks, but taking advantage of + * them if they are returned. + */ +static void * +chunk_alloc_core(arena_t *arena, void *new_addr, size_t size, size_t alignment, + bool *zero, bool *commit, dss_prec_t dss_prec) +{ + void *ret; + chunk_hooks_t chunk_hooks = CHUNK_HOOKS_INITIALIZER; + + assert(size != 0); + assert((size & chunksize_mask) == 0); + assert(alignment != 0); + assert((alignment & chunksize_mask) == 0); + + /* Retained. */ + if ((ret = chunk_recycle(arena, &chunk_hooks, + &arena->chunks_szad_retained, &arena->chunks_ad_retained, false, + new_addr, size, alignment, zero, commit, true)) != NULL) + return (ret); + + /* "primary" dss. */ + if (have_dss && dss_prec == dss_prec_primary && (ret = + chunk_alloc_dss(arena, new_addr, size, alignment, zero, commit)) != + NULL) + return (ret); + /* + * mmap. Requesting an address is not implemented for + * chunk_alloc_mmap(), so only call it if (new_addr == NULL). + */ + if (new_addr == NULL && (ret = chunk_alloc_mmap(size, alignment, zero, + commit)) != NULL) + return (ret); + /* "secondary" dss. */ + if (have_dss && dss_prec == dss_prec_secondary && (ret = + chunk_alloc_dss(arena, new_addr, size, alignment, zero, commit)) != + NULL) + return (ret); + + /* All strategies for allocation failed. */ + return (NULL); +} + +void * +chunk_alloc_base(size_t size) +{ + void *ret; + bool zero, commit; + + /* + * Directly call chunk_alloc_mmap() rather than chunk_alloc_core() + * because it's critical that chunk_alloc_base() return untouched + * demand-zeroed virtual memory. + */ + zero = true; + commit = true; + ret = chunk_alloc_mmap(size, chunksize, &zero, &commit); + if (ret == NULL) + return (NULL); + if (config_valgrind) + JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(ret, size); + + return (ret); +} + +void * +chunk_alloc_cache(arena_t *arena, chunk_hooks_t *chunk_hooks, void *new_addr, + size_t size, size_t alignment, bool *zero, bool dalloc_node) +{ + void *ret; + bool commit; + + assert(size != 0); + assert((size & chunksize_mask) == 0); + assert(alignment != 0); + assert((alignment & chunksize_mask) == 0); + + commit = true; + ret = chunk_recycle(arena, chunk_hooks, &arena->chunks_szad_cached, + &arena->chunks_ad_cached, true, new_addr, size, alignment, zero, + &commit, dalloc_node); + if (ret == NULL) + return (NULL); + assert(commit); + if (config_valgrind) + JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(ret, size); + return (ret); +} + +static arena_t * +chunk_arena_get(unsigned arena_ind) +{ + arena_t *arena; + + /* Dodge tsd for a0 in order to avoid bootstrapping issues. */ + arena = (arena_ind == 0) ? a0get() : arena_get(tsd_fetch(), arena_ind, + false, true); + /* + * The arena we're allocating on behalf of must have been initialized + * already. + */ + assert(arena != NULL); + return (arena); +} + +static void * +chunk_alloc_default(void *new_addr, size_t size, size_t alignment, bool *zero, + bool *commit, unsigned arena_ind) +{ + void *ret; + arena_t *arena; + + arena = chunk_arena_get(arena_ind); + ret = chunk_alloc_core(arena, new_addr, size, alignment, zero, + commit, arena->dss_prec); + if (ret == NULL) + return (NULL); + if (config_valgrind) + JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(ret, size); + + return (ret); +} + +void * +chunk_alloc_wrapper(arena_t *arena, chunk_hooks_t *chunk_hooks, void *new_addr, + size_t size, size_t alignment, bool *zero, bool *commit) +{ + void *ret; + + chunk_hooks_assure_initialized(arena, chunk_hooks); + ret = chunk_hooks->alloc(new_addr, size, alignment, zero, commit, + arena->ind); + if (ret == NULL) + return (NULL); + if (config_valgrind && chunk_hooks->alloc != chunk_alloc_default) + JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(ret, chunksize); + return (ret); +} + +static void +chunk_record(arena_t *arena, chunk_hooks_t *chunk_hooks, + extent_tree_t *chunks_szad, extent_tree_t *chunks_ad, bool cache, + void *chunk, size_t size, bool zeroed, bool committed) +{ + bool unzeroed; + extent_node_t *node, *prev; + extent_node_t key; + + assert(!cache || !zeroed); + unzeroed = cache || !zeroed; + JEMALLOC_VALGRIND_MAKE_MEM_NOACCESS(chunk, size); + + malloc_mutex_lock(&arena->chunks_mtx); + chunk_hooks_assure_initialized_locked(arena, chunk_hooks); + extent_node_init(&key, arena, (void *)((uintptr_t)chunk + size), 0, + false, false); + node = extent_tree_ad_nsearch(chunks_ad, &key); + /* Try to coalesce forward. */ + if (node != NULL && extent_node_addr_get(node) == + extent_node_addr_get(&key) && extent_node_committed_get(node) == + committed && !chunk_hooks->merge(chunk, size, + extent_node_addr_get(node), extent_node_size_get(node), false, + arena->ind)) { + /* + * Coalesce chunk with the following address range. This does + * not change the position within chunks_ad, so only + * remove/insert from/into chunks_szad. + */ + extent_tree_szad_remove(chunks_szad, node); + arena_chunk_cache_maybe_remove(arena, node, cache); + extent_node_addr_set(node, chunk); + extent_node_size_set(node, size + extent_node_size_get(node)); + extent_node_zeroed_set(node, extent_node_zeroed_get(node) && + !unzeroed); + extent_tree_szad_insert(chunks_szad, node); + arena_chunk_cache_maybe_insert(arena, node, cache); + } else { + /* Coalescing forward failed, so insert a new node. */ + node = arena_node_alloc(arena); + if (node == NULL) { + /* + * Node allocation failed, which is an exceedingly + * unlikely failure. Leak chunk after making sure its + * pages have already been purged, so that this is only + * a virtual memory leak. + */ + if (cache) { + chunk_purge_wrapper(arena, chunk_hooks, chunk, + size, 0, size); + } + goto label_return; + } + extent_node_init(node, arena, chunk, size, !unzeroed, + committed); + extent_tree_ad_insert(chunks_ad, node); + extent_tree_szad_insert(chunks_szad, node); + arena_chunk_cache_maybe_insert(arena, node, cache); + } + + /* Try to coalesce backward. */ + prev = extent_tree_ad_prev(chunks_ad, node); + if (prev != NULL && (void *)((uintptr_t)extent_node_addr_get(prev) + + extent_node_size_get(prev)) == chunk && + extent_node_committed_get(prev) == committed && + !chunk_hooks->merge(extent_node_addr_get(prev), + extent_node_size_get(prev), chunk, size, false, arena->ind)) { + /* + * Coalesce chunk with the previous address range. This does + * not change the position within chunks_ad, so only + * remove/insert node from/into chunks_szad. + */ + extent_tree_szad_remove(chunks_szad, prev); + extent_tree_ad_remove(chunks_ad, prev); + arena_chunk_cache_maybe_remove(arena, prev, cache); + extent_tree_szad_remove(chunks_szad, node); + arena_chunk_cache_maybe_remove(arena, node, cache); + extent_node_addr_set(node, extent_node_addr_get(prev)); + extent_node_size_set(node, extent_node_size_get(prev) + + extent_node_size_get(node)); + extent_node_zeroed_set(node, extent_node_zeroed_get(prev) && + extent_node_zeroed_get(node)); + extent_tree_szad_insert(chunks_szad, node); + arena_chunk_cache_maybe_insert(arena, node, cache); + + arena_node_dalloc(arena, prev); + } + +label_return: + malloc_mutex_unlock(&arena->chunks_mtx); +} + +void +chunk_dalloc_cache(arena_t *arena, chunk_hooks_t *chunk_hooks, void *chunk, + size_t size, bool committed) +{ + + assert(chunk != NULL); + assert(CHUNK_ADDR2BASE(chunk) == chunk); + assert(size != 0); + assert((size & chunksize_mask) == 0); + + chunk_record(arena, chunk_hooks, &arena->chunks_szad_cached, + &arena->chunks_ad_cached, true, chunk, size, false, committed); + arena_maybe_purge(arena); +} + +void +chunk_dalloc_arena(arena_t *arena, chunk_hooks_t *chunk_hooks, void *chunk, + size_t size, bool zeroed, bool committed) +{ + + assert(chunk != NULL); + assert(CHUNK_ADDR2BASE(chunk) == chunk); + assert(size != 0); + assert((size & chunksize_mask) == 0); + + chunk_hooks_assure_initialized(arena, chunk_hooks); + /* Try to deallocate. */ + if (!chunk_hooks->dalloc(chunk, size, committed, arena->ind)) + return; + /* Try to decommit; purge if that fails. */ + if (committed) { + committed = chunk_hooks->decommit(chunk, size, 0, size, + arena->ind); + } + zeroed = !committed || !chunk_hooks->purge(chunk, size, 0, size, + arena->ind); + chunk_record(arena, chunk_hooks, &arena->chunks_szad_retained, + &arena->chunks_ad_retained, false, chunk, size, zeroed, committed); +} + +static bool +chunk_dalloc_default(void *chunk, size_t size, bool committed, + unsigned arena_ind) +{ + + if (!have_dss || !chunk_in_dss(chunk)) + return (chunk_dalloc_mmap(chunk, size)); + return (true); +} + +void +chunk_dalloc_wrapper(arena_t *arena, chunk_hooks_t *chunk_hooks, void *chunk, + size_t size, bool committed) +{ + + chunk_hooks_assure_initialized(arena, chunk_hooks); + chunk_hooks->dalloc(chunk, size, committed, arena->ind); + if (config_valgrind && chunk_hooks->dalloc != chunk_dalloc_default) + JEMALLOC_VALGRIND_MAKE_MEM_NOACCESS(chunk, size); +} + +static bool +chunk_commit_default(void *chunk, size_t size, size_t offset, size_t length, + unsigned arena_ind) +{ + + return (pages_commit((void *)((uintptr_t)chunk + (uintptr_t)offset), + length)); +} + +static bool +chunk_decommit_default(void *chunk, size_t size, size_t offset, size_t length, + unsigned arena_ind) +{ + + return (pages_decommit((void *)((uintptr_t)chunk + (uintptr_t)offset), + length)); +} + +bool +chunk_purge_arena(arena_t *arena, void *chunk, size_t offset, size_t length) +{ + + assert(chunk != NULL); + assert(CHUNK_ADDR2BASE(chunk) == chunk); + assert((offset & PAGE_MASK) == 0); + assert(length != 0); + assert((length & PAGE_MASK) == 0); + + return (pages_purge((void *)((uintptr_t)chunk + (uintptr_t)offset), + length)); +} + +static bool +chunk_purge_default(void *chunk, size_t size, size_t offset, size_t length, + unsigned arena_ind) +{ + + return (chunk_purge_arena(chunk_arena_get(arena_ind), chunk, offset, + length)); +} + +bool +chunk_purge_wrapper(arena_t *arena, chunk_hooks_t *chunk_hooks, void *chunk, + size_t size, size_t offset, size_t length) +{ + + chunk_hooks_assure_initialized(arena, chunk_hooks); + return (chunk_hooks->purge(chunk, size, offset, length, arena->ind)); +} + +static bool +chunk_split_default(void *chunk, size_t size, size_t size_a, size_t size_b, + bool committed, unsigned arena_ind) +{ + + if (!maps_coalesce) + return (true); + return (false); +} + +static bool +chunk_merge_default(void *chunk_a, size_t size_a, void *chunk_b, size_t size_b, + bool committed, unsigned arena_ind) +{ + + if (!maps_coalesce) + return (true); + if (have_dss && chunk_in_dss(chunk_a) != chunk_in_dss(chunk_b)) + return (true); + + return (false); +} + +static rtree_node_elm_t * +chunks_rtree_node_alloc(size_t nelms) +{ + + return ((rtree_node_elm_t *)base_alloc(nelms * + sizeof(rtree_node_elm_t))); +} + +bool +chunk_boot(void) +{ +#ifdef _WIN32 + SYSTEM_INFO info; + GetSystemInfo(&info); + + /* + * Verify actual page size is equal to or an integral multiple of + * configured page size. + */ + if (info.dwPageSize & ((1U << LG_PAGE) - 1)) + return (true); + + /* + * Configure chunksize (if not set) to match granularity (usually 64K), + * so pages_map will always take fast path. + */ + if (!opt_lg_chunk) { + opt_lg_chunk = jemalloc_ffs((int)info.dwAllocationGranularity) + - 1; + } +#else + if (!opt_lg_chunk) + opt_lg_chunk = LG_CHUNK_DEFAULT; +#endif + + /* Set variables according to the value of opt_lg_chunk. */ + chunksize = (ZU(1) << opt_lg_chunk); + assert(chunksize >= PAGE); + chunksize_mask = chunksize - 1; + chunk_npages = (chunksize >> LG_PAGE); + + if (have_dss && chunk_dss_boot()) + return (true); + if (rtree_new(&chunks_rtree, (ZU(1) << (LG_SIZEOF_PTR+3)) - + opt_lg_chunk, chunks_rtree_node_alloc, NULL)) + return (true); + + return (false); +} + +void +chunk_prefork(void) +{ + + chunk_dss_prefork(); +} + +void +chunk_postfork_parent(void) +{ + + chunk_dss_postfork_parent(); +} + +void +chunk_postfork_child(void) +{ + + chunk_dss_postfork_child(); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/chunk_dss.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/chunk_dss.c new file mode 100644 index 0000000..61fc916 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/chunk_dss.c @@ -0,0 +1,214 @@ +#define JEMALLOC_CHUNK_DSS_C_ +#include "jemalloc/internal/jemalloc_internal.h" +/******************************************************************************/ +/* Data. */ + +const char *dss_prec_names[] = { + "disabled", + "primary", + "secondary", + "N/A" +}; + +/* Current dss precedence default, used when creating new arenas. */ +static dss_prec_t dss_prec_default = DSS_PREC_DEFAULT; + +/* + * Protects sbrk() calls. This avoids malloc races among threads, though it + * does not protect against races with threads that call sbrk() directly. + */ +static malloc_mutex_t dss_mtx; + +/* Base address of the DSS. */ +static void *dss_base; +/* Current end of the DSS, or ((void *)-1) if the DSS is exhausted. */ +static void *dss_prev; +/* Current upper limit on DSS addresses. */ +static void *dss_max; + +/******************************************************************************/ + +static void * +chunk_dss_sbrk(intptr_t increment) +{ + +#ifdef JEMALLOC_DSS + return (sbrk(increment)); +#else + not_implemented(); + return (NULL); +#endif +} + +dss_prec_t +chunk_dss_prec_get(void) +{ + dss_prec_t ret; + + if (!have_dss) + return (dss_prec_disabled); + malloc_mutex_lock(&dss_mtx); + ret = dss_prec_default; + malloc_mutex_unlock(&dss_mtx); + return (ret); +} + +bool +chunk_dss_prec_set(dss_prec_t dss_prec) +{ + + if (!have_dss) + return (dss_prec != dss_prec_disabled); + malloc_mutex_lock(&dss_mtx); + dss_prec_default = dss_prec; + malloc_mutex_unlock(&dss_mtx); + return (false); +} + +void * +chunk_alloc_dss(arena_t *arena, void *new_addr, size_t size, size_t alignment, + bool *zero, bool *commit) +{ + cassert(have_dss); + assert(size > 0 && (size & chunksize_mask) == 0); + assert(alignment > 0 && (alignment & chunksize_mask) == 0); + + /* + * sbrk() uses a signed increment argument, so take care not to + * interpret a huge allocation request as a negative increment. + */ + if ((intptr_t)size < 0) + return (NULL); + + malloc_mutex_lock(&dss_mtx); + if (dss_prev != (void *)-1) { + + /* + * The loop is necessary to recover from races with other + * threads that are using the DSS for something other than + * malloc. + */ + do { + void *ret, *cpad, *dss_next; + size_t gap_size, cpad_size; + intptr_t incr; + /* Avoid an unnecessary system call. */ + if (new_addr != NULL && dss_max != new_addr) + break; + + /* Get the current end of the DSS. */ + dss_max = chunk_dss_sbrk(0); + + /* Make sure the earlier condition still holds. */ + if (new_addr != NULL && dss_max != new_addr) + break; + + /* + * Calculate how much padding is necessary to + * chunk-align the end of the DSS. + */ + gap_size = (chunksize - CHUNK_ADDR2OFFSET(dss_max)) & + chunksize_mask; + /* + * Compute how much chunk-aligned pad space (if any) is + * necessary to satisfy alignment. This space can be + * recycled for later use. + */ + cpad = (void *)((uintptr_t)dss_max + gap_size); + ret = (void *)ALIGNMENT_CEILING((uintptr_t)dss_max, + alignment); + cpad_size = (uintptr_t)ret - (uintptr_t)cpad; + dss_next = (void *)((uintptr_t)ret + size); + if ((uintptr_t)ret < (uintptr_t)dss_max || + (uintptr_t)dss_next < (uintptr_t)dss_max) { + /* Wrap-around. */ + malloc_mutex_unlock(&dss_mtx); + return (NULL); + } + incr = gap_size + cpad_size + size; + dss_prev = chunk_dss_sbrk(incr); + if (dss_prev == dss_max) { + /* Success. */ + dss_max = dss_next; + malloc_mutex_unlock(&dss_mtx); + if (cpad_size != 0) { + chunk_hooks_t chunk_hooks = + CHUNK_HOOKS_INITIALIZER; + chunk_dalloc_wrapper(arena, + &chunk_hooks, cpad, cpad_size, + true); + } + if (*zero) { + JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED( + ret, size); + memset(ret, 0, size); + } + if (!*commit) + *commit = pages_decommit(ret, size); + return (ret); + } + } while (dss_prev != (void *)-1); + } + malloc_mutex_unlock(&dss_mtx); + + return (NULL); +} + +bool +chunk_in_dss(void *chunk) +{ + bool ret; + + cassert(have_dss); + + malloc_mutex_lock(&dss_mtx); + if ((uintptr_t)chunk >= (uintptr_t)dss_base + && (uintptr_t)chunk < (uintptr_t)dss_max) + ret = true; + else + ret = false; + malloc_mutex_unlock(&dss_mtx); + + return (ret); +} + +bool +chunk_dss_boot(void) +{ + + cassert(have_dss); + + if (malloc_mutex_init(&dss_mtx)) + return (true); + dss_base = chunk_dss_sbrk(0); + dss_prev = dss_base; + dss_max = dss_base; + + return (false); +} + +void +chunk_dss_prefork(void) +{ + + if (have_dss) + malloc_mutex_prefork(&dss_mtx); +} + +void +chunk_dss_postfork_parent(void) +{ + + if (have_dss) + malloc_mutex_postfork_parent(&dss_mtx); +} + +void +chunk_dss_postfork_child(void) +{ + + if (have_dss) + malloc_mutex_postfork_child(&dss_mtx); +} + +/******************************************************************************/ diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/chunk_mmap.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/chunk_mmap.c new file mode 100644 index 0000000..b9ba741 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/chunk_mmap.c @@ -0,0 +1,80 @@ +#define JEMALLOC_CHUNK_MMAP_C_ +#include "jemalloc/internal/jemalloc_internal.h" + +/******************************************************************************/ + +static void * +chunk_alloc_mmap_slow(size_t size, size_t alignment, bool *zero, bool *commit) +{ + void *ret; + size_t alloc_size; + + alloc_size = size + alignment - PAGE; + /* Beware size_t wrap-around. */ + if (alloc_size < size) + return (NULL); + do { + void *pages; + size_t leadsize; + pages = pages_map(NULL, alloc_size); + if (pages == NULL) + return (NULL); + leadsize = ALIGNMENT_CEILING((uintptr_t)pages, alignment) - + (uintptr_t)pages; + ret = pages_trim(pages, alloc_size, leadsize, size); + } while (ret == NULL); + + assert(ret != NULL); + *zero = true; + if (!*commit) + *commit = pages_decommit(ret, size); + return (ret); +} + +void * +chunk_alloc_mmap(size_t size, size_t alignment, bool *zero, bool *commit) +{ + void *ret; + size_t offset; + + /* + * Ideally, there would be a way to specify alignment to mmap() (like + * NetBSD has), but in the absence of such a feature, we have to work + * hard to efficiently create aligned mappings. The reliable, but + * slow method is to create a mapping that is over-sized, then trim the + * excess. However, that always results in one or two calls to + * pages_unmap(). + * + * Optimistically try mapping precisely the right amount before falling + * back to the slow method, with the expectation that the optimistic + * approach works most of the time. + */ + + assert(alignment != 0); + assert((alignment & chunksize_mask) == 0); + + ret = pages_map(NULL, size); + if (ret == NULL) + return (NULL); + offset = ALIGNMENT_ADDR2OFFSET(ret, alignment); + if (offset != 0) { + pages_unmap(ret, size); + return (chunk_alloc_mmap_slow(size, alignment, zero, commit)); + } + + assert(ret != NULL); + *zero = true; + if (!*commit) + *commit = pages_decommit(ret, size); + return (ret); +} + +bool +chunk_dalloc_mmap(void *chunk, size_t size) +{ + + if (config_munmap) + pages_unmap(chunk, size); + + return (!config_munmap); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/ckh.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/ckh.c new file mode 100644 index 0000000..53a1c1e --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/ckh.c @@ -0,0 +1,568 @@ +/* + ******************************************************************************* + * Implementation of (2^1+,2) cuckoo hashing, where 2^1+ indicates that each + * hash bucket contains 2^n cells, for n >= 1, and 2 indicates that two hash + * functions are employed. The original cuckoo hashing algorithm was described + * in: + * + * Pagh, R., F.F. Rodler (2004) Cuckoo Hashing. Journal of Algorithms + * 51(2):122-144. + * + * Generalization of cuckoo hashing was discussed in: + * + * Erlingsson, U., M. Manasse, F. McSherry (2006) A cool and practical + * alternative to traditional hash tables. In Proceedings of the 7th + * Workshop on Distributed Data and Structures (WDAS'06), Santa Clara, CA, + * January 2006. + * + * This implementation uses precisely two hash functions because that is the + * fewest that can work, and supporting multiple hashes is an implementation + * burden. Here is a reproduction of Figure 1 from Erlingsson et al. (2006) + * that shows approximate expected maximum load factors for various + * configurations: + * + * | #cells/bucket | + * #hashes | 1 | 2 | 4 | 8 | + * --------+-------+-------+-------+-------+ + * 1 | 0.006 | 0.006 | 0.03 | 0.12 | + * 2 | 0.49 | 0.86 |>0.93< |>0.96< | + * 3 | 0.91 | 0.97 | 0.98 | 0.999 | + * 4 | 0.97 | 0.99 | 0.999 | | + * + * The number of cells per bucket is chosen such that a bucket fits in one cache + * line. So, on 32- and 64-bit systems, we use (8,2) and (4,2) cuckoo hashing, + * respectively. + * + ******************************************************************************/ +#define JEMALLOC_CKH_C_ +#include "jemalloc/internal/jemalloc_internal.h" + +/******************************************************************************/ +/* Function prototypes for non-inline static functions. */ + +static bool ckh_grow(tsd_t *tsd, ckh_t *ckh); +static void ckh_shrink(tsd_t *tsd, ckh_t *ckh); + +/******************************************************************************/ + +/* + * Search bucket for key and return the cell number if found; SIZE_T_MAX + * otherwise. + */ +JEMALLOC_INLINE_C size_t +ckh_bucket_search(ckh_t *ckh, size_t bucket, const void *key) +{ + ckhc_t *cell; + unsigned i; + + for (i = 0; i < (ZU(1) << LG_CKH_BUCKET_CELLS); i++) { + cell = &ckh->tab[(bucket << LG_CKH_BUCKET_CELLS) + i]; + if (cell->key != NULL && ckh->keycomp(key, cell->key)) + return ((bucket << LG_CKH_BUCKET_CELLS) + i); + } + + return (SIZE_T_MAX); +} + +/* + * Search table for key and return cell number if found; SIZE_T_MAX otherwise. + */ +JEMALLOC_INLINE_C size_t +ckh_isearch(ckh_t *ckh, const void *key) +{ + size_t hashes[2], bucket, cell; + + assert(ckh != NULL); + + ckh->hash(key, hashes); + + /* Search primary bucket. */ + bucket = hashes[0] & ((ZU(1) << ckh->lg_curbuckets) - 1); + cell = ckh_bucket_search(ckh, bucket, key); + if (cell != SIZE_T_MAX) + return (cell); + + /* Search secondary bucket. */ + bucket = hashes[1] & ((ZU(1) << ckh->lg_curbuckets) - 1); + cell = ckh_bucket_search(ckh, bucket, key); + return (cell); +} + +JEMALLOC_INLINE_C bool +ckh_try_bucket_insert(ckh_t *ckh, size_t bucket, const void *key, + const void *data) +{ + ckhc_t *cell; + unsigned offset, i; + + /* + * Cycle through the cells in the bucket, starting at a random position. + * The randomness avoids worst-case search overhead as buckets fill up. + */ + prng32(offset, LG_CKH_BUCKET_CELLS, ckh->prng_state, CKH_A, CKH_C); + for (i = 0; i < (ZU(1) << LG_CKH_BUCKET_CELLS); i++) { + cell = &ckh->tab[(bucket << LG_CKH_BUCKET_CELLS) + + ((i + offset) & ((ZU(1) << LG_CKH_BUCKET_CELLS) - 1))]; + if (cell->key == NULL) { + cell->key = key; + cell->data = data; + ckh->count++; + return (false); + } + } + + return (true); +} + +/* + * No space is available in bucket. Randomly evict an item, then try to find an + * alternate location for that item. Iteratively repeat this + * eviction/relocation procedure until either success or detection of an + * eviction/relocation bucket cycle. + */ +JEMALLOC_INLINE_C bool +ckh_evict_reloc_insert(ckh_t *ckh, size_t argbucket, void const **argkey, + void const **argdata) +{ + const void *key, *data, *tkey, *tdata; + ckhc_t *cell; + size_t hashes[2], bucket, tbucket; + unsigned i; + + bucket = argbucket; + key = *argkey; + data = *argdata; + while (true) { + /* + * Choose a random item within the bucket to evict. This is + * critical to correct function, because without (eventually) + * evicting all items within a bucket during iteration, it + * would be possible to get stuck in an infinite loop if there + * were an item for which both hashes indicated the same + * bucket. + */ + prng32(i, LG_CKH_BUCKET_CELLS, ckh->prng_state, CKH_A, CKH_C); + cell = &ckh->tab[(bucket << LG_CKH_BUCKET_CELLS) + i]; + assert(cell->key != NULL); + + /* Swap cell->{key,data} and {key,data} (evict). */ + tkey = cell->key; tdata = cell->data; + cell->key = key; cell->data = data; + key = tkey; data = tdata; + +#ifdef CKH_COUNT + ckh->nrelocs++; +#endif + + /* Find the alternate bucket for the evicted item. */ + ckh->hash(key, hashes); + tbucket = hashes[1] & ((ZU(1) << ckh->lg_curbuckets) - 1); + if (tbucket == bucket) { + tbucket = hashes[0] & ((ZU(1) << ckh->lg_curbuckets) + - 1); + /* + * It may be that (tbucket == bucket) still, if the + * item's hashes both indicate this bucket. However, + * we are guaranteed to eventually escape this bucket + * during iteration, assuming pseudo-random item + * selection (true randomness would make infinite + * looping a remote possibility). The reason we can + * never get trapped forever is that there are two + * cases: + * + * 1) This bucket == argbucket, so we will quickly + * detect an eviction cycle and terminate. + * 2) An item was evicted to this bucket from another, + * which means that at least one item in this bucket + * has hashes that indicate distinct buckets. + */ + } + /* Check for a cycle. */ + if (tbucket == argbucket) { + *argkey = key; + *argdata = data; + return (true); + } + + bucket = tbucket; + if (!ckh_try_bucket_insert(ckh, bucket, key, data)) + return (false); + } +} + +JEMALLOC_INLINE_C bool +ckh_try_insert(ckh_t *ckh, void const**argkey, void const**argdata) +{ + size_t hashes[2], bucket; + const void *key = *argkey; + const void *data = *argdata; + + ckh->hash(key, hashes); + + /* Try to insert in primary bucket. */ + bucket = hashes[0] & ((ZU(1) << ckh->lg_curbuckets) - 1); + if (!ckh_try_bucket_insert(ckh, bucket, key, data)) + return (false); + + /* Try to insert in secondary bucket. */ + bucket = hashes[1] & ((ZU(1) << ckh->lg_curbuckets) - 1); + if (!ckh_try_bucket_insert(ckh, bucket, key, data)) + return (false); + + /* + * Try to find a place for this item via iterative eviction/relocation. + */ + return (ckh_evict_reloc_insert(ckh, bucket, argkey, argdata)); +} + +/* + * Try to rebuild the hash table from scratch by inserting all items from the + * old table into the new. + */ +JEMALLOC_INLINE_C bool +ckh_rebuild(ckh_t *ckh, ckhc_t *aTab) +{ + size_t count, i, nins; + const void *key, *data; + + count = ckh->count; + ckh->count = 0; + for (i = nins = 0; nins < count; i++) { + if (aTab[i].key != NULL) { + key = aTab[i].key; + data = aTab[i].data; + if (ckh_try_insert(ckh, &key, &data)) { + ckh->count = count; + return (true); + } + nins++; + } + } + + return (false); +} + +static bool +ckh_grow(tsd_t *tsd, ckh_t *ckh) +{ + bool ret; + ckhc_t *tab, *ttab; + size_t lg_curcells; + unsigned lg_prevbuckets; + +#ifdef CKH_COUNT + ckh->ngrows++; +#endif + + /* + * It is possible (though unlikely, given well behaved hashes) that the + * table will have to be doubled more than once in order to create a + * usable table. + */ + lg_prevbuckets = ckh->lg_curbuckets; + lg_curcells = ckh->lg_curbuckets + LG_CKH_BUCKET_CELLS; + while (true) { + size_t usize; + + lg_curcells++; + usize = sa2u(sizeof(ckhc_t) << lg_curcells, CACHELINE); + if (usize == 0) { + ret = true; + goto label_return; + } + tab = (ckhc_t *)ipallocztm(tsd, usize, CACHELINE, true, NULL, + true, NULL); + if (tab == NULL) { + ret = true; + goto label_return; + } + /* Swap in new table. */ + ttab = ckh->tab; + ckh->tab = tab; + tab = ttab; + ckh->lg_curbuckets = lg_curcells - LG_CKH_BUCKET_CELLS; + + if (!ckh_rebuild(ckh, tab)) { + idalloctm(tsd, tab, tcache_get(tsd, false), true); + break; + } + + /* Rebuilding failed, so back out partially rebuilt table. */ + idalloctm(tsd, ckh->tab, tcache_get(tsd, false), true); + ckh->tab = tab; + ckh->lg_curbuckets = lg_prevbuckets; + } + + ret = false; +label_return: + return (ret); +} + +static void +ckh_shrink(tsd_t *tsd, ckh_t *ckh) +{ + ckhc_t *tab, *ttab; + size_t lg_curcells, usize; + unsigned lg_prevbuckets; + + /* + * It is possible (though unlikely, given well behaved hashes) that the + * table rebuild will fail. + */ + lg_prevbuckets = ckh->lg_curbuckets; + lg_curcells = ckh->lg_curbuckets + LG_CKH_BUCKET_CELLS - 1; + usize = sa2u(sizeof(ckhc_t) << lg_curcells, CACHELINE); + if (usize == 0) + return; + tab = (ckhc_t *)ipallocztm(tsd, usize, CACHELINE, true, NULL, true, + NULL); + if (tab == NULL) { + /* + * An OOM error isn't worth propagating, since it doesn't + * prevent this or future operations from proceeding. + */ + return; + } + /* Swap in new table. */ + ttab = ckh->tab; + ckh->tab = tab; + tab = ttab; + ckh->lg_curbuckets = lg_curcells - LG_CKH_BUCKET_CELLS; + + if (!ckh_rebuild(ckh, tab)) { + idalloctm(tsd, tab, tcache_get(tsd, false), true); +#ifdef CKH_COUNT + ckh->nshrinks++; +#endif + return; + } + + /* Rebuilding failed, so back out partially rebuilt table. */ + idalloctm(tsd, ckh->tab, tcache_get(tsd, false), true); + ckh->tab = tab; + ckh->lg_curbuckets = lg_prevbuckets; +#ifdef CKH_COUNT + ckh->nshrinkfails++; +#endif +} + +bool +ckh_new(tsd_t *tsd, ckh_t *ckh, size_t minitems, ckh_hash_t *hash, + ckh_keycomp_t *keycomp) +{ + bool ret; + size_t mincells, usize; + unsigned lg_mincells; + + assert(minitems > 0); + assert(hash != NULL); + assert(keycomp != NULL); + +#ifdef CKH_COUNT + ckh->ngrows = 0; + ckh->nshrinks = 0; + ckh->nshrinkfails = 0; + ckh->ninserts = 0; + ckh->nrelocs = 0; +#endif + ckh->prng_state = 42; /* Value doesn't really matter. */ + ckh->count = 0; + + /* + * Find the minimum power of 2 that is large enough to fit minitems + * entries. We are using (2+,2) cuckoo hashing, which has an expected + * maximum load factor of at least ~0.86, so 0.75 is a conservative load + * factor that will typically allow mincells items to fit without ever + * growing the table. + */ + assert(LG_CKH_BUCKET_CELLS > 0); + mincells = ((minitems + (3 - (minitems % 3))) / 3) << 2; + for (lg_mincells = LG_CKH_BUCKET_CELLS; + (ZU(1) << lg_mincells) < mincells; + lg_mincells++) + ; /* Do nothing. */ + ckh->lg_minbuckets = lg_mincells - LG_CKH_BUCKET_CELLS; + ckh->lg_curbuckets = lg_mincells - LG_CKH_BUCKET_CELLS; + ckh->hash = hash; + ckh->keycomp = keycomp; + + usize = sa2u(sizeof(ckhc_t) << lg_mincells, CACHELINE); + if (usize == 0) { + ret = true; + goto label_return; + } + ckh->tab = (ckhc_t *)ipallocztm(tsd, usize, CACHELINE, true, NULL, true, + NULL); + if (ckh->tab == NULL) { + ret = true; + goto label_return; + } + + ret = false; +label_return: + return (ret); +} + +void +ckh_delete(tsd_t *tsd, ckh_t *ckh) +{ + + assert(ckh != NULL); + +#ifdef CKH_VERBOSE + malloc_printf( + "%s(%p): ngrows: %"FMTu64", nshrinks: %"FMTu64"," + " nshrinkfails: %"FMTu64", ninserts: %"FMTu64"," + " nrelocs: %"FMTu64"\n", __func__, ckh, + (unsigned long long)ckh->ngrows, + (unsigned long long)ckh->nshrinks, + (unsigned long long)ckh->nshrinkfails, + (unsigned long long)ckh->ninserts, + (unsigned long long)ckh->nrelocs); +#endif + + idalloctm(tsd, ckh->tab, tcache_get(tsd, false), true); + if (config_debug) + memset(ckh, 0x5a, sizeof(ckh_t)); +} + +size_t +ckh_count(ckh_t *ckh) +{ + + assert(ckh != NULL); + + return (ckh->count); +} + +bool +ckh_iter(ckh_t *ckh, size_t *tabind, void **key, void **data) +{ + size_t i, ncells; + + for (i = *tabind, ncells = (ZU(1) << (ckh->lg_curbuckets + + LG_CKH_BUCKET_CELLS)); i < ncells; i++) { + if (ckh->tab[i].key != NULL) { + if (key != NULL) + *key = (void *)ckh->tab[i].key; + if (data != NULL) + *data = (void *)ckh->tab[i].data; + *tabind = i + 1; + return (false); + } + } + + return (true); +} + +bool +ckh_insert(tsd_t *tsd, ckh_t *ckh, const void *key, const void *data) +{ + bool ret; + + assert(ckh != NULL); + assert(ckh_search(ckh, key, NULL, NULL)); + +#ifdef CKH_COUNT + ckh->ninserts++; +#endif + + while (ckh_try_insert(ckh, &key, &data)) { + if (ckh_grow(tsd, ckh)) { + ret = true; + goto label_return; + } + } + + ret = false; +label_return: + return (ret); +} + +bool +ckh_remove(tsd_t *tsd, ckh_t *ckh, const void *searchkey, void **key, + void **data) +{ + size_t cell; + + assert(ckh != NULL); + + cell = ckh_isearch(ckh, searchkey); + if (cell != SIZE_T_MAX) { + if (key != NULL) + *key = (void *)ckh->tab[cell].key; + if (data != NULL) + *data = (void *)ckh->tab[cell].data; + ckh->tab[cell].key = NULL; + ckh->tab[cell].data = NULL; /* Not necessary. */ + + ckh->count--; + /* Try to halve the table if it is less than 1/4 full. */ + if (ckh->count < (ZU(1) << (ckh->lg_curbuckets + + LG_CKH_BUCKET_CELLS - 2)) && ckh->lg_curbuckets + > ckh->lg_minbuckets) { + /* Ignore error due to OOM. */ + ckh_shrink(tsd, ckh); + } + + return (false); + } + + return (true); +} + +bool +ckh_search(ckh_t *ckh, const void *searchkey, void **key, void **data) +{ + size_t cell; + + assert(ckh != NULL); + + cell = ckh_isearch(ckh, searchkey); + if (cell != SIZE_T_MAX) { + if (key != NULL) + *key = (void *)ckh->tab[cell].key; + if (data != NULL) + *data = (void *)ckh->tab[cell].data; + return (false); + } + + return (true); +} + +void +ckh_string_hash(const void *key, size_t r_hash[2]) +{ + + hash(key, strlen((const char *)key), 0x94122f33U, r_hash); +} + +bool +ckh_string_keycomp(const void *k1, const void *k2) +{ + + assert(k1 != NULL); + assert(k2 != NULL); + + return (strcmp((char *)k1, (char *)k2) ? false : true); +} + +void +ckh_pointer_hash(const void *key, size_t r_hash[2]) +{ + union { + const void *v; + size_t i; + } u; + + assert(sizeof(u.v) == sizeof(u.i)); + u.v = key; + hash(&u.i, sizeof(u.i), 0xd983396eU, r_hash); +} + +bool +ckh_pointer_keycomp(const void *k1, const void *k2) +{ + + return ((k1 == k2) ? true : false); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/ctl.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/ctl.c new file mode 100644 index 0000000..3de8e60 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/ctl.c @@ -0,0 +1,2123 @@ +#define JEMALLOC_CTL_C_ +#include "jemalloc/internal/jemalloc_internal.h" + +/******************************************************************************/ +/* Data. */ + +/* + * ctl_mtx protects the following: + * - ctl_stats.* + */ +static malloc_mutex_t ctl_mtx; +static bool ctl_initialized; +static uint64_t ctl_epoch; +static ctl_stats_t ctl_stats; + +/******************************************************************************/ +/* Helpers for named and indexed nodes. */ + +JEMALLOC_INLINE_C const ctl_named_node_t * +ctl_named_node(const ctl_node_t *node) +{ + + return ((node->named) ? (const ctl_named_node_t *)node : NULL); +} + +JEMALLOC_INLINE_C const ctl_named_node_t * +ctl_named_children(const ctl_named_node_t *node, int index) +{ + const ctl_named_node_t *children = ctl_named_node(node->children); + + return (children ? &children[index] : NULL); +} + +JEMALLOC_INLINE_C const ctl_indexed_node_t * +ctl_indexed_node(const ctl_node_t *node) +{ + + return (!node->named ? (const ctl_indexed_node_t *)node : NULL); +} + +/******************************************************************************/ +/* Function prototypes for non-inline static functions. */ + +#define CTL_PROTO(n) \ +static int n##_ctl(const size_t *mib, size_t miblen, void *oldp, \ + size_t *oldlenp, void *newp, size_t newlen); + +#define INDEX_PROTO(n) \ +static const ctl_named_node_t *n##_index(const size_t *mib, \ + size_t miblen, size_t i); + +static bool ctl_arena_init(ctl_arena_stats_t *astats); +static void ctl_arena_clear(ctl_arena_stats_t *astats); +static void ctl_arena_stats_amerge(ctl_arena_stats_t *cstats, + arena_t *arena); +static void ctl_arena_stats_smerge(ctl_arena_stats_t *sstats, + ctl_arena_stats_t *astats); +static void ctl_arena_refresh(arena_t *arena, unsigned i); +static bool ctl_grow(void); +static void ctl_refresh(void); +static bool ctl_init(void); +static int ctl_lookup(const char *name, ctl_node_t const **nodesp, + size_t *mibp, size_t *depthp); + +CTL_PROTO(version) +CTL_PROTO(epoch) +CTL_PROTO(thread_tcache_enabled) +CTL_PROTO(thread_tcache_flush) +CTL_PROTO(thread_prof_name) +CTL_PROTO(thread_prof_active) +CTL_PROTO(thread_arena) +CTL_PROTO(thread_allocated) +CTL_PROTO(thread_allocatedp) +CTL_PROTO(thread_deallocated) +CTL_PROTO(thread_deallocatedp) +CTL_PROTO(config_cache_oblivious) +CTL_PROTO(config_debug) +CTL_PROTO(config_fill) +CTL_PROTO(config_lazy_lock) +CTL_PROTO(config_munmap) +CTL_PROTO(config_prof) +CTL_PROTO(config_prof_libgcc) +CTL_PROTO(config_prof_libunwind) +CTL_PROTO(config_stats) +CTL_PROTO(config_tcache) +CTL_PROTO(config_tls) +CTL_PROTO(config_utrace) +CTL_PROTO(config_valgrind) +CTL_PROTO(config_xmalloc) +CTL_PROTO(opt_abort) +CTL_PROTO(opt_dss) +CTL_PROTO(opt_lg_chunk) +CTL_PROTO(opt_narenas) +CTL_PROTO(opt_lg_dirty_mult) +CTL_PROTO(opt_stats_print) +CTL_PROTO(opt_junk) +CTL_PROTO(opt_zero) +CTL_PROTO(opt_quarantine) +CTL_PROTO(opt_redzone) +CTL_PROTO(opt_utrace) +CTL_PROTO(opt_xmalloc) +CTL_PROTO(opt_tcache) +CTL_PROTO(opt_lg_tcache_max) +CTL_PROTO(opt_prof) +CTL_PROTO(opt_prof_prefix) +CTL_PROTO(opt_prof_active) +CTL_PROTO(opt_prof_thread_active_init) +CTL_PROTO(opt_lg_prof_sample) +CTL_PROTO(opt_lg_prof_interval) +CTL_PROTO(opt_prof_gdump) +CTL_PROTO(opt_prof_final) +CTL_PROTO(opt_prof_leak) +CTL_PROTO(opt_prof_accum) +CTL_PROTO(tcache_create) +CTL_PROTO(tcache_flush) +CTL_PROTO(tcache_destroy) +CTL_PROTO(arena_i_purge) +static void arena_purge(unsigned arena_ind); +CTL_PROTO(arena_i_dss) +CTL_PROTO(arena_i_lg_dirty_mult) +CTL_PROTO(arena_i_chunk_hooks) +INDEX_PROTO(arena_i) +CTL_PROTO(arenas_bin_i_size) +CTL_PROTO(arenas_bin_i_nregs) +CTL_PROTO(arenas_bin_i_run_size) +INDEX_PROTO(arenas_bin_i) +CTL_PROTO(arenas_lrun_i_size) +INDEX_PROTO(arenas_lrun_i) +CTL_PROTO(arenas_hchunk_i_size) +INDEX_PROTO(arenas_hchunk_i) +CTL_PROTO(arenas_narenas) +CTL_PROTO(arenas_initialized) +CTL_PROTO(arenas_lg_dirty_mult) +CTL_PROTO(arenas_quantum) +CTL_PROTO(arenas_page) +CTL_PROTO(arenas_tcache_max) +CTL_PROTO(arenas_nbins) +CTL_PROTO(arenas_nhbins) +CTL_PROTO(arenas_nlruns) +CTL_PROTO(arenas_nhchunks) +CTL_PROTO(arenas_extend) +CTL_PROTO(prof_thread_active_init) +CTL_PROTO(prof_active) +CTL_PROTO(prof_dump) +CTL_PROTO(prof_gdump) +CTL_PROTO(prof_reset) +CTL_PROTO(prof_interval) +CTL_PROTO(lg_prof_sample) +CTL_PROTO(stats_arenas_i_small_allocated) +CTL_PROTO(stats_arenas_i_small_nmalloc) +CTL_PROTO(stats_arenas_i_small_ndalloc) +CTL_PROTO(stats_arenas_i_small_nrequests) +CTL_PROTO(stats_arenas_i_large_allocated) +CTL_PROTO(stats_arenas_i_large_nmalloc) +CTL_PROTO(stats_arenas_i_large_ndalloc) +CTL_PROTO(stats_arenas_i_large_nrequests) +CTL_PROTO(stats_arenas_i_huge_allocated) +CTL_PROTO(stats_arenas_i_huge_nmalloc) +CTL_PROTO(stats_arenas_i_huge_ndalloc) +CTL_PROTO(stats_arenas_i_huge_nrequests) +CTL_PROTO(stats_arenas_i_bins_j_nmalloc) +CTL_PROTO(stats_arenas_i_bins_j_ndalloc) +CTL_PROTO(stats_arenas_i_bins_j_nrequests) +CTL_PROTO(stats_arenas_i_bins_j_curregs) +CTL_PROTO(stats_arenas_i_bins_j_nfills) +CTL_PROTO(stats_arenas_i_bins_j_nflushes) +CTL_PROTO(stats_arenas_i_bins_j_nruns) +CTL_PROTO(stats_arenas_i_bins_j_nreruns) +CTL_PROTO(stats_arenas_i_bins_j_curruns) +INDEX_PROTO(stats_arenas_i_bins_j) +CTL_PROTO(stats_arenas_i_lruns_j_nmalloc) +CTL_PROTO(stats_arenas_i_lruns_j_ndalloc) +CTL_PROTO(stats_arenas_i_lruns_j_nrequests) +CTL_PROTO(stats_arenas_i_lruns_j_curruns) +INDEX_PROTO(stats_arenas_i_lruns_j) +CTL_PROTO(stats_arenas_i_hchunks_j_nmalloc) +CTL_PROTO(stats_arenas_i_hchunks_j_ndalloc) +CTL_PROTO(stats_arenas_i_hchunks_j_nrequests) +CTL_PROTO(stats_arenas_i_hchunks_j_curhchunks) +INDEX_PROTO(stats_arenas_i_hchunks_j) +CTL_PROTO(stats_arenas_i_nthreads) +CTL_PROTO(stats_arenas_i_dss) +CTL_PROTO(stats_arenas_i_lg_dirty_mult) +CTL_PROTO(stats_arenas_i_pactive) +CTL_PROTO(stats_arenas_i_pdirty) +CTL_PROTO(stats_arenas_i_mapped) +CTL_PROTO(stats_arenas_i_npurge) +CTL_PROTO(stats_arenas_i_nmadvise) +CTL_PROTO(stats_arenas_i_purged) +CTL_PROTO(stats_arenas_i_metadata_mapped) +CTL_PROTO(stats_arenas_i_metadata_allocated) +INDEX_PROTO(stats_arenas_i) +CTL_PROTO(stats_cactive) +CTL_PROTO(stats_allocated) +CTL_PROTO(stats_active) +CTL_PROTO(stats_metadata) +CTL_PROTO(stats_resident) +CTL_PROTO(stats_mapped) + +/******************************************************************************/ +/* mallctl tree. */ + +/* Maximum tree depth. */ +#define CTL_MAX_DEPTH 6 + +#define NAME(n) {true}, n +#define CHILD(t, c) \ + sizeof(c##_node) / sizeof(ctl_##t##_node_t), \ + (ctl_node_t *)c##_node, \ + NULL +#define CTL(c) 0, NULL, c##_ctl + +/* + * Only handles internal indexed nodes, since there are currently no external + * ones. + */ +#define INDEX(i) {false}, i##_index + +static const ctl_named_node_t thread_tcache_node[] = { + {NAME("enabled"), CTL(thread_tcache_enabled)}, + {NAME("flush"), CTL(thread_tcache_flush)} +}; + +static const ctl_named_node_t thread_prof_node[] = { + {NAME("name"), CTL(thread_prof_name)}, + {NAME("active"), CTL(thread_prof_active)} +}; + +static const ctl_named_node_t thread_node[] = { + {NAME("arena"), CTL(thread_arena)}, + {NAME("allocated"), CTL(thread_allocated)}, + {NAME("allocatedp"), CTL(thread_allocatedp)}, + {NAME("deallocated"), CTL(thread_deallocated)}, + {NAME("deallocatedp"), CTL(thread_deallocatedp)}, + {NAME("tcache"), CHILD(named, thread_tcache)}, + {NAME("prof"), CHILD(named, thread_prof)} +}; + +static const ctl_named_node_t config_node[] = { + {NAME("cache_oblivious"), CTL(config_cache_oblivious)}, + {NAME("debug"), CTL(config_debug)}, + {NAME("fill"), CTL(config_fill)}, + {NAME("lazy_lock"), CTL(config_lazy_lock)}, + {NAME("munmap"), CTL(config_munmap)}, + {NAME("prof"), CTL(config_prof)}, + {NAME("prof_libgcc"), CTL(config_prof_libgcc)}, + {NAME("prof_libunwind"), CTL(config_prof_libunwind)}, + {NAME("stats"), CTL(config_stats)}, + {NAME("tcache"), CTL(config_tcache)}, + {NAME("tls"), CTL(config_tls)}, + {NAME("utrace"), CTL(config_utrace)}, + {NAME("valgrind"), CTL(config_valgrind)}, + {NAME("xmalloc"), CTL(config_xmalloc)} +}; + +static const ctl_named_node_t opt_node[] = { + {NAME("abort"), CTL(opt_abort)}, + {NAME("dss"), CTL(opt_dss)}, + {NAME("lg_chunk"), CTL(opt_lg_chunk)}, + {NAME("narenas"), CTL(opt_narenas)}, + {NAME("lg_dirty_mult"), CTL(opt_lg_dirty_mult)}, + {NAME("stats_print"), CTL(opt_stats_print)}, + {NAME("junk"), CTL(opt_junk)}, + {NAME("zero"), CTL(opt_zero)}, + {NAME("quarantine"), CTL(opt_quarantine)}, + {NAME("redzone"), CTL(opt_redzone)}, + {NAME("utrace"), CTL(opt_utrace)}, + {NAME("xmalloc"), CTL(opt_xmalloc)}, + {NAME("tcache"), CTL(opt_tcache)}, + {NAME("lg_tcache_max"), CTL(opt_lg_tcache_max)}, + {NAME("prof"), CTL(opt_prof)}, + {NAME("prof_prefix"), CTL(opt_prof_prefix)}, + {NAME("prof_active"), CTL(opt_prof_active)}, + {NAME("prof_thread_active_init"), CTL(opt_prof_thread_active_init)}, + {NAME("lg_prof_sample"), CTL(opt_lg_prof_sample)}, + {NAME("lg_prof_interval"), CTL(opt_lg_prof_interval)}, + {NAME("prof_gdump"), CTL(opt_prof_gdump)}, + {NAME("prof_final"), CTL(opt_prof_final)}, + {NAME("prof_leak"), CTL(opt_prof_leak)}, + {NAME("prof_accum"), CTL(opt_prof_accum)} +}; + +static const ctl_named_node_t tcache_node[] = { + {NAME("create"), CTL(tcache_create)}, + {NAME("flush"), CTL(tcache_flush)}, + {NAME("destroy"), CTL(tcache_destroy)} +}; + +static const ctl_named_node_t arena_i_node[] = { + {NAME("purge"), CTL(arena_i_purge)}, + {NAME("dss"), CTL(arena_i_dss)}, + {NAME("lg_dirty_mult"), CTL(arena_i_lg_dirty_mult)}, + {NAME("chunk_hooks"), CTL(arena_i_chunk_hooks)} +}; +static const ctl_named_node_t super_arena_i_node[] = { + {NAME(""), CHILD(named, arena_i)} +}; + +static const ctl_indexed_node_t arena_node[] = { + {INDEX(arena_i)} +}; + +static const ctl_named_node_t arenas_bin_i_node[] = { + {NAME("size"), CTL(arenas_bin_i_size)}, + {NAME("nregs"), CTL(arenas_bin_i_nregs)}, + {NAME("run_size"), CTL(arenas_bin_i_run_size)} +}; +static const ctl_named_node_t super_arenas_bin_i_node[] = { + {NAME(""), CHILD(named, arenas_bin_i)} +}; + +static const ctl_indexed_node_t arenas_bin_node[] = { + {INDEX(arenas_bin_i)} +}; + +static const ctl_named_node_t arenas_lrun_i_node[] = { + {NAME("size"), CTL(arenas_lrun_i_size)} +}; +static const ctl_named_node_t super_arenas_lrun_i_node[] = { + {NAME(""), CHILD(named, arenas_lrun_i)} +}; + +static const ctl_indexed_node_t arenas_lrun_node[] = { + {INDEX(arenas_lrun_i)} +}; + +static const ctl_named_node_t arenas_hchunk_i_node[] = { + {NAME("size"), CTL(arenas_hchunk_i_size)} +}; +static const ctl_named_node_t super_arenas_hchunk_i_node[] = { + {NAME(""), CHILD(named, arenas_hchunk_i)} +}; + +static const ctl_indexed_node_t arenas_hchunk_node[] = { + {INDEX(arenas_hchunk_i)} +}; + +static const ctl_named_node_t arenas_node[] = { + {NAME("narenas"), CTL(arenas_narenas)}, + {NAME("initialized"), CTL(arenas_initialized)}, + {NAME("lg_dirty_mult"), CTL(arenas_lg_dirty_mult)}, + {NAME("quantum"), CTL(arenas_quantum)}, + {NAME("page"), CTL(arenas_page)}, + {NAME("tcache_max"), CTL(arenas_tcache_max)}, + {NAME("nbins"), CTL(arenas_nbins)}, + {NAME("nhbins"), CTL(arenas_nhbins)}, + {NAME("bin"), CHILD(indexed, arenas_bin)}, + {NAME("nlruns"), CTL(arenas_nlruns)}, + {NAME("lrun"), CHILD(indexed, arenas_lrun)}, + {NAME("nhchunks"), CTL(arenas_nhchunks)}, + {NAME("hchunk"), CHILD(indexed, arenas_hchunk)}, + {NAME("extend"), CTL(arenas_extend)} +}; + +static const ctl_named_node_t prof_node[] = { + {NAME("thread_active_init"), CTL(prof_thread_active_init)}, + {NAME("active"), CTL(prof_active)}, + {NAME("dump"), CTL(prof_dump)}, + {NAME("gdump"), CTL(prof_gdump)}, + {NAME("reset"), CTL(prof_reset)}, + {NAME("interval"), CTL(prof_interval)}, + {NAME("lg_sample"), CTL(lg_prof_sample)} +}; + +static const ctl_named_node_t stats_arenas_i_metadata_node[] = { + {NAME("mapped"), CTL(stats_arenas_i_metadata_mapped)}, + {NAME("allocated"), CTL(stats_arenas_i_metadata_allocated)} +}; + +static const ctl_named_node_t stats_arenas_i_small_node[] = { + {NAME("allocated"), CTL(stats_arenas_i_small_allocated)}, + {NAME("nmalloc"), CTL(stats_arenas_i_small_nmalloc)}, + {NAME("ndalloc"), CTL(stats_arenas_i_small_ndalloc)}, + {NAME("nrequests"), CTL(stats_arenas_i_small_nrequests)} +}; + +static const ctl_named_node_t stats_arenas_i_large_node[] = { + {NAME("allocated"), CTL(stats_arenas_i_large_allocated)}, + {NAME("nmalloc"), CTL(stats_arenas_i_large_nmalloc)}, + {NAME("ndalloc"), CTL(stats_arenas_i_large_ndalloc)}, + {NAME("nrequests"), CTL(stats_arenas_i_large_nrequests)} +}; + +static const ctl_named_node_t stats_arenas_i_huge_node[] = { + {NAME("allocated"), CTL(stats_arenas_i_huge_allocated)}, + {NAME("nmalloc"), CTL(stats_arenas_i_huge_nmalloc)}, + {NAME("ndalloc"), CTL(stats_arenas_i_huge_ndalloc)}, + {NAME("nrequests"), CTL(stats_arenas_i_huge_nrequests)} +}; + +static const ctl_named_node_t stats_arenas_i_bins_j_node[] = { + {NAME("nmalloc"), CTL(stats_arenas_i_bins_j_nmalloc)}, + {NAME("ndalloc"), CTL(stats_arenas_i_bins_j_ndalloc)}, + {NAME("nrequests"), CTL(stats_arenas_i_bins_j_nrequests)}, + {NAME("curregs"), CTL(stats_arenas_i_bins_j_curregs)}, + {NAME("nfills"), CTL(stats_arenas_i_bins_j_nfills)}, + {NAME("nflushes"), CTL(stats_arenas_i_bins_j_nflushes)}, + {NAME("nruns"), CTL(stats_arenas_i_bins_j_nruns)}, + {NAME("nreruns"), CTL(stats_arenas_i_bins_j_nreruns)}, + {NAME("curruns"), CTL(stats_arenas_i_bins_j_curruns)} +}; +static const ctl_named_node_t super_stats_arenas_i_bins_j_node[] = { + {NAME(""), CHILD(named, stats_arenas_i_bins_j)} +}; + +static const ctl_indexed_node_t stats_arenas_i_bins_node[] = { + {INDEX(stats_arenas_i_bins_j)} +}; + +static const ctl_named_node_t stats_arenas_i_lruns_j_node[] = { + {NAME("nmalloc"), CTL(stats_arenas_i_lruns_j_nmalloc)}, + {NAME("ndalloc"), CTL(stats_arenas_i_lruns_j_ndalloc)}, + {NAME("nrequests"), CTL(stats_arenas_i_lruns_j_nrequests)}, + {NAME("curruns"), CTL(stats_arenas_i_lruns_j_curruns)} +}; +static const ctl_named_node_t super_stats_arenas_i_lruns_j_node[] = { + {NAME(""), CHILD(named, stats_arenas_i_lruns_j)} +}; + +static const ctl_indexed_node_t stats_arenas_i_lruns_node[] = { + {INDEX(stats_arenas_i_lruns_j)} +}; + +static const ctl_named_node_t stats_arenas_i_hchunks_j_node[] = { + {NAME("nmalloc"), CTL(stats_arenas_i_hchunks_j_nmalloc)}, + {NAME("ndalloc"), CTL(stats_arenas_i_hchunks_j_ndalloc)}, + {NAME("nrequests"), CTL(stats_arenas_i_hchunks_j_nrequests)}, + {NAME("curhchunks"), CTL(stats_arenas_i_hchunks_j_curhchunks)} +}; +static const ctl_named_node_t super_stats_arenas_i_hchunks_j_node[] = { + {NAME(""), CHILD(named, stats_arenas_i_hchunks_j)} +}; + +static const ctl_indexed_node_t stats_arenas_i_hchunks_node[] = { + {INDEX(stats_arenas_i_hchunks_j)} +}; + +static const ctl_named_node_t stats_arenas_i_node[] = { + {NAME("nthreads"), CTL(stats_arenas_i_nthreads)}, + {NAME("dss"), CTL(stats_arenas_i_dss)}, + {NAME("lg_dirty_mult"), CTL(stats_arenas_i_lg_dirty_mult)}, + {NAME("pactive"), CTL(stats_arenas_i_pactive)}, + {NAME("pdirty"), CTL(stats_arenas_i_pdirty)}, + {NAME("mapped"), CTL(stats_arenas_i_mapped)}, + {NAME("npurge"), CTL(stats_arenas_i_npurge)}, + {NAME("nmadvise"), CTL(stats_arenas_i_nmadvise)}, + {NAME("purged"), CTL(stats_arenas_i_purged)}, + {NAME("metadata"), CHILD(named, stats_arenas_i_metadata)}, + {NAME("small"), CHILD(named, stats_arenas_i_small)}, + {NAME("large"), CHILD(named, stats_arenas_i_large)}, + {NAME("huge"), CHILD(named, stats_arenas_i_huge)}, + {NAME("bins"), CHILD(indexed, stats_arenas_i_bins)}, + {NAME("lruns"), CHILD(indexed, stats_arenas_i_lruns)}, + {NAME("hchunks"), CHILD(indexed, stats_arenas_i_hchunks)} +}; +static const ctl_named_node_t super_stats_arenas_i_node[] = { + {NAME(""), CHILD(named, stats_arenas_i)} +}; + +static const ctl_indexed_node_t stats_arenas_node[] = { + {INDEX(stats_arenas_i)} +}; + +static const ctl_named_node_t stats_node[] = { + {NAME("cactive"), CTL(stats_cactive)}, + {NAME("allocated"), CTL(stats_allocated)}, + {NAME("active"), CTL(stats_active)}, + {NAME("metadata"), CTL(stats_metadata)}, + {NAME("resident"), CTL(stats_resident)}, + {NAME("mapped"), CTL(stats_mapped)}, + {NAME("arenas"), CHILD(indexed, stats_arenas)} +}; + +static const ctl_named_node_t root_node[] = { + {NAME("version"), CTL(version)}, + {NAME("epoch"), CTL(epoch)}, + {NAME("thread"), CHILD(named, thread)}, + {NAME("config"), CHILD(named, config)}, + {NAME("opt"), CHILD(named, opt)}, + {NAME("tcache"), CHILD(named, tcache)}, + {NAME("arena"), CHILD(indexed, arena)}, + {NAME("arenas"), CHILD(named, arenas)}, + {NAME("prof"), CHILD(named, prof)}, + {NAME("stats"), CHILD(named, stats)} +}; +static const ctl_named_node_t super_root_node[] = { + {NAME(""), CHILD(named, root)} +}; + +#undef NAME +#undef CHILD +#undef CTL +#undef INDEX + +/******************************************************************************/ + +static bool +ctl_arena_init(ctl_arena_stats_t *astats) +{ + + if (astats->lstats == NULL) { + astats->lstats = (malloc_large_stats_t *)a0malloc(nlclasses * + sizeof(malloc_large_stats_t)); + if (astats->lstats == NULL) + return (true); + } + + if (astats->hstats == NULL) { + astats->hstats = (malloc_huge_stats_t *)a0malloc(nhclasses * + sizeof(malloc_huge_stats_t)); + if (astats->hstats == NULL) + return (true); + } + + return (false); +} + +static void +ctl_arena_clear(ctl_arena_stats_t *astats) +{ + + astats->dss = dss_prec_names[dss_prec_limit]; + astats->lg_dirty_mult = -1; + astats->pactive = 0; + astats->pdirty = 0; + if (config_stats) { + memset(&astats->astats, 0, sizeof(arena_stats_t)); + astats->allocated_small = 0; + astats->nmalloc_small = 0; + astats->ndalloc_small = 0; + astats->nrequests_small = 0; + memset(astats->bstats, 0, NBINS * sizeof(malloc_bin_stats_t)); + memset(astats->lstats, 0, nlclasses * + sizeof(malloc_large_stats_t)); + memset(astats->hstats, 0, nhclasses * + sizeof(malloc_huge_stats_t)); + } +} + +static void +ctl_arena_stats_amerge(ctl_arena_stats_t *cstats, arena_t *arena) +{ + unsigned i; + + arena_stats_merge(arena, &cstats->dss, &cstats->lg_dirty_mult, + &cstats->pactive, &cstats->pdirty, &cstats->astats, cstats->bstats, + cstats->lstats, cstats->hstats); + + for (i = 0; i < NBINS; i++) { + cstats->allocated_small += cstats->bstats[i].curregs * + index2size(i); + cstats->nmalloc_small += cstats->bstats[i].nmalloc; + cstats->ndalloc_small += cstats->bstats[i].ndalloc; + cstats->nrequests_small += cstats->bstats[i].nrequests; + } +} + +static void +ctl_arena_stats_smerge(ctl_arena_stats_t *sstats, ctl_arena_stats_t *astats) +{ + unsigned i; + + sstats->pactive += astats->pactive; + sstats->pdirty += astats->pdirty; + + sstats->astats.mapped += astats->astats.mapped; + sstats->astats.npurge += astats->astats.npurge; + sstats->astats.nmadvise += astats->astats.nmadvise; + sstats->astats.purged += astats->astats.purged; + + sstats->astats.metadata_mapped += astats->astats.metadata_mapped; + sstats->astats.metadata_allocated += astats->astats.metadata_allocated; + + sstats->allocated_small += astats->allocated_small; + sstats->nmalloc_small += astats->nmalloc_small; + sstats->ndalloc_small += astats->ndalloc_small; + sstats->nrequests_small += astats->nrequests_small; + + sstats->astats.allocated_large += astats->astats.allocated_large; + sstats->astats.nmalloc_large += astats->astats.nmalloc_large; + sstats->astats.ndalloc_large += astats->astats.ndalloc_large; + sstats->astats.nrequests_large += astats->astats.nrequests_large; + + sstats->astats.allocated_huge += astats->astats.allocated_huge; + sstats->astats.nmalloc_huge += astats->astats.nmalloc_huge; + sstats->astats.ndalloc_huge += astats->astats.ndalloc_huge; + + for (i = 0; i < NBINS; i++) { + sstats->bstats[i].nmalloc += astats->bstats[i].nmalloc; + sstats->bstats[i].ndalloc += astats->bstats[i].ndalloc; + sstats->bstats[i].nrequests += astats->bstats[i].nrequests; + sstats->bstats[i].curregs += astats->bstats[i].curregs; + if (config_tcache) { + sstats->bstats[i].nfills += astats->bstats[i].nfills; + sstats->bstats[i].nflushes += + astats->bstats[i].nflushes; + } + sstats->bstats[i].nruns += astats->bstats[i].nruns; + sstats->bstats[i].reruns += astats->bstats[i].reruns; + sstats->bstats[i].curruns += astats->bstats[i].curruns; + } + + for (i = 0; i < nlclasses; i++) { + sstats->lstats[i].nmalloc += astats->lstats[i].nmalloc; + sstats->lstats[i].ndalloc += astats->lstats[i].ndalloc; + sstats->lstats[i].nrequests += astats->lstats[i].nrequests; + sstats->lstats[i].curruns += astats->lstats[i].curruns; + } + + for (i = 0; i < nhclasses; i++) { + sstats->hstats[i].nmalloc += astats->hstats[i].nmalloc; + sstats->hstats[i].ndalloc += astats->hstats[i].ndalloc; + sstats->hstats[i].curhchunks += astats->hstats[i].curhchunks; + } +} + +static void +ctl_arena_refresh(arena_t *arena, unsigned i) +{ + ctl_arena_stats_t *astats = &ctl_stats.arenas[i]; + ctl_arena_stats_t *sstats = &ctl_stats.arenas[ctl_stats.narenas]; + + ctl_arena_clear(astats); + + sstats->nthreads += astats->nthreads; + if (config_stats) { + ctl_arena_stats_amerge(astats, arena); + /* Merge into sum stats as well. */ + ctl_arena_stats_smerge(sstats, astats); + } else { + astats->pactive += arena->nactive; + astats->pdirty += arena->ndirty; + /* Merge into sum stats as well. */ + sstats->pactive += arena->nactive; + sstats->pdirty += arena->ndirty; + } +} + +static bool +ctl_grow(void) +{ + ctl_arena_stats_t *astats; + + /* Initialize new arena. */ + if (arena_init(ctl_stats.narenas) == NULL) + return (true); + + /* Allocate extended arena stats. */ + astats = (ctl_arena_stats_t *)a0malloc((ctl_stats.narenas + 2) * + sizeof(ctl_arena_stats_t)); + if (astats == NULL) + return (true); + + /* Initialize the new astats element. */ + memcpy(astats, ctl_stats.arenas, (ctl_stats.narenas + 1) * + sizeof(ctl_arena_stats_t)); + memset(&astats[ctl_stats.narenas + 1], 0, sizeof(ctl_arena_stats_t)); + if (ctl_arena_init(&astats[ctl_stats.narenas + 1])) { + a0dalloc(astats); + return (true); + } + /* Swap merged stats to their new location. */ + { + ctl_arena_stats_t tstats; + memcpy(&tstats, &astats[ctl_stats.narenas], + sizeof(ctl_arena_stats_t)); + memcpy(&astats[ctl_stats.narenas], + &astats[ctl_stats.narenas + 1], sizeof(ctl_arena_stats_t)); + memcpy(&astats[ctl_stats.narenas + 1], &tstats, + sizeof(ctl_arena_stats_t)); + } + a0dalloc(ctl_stats.arenas); + ctl_stats.arenas = astats; + ctl_stats.narenas++; + + return (false); +} + +static void +ctl_refresh(void) +{ + tsd_t *tsd; + unsigned i; + bool refreshed; + VARIABLE_ARRAY(arena_t *, tarenas, ctl_stats.narenas); + + /* + * Clear sum stats, since they will be merged into by + * ctl_arena_refresh(). + */ + ctl_stats.arenas[ctl_stats.narenas].nthreads = 0; + ctl_arena_clear(&ctl_stats.arenas[ctl_stats.narenas]); + + tsd = tsd_fetch(); + for (i = 0, refreshed = false; i < ctl_stats.narenas; i++) { + tarenas[i] = arena_get(tsd, i, false, false); + if (tarenas[i] == NULL && !refreshed) { + tarenas[i] = arena_get(tsd, i, false, true); + refreshed = true; + } + } + + for (i = 0; i < ctl_stats.narenas; i++) { + if (tarenas[i] != NULL) + ctl_stats.arenas[i].nthreads = arena_nbound(i); + else + ctl_stats.arenas[i].nthreads = 0; + } + + for (i = 0; i < ctl_stats.narenas; i++) { + bool initialized = (tarenas[i] != NULL); + + ctl_stats.arenas[i].initialized = initialized; + if (initialized) + ctl_arena_refresh(tarenas[i], i); + } + + if (config_stats) { + size_t base_allocated, base_resident, base_mapped; + base_stats_get(&base_allocated, &base_resident, &base_mapped); + ctl_stats.allocated = + ctl_stats.arenas[ctl_stats.narenas].allocated_small + + ctl_stats.arenas[ctl_stats.narenas].astats.allocated_large + + ctl_stats.arenas[ctl_stats.narenas].astats.allocated_huge; + ctl_stats.active = + (ctl_stats.arenas[ctl_stats.narenas].pactive << LG_PAGE); + ctl_stats.metadata = base_allocated + + ctl_stats.arenas[ctl_stats.narenas].astats.metadata_mapped + + ctl_stats.arenas[ctl_stats.narenas].astats + .metadata_allocated; + ctl_stats.resident = base_resident + + ctl_stats.arenas[ctl_stats.narenas].astats.metadata_mapped + + ((ctl_stats.arenas[ctl_stats.narenas].pactive + + ctl_stats.arenas[ctl_stats.narenas].pdirty) << LG_PAGE); + ctl_stats.mapped = base_mapped + + ctl_stats.arenas[ctl_stats.narenas].astats.mapped; + } + + ctl_epoch++; +} + +static bool +ctl_init(void) +{ + bool ret; + + malloc_mutex_lock(&ctl_mtx); + if (!ctl_initialized) { + /* + * Allocate space for one extra arena stats element, which + * contains summed stats across all arenas. + */ + ctl_stats.narenas = narenas_total_get(); + ctl_stats.arenas = (ctl_arena_stats_t *)a0malloc( + (ctl_stats.narenas + 1) * sizeof(ctl_arena_stats_t)); + if (ctl_stats.arenas == NULL) { + ret = true; + goto label_return; + } + memset(ctl_stats.arenas, 0, (ctl_stats.narenas + 1) * + sizeof(ctl_arena_stats_t)); + + /* + * Initialize all stats structures, regardless of whether they + * ever get used. Lazy initialization would allow errors to + * cause inconsistent state to be viewable by the application. + */ + if (config_stats) { + unsigned i; + for (i = 0; i <= ctl_stats.narenas; i++) { + if (ctl_arena_init(&ctl_stats.arenas[i])) { + unsigned j; + for (j = 0; j < i; j++) { + a0dalloc( + ctl_stats.arenas[j].lstats); + a0dalloc( + ctl_stats.arenas[j].hstats); + } + a0dalloc(ctl_stats.arenas); + ctl_stats.arenas = NULL; + ret = true; + goto label_return; + } + } + } + ctl_stats.arenas[ctl_stats.narenas].initialized = true; + + ctl_epoch = 0; + ctl_refresh(); + ctl_initialized = true; + } + + ret = false; +label_return: + malloc_mutex_unlock(&ctl_mtx); + return (ret); +} + +static int +ctl_lookup(const char *name, ctl_node_t const **nodesp, size_t *mibp, + size_t *depthp) +{ + int ret; + const char *elm, *tdot, *dot; + size_t elen, i, j; + const ctl_named_node_t *node; + + elm = name; + /* Equivalent to strchrnul(). */ + dot = ((tdot = strchr(elm, '.')) != NULL) ? tdot : strchr(elm, '\0'); + elen = (size_t)((uintptr_t)dot - (uintptr_t)elm); + if (elen == 0) { + ret = ENOENT; + goto label_return; + } + node = super_root_node; + for (i = 0; i < *depthp; i++) { + assert(node); + assert(node->nchildren > 0); + if (ctl_named_node(node->children) != NULL) { + const ctl_named_node_t *pnode = node; + + /* Children are named. */ + for (j = 0; j < node->nchildren; j++) { + const ctl_named_node_t *child = + ctl_named_children(node, j); + if (strlen(child->name) == elen && + strncmp(elm, child->name, elen) == 0) { + node = child; + if (nodesp != NULL) + nodesp[i] = + (const ctl_node_t *)node; + mibp[i] = j; + break; + } + } + if (node == pnode) { + ret = ENOENT; + goto label_return; + } + } else { + uintmax_t index; + const ctl_indexed_node_t *inode; + + /* Children are indexed. */ + index = malloc_strtoumax(elm, NULL, 10); + if (index == UINTMAX_MAX || index > SIZE_T_MAX) { + ret = ENOENT; + goto label_return; + } + + inode = ctl_indexed_node(node->children); + node = inode->index(mibp, *depthp, (size_t)index); + if (node == NULL) { + ret = ENOENT; + goto label_return; + } + + if (nodesp != NULL) + nodesp[i] = (const ctl_node_t *)node; + mibp[i] = (size_t)index; + } + + if (node->ctl != NULL) { + /* Terminal node. */ + if (*dot != '\0') { + /* + * The name contains more elements than are + * in this path through the tree. + */ + ret = ENOENT; + goto label_return; + } + /* Complete lookup successful. */ + *depthp = i + 1; + break; + } + + /* Update elm. */ + if (*dot == '\0') { + /* No more elements. */ + ret = ENOENT; + goto label_return; + } + elm = &dot[1]; + dot = ((tdot = strchr(elm, '.')) != NULL) ? tdot : + strchr(elm, '\0'); + elen = (size_t)((uintptr_t)dot - (uintptr_t)elm); + } + + ret = 0; +label_return: + return (ret); +} + +int +ctl_byname(const char *name, void *oldp, size_t *oldlenp, void *newp, + size_t newlen) +{ + int ret; + size_t depth; + ctl_node_t const *nodes[CTL_MAX_DEPTH]; + size_t mib[CTL_MAX_DEPTH]; + const ctl_named_node_t *node; + + if (!ctl_initialized && ctl_init()) { + ret = EAGAIN; + goto label_return; + } + + depth = CTL_MAX_DEPTH; + ret = ctl_lookup(name, nodes, mib, &depth); + if (ret != 0) + goto label_return; + + node = ctl_named_node(nodes[depth-1]); + if (node != NULL && node->ctl) + ret = node->ctl(mib, depth, oldp, oldlenp, newp, newlen); + else { + /* The name refers to a partial path through the ctl tree. */ + ret = ENOENT; + } + +label_return: + return(ret); +} + +int +ctl_nametomib(const char *name, size_t *mibp, size_t *miblenp) +{ + int ret; + + if (!ctl_initialized && ctl_init()) { + ret = EAGAIN; + goto label_return; + } + + ret = ctl_lookup(name, NULL, mibp, miblenp); +label_return: + return(ret); +} + +int +ctl_bymib(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, + void *newp, size_t newlen) +{ + int ret; + const ctl_named_node_t *node; + size_t i; + + if (!ctl_initialized && ctl_init()) { + ret = EAGAIN; + goto label_return; + } + + /* Iterate down the tree. */ + node = super_root_node; + for (i = 0; i < miblen; i++) { + assert(node); + assert(node->nchildren > 0); + if (ctl_named_node(node->children) != NULL) { + /* Children are named. */ + if (node->nchildren <= mib[i]) { + ret = ENOENT; + goto label_return; + } + node = ctl_named_children(node, mib[i]); + } else { + const ctl_indexed_node_t *inode; + + /* Indexed element. */ + inode = ctl_indexed_node(node->children); + node = inode->index(mib, miblen, mib[i]); + if (node == NULL) { + ret = ENOENT; + goto label_return; + } + } + } + + /* Call the ctl function. */ + if (node && node->ctl) + ret = node->ctl(mib, miblen, oldp, oldlenp, newp, newlen); + else { + /* Partial MIB. */ + ret = ENOENT; + } + +label_return: + return(ret); +} + +bool +ctl_boot(void) +{ + + if (malloc_mutex_init(&ctl_mtx)) + return (true); + + ctl_initialized = false; + + return (false); +} + +void +ctl_prefork(void) +{ + + malloc_mutex_prefork(&ctl_mtx); +} + +void +ctl_postfork_parent(void) +{ + + malloc_mutex_postfork_parent(&ctl_mtx); +} + +void +ctl_postfork_child(void) +{ + + malloc_mutex_postfork_child(&ctl_mtx); +} + +/******************************************************************************/ +/* *_ctl() functions. */ + +#define READONLY() do { \ + if (newp != NULL || newlen != 0) { \ + ret = EPERM; \ + goto label_return; \ + } \ +} while (0) + +#define WRITEONLY() do { \ + if (oldp != NULL || oldlenp != NULL) { \ + ret = EPERM; \ + goto label_return; \ + } \ +} while (0) + +#define READ_XOR_WRITE() do { \ + if ((oldp != NULL && oldlenp != NULL) && (newp != NULL || \ + newlen != 0)) { \ + ret = EPERM; \ + goto label_return; \ + } \ +} while (0) + +#define READ(v, t) do { \ + if (oldp != NULL && oldlenp != NULL) { \ + if (*oldlenp != sizeof(t)) { \ + size_t copylen = (sizeof(t) <= *oldlenp) \ + ? sizeof(t) : *oldlenp; \ + memcpy(oldp, (void *)&(v), copylen); \ + ret = EINVAL; \ + goto label_return; \ + } \ + *(t *)oldp = (v); \ + } \ +} while (0) + +#define WRITE(v, t) do { \ + if (newp != NULL) { \ + if (newlen != sizeof(t)) { \ + ret = EINVAL; \ + goto label_return; \ + } \ + (v) = *(t *)newp; \ + } \ +} while (0) + +/* + * There's a lot of code duplication in the following macros due to limitations + * in how nested cpp macros are expanded. + */ +#define CTL_RO_CLGEN(c, l, n, v, t) \ +static int \ +n##_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, \ + void *newp, size_t newlen) \ +{ \ + int ret; \ + t oldval; \ + \ + if (!(c)) \ + return (ENOENT); \ + if (l) \ + malloc_mutex_lock(&ctl_mtx); \ + READONLY(); \ + oldval = (v); \ + READ(oldval, t); \ + \ + ret = 0; \ +label_return: \ + if (l) \ + malloc_mutex_unlock(&ctl_mtx); \ + return (ret); \ +} + +#define CTL_RO_CGEN(c, n, v, t) \ +static int \ +n##_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, \ + void *newp, size_t newlen) \ +{ \ + int ret; \ + t oldval; \ + \ + if (!(c)) \ + return (ENOENT); \ + malloc_mutex_lock(&ctl_mtx); \ + READONLY(); \ + oldval = (v); \ + READ(oldval, t); \ + \ + ret = 0; \ +label_return: \ + malloc_mutex_unlock(&ctl_mtx); \ + return (ret); \ +} + +#define CTL_RO_GEN(n, v, t) \ +static int \ +n##_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, \ + void *newp, size_t newlen) \ +{ \ + int ret; \ + t oldval; \ + \ + malloc_mutex_lock(&ctl_mtx); \ + READONLY(); \ + oldval = (v); \ + READ(oldval, t); \ + \ + ret = 0; \ +label_return: \ + malloc_mutex_unlock(&ctl_mtx); \ + return (ret); \ +} + +/* + * ctl_mtx is not acquired, under the assumption that no pertinent data will + * mutate during the call. + */ +#define CTL_RO_NL_CGEN(c, n, v, t) \ +static int \ +n##_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, \ + void *newp, size_t newlen) \ +{ \ + int ret; \ + t oldval; \ + \ + if (!(c)) \ + return (ENOENT); \ + READONLY(); \ + oldval = (v); \ + READ(oldval, t); \ + \ + ret = 0; \ +label_return: \ + return (ret); \ +} + +#define CTL_RO_NL_GEN(n, v, t) \ +static int \ +n##_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, \ + void *newp, size_t newlen) \ +{ \ + int ret; \ + t oldval; \ + \ + READONLY(); \ + oldval = (v); \ + READ(oldval, t); \ + \ + ret = 0; \ +label_return: \ + return (ret); \ +} + +#define CTL_TSD_RO_NL_CGEN(c, n, m, t) \ +static int \ +n##_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, \ + void *newp, size_t newlen) \ +{ \ + int ret; \ + t oldval; \ + tsd_t *tsd; \ + \ + if (!(c)) \ + return (ENOENT); \ + READONLY(); \ + tsd = tsd_fetch(); \ + oldval = (m(tsd)); \ + READ(oldval, t); \ + \ + ret = 0; \ +label_return: \ + return (ret); \ +} + +#define CTL_RO_BOOL_CONFIG_GEN(n) \ +static int \ +n##_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, \ + void *newp, size_t newlen) \ +{ \ + int ret; \ + bool oldval; \ + \ + READONLY(); \ + oldval = n; \ + READ(oldval, bool); \ + \ + ret = 0; \ +label_return: \ + return (ret); \ +} + +/******************************************************************************/ + +CTL_RO_NL_GEN(version, JEMALLOC_VERSION, const char *) + +static int +epoch_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, + void *newp, size_t newlen) +{ + int ret; + UNUSED uint64_t newval; + + malloc_mutex_lock(&ctl_mtx); + WRITE(newval, uint64_t); + if (newp != NULL) + ctl_refresh(); + READ(ctl_epoch, uint64_t); + + ret = 0; +label_return: + malloc_mutex_unlock(&ctl_mtx); + return (ret); +} + +/******************************************************************************/ + +CTL_RO_BOOL_CONFIG_GEN(config_cache_oblivious) +CTL_RO_BOOL_CONFIG_GEN(config_debug) +CTL_RO_BOOL_CONFIG_GEN(config_fill) +CTL_RO_BOOL_CONFIG_GEN(config_lazy_lock) +CTL_RO_BOOL_CONFIG_GEN(config_munmap) +CTL_RO_BOOL_CONFIG_GEN(config_prof) +CTL_RO_BOOL_CONFIG_GEN(config_prof_libgcc) +CTL_RO_BOOL_CONFIG_GEN(config_prof_libunwind) +CTL_RO_BOOL_CONFIG_GEN(config_stats) +CTL_RO_BOOL_CONFIG_GEN(config_tcache) +CTL_RO_BOOL_CONFIG_GEN(config_tls) +CTL_RO_BOOL_CONFIG_GEN(config_utrace) +CTL_RO_BOOL_CONFIG_GEN(config_valgrind) +CTL_RO_BOOL_CONFIG_GEN(config_xmalloc) + +/******************************************************************************/ + +CTL_RO_NL_GEN(opt_abort, opt_abort, bool) +CTL_RO_NL_GEN(opt_dss, opt_dss, const char *) +CTL_RO_NL_GEN(opt_lg_chunk, opt_lg_chunk, size_t) +CTL_RO_NL_GEN(opt_narenas, opt_narenas, size_t) +CTL_RO_NL_GEN(opt_lg_dirty_mult, opt_lg_dirty_mult, ssize_t) +CTL_RO_NL_GEN(opt_stats_print, opt_stats_print, bool) +CTL_RO_NL_CGEN(config_fill, opt_junk, opt_junk, const char *) +CTL_RO_NL_CGEN(config_fill, opt_quarantine, opt_quarantine, size_t) +CTL_RO_NL_CGEN(config_fill, opt_redzone, opt_redzone, bool) +CTL_RO_NL_CGEN(config_fill, opt_zero, opt_zero, bool) +CTL_RO_NL_CGEN(config_utrace, opt_utrace, opt_utrace, bool) +CTL_RO_NL_CGEN(config_xmalloc, opt_xmalloc, opt_xmalloc, bool) +CTL_RO_NL_CGEN(config_tcache, opt_tcache, opt_tcache, bool) +CTL_RO_NL_CGEN(config_tcache, opt_lg_tcache_max, opt_lg_tcache_max, ssize_t) +CTL_RO_NL_CGEN(config_prof, opt_prof, opt_prof, bool) +CTL_RO_NL_CGEN(config_prof, opt_prof_prefix, opt_prof_prefix, const char *) +CTL_RO_NL_CGEN(config_prof, opt_prof_active, opt_prof_active, bool) +CTL_RO_NL_CGEN(config_prof, opt_prof_thread_active_init, + opt_prof_thread_active_init, bool) +CTL_RO_NL_CGEN(config_prof, opt_lg_prof_sample, opt_lg_prof_sample, size_t) +CTL_RO_NL_CGEN(config_prof, opt_prof_accum, opt_prof_accum, bool) +CTL_RO_NL_CGEN(config_prof, opt_lg_prof_interval, opt_lg_prof_interval, ssize_t) +CTL_RO_NL_CGEN(config_prof, opt_prof_gdump, opt_prof_gdump, bool) +CTL_RO_NL_CGEN(config_prof, opt_prof_final, opt_prof_final, bool) +CTL_RO_NL_CGEN(config_prof, opt_prof_leak, opt_prof_leak, bool) + +/******************************************************************************/ + +static int +thread_arena_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, + void *newp, size_t newlen) +{ + int ret; + tsd_t *tsd; + arena_t *oldarena; + unsigned newind, oldind; + + tsd = tsd_fetch(); + oldarena = arena_choose(tsd, NULL); + if (oldarena == NULL) + return (EAGAIN); + + malloc_mutex_lock(&ctl_mtx); + newind = oldind = oldarena->ind; + WRITE(newind, unsigned); + READ(oldind, unsigned); + if (newind != oldind) { + arena_t *newarena; + + if (newind >= ctl_stats.narenas) { + /* New arena index is out of range. */ + ret = EFAULT; + goto label_return; + } + + /* Initialize arena if necessary. */ + newarena = arena_get(tsd, newind, true, true); + if (newarena == NULL) { + ret = EAGAIN; + goto label_return; + } + /* Set new arena/tcache associations. */ + arena_migrate(tsd, oldind, newind); + if (config_tcache) { + tcache_t *tcache = tsd_tcache_get(tsd); + if (tcache != NULL) { + tcache_arena_reassociate(tcache, oldarena, + newarena); + } + } + } + + ret = 0; +label_return: + malloc_mutex_unlock(&ctl_mtx); + return (ret); +} + +CTL_TSD_RO_NL_CGEN(config_stats, thread_allocated, tsd_thread_allocated_get, + uint64_t) +CTL_TSD_RO_NL_CGEN(config_stats, thread_allocatedp, tsd_thread_allocatedp_get, + uint64_t *) +CTL_TSD_RO_NL_CGEN(config_stats, thread_deallocated, tsd_thread_deallocated_get, + uint64_t) +CTL_TSD_RO_NL_CGEN(config_stats, thread_deallocatedp, + tsd_thread_deallocatedp_get, uint64_t *) + +static int +thread_tcache_enabled_ctl(const size_t *mib, size_t miblen, void *oldp, + size_t *oldlenp, void *newp, size_t newlen) +{ + int ret; + bool oldval; + + if (!config_tcache) + return (ENOENT); + + oldval = tcache_enabled_get(); + if (newp != NULL) { + if (newlen != sizeof(bool)) { + ret = EINVAL; + goto label_return; + } + tcache_enabled_set(*(bool *)newp); + } + READ(oldval, bool); + + ret = 0; +label_return: + return (ret); +} + +static int +thread_tcache_flush_ctl(const size_t *mib, size_t miblen, void *oldp, + size_t *oldlenp, void *newp, size_t newlen) +{ + int ret; + + if (!config_tcache) + return (ENOENT); + + READONLY(); + WRITEONLY(); + + tcache_flush(); + + ret = 0; +label_return: + return (ret); +} + +static int +thread_prof_name_ctl(const size_t *mib, size_t miblen, void *oldp, + size_t *oldlenp, void *newp, size_t newlen) +{ + int ret; + + if (!config_prof) + return (ENOENT); + + READ_XOR_WRITE(); + + if (newp != NULL) { + tsd_t *tsd; + + if (newlen != sizeof(const char *)) { + ret = EINVAL; + goto label_return; + } + + tsd = tsd_fetch(); + + if ((ret = prof_thread_name_set(tsd, *(const char **)newp)) != + 0) + goto label_return; + } else { + const char *oldname = prof_thread_name_get(); + READ(oldname, const char *); + } + + ret = 0; +label_return: + return (ret); +} + +static int +thread_prof_active_ctl(const size_t *mib, size_t miblen, void *oldp, + size_t *oldlenp, void *newp, size_t newlen) +{ + int ret; + bool oldval; + + if (!config_prof) + return (ENOENT); + + oldval = prof_thread_active_get(); + if (newp != NULL) { + if (newlen != sizeof(bool)) { + ret = EINVAL; + goto label_return; + } + if (prof_thread_active_set(*(bool *)newp)) { + ret = EAGAIN; + goto label_return; + } + } + READ(oldval, bool); + + ret = 0; +label_return: + return (ret); +} + +/******************************************************************************/ + +static int +tcache_create_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, + void *newp, size_t newlen) +{ + int ret; + tsd_t *tsd; + unsigned tcache_ind; + + if (!config_tcache) + return (ENOENT); + + tsd = tsd_fetch(); + + malloc_mutex_lock(&ctl_mtx); + READONLY(); + if (tcaches_create(tsd, &tcache_ind)) { + ret = EFAULT; + goto label_return; + } + READ(tcache_ind, unsigned); + + ret = 0; +label_return: + malloc_mutex_unlock(&ctl_mtx); + return (ret); +} + +static int +tcache_flush_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, + void *newp, size_t newlen) +{ + int ret; + tsd_t *tsd; + unsigned tcache_ind; + + if (!config_tcache) + return (ENOENT); + + tsd = tsd_fetch(); + + WRITEONLY(); + tcache_ind = UINT_MAX; + WRITE(tcache_ind, unsigned); + if (tcache_ind == UINT_MAX) { + ret = EFAULT; + goto label_return; + } + tcaches_flush(tsd, tcache_ind); + + ret = 0; +label_return: + return (ret); +} + +static int +tcache_destroy_ctl(const size_t *mib, size_t miblen, void *oldp, + size_t *oldlenp, void *newp, size_t newlen) +{ + int ret; + tsd_t *tsd; + unsigned tcache_ind; + + if (!config_tcache) + return (ENOENT); + + tsd = tsd_fetch(); + + WRITEONLY(); + tcache_ind = UINT_MAX; + WRITE(tcache_ind, unsigned); + if (tcache_ind == UINT_MAX) { + ret = EFAULT; + goto label_return; + } + tcaches_destroy(tsd, tcache_ind); + + ret = 0; +label_return: + return (ret); +} + +/******************************************************************************/ + +/* ctl_mutex must be held during execution of this function. */ +static void +arena_purge(unsigned arena_ind) +{ + tsd_t *tsd; + unsigned i; + bool refreshed; + VARIABLE_ARRAY(arena_t *, tarenas, ctl_stats.narenas); + + tsd = tsd_fetch(); + for (i = 0, refreshed = false; i < ctl_stats.narenas; i++) { + tarenas[i] = arena_get(tsd, i, false, false); + if (tarenas[i] == NULL && !refreshed) { + tarenas[i] = arena_get(tsd, i, false, true); + refreshed = true; + } + } + + if (arena_ind == ctl_stats.narenas) { + unsigned i; + for (i = 0; i < ctl_stats.narenas; i++) { + if (tarenas[i] != NULL) + arena_purge_all(tarenas[i]); + } + } else { + assert(arena_ind < ctl_stats.narenas); + if (tarenas[arena_ind] != NULL) + arena_purge_all(tarenas[arena_ind]); + } +} + +static int +arena_i_purge_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, + void *newp, size_t newlen) +{ + int ret; + + READONLY(); + WRITEONLY(); + malloc_mutex_lock(&ctl_mtx); + arena_purge(mib[1]); + malloc_mutex_unlock(&ctl_mtx); + + ret = 0; +label_return: + return (ret); +} + +static int +arena_i_dss_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, + void *newp, size_t newlen) +{ + int ret; + const char *dss = NULL; + unsigned arena_ind = mib[1]; + dss_prec_t dss_prec_old = dss_prec_limit; + dss_prec_t dss_prec = dss_prec_limit; + + malloc_mutex_lock(&ctl_mtx); + WRITE(dss, const char *); + if (dss != NULL) { + int i; + bool match = false; + + for (i = 0; i < dss_prec_limit; i++) { + if (strcmp(dss_prec_names[i], dss) == 0) { + dss_prec = i; + match = true; + break; + } + } + + if (!match) { + ret = EINVAL; + goto label_return; + } + } + + if (arena_ind < ctl_stats.narenas) { + arena_t *arena = arena_get(tsd_fetch(), arena_ind, false, true); + if (arena == NULL || (dss_prec != dss_prec_limit && + arena_dss_prec_set(arena, dss_prec))) { + ret = EFAULT; + goto label_return; + } + dss_prec_old = arena_dss_prec_get(arena); + } else { + if (dss_prec != dss_prec_limit && + chunk_dss_prec_set(dss_prec)) { + ret = EFAULT; + goto label_return; + } + dss_prec_old = chunk_dss_prec_get(); + } + + dss = dss_prec_names[dss_prec_old]; + READ(dss, const char *); + + ret = 0; +label_return: + malloc_mutex_unlock(&ctl_mtx); + return (ret); +} + +static int +arena_i_lg_dirty_mult_ctl(const size_t *mib, size_t miblen, void *oldp, + size_t *oldlenp, void *newp, size_t newlen) +{ + int ret; + unsigned arena_ind = mib[1]; + arena_t *arena; + + arena = arena_get(tsd_fetch(), arena_ind, false, true); + if (arena == NULL) { + ret = EFAULT; + goto label_return; + } + + if (oldp != NULL && oldlenp != NULL) { + size_t oldval = arena_lg_dirty_mult_get(arena); + READ(oldval, ssize_t); + } + if (newp != NULL) { + if (newlen != sizeof(ssize_t)) { + ret = EINVAL; + goto label_return; + } + if (arena_lg_dirty_mult_set(arena, *(ssize_t *)newp)) { + ret = EFAULT; + goto label_return; + } + } + + ret = 0; +label_return: + return (ret); +} + +static int +arena_i_chunk_hooks_ctl(const size_t *mib, size_t miblen, void *oldp, + size_t *oldlenp, void *newp, size_t newlen) +{ + int ret; + unsigned arena_ind = mib[1]; + arena_t *arena; + + malloc_mutex_lock(&ctl_mtx); + if (arena_ind < narenas_total_get() && (arena = + arena_get(tsd_fetch(), arena_ind, false, true)) != NULL) { + if (newp != NULL) { + chunk_hooks_t old_chunk_hooks, new_chunk_hooks; + WRITE(new_chunk_hooks, chunk_hooks_t); + old_chunk_hooks = chunk_hooks_set(arena, + &new_chunk_hooks); + READ(old_chunk_hooks, chunk_hooks_t); + } else { + chunk_hooks_t old_chunk_hooks = chunk_hooks_get(arena); + READ(old_chunk_hooks, chunk_hooks_t); + } + } else { + ret = EFAULT; + goto label_return; + } + ret = 0; +label_return: + malloc_mutex_unlock(&ctl_mtx); + return (ret); +} + +static const ctl_named_node_t * +arena_i_index(const size_t *mib, size_t miblen, size_t i) +{ + const ctl_named_node_t * ret; + + malloc_mutex_lock(&ctl_mtx); + if (i > ctl_stats.narenas) { + ret = NULL; + goto label_return; + } + + ret = super_arena_i_node; +label_return: + malloc_mutex_unlock(&ctl_mtx); + return (ret); +} + +/******************************************************************************/ + +static int +arenas_narenas_ctl(const size_t *mib, size_t miblen, void *oldp, + size_t *oldlenp, void *newp, size_t newlen) +{ + int ret; + unsigned narenas; + + malloc_mutex_lock(&ctl_mtx); + READONLY(); + if (*oldlenp != sizeof(unsigned)) { + ret = EINVAL; + goto label_return; + } + narenas = ctl_stats.narenas; + READ(narenas, unsigned); + + ret = 0; +label_return: + malloc_mutex_unlock(&ctl_mtx); + return (ret); +} + +static int +arenas_initialized_ctl(const size_t *mib, size_t miblen, void *oldp, + size_t *oldlenp, void *newp, size_t newlen) +{ + int ret; + unsigned nread, i; + + malloc_mutex_lock(&ctl_mtx); + READONLY(); + if (*oldlenp != ctl_stats.narenas * sizeof(bool)) { + ret = EINVAL; + nread = (*oldlenp < ctl_stats.narenas * sizeof(bool)) + ? (*oldlenp / sizeof(bool)) : ctl_stats.narenas; + } else { + ret = 0; + nread = ctl_stats.narenas; + } + + for (i = 0; i < nread; i++) + ((bool *)oldp)[i] = ctl_stats.arenas[i].initialized; + +label_return: + malloc_mutex_unlock(&ctl_mtx); + return (ret); +} + +static int +arenas_lg_dirty_mult_ctl(const size_t *mib, size_t miblen, void *oldp, + size_t *oldlenp, void *newp, size_t newlen) +{ + int ret; + + if (oldp != NULL && oldlenp != NULL) { + size_t oldval = arena_lg_dirty_mult_default_get(); + READ(oldval, ssize_t); + } + if (newp != NULL) { + if (newlen != sizeof(ssize_t)) { + ret = EINVAL; + goto label_return; + } + if (arena_lg_dirty_mult_default_set(*(ssize_t *)newp)) { + ret = EFAULT; + goto label_return; + } + } + + ret = 0; +label_return: + return (ret); +} + +CTL_RO_NL_GEN(arenas_quantum, QUANTUM, size_t) +CTL_RO_NL_GEN(arenas_page, PAGE, size_t) +CTL_RO_NL_CGEN(config_tcache, arenas_tcache_max, tcache_maxclass, size_t) +CTL_RO_NL_GEN(arenas_nbins, NBINS, unsigned) +CTL_RO_NL_CGEN(config_tcache, arenas_nhbins, nhbins, unsigned) +CTL_RO_NL_GEN(arenas_bin_i_size, arena_bin_info[mib[2]].reg_size, size_t) +CTL_RO_NL_GEN(arenas_bin_i_nregs, arena_bin_info[mib[2]].nregs, uint32_t) +CTL_RO_NL_GEN(arenas_bin_i_run_size, arena_bin_info[mib[2]].run_size, size_t) +static const ctl_named_node_t * +arenas_bin_i_index(const size_t *mib, size_t miblen, size_t i) +{ + + if (i > NBINS) + return (NULL); + return (super_arenas_bin_i_node); +} + +CTL_RO_NL_GEN(arenas_nlruns, nlclasses, unsigned) +CTL_RO_NL_GEN(arenas_lrun_i_size, index2size(NBINS+mib[2]), size_t) +static const ctl_named_node_t * +arenas_lrun_i_index(const size_t *mib, size_t miblen, size_t i) +{ + + if (i > nlclasses) + return (NULL); + return (super_arenas_lrun_i_node); +} + +CTL_RO_NL_GEN(arenas_nhchunks, nhclasses, unsigned) +CTL_RO_NL_GEN(arenas_hchunk_i_size, index2size(NBINS+nlclasses+mib[2]), size_t) +static const ctl_named_node_t * +arenas_hchunk_i_index(const size_t *mib, size_t miblen, size_t i) +{ + + if (i > nhclasses) + return (NULL); + return (super_arenas_hchunk_i_node); +} + +static int +arenas_extend_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, + void *newp, size_t newlen) +{ + int ret; + unsigned narenas; + + malloc_mutex_lock(&ctl_mtx); + READONLY(); + if (ctl_grow()) { + ret = EAGAIN; + goto label_return; + } + narenas = ctl_stats.narenas - 1; + READ(narenas, unsigned); + + ret = 0; +label_return: + malloc_mutex_unlock(&ctl_mtx); + return (ret); +} + +/******************************************************************************/ + +static int +prof_thread_active_init_ctl(const size_t *mib, size_t miblen, void *oldp, + size_t *oldlenp, void *newp, size_t newlen) +{ + int ret; + bool oldval; + + if (!config_prof) + return (ENOENT); + + if (newp != NULL) { + if (newlen != sizeof(bool)) { + ret = EINVAL; + goto label_return; + } + oldval = prof_thread_active_init_set(*(bool *)newp); + } else + oldval = prof_thread_active_init_get(); + READ(oldval, bool); + + ret = 0; +label_return: + return (ret); +} + +static int +prof_active_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, + void *newp, size_t newlen) +{ + int ret; + bool oldval; + + if (!config_prof) + return (ENOENT); + + if (newp != NULL) { + if (newlen != sizeof(bool)) { + ret = EINVAL; + goto label_return; + } + oldval = prof_active_set(*(bool *)newp); + } else + oldval = prof_active_get(); + READ(oldval, bool); + + ret = 0; +label_return: + return (ret); +} + +static int +prof_dump_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, + void *newp, size_t newlen) +{ + int ret; + const char *filename = NULL; + + if (!config_prof) + return (ENOENT); + + WRITEONLY(); + WRITE(filename, const char *); + + if (prof_mdump(filename)) { + ret = EFAULT; + goto label_return; + } + + ret = 0; +label_return: + return (ret); +} + +static int +prof_gdump_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, + void *newp, size_t newlen) +{ + int ret; + bool oldval; + + if (!config_prof) + return (ENOENT); + + if (newp != NULL) { + if (newlen != sizeof(bool)) { + ret = EINVAL; + goto label_return; + } + oldval = prof_gdump_set(*(bool *)newp); + } else + oldval = prof_gdump_get(); + READ(oldval, bool); + + ret = 0; +label_return: + return (ret); +} + +static int +prof_reset_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, + void *newp, size_t newlen) +{ + int ret; + size_t lg_sample = lg_prof_sample; + tsd_t *tsd; + + if (!config_prof) + return (ENOENT); + + WRITEONLY(); + WRITE(lg_sample, size_t); + if (lg_sample >= (sizeof(uint64_t) << 3)) + lg_sample = (sizeof(uint64_t) << 3) - 1; + + tsd = tsd_fetch(); + + prof_reset(tsd, lg_sample); + + ret = 0; +label_return: + return (ret); +} + +CTL_RO_NL_CGEN(config_prof, prof_interval, prof_interval, uint64_t) +CTL_RO_NL_CGEN(config_prof, lg_prof_sample, lg_prof_sample, size_t) + +/******************************************************************************/ + +CTL_RO_CGEN(config_stats, stats_cactive, &stats_cactive, size_t *) +CTL_RO_CGEN(config_stats, stats_allocated, ctl_stats.allocated, size_t) +CTL_RO_CGEN(config_stats, stats_active, ctl_stats.active, size_t) +CTL_RO_CGEN(config_stats, stats_metadata, ctl_stats.metadata, size_t) +CTL_RO_CGEN(config_stats, stats_resident, ctl_stats.resident, size_t) +CTL_RO_CGEN(config_stats, stats_mapped, ctl_stats.mapped, size_t) + +CTL_RO_GEN(stats_arenas_i_dss, ctl_stats.arenas[mib[2]].dss, const char *) +CTL_RO_GEN(stats_arenas_i_lg_dirty_mult, ctl_stats.arenas[mib[2]].lg_dirty_mult, + ssize_t) +CTL_RO_GEN(stats_arenas_i_nthreads, ctl_stats.arenas[mib[2]].nthreads, unsigned) +CTL_RO_GEN(stats_arenas_i_pactive, ctl_stats.arenas[mib[2]].pactive, size_t) +CTL_RO_GEN(stats_arenas_i_pdirty, ctl_stats.arenas[mib[2]].pdirty, size_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_mapped, + ctl_stats.arenas[mib[2]].astats.mapped, size_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_npurge, + ctl_stats.arenas[mib[2]].astats.npurge, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_nmadvise, + ctl_stats.arenas[mib[2]].astats.nmadvise, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_purged, + ctl_stats.arenas[mib[2]].astats.purged, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_metadata_mapped, + ctl_stats.arenas[mib[2]].astats.metadata_mapped, size_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_metadata_allocated, + ctl_stats.arenas[mib[2]].astats.metadata_allocated, size_t) + +CTL_RO_CGEN(config_stats, stats_arenas_i_small_allocated, + ctl_stats.arenas[mib[2]].allocated_small, size_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_small_nmalloc, + ctl_stats.arenas[mib[2]].nmalloc_small, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_small_ndalloc, + ctl_stats.arenas[mib[2]].ndalloc_small, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_small_nrequests, + ctl_stats.arenas[mib[2]].nrequests_small, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_large_allocated, + ctl_stats.arenas[mib[2]].astats.allocated_large, size_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_large_nmalloc, + ctl_stats.arenas[mib[2]].astats.nmalloc_large, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_large_ndalloc, + ctl_stats.arenas[mib[2]].astats.ndalloc_large, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_large_nrequests, + ctl_stats.arenas[mib[2]].astats.nrequests_large, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_huge_allocated, + ctl_stats.arenas[mib[2]].astats.allocated_huge, size_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_huge_nmalloc, + ctl_stats.arenas[mib[2]].astats.nmalloc_huge, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_huge_ndalloc, + ctl_stats.arenas[mib[2]].astats.ndalloc_huge, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_huge_nrequests, + ctl_stats.arenas[mib[2]].astats.nmalloc_huge, uint64_t) /* Intentional. */ + +CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nmalloc, + ctl_stats.arenas[mib[2]].bstats[mib[4]].nmalloc, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_ndalloc, + ctl_stats.arenas[mib[2]].bstats[mib[4]].ndalloc, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nrequests, + ctl_stats.arenas[mib[2]].bstats[mib[4]].nrequests, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_curregs, + ctl_stats.arenas[mib[2]].bstats[mib[4]].curregs, size_t) +CTL_RO_CGEN(config_stats && config_tcache, stats_arenas_i_bins_j_nfills, + ctl_stats.arenas[mib[2]].bstats[mib[4]].nfills, uint64_t) +CTL_RO_CGEN(config_stats && config_tcache, stats_arenas_i_bins_j_nflushes, + ctl_stats.arenas[mib[2]].bstats[mib[4]].nflushes, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nruns, + ctl_stats.arenas[mib[2]].bstats[mib[4]].nruns, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_nreruns, + ctl_stats.arenas[mib[2]].bstats[mib[4]].reruns, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_bins_j_curruns, + ctl_stats.arenas[mib[2]].bstats[mib[4]].curruns, size_t) + +static const ctl_named_node_t * +stats_arenas_i_bins_j_index(const size_t *mib, size_t miblen, size_t j) +{ + + if (j > NBINS) + return (NULL); + return (super_stats_arenas_i_bins_j_node); +} + +CTL_RO_CGEN(config_stats, stats_arenas_i_lruns_j_nmalloc, + ctl_stats.arenas[mib[2]].lstats[mib[4]].nmalloc, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_lruns_j_ndalloc, + ctl_stats.arenas[mib[2]].lstats[mib[4]].ndalloc, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_lruns_j_nrequests, + ctl_stats.arenas[mib[2]].lstats[mib[4]].nrequests, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_lruns_j_curruns, + ctl_stats.arenas[mib[2]].lstats[mib[4]].curruns, size_t) + +static const ctl_named_node_t * +stats_arenas_i_lruns_j_index(const size_t *mib, size_t miblen, size_t j) +{ + + if (j > nlclasses) + return (NULL); + return (super_stats_arenas_i_lruns_j_node); +} + +CTL_RO_CGEN(config_stats, stats_arenas_i_hchunks_j_nmalloc, + ctl_stats.arenas[mib[2]].hstats[mib[4]].nmalloc, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_hchunks_j_ndalloc, + ctl_stats.arenas[mib[2]].hstats[mib[4]].ndalloc, uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_hchunks_j_nrequests, + ctl_stats.arenas[mib[2]].hstats[mib[4]].nmalloc, /* Intentional. */ + uint64_t) +CTL_RO_CGEN(config_stats, stats_arenas_i_hchunks_j_curhchunks, + ctl_stats.arenas[mib[2]].hstats[mib[4]].curhchunks, size_t) + +static const ctl_named_node_t * +stats_arenas_i_hchunks_j_index(const size_t *mib, size_t miblen, size_t j) +{ + + if (j > nhclasses) + return (NULL); + return (super_stats_arenas_i_hchunks_j_node); +} + +static const ctl_named_node_t * +stats_arenas_i_index(const size_t *mib, size_t miblen, size_t i) +{ + const ctl_named_node_t * ret; + + malloc_mutex_lock(&ctl_mtx); + if (i > ctl_stats.narenas || !ctl_stats.arenas[i].initialized) { + ret = NULL; + goto label_return; + } + + ret = super_stats_arenas_i_node; +label_return: + malloc_mutex_unlock(&ctl_mtx); + return (ret); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/extent.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/extent.c new file mode 100644 index 0000000..13f9441 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/extent.c @@ -0,0 +1,53 @@ +#define JEMALLOC_EXTENT_C_ +#include "jemalloc/internal/jemalloc_internal.h" + +/******************************************************************************/ + +JEMALLOC_INLINE_C size_t +extent_quantize(size_t size) +{ + + /* + * Round down to the nearest chunk size that can actually be requested + * during normal huge allocation. + */ + return (index2size(size2index(size + 1) - 1)); +} + +JEMALLOC_INLINE_C int +extent_szad_comp(extent_node_t *a, extent_node_t *b) +{ + int ret; + size_t a_qsize = extent_quantize(extent_node_size_get(a)); + size_t b_qsize = extent_quantize(extent_node_size_get(b)); + + /* + * Compare based on quantized size rather than size, in order to sort + * equally useful extents only by address. + */ + ret = (a_qsize > b_qsize) - (a_qsize < b_qsize); + if (ret == 0) { + uintptr_t a_addr = (uintptr_t)extent_node_addr_get(a); + uintptr_t b_addr = (uintptr_t)extent_node_addr_get(b); + + ret = (a_addr > b_addr) - (a_addr < b_addr); + } + + return (ret); +} + +/* Generate red-black tree functions. */ +rb_gen(, extent_tree_szad_, extent_tree_t, extent_node_t, szad_link, + extent_szad_comp) + +JEMALLOC_INLINE_C int +extent_ad_comp(extent_node_t *a, extent_node_t *b) +{ + uintptr_t a_addr = (uintptr_t)extent_node_addr_get(a); + uintptr_t b_addr = (uintptr_t)extent_node_addr_get(b); + + return ((a_addr > b_addr) - (a_addr < b_addr)); +} + +/* Generate red-black tree functions. */ +rb_gen(, extent_tree_ad_, extent_tree_t, extent_node_t, ad_link, extent_ad_comp) diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/hash.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/hash.c new file mode 100644 index 0000000..cfa4da0 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/hash.c @@ -0,0 +1,2 @@ +#define JEMALLOC_HASH_C_ +#include "jemalloc/internal/jemalloc_internal.h" diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/huge.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/huge.c new file mode 100644 index 0000000..1e9a665 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/huge.c @@ -0,0 +1,435 @@ +#define JEMALLOC_HUGE_C_ +#include "jemalloc/internal/jemalloc_internal.h" + +/******************************************************************************/ + +static extent_node_t * +huge_node_get(const void *ptr) +{ + extent_node_t *node; + + node = chunk_lookup(ptr, true); + assert(!extent_node_achunk_get(node)); + + return (node); +} + +static bool +huge_node_set(const void *ptr, extent_node_t *node) +{ + + assert(extent_node_addr_get(node) == ptr); + assert(!extent_node_achunk_get(node)); + return (chunk_register(ptr, node)); +} + +static void +huge_node_unset(const void *ptr, const extent_node_t *node) +{ + + chunk_deregister(ptr, node); +} + +void * +huge_malloc(tsd_t *tsd, arena_t *arena, size_t size, bool zero, + tcache_t *tcache) +{ + size_t usize; + + usize = s2u(size); + if (usize == 0) { + /* size_t overflow. */ + return (NULL); + } + + return (huge_palloc(tsd, arena, usize, chunksize, zero, tcache)); +} + +void * +huge_palloc(tsd_t *tsd, arena_t *arena, size_t size, size_t alignment, + bool zero, tcache_t *tcache) +{ + void *ret; + size_t usize; + extent_node_t *node; + bool is_zeroed; + + /* Allocate one or more contiguous chunks for this request. */ + + usize = sa2u(size, alignment); + if (unlikely(usize == 0)) + return (NULL); + assert(usize >= chunksize); + + /* Allocate an extent node with which to track the chunk. */ + node = ipallocztm(tsd, CACHELINE_CEILING(sizeof(extent_node_t)), + CACHELINE, false, tcache, true, arena); + if (node == NULL) + return (NULL); + + /* + * Copy zero into is_zeroed and pass the copy to chunk_alloc(), so that + * it is possible to make correct junk/zero fill decisions below. + */ + is_zeroed = zero; + arena = arena_choose(tsd, arena); + if (unlikely(arena == NULL) || (ret = arena_chunk_alloc_huge(arena, + size, alignment, &is_zeroed)) == NULL) { + idalloctm(tsd, node, tcache, true); + return (NULL); + } + + extent_node_init(node, arena, ret, size, is_zeroed, true); + + if (huge_node_set(ret, node)) { + arena_chunk_dalloc_huge(arena, ret, size); + idalloctm(tsd, node, tcache, true); + return (NULL); + } + + /* Insert node into huge. */ + malloc_mutex_lock(&arena->huge_mtx); + ql_elm_new(node, ql_link); + ql_tail_insert(&arena->huge, node, ql_link); + malloc_mutex_unlock(&arena->huge_mtx); + + if (zero || (config_fill && unlikely(opt_zero))) { + if (!is_zeroed) + memset(ret, 0, size); + } else if (config_fill && unlikely(opt_junk_alloc)) + memset(ret, 0xa5, size); + + return (ret); +} + +#ifdef JEMALLOC_JET +#undef huge_dalloc_junk +#define huge_dalloc_junk JEMALLOC_N(huge_dalloc_junk_impl) +#endif +static void +huge_dalloc_junk(void *ptr, size_t usize) +{ + + if (config_fill && have_dss && unlikely(opt_junk_free)) { + /* + * Only bother junk filling if the chunk isn't about to be + * unmapped. + */ + if (!config_munmap || (have_dss && chunk_in_dss(ptr))) + memset(ptr, 0x5a, usize); + } +} +#ifdef JEMALLOC_JET +#undef huge_dalloc_junk +#define huge_dalloc_junk JEMALLOC_N(huge_dalloc_junk) +huge_dalloc_junk_t *huge_dalloc_junk = JEMALLOC_N(huge_dalloc_junk_impl); +#endif + +static void +huge_ralloc_no_move_similar(void *ptr, size_t oldsize, size_t usize_min, + size_t usize_max, bool zero) +{ + size_t usize, usize_next; + extent_node_t *node; + arena_t *arena; + chunk_hooks_t chunk_hooks = CHUNK_HOOKS_INITIALIZER; + bool pre_zeroed, post_zeroed; + + /* Increase usize to incorporate extra. */ + for (usize = usize_min; usize < usize_max && (usize_next = s2u(usize+1)) + <= oldsize; usize = usize_next) + ; /* Do nothing. */ + + if (oldsize == usize) + return; + + node = huge_node_get(ptr); + arena = extent_node_arena_get(node); + pre_zeroed = extent_node_zeroed_get(node); + + /* Fill if necessary (shrinking). */ + if (oldsize > usize) { + size_t sdiff = oldsize - usize; + if (config_fill && unlikely(opt_junk_free)) { + memset((void *)((uintptr_t)ptr + usize), 0x5a, sdiff); + post_zeroed = false; + } else { + post_zeroed = !chunk_purge_wrapper(arena, &chunk_hooks, + ptr, CHUNK_CEILING(oldsize), usize, sdiff); + } + } else + post_zeroed = pre_zeroed; + + malloc_mutex_lock(&arena->huge_mtx); + /* Update the size of the huge allocation. */ + assert(extent_node_size_get(node) != usize); + extent_node_size_set(node, usize); + /* Update zeroed. */ + extent_node_zeroed_set(node, post_zeroed); + malloc_mutex_unlock(&arena->huge_mtx); + + arena_chunk_ralloc_huge_similar(arena, ptr, oldsize, usize); + + /* Fill if necessary (growing). */ + if (oldsize < usize) { + if (zero || (config_fill && unlikely(opt_zero))) { + if (!pre_zeroed) { + memset((void *)((uintptr_t)ptr + oldsize), 0, + usize - oldsize); + } + } else if (config_fill && unlikely(opt_junk_alloc)) { + memset((void *)((uintptr_t)ptr + oldsize), 0xa5, usize - + oldsize); + } + } +} + +static bool +huge_ralloc_no_move_shrink(void *ptr, size_t oldsize, size_t usize) +{ + extent_node_t *node; + arena_t *arena; + chunk_hooks_t chunk_hooks; + size_t cdiff; + bool pre_zeroed, post_zeroed; + + node = huge_node_get(ptr); + arena = extent_node_arena_get(node); + pre_zeroed = extent_node_zeroed_get(node); + chunk_hooks = chunk_hooks_get(arena); + + assert(oldsize > usize); + + /* Split excess chunks. */ + cdiff = CHUNK_CEILING(oldsize) - CHUNK_CEILING(usize); + if (cdiff != 0 && chunk_hooks.split(ptr, CHUNK_CEILING(oldsize), + CHUNK_CEILING(usize), cdiff, true, arena->ind)) + return (true); + + if (oldsize > usize) { + size_t sdiff = oldsize - usize; + if (config_fill && unlikely(opt_junk_free)) { + huge_dalloc_junk((void *)((uintptr_t)ptr + usize), + sdiff); + post_zeroed = false; + } else { + post_zeroed = !chunk_purge_wrapper(arena, &chunk_hooks, + CHUNK_ADDR2BASE((uintptr_t)ptr + usize), + CHUNK_CEILING(oldsize), + CHUNK_ADDR2OFFSET((uintptr_t)ptr + usize), sdiff); + } + } else + post_zeroed = pre_zeroed; + + malloc_mutex_lock(&arena->huge_mtx); + /* Update the size of the huge allocation. */ + extent_node_size_set(node, usize); + /* Update zeroed. */ + extent_node_zeroed_set(node, post_zeroed); + malloc_mutex_unlock(&arena->huge_mtx); + + /* Zap the excess chunks. */ + arena_chunk_ralloc_huge_shrink(arena, ptr, oldsize, usize); + + return (false); +} + +static bool +huge_ralloc_no_move_expand(void *ptr, size_t oldsize, size_t usize, bool zero) { + extent_node_t *node; + arena_t *arena; + bool is_zeroed_subchunk, is_zeroed_chunk; + + node = huge_node_get(ptr); + arena = extent_node_arena_get(node); + malloc_mutex_lock(&arena->huge_mtx); + is_zeroed_subchunk = extent_node_zeroed_get(node); + malloc_mutex_unlock(&arena->huge_mtx); + + /* + * Copy zero into is_zeroed_chunk and pass the copy to chunk_alloc(), so + * that it is possible to make correct junk/zero fill decisions below. + */ + is_zeroed_chunk = zero; + + if (arena_chunk_ralloc_huge_expand(arena, ptr, oldsize, usize, + &is_zeroed_chunk)) + return (true); + + malloc_mutex_lock(&arena->huge_mtx); + /* Update the size of the huge allocation. */ + extent_node_size_set(node, usize); + malloc_mutex_unlock(&arena->huge_mtx); + + if (zero || (config_fill && unlikely(opt_zero))) { + if (!is_zeroed_subchunk) { + memset((void *)((uintptr_t)ptr + oldsize), 0, + CHUNK_CEILING(oldsize) - oldsize); + } + if (!is_zeroed_chunk) { + memset((void *)((uintptr_t)ptr + + CHUNK_CEILING(oldsize)), 0, usize - + CHUNK_CEILING(oldsize)); + } + } else if (config_fill && unlikely(opt_junk_alloc)) { + memset((void *)((uintptr_t)ptr + oldsize), 0xa5, usize - + oldsize); + } + + return (false); +} + +bool +huge_ralloc_no_move(void *ptr, size_t oldsize, size_t usize_min, + size_t usize_max, bool zero) +{ + + assert(s2u(oldsize) == oldsize); + + /* Both allocations must be huge to avoid a move. */ + if (oldsize < chunksize || usize_max < chunksize) + return (true); + + if (CHUNK_CEILING(usize_max) > CHUNK_CEILING(oldsize)) { + /* Attempt to expand the allocation in-place. */ + if (!huge_ralloc_no_move_expand(ptr, oldsize, usize_max, zero)) + return (false); + /* Try again, this time with usize_min. */ + if (usize_min < usize_max && CHUNK_CEILING(usize_min) > + CHUNK_CEILING(oldsize) && huge_ralloc_no_move_expand(ptr, + oldsize, usize_min, zero)) + return (false); + } + + /* + * Avoid moving the allocation if the existing chunk size accommodates + * the new size. + */ + if (CHUNK_CEILING(oldsize) >= CHUNK_CEILING(usize_min) + && CHUNK_CEILING(oldsize) <= CHUNK_CEILING(usize_max)) { + huge_ralloc_no_move_similar(ptr, oldsize, usize_min, usize_max, + zero); + return (false); + } + + /* Attempt to shrink the allocation in-place. */ + if (CHUNK_CEILING(oldsize) > CHUNK_CEILING(usize_max)) + return (huge_ralloc_no_move_shrink(ptr, oldsize, usize_max)); + return (true); +} + +static void * +huge_ralloc_move_helper(tsd_t *tsd, arena_t *arena, size_t usize, + size_t alignment, bool zero, tcache_t *tcache) +{ + + if (alignment <= chunksize) + return (huge_malloc(tsd, arena, usize, zero, tcache)); + return (huge_palloc(tsd, arena, usize, alignment, zero, tcache)); +} + +void * +huge_ralloc(tsd_t *tsd, arena_t *arena, void *ptr, size_t oldsize, size_t usize, + size_t alignment, bool zero, tcache_t *tcache) +{ + void *ret; + size_t copysize; + + /* Try to avoid moving the allocation. */ + if (!huge_ralloc_no_move(ptr, oldsize, usize, usize, zero)) + return (ptr); + + /* + * usize and oldsize are different enough that we need to use a + * different size class. In that case, fall back to allocating new + * space and copying. + */ + ret = huge_ralloc_move_helper(tsd, arena, usize, alignment, zero, + tcache); + if (ret == NULL) + return (NULL); + + copysize = (usize < oldsize) ? usize : oldsize; + memcpy(ret, ptr, copysize); + isqalloc(tsd, ptr, oldsize, tcache); + return (ret); +} + +void +huge_dalloc(tsd_t *tsd, void *ptr, tcache_t *tcache) +{ + extent_node_t *node; + arena_t *arena; + + node = huge_node_get(ptr); + arena = extent_node_arena_get(node); + huge_node_unset(ptr, node); + malloc_mutex_lock(&arena->huge_mtx); + ql_remove(&arena->huge, node, ql_link); + malloc_mutex_unlock(&arena->huge_mtx); + + huge_dalloc_junk(extent_node_addr_get(node), + extent_node_size_get(node)); + arena_chunk_dalloc_huge(extent_node_arena_get(node), + extent_node_addr_get(node), extent_node_size_get(node)); + idalloctm(tsd, node, tcache, true); +} + +arena_t * +huge_aalloc(const void *ptr) +{ + + return (extent_node_arena_get(huge_node_get(ptr))); +} + +size_t +huge_salloc(const void *ptr) +{ + size_t size; + extent_node_t *node; + arena_t *arena; + + node = huge_node_get(ptr); + arena = extent_node_arena_get(node); + malloc_mutex_lock(&arena->huge_mtx); + size = extent_node_size_get(node); + malloc_mutex_unlock(&arena->huge_mtx); + + return (size); +} + +prof_tctx_t * +huge_prof_tctx_get(const void *ptr) +{ + prof_tctx_t *tctx; + extent_node_t *node; + arena_t *arena; + + node = huge_node_get(ptr); + arena = extent_node_arena_get(node); + malloc_mutex_lock(&arena->huge_mtx); + tctx = extent_node_prof_tctx_get(node); + malloc_mutex_unlock(&arena->huge_mtx); + + return (tctx); +} + +void +huge_prof_tctx_set(const void *ptr, prof_tctx_t *tctx) +{ + extent_node_t *node; + arena_t *arena; + + node = huge_node_get(ptr); + arena = extent_node_arena_get(node); + malloc_mutex_lock(&arena->huge_mtx); + extent_node_prof_tctx_set(node, tctx); + malloc_mutex_unlock(&arena->huge_mtx); +} + +void +huge_prof_tctx_reset(const void *ptr) +{ + + huge_prof_tctx_set(ptr, (prof_tctx_t *)(uintptr_t)1U); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/jemalloc.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/jemalloc.c new file mode 100644 index 0000000..fe77c24 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/jemalloc.c @@ -0,0 +1,2625 @@ +#define JEMALLOC_C_ +#include "jemalloc/internal/jemalloc_internal.h" + +/******************************************************************************/ +/* Data. */ + +/* Runtime configuration options. */ +const char *je_malloc_conf JEMALLOC_ATTR(weak); +bool opt_abort = +#ifdef JEMALLOC_DEBUG + true +#else + false +#endif + ; +const char *opt_junk = +#if (defined(JEMALLOC_DEBUG) && defined(JEMALLOC_FILL)) + "true" +#else + "false" +#endif + ; +bool opt_junk_alloc = +#if (defined(JEMALLOC_DEBUG) && defined(JEMALLOC_FILL)) + true +#else + false +#endif + ; +bool opt_junk_free = +#if (defined(JEMALLOC_DEBUG) && defined(JEMALLOC_FILL)) + true +#else + false +#endif + ; + +size_t opt_quarantine = ZU(0); +bool opt_redzone = false; +bool opt_utrace = false; +bool opt_xmalloc = false; +bool opt_zero = false; +size_t opt_narenas = 0; + +/* Initialized to true if the process is running inside Valgrind. */ +bool in_valgrind; + +unsigned ncpus; + +/* Protects arenas initialization (arenas, narenas_total). */ +static malloc_mutex_t arenas_lock; +/* + * Arenas that are used to service external requests. Not all elements of the + * arenas array are necessarily used; arenas are created lazily as needed. + * + * arenas[0..narenas_auto) are used for automatic multiplexing of threads and + * arenas. arenas[narenas_auto..narenas_total) are only used if the application + * takes some action to create them and allocate from them. + */ +static arena_t **arenas; +static unsigned narenas_total; +static arena_t *a0; /* arenas[0]; read-only after initialization. */ +static unsigned narenas_auto; /* Read-only after initialization. */ + +typedef enum { + malloc_init_uninitialized = 3, + malloc_init_a0_initialized = 2, + malloc_init_recursible = 1, + malloc_init_initialized = 0 /* Common case --> jnz. */ +} malloc_init_t; +static malloc_init_t malloc_init_state = malloc_init_uninitialized; + +JEMALLOC_ALIGNED(CACHELINE) +const size_t index2size_tab[NSIZES] = { +#define SC(index, lg_grp, lg_delta, ndelta, bin, lg_delta_lookup) \ + ((ZU(1)<= 0x0600 +static malloc_mutex_t init_lock = SRWLOCK_INIT; +#else +static malloc_mutex_t init_lock; +static bool init_lock_initialized = false; + +JEMALLOC_ATTR(constructor) +static void WINAPI +_init_init_lock(void) +{ + + /* If another constructor in the same binary is using mallctl to + * e.g. setup chunk hooks, it may end up running before this one, + * and malloc_init_hard will crash trying to lock the uninitialized + * lock. So we force an initialization of the lock in + * malloc_init_hard as well. We don't try to care about atomicity + * of the accessed to the init_lock_initialized boolean, since it + * really only matters early in the process creation, before any + * separate thread normally starts doing anything. */ + if (!init_lock_initialized) + malloc_mutex_init(&init_lock); + init_lock_initialized = true; +} + +#ifdef _MSC_VER +# pragma section(".CRT$XCU", read) +JEMALLOC_SECTION(".CRT$XCU") JEMALLOC_ATTR(used) +static const void (WINAPI *init_init_lock)(void) = _init_init_lock; +#endif +#endif +#else +static malloc_mutex_t init_lock = MALLOC_MUTEX_INITIALIZER; +#endif + +typedef struct { + void *p; /* Input pointer (as in realloc(p, s)). */ + size_t s; /* Request size. */ + void *r; /* Result pointer. */ +} malloc_utrace_t; + +#ifdef JEMALLOC_UTRACE +# define UTRACE(a, b, c) do { \ + if (unlikely(opt_utrace)) { \ + int utrace_serrno = errno; \ + malloc_utrace_t ut; \ + ut.p = (a); \ + ut.s = (b); \ + ut.r = (c); \ + utrace(&ut, sizeof(ut)); \ + errno = utrace_serrno; \ + } \ +} while (0) +#else +# define UTRACE(a, b, c) +#endif + +/******************************************************************************/ +/* + * Function prototypes for static functions that are referenced prior to + * definition. + */ + +static bool malloc_init_hard_a0(void); +static bool malloc_init_hard(void); + +/******************************************************************************/ +/* + * Begin miscellaneous support functions. + */ + +JEMALLOC_ALWAYS_INLINE_C bool +malloc_initialized(void) +{ + + return (malloc_init_state == malloc_init_initialized); +} + +JEMALLOC_ALWAYS_INLINE_C void +malloc_thread_init(void) +{ + + /* + * TSD initialization can't be safely done as a side effect of + * deallocation, because it is possible for a thread to do nothing but + * deallocate its TLS data via free(), in which case writing to TLS + * would cause write-after-free memory corruption. The quarantine + * facility *only* gets used as a side effect of deallocation, so make + * a best effort attempt at initializing its TSD by hooking all + * allocation events. + */ + if (config_fill && unlikely(opt_quarantine)) + quarantine_alloc_hook(); +} + +JEMALLOC_ALWAYS_INLINE_C bool +malloc_init_a0(void) +{ + + if (unlikely(malloc_init_state == malloc_init_uninitialized)) + return (malloc_init_hard_a0()); + return (false); +} + +JEMALLOC_ALWAYS_INLINE_C bool +malloc_init(void) +{ + + if (unlikely(!malloc_initialized()) && malloc_init_hard()) + return (true); + malloc_thread_init(); + + return (false); +} + +/* + * The a0*() functions are used instead of i[mcd]alloc() in situations that + * cannot tolerate TLS variable access. + */ + +arena_t * +a0get(void) +{ + + assert(a0 != NULL); + return (a0); +} + +static void * +a0ialloc(size_t size, bool zero, bool is_metadata) +{ + + if (unlikely(malloc_init_a0())) + return (NULL); + + return (iallocztm(NULL, size, zero, false, is_metadata, a0get())); +} + +static void +a0idalloc(void *ptr, bool is_metadata) +{ + + idalloctm(NULL, ptr, false, is_metadata); +} + +void * +a0malloc(size_t size) +{ + + return (a0ialloc(size, false, true)); +} + +void +a0dalloc(void *ptr) +{ + + a0idalloc(ptr, true); +} + +/* + * FreeBSD's libc uses the bootstrap_*() functions in bootstrap-senstive + * situations that cannot tolerate TLS variable access (TLS allocation and very + * early internal data structure initialization). + */ + +void * +bootstrap_malloc(size_t size) +{ + + if (unlikely(size == 0)) + size = 1; + + return (a0ialloc(size, false, false)); +} + +void * +bootstrap_calloc(size_t num, size_t size) +{ + size_t num_size; + + num_size = num * size; + if (unlikely(num_size == 0)) { + assert(num == 0 || size == 0); + num_size = 1; + } + + return (a0ialloc(num_size, true, false)); +} + +void +bootstrap_free(void *ptr) +{ + + if (unlikely(ptr == NULL)) + return; + + a0idalloc(ptr, false); +} + +/* Create a new arena and insert it into the arenas array at index ind. */ +static arena_t * +arena_init_locked(unsigned ind) +{ + arena_t *arena; + + /* Expand arenas if necessary. */ + assert(ind <= narenas_total); + if (ind > MALLOCX_ARENA_MAX) + return (NULL); + if (ind == narenas_total) { + unsigned narenas_new = narenas_total + 1; + arena_t **arenas_new = + (arena_t **)a0malloc(CACHELINE_CEILING(narenas_new * + sizeof(arena_t *))); + if (arenas_new == NULL) + return (NULL); + memcpy(arenas_new, arenas, narenas_total * sizeof(arena_t *)); + arenas_new[ind] = NULL; + /* + * Deallocate only if arenas came from a0malloc() (not + * base_alloc()). + */ + if (narenas_total != narenas_auto) + a0dalloc(arenas); + arenas = arenas_new; + narenas_total = narenas_new; + } + + /* + * Another thread may have already initialized arenas[ind] if it's an + * auto arena. + */ + arena = arenas[ind]; + if (arena != NULL) { + assert(ind < narenas_auto); + return (arena); + } + + /* Actually initialize the arena. */ + arena = arenas[ind] = arena_new(ind); + return (arena); +} + +arena_t * +arena_init(unsigned ind) +{ + arena_t *arena; + + malloc_mutex_lock(&arenas_lock); + arena = arena_init_locked(ind); + malloc_mutex_unlock(&arenas_lock); + return (arena); +} + +unsigned +narenas_total_get(void) +{ + unsigned narenas; + + malloc_mutex_lock(&arenas_lock); + narenas = narenas_total; + malloc_mutex_unlock(&arenas_lock); + + return (narenas); +} + +static void +arena_bind_locked(tsd_t *tsd, unsigned ind) +{ + arena_t *arena; + + arena = arenas[ind]; + arena->nthreads++; + + if (tsd_nominal(tsd)) + tsd_arena_set(tsd, arena); +} + +static void +arena_bind(tsd_t *tsd, unsigned ind) +{ + + malloc_mutex_lock(&arenas_lock); + arena_bind_locked(tsd, ind); + malloc_mutex_unlock(&arenas_lock); +} + +void +arena_migrate(tsd_t *tsd, unsigned oldind, unsigned newind) +{ + arena_t *oldarena, *newarena; + + malloc_mutex_lock(&arenas_lock); + oldarena = arenas[oldind]; + newarena = arenas[newind]; + oldarena->nthreads--; + newarena->nthreads++; + malloc_mutex_unlock(&arenas_lock); + tsd_arena_set(tsd, newarena); +} + +unsigned +arena_nbound(unsigned ind) +{ + unsigned nthreads; + + malloc_mutex_lock(&arenas_lock); + nthreads = arenas[ind]->nthreads; + malloc_mutex_unlock(&arenas_lock); + return (nthreads); +} + +static void +arena_unbind(tsd_t *tsd, unsigned ind) +{ + arena_t *arena; + + malloc_mutex_lock(&arenas_lock); + arena = arenas[ind]; + arena->nthreads--; + malloc_mutex_unlock(&arenas_lock); + tsd_arena_set(tsd, NULL); +} + +arena_t * +arena_get_hard(tsd_t *tsd, unsigned ind, bool init_if_missing) +{ + arena_t *arena; + arena_t **arenas_cache = tsd_arenas_cache_get(tsd); + unsigned narenas_cache = tsd_narenas_cache_get(tsd); + unsigned narenas_actual = narenas_total_get(); + + /* Deallocate old cache if it's too small. */ + if (arenas_cache != NULL && narenas_cache < narenas_actual) { + a0dalloc(arenas_cache); + arenas_cache = NULL; + narenas_cache = 0; + tsd_arenas_cache_set(tsd, arenas_cache); + tsd_narenas_cache_set(tsd, narenas_cache); + } + + /* Allocate cache if it's missing. */ + if (arenas_cache == NULL) { + bool *arenas_cache_bypassp = tsd_arenas_cache_bypassp_get(tsd); + assert(ind < narenas_actual || !init_if_missing); + narenas_cache = (ind < narenas_actual) ? narenas_actual : ind+1; + + if (tsd_nominal(tsd) && !*arenas_cache_bypassp) { + *arenas_cache_bypassp = true; + arenas_cache = (arena_t **)a0malloc(sizeof(arena_t *) * + narenas_cache); + *arenas_cache_bypassp = false; + } + if (arenas_cache == NULL) { + /* + * This function must always tell the truth, even if + * it's slow, so don't let OOM, thread cleanup (note + * tsd_nominal check), nor recursive allocation + * avoidance (note arenas_cache_bypass check) get in the + * way. + */ + if (ind >= narenas_actual) + return (NULL); + malloc_mutex_lock(&arenas_lock); + arena = arenas[ind]; + malloc_mutex_unlock(&arenas_lock); + return (arena); + } + assert(tsd_nominal(tsd) && !*arenas_cache_bypassp); + tsd_arenas_cache_set(tsd, arenas_cache); + tsd_narenas_cache_set(tsd, narenas_cache); + } + + /* + * Copy to cache. It's possible that the actual number of arenas has + * increased since narenas_total_get() was called above, but that causes + * no correctness issues unless two threads concurrently execute the + * arenas.extend mallctl, which we trust mallctl synchronization to + * prevent. + */ + malloc_mutex_lock(&arenas_lock); + memcpy(arenas_cache, arenas, sizeof(arena_t *) * narenas_actual); + malloc_mutex_unlock(&arenas_lock); + if (narenas_cache > narenas_actual) { + memset(&arenas_cache[narenas_actual], 0, sizeof(arena_t *) * + (narenas_cache - narenas_actual)); + } + + /* Read the refreshed cache, and init the arena if necessary. */ + arena = arenas_cache[ind]; + if (init_if_missing && arena == NULL) + arena = arenas_cache[ind] = arena_init(ind); + return (arena); +} + +/* Slow path, called only by arena_choose(). */ +arena_t * +arena_choose_hard(tsd_t *tsd) +{ + arena_t *ret; + + if (narenas_auto > 1) { + unsigned i, choose, first_null; + + choose = 0; + first_null = narenas_auto; + malloc_mutex_lock(&arenas_lock); + assert(a0get() != NULL); + for (i = 1; i < narenas_auto; i++) { + if (arenas[i] != NULL) { + /* + * Choose the first arena that has the lowest + * number of threads assigned to it. + */ + if (arenas[i]->nthreads < + arenas[choose]->nthreads) + choose = i; + } else if (first_null == narenas_auto) { + /* + * Record the index of the first uninitialized + * arena, in case all extant arenas are in use. + * + * NB: It is possible for there to be + * discontinuities in terms of initialized + * versus uninitialized arenas, due to the + * "thread.arena" mallctl. + */ + first_null = i; + } + } + + if (arenas[choose]->nthreads == 0 + || first_null == narenas_auto) { + /* + * Use an unloaded arena, or the least loaded arena if + * all arenas are already initialized. + */ + ret = arenas[choose]; + } else { + /* Initialize a new arena. */ + choose = first_null; + ret = arena_init_locked(choose); + if (ret == NULL) { + malloc_mutex_unlock(&arenas_lock); + return (NULL); + } + } + arena_bind_locked(tsd, choose); + malloc_mutex_unlock(&arenas_lock); + } else { + ret = a0get(); + arena_bind(tsd, 0); + } + + return (ret); +} + +void +thread_allocated_cleanup(tsd_t *tsd) +{ + + /* Do nothing. */ +} + +void +thread_deallocated_cleanup(tsd_t *tsd) +{ + + /* Do nothing. */ +} + +void +arena_cleanup(tsd_t *tsd) +{ + arena_t *arena; + + arena = tsd_arena_get(tsd); + if (arena != NULL) + arena_unbind(tsd, arena->ind); +} + +void +arenas_cache_cleanup(tsd_t *tsd) +{ + arena_t **arenas_cache; + + arenas_cache = tsd_arenas_cache_get(tsd); + if (arenas_cache != NULL) { + tsd_arenas_cache_set(tsd, NULL); + a0dalloc(arenas_cache); + } +} + +void +narenas_cache_cleanup(tsd_t *tsd) +{ + + /* Do nothing. */ +} + +void +arenas_cache_bypass_cleanup(tsd_t *tsd) +{ + + /* Do nothing. */ +} + +static void +stats_print_atexit(void) +{ + + if (config_tcache && config_stats) { + unsigned narenas, i; + + /* + * Merge stats from extant threads. This is racy, since + * individual threads do not lock when recording tcache stats + * events. As a consequence, the final stats may be slightly + * out of date by the time they are reported, if other threads + * continue to allocate. + */ + for (i = 0, narenas = narenas_total_get(); i < narenas; i++) { + arena_t *arena = arenas[i]; + if (arena != NULL) { + tcache_t *tcache; + + /* + * tcache_stats_merge() locks bins, so if any + * code is introduced that acquires both arena + * and bin locks in the opposite order, + * deadlocks may result. + */ + malloc_mutex_lock(&arena->lock); + ql_foreach(tcache, &arena->tcache_ql, link) { + tcache_stats_merge(tcache, arena); + } + malloc_mutex_unlock(&arena->lock); + } + } + } + je_malloc_stats_print(NULL, NULL, NULL); +} + +/* + * End miscellaneous support functions. + */ +/******************************************************************************/ +/* + * Begin initialization functions. + */ + +#ifndef JEMALLOC_HAVE_SECURE_GETENV +static char * +secure_getenv(const char *name) +{ + +# ifdef JEMALLOC_HAVE_ISSETUGID + if (issetugid() != 0) + return (NULL); +# endif + return (getenv(name)); +} +#endif + +static unsigned +malloc_ncpus(void) +{ + long result; + +#ifdef _WIN32 + SYSTEM_INFO si; + GetSystemInfo(&si); + result = si.dwNumberOfProcessors; +#else + result = sysconf(_SC_NPROCESSORS_ONLN); +#endif + return ((result == -1) ? 1 : (unsigned)result); +} + +static bool +malloc_conf_next(char const **opts_p, char const **k_p, size_t *klen_p, + char const **v_p, size_t *vlen_p) +{ + bool accept; + const char *opts = *opts_p; + + *k_p = opts; + + for (accept = false; !accept;) { + switch (*opts) { + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': + case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': + case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': + case 'Y': case 'Z': + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': + case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': + case 's': case 't': case 'u': case 'v': case 'w': case 'x': + case 'y': case 'z': + case '0': case '1': case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + case '_': + opts++; + break; + case ':': + opts++; + *klen_p = (uintptr_t)opts - 1 - (uintptr_t)*k_p; + *v_p = opts; + accept = true; + break; + case '\0': + if (opts != *opts_p) { + malloc_write(": Conf string ends " + "with key\n"); + } + return (true); + default: + malloc_write(": Malformed conf string\n"); + return (true); + } + } + + for (accept = false; !accept;) { + switch (*opts) { + case ',': + opts++; + /* + * Look ahead one character here, because the next time + * this function is called, it will assume that end of + * input has been cleanly reached if no input remains, + * but we have optimistically already consumed the + * comma if one exists. + */ + if (*opts == '\0') { + malloc_write(": Conf string ends " + "with comma\n"); + } + *vlen_p = (uintptr_t)opts - 1 - (uintptr_t)*v_p; + accept = true; + break; + case '\0': + *vlen_p = (uintptr_t)opts - (uintptr_t)*v_p; + accept = true; + break; + default: + opts++; + break; + } + } + + *opts_p = opts; + return (false); +} + +static void +malloc_conf_error(const char *msg, const char *k, size_t klen, const char *v, + size_t vlen) +{ + + malloc_printf(": %s: %.*s:%.*s\n", msg, (int)klen, k, + (int)vlen, v); +} + +static void +malloc_conf_init(void) +{ + unsigned i; + char buf[PATH_MAX + 1]; + const char *opts, *k, *v; + size_t klen, vlen; + + /* + * Automatically configure valgrind before processing options. The + * valgrind option remains in jemalloc 3.x for compatibility reasons. + */ + if (config_valgrind) { + in_valgrind = (RUNNING_ON_VALGRIND != 0) ? true : false; + if (config_fill && unlikely(in_valgrind)) { + opt_junk = "false"; + opt_junk_alloc = false; + opt_junk_free = false; + assert(!opt_zero); + opt_quarantine = JEMALLOC_VALGRIND_QUARANTINE_DEFAULT; + opt_redzone = true; + } + if (config_tcache && unlikely(in_valgrind)) + opt_tcache = false; + } + + for (i = 0; i < 3; i++) { + /* Get runtime configuration. */ + switch (i) { + case 0: + if (je_malloc_conf != NULL) { + /* + * Use options that were compiled into the + * program. + */ + opts = je_malloc_conf; + } else { + /* No configuration specified. */ + buf[0] = '\0'; + opts = buf; + } + break; + case 1: { + int linklen = 0; +#ifndef _WIN32 + int saved_errno = errno; + const char *linkname = +# ifdef JEMALLOC_PREFIX + "/etc/"JEMALLOC_PREFIX"malloc.conf" +# else + "/etc/malloc.conf" +# endif + ; + + /* + * Try to use the contents of the "/etc/malloc.conf" + * symbolic link's name. + */ + linklen = readlink(linkname, buf, sizeof(buf) - 1); + if (linklen == -1) { + /* No configuration specified. */ + linklen = 0; + /* Restore errno. */ + set_errno(saved_errno); + } +#endif + buf[linklen] = '\0'; + opts = buf; + break; + } case 2: { + const char *envname = +#ifdef JEMALLOC_PREFIX + JEMALLOC_CPREFIX"MALLOC_CONF" +#else + "MALLOC_CONF" +#endif + ; + + if ((opts = secure_getenv(envname)) != NULL) { + /* + * Do nothing; opts is already initialized to + * the value of the MALLOC_CONF environment + * variable. + */ + } else { + /* No configuration specified. */ + buf[0] = '\0'; + opts = buf; + } + break; + } default: + not_reached(); + buf[0] = '\0'; + opts = buf; + } + + while (*opts != '\0' && !malloc_conf_next(&opts, &k, &klen, &v, + &vlen)) { +#define CONF_MATCH(n) \ + (sizeof(n)-1 == klen && strncmp(n, k, klen) == 0) +#define CONF_MATCH_VALUE(n) \ + (sizeof(n)-1 == vlen && strncmp(n, v, vlen) == 0) +#define CONF_HANDLE_BOOL(o, n, cont) \ + if (CONF_MATCH(n)) { \ + if (CONF_MATCH_VALUE("true")) \ + o = true; \ + else if (CONF_MATCH_VALUE("false")) \ + o = false; \ + else { \ + malloc_conf_error( \ + "Invalid conf value", \ + k, klen, v, vlen); \ + } \ + if (cont) \ + continue; \ + } +#define CONF_HANDLE_SIZE_T(o, n, min, max, clip) \ + if (CONF_MATCH(n)) { \ + uintmax_t um; \ + char *end; \ + \ + set_errno(0); \ + um = malloc_strtoumax(v, &end, 0); \ + if (get_errno() != 0 || (uintptr_t)end -\ + (uintptr_t)v != vlen) { \ + malloc_conf_error( \ + "Invalid conf value", \ + k, klen, v, vlen); \ + } else if (clip) { \ + if ((min) != 0 && um < (min)) \ + o = (min); \ + else if (um > (max)) \ + o = (max); \ + else \ + o = um; \ + } else { \ + if (((min) != 0 && um < (min)) \ + || um > (max)) { \ + malloc_conf_error( \ + "Out-of-range " \ + "conf value", \ + k, klen, v, vlen); \ + } else \ + o = um; \ + } \ + continue; \ + } +#define CONF_HANDLE_SSIZE_T(o, n, min, max) \ + if (CONF_MATCH(n)) { \ + long l; \ + char *end; \ + \ + set_errno(0); \ + l = strtol(v, &end, 0); \ + if (get_errno() != 0 || (uintptr_t)end -\ + (uintptr_t)v != vlen) { \ + malloc_conf_error( \ + "Invalid conf value", \ + k, klen, v, vlen); \ + } else if (l < (ssize_t)(min) || l > \ + (ssize_t)(max)) { \ + malloc_conf_error( \ + "Out-of-range conf value", \ + k, klen, v, vlen); \ + } else \ + o = l; \ + continue; \ + } +#define CONF_HANDLE_CHAR_P(o, n, d) \ + if (CONF_MATCH(n)) { \ + size_t cpylen = (vlen <= \ + sizeof(o)-1) ? vlen : \ + sizeof(o)-1; \ + strncpy(o, v, cpylen); \ + o[cpylen] = '\0'; \ + continue; \ + } + + CONF_HANDLE_BOOL(opt_abort, "abort", true) + /* + * Chunks always require at least one header page, + * as many as 2^(LG_SIZE_CLASS_GROUP+1) data pages, and + * possibly an additional page in the presence of + * redzones. In order to simplify options processing, + * use a conservative bound that accommodates all these + * constraints. + */ + CONF_HANDLE_SIZE_T(opt_lg_chunk, "lg_chunk", LG_PAGE + + LG_SIZE_CLASS_GROUP + (config_fill ? 2 : 1), + (sizeof(size_t) << 3) - 1, true) + if (strncmp("dss", k, klen) == 0) { + int i; + bool match = false; + for (i = 0; i < dss_prec_limit; i++) { + if (strncmp(dss_prec_names[i], v, vlen) + == 0) { + if (chunk_dss_prec_set(i)) { + malloc_conf_error( + "Error setting dss", + k, klen, v, vlen); + } else { + opt_dss = + dss_prec_names[i]; + match = true; + break; + } + } + } + if (!match) { + malloc_conf_error("Invalid conf value", + k, klen, v, vlen); + } + continue; + } + CONF_HANDLE_SIZE_T(opt_narenas, "narenas", 1, + SIZE_T_MAX, false) + CONF_HANDLE_SSIZE_T(opt_lg_dirty_mult, "lg_dirty_mult", + -1, (sizeof(size_t) << 3) - 1) + CONF_HANDLE_BOOL(opt_stats_print, "stats_print", true) + if (config_fill) { + if (CONF_MATCH("junk")) { + if (CONF_MATCH_VALUE("true")) { + opt_junk = "true"; + opt_junk_alloc = opt_junk_free = + true; + } else if (CONF_MATCH_VALUE("false")) { + opt_junk = "false"; + opt_junk_alloc = opt_junk_free = + false; + } else if (CONF_MATCH_VALUE("alloc")) { + opt_junk = "alloc"; + opt_junk_alloc = true; + opt_junk_free = false; + } else if (CONF_MATCH_VALUE("free")) { + opt_junk = "free"; + opt_junk_alloc = false; + opt_junk_free = true; + } else { + malloc_conf_error( + "Invalid conf value", k, + klen, v, vlen); + } + continue; + } + CONF_HANDLE_SIZE_T(opt_quarantine, "quarantine", + 0, SIZE_T_MAX, false) + CONF_HANDLE_BOOL(opt_redzone, "redzone", true) + CONF_HANDLE_BOOL(opt_zero, "zero", true) + } + if (config_utrace) { + CONF_HANDLE_BOOL(opt_utrace, "utrace", true) + } + if (config_xmalloc) { + CONF_HANDLE_BOOL(opt_xmalloc, "xmalloc", true) + } + if (config_tcache) { + CONF_HANDLE_BOOL(opt_tcache, "tcache", + !config_valgrind || !in_valgrind) + if (CONF_MATCH("tcache")) { + assert(config_valgrind && in_valgrind); + if (opt_tcache) { + opt_tcache = false; + malloc_conf_error( + "tcache cannot be enabled " + "while running inside Valgrind", + k, klen, v, vlen); + } + continue; + } + CONF_HANDLE_SSIZE_T(opt_lg_tcache_max, + "lg_tcache_max", -1, + (sizeof(size_t) << 3) - 1) + } + if (config_prof) { + CONF_HANDLE_BOOL(opt_prof, "prof", true) + CONF_HANDLE_CHAR_P(opt_prof_prefix, + "prof_prefix", "jeprof") + CONF_HANDLE_BOOL(opt_prof_active, "prof_active", + true) + CONF_HANDLE_BOOL(opt_prof_thread_active_init, + "prof_thread_active_init", true) + CONF_HANDLE_SIZE_T(opt_lg_prof_sample, + "lg_prof_sample", 0, + (sizeof(uint64_t) << 3) - 1, true) + CONF_HANDLE_BOOL(opt_prof_accum, "prof_accum", + true) + CONF_HANDLE_SSIZE_T(opt_lg_prof_interval, + "lg_prof_interval", -1, + (sizeof(uint64_t) << 3) - 1) + CONF_HANDLE_BOOL(opt_prof_gdump, "prof_gdump", + true) + CONF_HANDLE_BOOL(opt_prof_final, "prof_final", + true) + CONF_HANDLE_BOOL(opt_prof_leak, "prof_leak", + true) + } + malloc_conf_error("Invalid conf pair", k, klen, v, + vlen); +#undef CONF_MATCH +#undef CONF_HANDLE_BOOL +#undef CONF_HANDLE_SIZE_T +#undef CONF_HANDLE_SSIZE_T +#undef CONF_HANDLE_CHAR_P + } + } +} + +/* init_lock must be held. */ +static bool +malloc_init_hard_needed(void) +{ + + if (malloc_initialized() || (IS_INITIALIZER && malloc_init_state == + malloc_init_recursible)) { + /* + * Another thread initialized the allocator before this one + * acquired init_lock, or this thread is the initializing + * thread, and it is recursively allocating. + */ + return (false); + } +#ifdef JEMALLOC_THREADED_INIT + if (malloc_initializer != NO_INITIALIZER && !IS_INITIALIZER) { + /* Busy-wait until the initializing thread completes. */ + do { + malloc_mutex_unlock(&init_lock); + CPU_SPINWAIT; + malloc_mutex_lock(&init_lock); + } while (!malloc_initialized()); + return (false); + } +#endif + return (true); +} + +/* init_lock must be held. */ +static bool +malloc_init_hard_a0_locked(void) +{ + + malloc_initializer = INITIALIZER; + + if (config_prof) + prof_boot0(); + malloc_conf_init(); + if (opt_stats_print) { + /* Print statistics at exit. */ + if (atexit(stats_print_atexit) != 0) { + malloc_write(": Error in atexit()\n"); + if (opt_abort) + abort(); + } + } + if (base_boot()) + return (true); + if (chunk_boot()) + return (true); + if (ctl_boot()) + return (true); + if (config_prof) + prof_boot1(); + if (arena_boot()) + return (true); + if (config_tcache && tcache_boot()) + return (true); + if (malloc_mutex_init(&arenas_lock)) + return (true); + /* + * Create enough scaffolding to allow recursive allocation in + * malloc_ncpus(). + */ + narenas_total = narenas_auto = 1; + arenas = &a0; + memset(arenas, 0, sizeof(arena_t *) * narenas_auto); + /* + * Initialize one arena here. The rest are lazily created in + * arena_choose_hard(). + */ + if (arena_init(0) == NULL) + return (true); + malloc_init_state = malloc_init_a0_initialized; + return (false); +} + +static bool +malloc_init_hard_a0(void) +{ + bool ret; + + malloc_mutex_lock(&init_lock); + ret = malloc_init_hard_a0_locked(); + malloc_mutex_unlock(&init_lock); + return (ret); +} + +/* + * Initialize data structures which may trigger recursive allocation. + * + * init_lock must be held. + */ +static void +malloc_init_hard_recursible(void) +{ + + malloc_init_state = malloc_init_recursible; + malloc_mutex_unlock(&init_lock); + + ncpus = malloc_ncpus(); + +#if (!defined(JEMALLOC_MUTEX_INIT_CB) && !defined(JEMALLOC_ZONE) \ + && !defined(_WIN32) && !defined(__native_client__)) + /* LinuxThreads's pthread_atfork() allocates. */ + if (pthread_atfork(jemalloc_prefork, jemalloc_postfork_parent, + jemalloc_postfork_child) != 0) { + malloc_write(": Error in pthread_atfork()\n"); + if (opt_abort) + abort(); + } +#endif + malloc_mutex_lock(&init_lock); +} + +/* init_lock must be held. */ +static bool +malloc_init_hard_finish(void) +{ + + if (mutex_boot()) + return (true); + + if (opt_narenas == 0) { + /* + * For SMP systems, create more than one arena per CPU by + * default. + */ + if (ncpus > 1) + opt_narenas = ncpus << 2; + else + opt_narenas = 1; + } + narenas_auto = opt_narenas; + /* + * Make sure that the arenas array can be allocated. In practice, this + * limit is enough to allow the allocator to function, but the ctl + * machinery will fail to allocate memory at far lower limits. + */ + if (narenas_auto > chunksize / sizeof(arena_t *)) { + narenas_auto = chunksize / sizeof(arena_t *); + malloc_printf(": Reducing narenas to limit (%d)\n", + narenas_auto); + } + narenas_total = narenas_auto; + + /* Allocate and initialize arenas. */ + arenas = (arena_t **)base_alloc(sizeof(arena_t *) * narenas_total); + if (arenas == NULL) + return (true); + /* + * Zero the array. In practice, this should always be pre-zeroed, + * since it was just mmap()ed, but let's be sure. + */ + memset(arenas, 0, sizeof(arena_t *) * narenas_total); + /* Copy the pointer to the one arena that was already initialized. */ + arenas[0] = a0; + + malloc_init_state = malloc_init_initialized; + return (false); +} + +static bool +malloc_init_hard(void) +{ + +#if defined(_WIN32) && _WIN32_WINNT < 0x0600 + _init_init_lock(); +#endif + malloc_mutex_lock(&init_lock); + if (!malloc_init_hard_needed()) { + malloc_mutex_unlock(&init_lock); + return (false); + } + + if (malloc_init_state != malloc_init_a0_initialized && + malloc_init_hard_a0_locked()) { + malloc_mutex_unlock(&init_lock); + return (true); + } + if (malloc_tsd_boot0()) { + malloc_mutex_unlock(&init_lock); + return (true); + } + if (config_prof && prof_boot2()) { + malloc_mutex_unlock(&init_lock); + return (true); + } + + malloc_init_hard_recursible(); + + if (malloc_init_hard_finish()) { + malloc_mutex_unlock(&init_lock); + return (true); + } + + malloc_mutex_unlock(&init_lock); + malloc_tsd_boot1(); + return (false); +} + +/* + * End initialization functions. + */ +/******************************************************************************/ +/* + * Begin malloc(3)-compatible functions. + */ + +static void * +imalloc_prof_sample(tsd_t *tsd, size_t usize, prof_tctx_t *tctx) +{ + void *p; + + if (tctx == NULL) + return (NULL); + if (usize <= SMALL_MAXCLASS) { + p = imalloc(tsd, LARGE_MINCLASS); + if (p == NULL) + return (NULL); + arena_prof_promoted(p, usize); + } else + p = imalloc(tsd, usize); + + return (p); +} + +JEMALLOC_ALWAYS_INLINE_C void * +imalloc_prof(tsd_t *tsd, size_t usize) +{ + void *p; + prof_tctx_t *tctx; + + tctx = prof_alloc_prep(tsd, usize, prof_active_get_unlocked(), true); + if (unlikely((uintptr_t)tctx != (uintptr_t)1U)) + p = imalloc_prof_sample(tsd, usize, tctx); + else + p = imalloc(tsd, usize); + if (unlikely(p == NULL)) { + prof_alloc_rollback(tsd, tctx, true); + return (NULL); + } + prof_malloc(p, usize, tctx); + + return (p); +} + +JEMALLOC_ALWAYS_INLINE_C void * +imalloc_body(size_t size, tsd_t **tsd, size_t *usize) +{ + + if (unlikely(malloc_init())) + return (NULL); + *tsd = tsd_fetch(); + + if (config_prof && opt_prof) { + *usize = s2u(size); + if (unlikely(*usize == 0)) + return (NULL); + return (imalloc_prof(*tsd, *usize)); + } + + if (config_stats || (config_valgrind && unlikely(in_valgrind))) + *usize = s2u(size); + return (imalloc(*tsd, size)); +} + +JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN +void JEMALLOC_NOTHROW * +JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE(1) +je_malloc(size_t size) +{ + void *ret; + tsd_t *tsd; + size_t usize JEMALLOC_CC_SILENCE_INIT(0); + + if (size == 0) + size = 1; + + ret = imalloc_body(size, &tsd, &usize); + if (unlikely(ret == NULL)) { + if (config_xmalloc && unlikely(opt_xmalloc)) { + malloc_write(": Error in malloc(): " + "out of memory\n"); + abort(); + } + set_errno(ENOMEM); + } + if (config_stats && likely(ret != NULL)) { + assert(usize == isalloc(ret, config_prof)); + *tsd_thread_allocatedp_get(tsd) += usize; + } + UTRACE(0, size, ret); + JEMALLOC_VALGRIND_MALLOC(ret != NULL, ret, usize, false); + return (ret); +} + +static void * +imemalign_prof_sample(tsd_t *tsd, size_t alignment, size_t usize, + prof_tctx_t *tctx) +{ + void *p; + + if (tctx == NULL) + return (NULL); + if (usize <= SMALL_MAXCLASS) { + assert(sa2u(LARGE_MINCLASS, alignment) == LARGE_MINCLASS); + p = ipalloc(tsd, LARGE_MINCLASS, alignment, false); + if (p == NULL) + return (NULL); + arena_prof_promoted(p, usize); + } else + p = ipalloc(tsd, usize, alignment, false); + + return (p); +} + +JEMALLOC_ALWAYS_INLINE_C void * +imemalign_prof(tsd_t *tsd, size_t alignment, size_t usize) +{ + void *p; + prof_tctx_t *tctx; + + tctx = prof_alloc_prep(tsd, usize, prof_active_get_unlocked(), true); + if (unlikely((uintptr_t)tctx != (uintptr_t)1U)) + p = imemalign_prof_sample(tsd, alignment, usize, tctx); + else + p = ipalloc(tsd, usize, alignment, false); + if (unlikely(p == NULL)) { + prof_alloc_rollback(tsd, tctx, true); + return (NULL); + } + prof_malloc(p, usize, tctx); + + return (p); +} + +JEMALLOC_ATTR(nonnull(1)) +static int +imemalign(void **memptr, size_t alignment, size_t size, size_t min_alignment) +{ + int ret; + tsd_t *tsd; + size_t usize; + void *result; + + assert(min_alignment != 0); + + if (unlikely(malloc_init())) { + result = NULL; + goto label_oom; + } + tsd = tsd_fetch(); + if (size == 0) + size = 1; + + /* Make sure that alignment is a large enough power of 2. */ + if (unlikely(((alignment - 1) & alignment) != 0 + || (alignment < min_alignment))) { + if (config_xmalloc && unlikely(opt_xmalloc)) { + malloc_write(": Error allocating " + "aligned memory: invalid alignment\n"); + abort(); + } + result = NULL; + ret = EINVAL; + goto label_return; + } + + usize = sa2u(size, alignment); + if (unlikely(usize == 0)) { + result = NULL; + goto label_oom; + } + + if (config_prof && opt_prof) + result = imemalign_prof(tsd, alignment, usize); + else + result = ipalloc(tsd, usize, alignment, false); + if (unlikely(result == NULL)) + goto label_oom; + assert(((uintptr_t)result & (alignment - 1)) == ZU(0)); + + *memptr = result; + ret = 0; +label_return: + if (config_stats && likely(result != NULL)) { + assert(usize == isalloc(result, config_prof)); + *tsd_thread_allocatedp_get(tsd) += usize; + } + UTRACE(0, size, result); + return (ret); +label_oom: + assert(result == NULL); + if (config_xmalloc && unlikely(opt_xmalloc)) { + malloc_write(": Error allocating aligned memory: " + "out of memory\n"); + abort(); + } + ret = ENOMEM; + goto label_return; +} + +JEMALLOC_EXPORT int JEMALLOC_NOTHROW +JEMALLOC_ATTR(nonnull(1)) +je_posix_memalign(void **memptr, size_t alignment, size_t size) +{ + int ret = imemalign(memptr, alignment, size, sizeof(void *)); + JEMALLOC_VALGRIND_MALLOC(ret == 0, *memptr, isalloc(*memptr, + config_prof), false); + return (ret); +} + +JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN +void JEMALLOC_NOTHROW * +JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE(2) +je_aligned_alloc(size_t alignment, size_t size) +{ + void *ret; + int err; + + if (unlikely((err = imemalign(&ret, alignment, size, 1)) != 0)) { + ret = NULL; + set_errno(err); + } + JEMALLOC_VALGRIND_MALLOC(err == 0, ret, isalloc(ret, config_prof), + false); + return (ret); +} + +static void * +icalloc_prof_sample(tsd_t *tsd, size_t usize, prof_tctx_t *tctx) +{ + void *p; + + if (tctx == NULL) + return (NULL); + if (usize <= SMALL_MAXCLASS) { + p = icalloc(tsd, LARGE_MINCLASS); + if (p == NULL) + return (NULL); + arena_prof_promoted(p, usize); + } else + p = icalloc(tsd, usize); + + return (p); +} + +JEMALLOC_ALWAYS_INLINE_C void * +icalloc_prof(tsd_t *tsd, size_t usize) +{ + void *p; + prof_tctx_t *tctx; + + tctx = prof_alloc_prep(tsd, usize, prof_active_get_unlocked(), true); + if (unlikely((uintptr_t)tctx != (uintptr_t)1U)) + p = icalloc_prof_sample(tsd, usize, tctx); + else + p = icalloc(tsd, usize); + if (unlikely(p == NULL)) { + prof_alloc_rollback(tsd, tctx, true); + return (NULL); + } + prof_malloc(p, usize, tctx); + + return (p); +} + +JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN +void JEMALLOC_NOTHROW * +JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE2(1, 2) +je_calloc(size_t num, size_t size) +{ + void *ret; + tsd_t *tsd; + size_t num_size; + size_t usize JEMALLOC_CC_SILENCE_INIT(0); + + if (unlikely(malloc_init())) { + num_size = 0; + ret = NULL; + goto label_return; + } + tsd = tsd_fetch(); + + num_size = num * size; + if (unlikely(num_size == 0)) { + if (num == 0 || size == 0) + num_size = 1; + else { + ret = NULL; + goto label_return; + } + /* + * Try to avoid division here. We know that it isn't possible to + * overflow during multiplication if neither operand uses any of the + * most significant half of the bits in a size_t. + */ + } else if (unlikely(((num | size) & (SIZE_T_MAX << (sizeof(size_t) << + 2))) && (num_size / size != num))) { + /* size_t overflow. */ + ret = NULL; + goto label_return; + } + + if (config_prof && opt_prof) { + usize = s2u(num_size); + if (unlikely(usize == 0)) { + ret = NULL; + goto label_return; + } + ret = icalloc_prof(tsd, usize); + } else { + if (config_stats || (config_valgrind && unlikely(in_valgrind))) + usize = s2u(num_size); + ret = icalloc(tsd, num_size); + } + +label_return: + if (unlikely(ret == NULL)) { + if (config_xmalloc && unlikely(opt_xmalloc)) { + malloc_write(": Error in calloc(): out of " + "memory\n"); + abort(); + } + set_errno(ENOMEM); + } + if (config_stats && likely(ret != NULL)) { + assert(usize == isalloc(ret, config_prof)); + *tsd_thread_allocatedp_get(tsd) += usize; + } + UTRACE(0, num_size, ret); + JEMALLOC_VALGRIND_MALLOC(ret != NULL, ret, usize, true); + return (ret); +} + +static void * +irealloc_prof_sample(tsd_t *tsd, void *old_ptr, size_t old_usize, size_t usize, + prof_tctx_t *tctx) +{ + void *p; + + if (tctx == NULL) + return (NULL); + if (usize <= SMALL_MAXCLASS) { + p = iralloc(tsd, old_ptr, old_usize, LARGE_MINCLASS, 0, false); + if (p == NULL) + return (NULL); + arena_prof_promoted(p, usize); + } else + p = iralloc(tsd, old_ptr, old_usize, usize, 0, false); + + return (p); +} + +JEMALLOC_ALWAYS_INLINE_C void * +irealloc_prof(tsd_t *tsd, void *old_ptr, size_t old_usize, size_t usize) +{ + void *p; + bool prof_active; + prof_tctx_t *old_tctx, *tctx; + + prof_active = prof_active_get_unlocked(); + old_tctx = prof_tctx_get(old_ptr); + tctx = prof_alloc_prep(tsd, usize, prof_active, true); + if (unlikely((uintptr_t)tctx != (uintptr_t)1U)) + p = irealloc_prof_sample(tsd, old_ptr, old_usize, usize, tctx); + else + p = iralloc(tsd, old_ptr, old_usize, usize, 0, false); + if (unlikely(p == NULL)) { + prof_alloc_rollback(tsd, tctx, true); + return (NULL); + } + prof_realloc(tsd, p, usize, tctx, prof_active, true, old_ptr, old_usize, + old_tctx); + + return (p); +} + +JEMALLOC_INLINE_C void +ifree(tsd_t *tsd, void *ptr, tcache_t *tcache) +{ + size_t usize; + UNUSED size_t rzsize JEMALLOC_CC_SILENCE_INIT(0); + + assert(ptr != NULL); + assert(malloc_initialized() || IS_INITIALIZER); + + if (config_prof && opt_prof) { + usize = isalloc(ptr, config_prof); + prof_free(tsd, ptr, usize); + } else if (config_stats || config_valgrind) + usize = isalloc(ptr, config_prof); + if (config_stats) + *tsd_thread_deallocatedp_get(tsd) += usize; + if (config_valgrind && unlikely(in_valgrind)) + rzsize = p2rz(ptr); + iqalloc(tsd, ptr, tcache); + JEMALLOC_VALGRIND_FREE(ptr, rzsize); +} + +JEMALLOC_INLINE_C void +isfree(tsd_t *tsd, void *ptr, size_t usize, tcache_t *tcache) +{ + UNUSED size_t rzsize JEMALLOC_CC_SILENCE_INIT(0); + + assert(ptr != NULL); + assert(malloc_initialized() || IS_INITIALIZER); + + if (config_prof && opt_prof) + prof_free(tsd, ptr, usize); + if (config_stats) + *tsd_thread_deallocatedp_get(tsd) += usize; + if (config_valgrind && unlikely(in_valgrind)) + rzsize = p2rz(ptr); + isqalloc(tsd, ptr, usize, tcache); + JEMALLOC_VALGRIND_FREE(ptr, rzsize); +} + +JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN +void JEMALLOC_NOTHROW * +JEMALLOC_ALLOC_SIZE(2) +je_realloc(void *ptr, size_t size) +{ + void *ret; + tsd_t *tsd JEMALLOC_CC_SILENCE_INIT(NULL); + size_t usize JEMALLOC_CC_SILENCE_INIT(0); + size_t old_usize = 0; + UNUSED size_t old_rzsize JEMALLOC_CC_SILENCE_INIT(0); + + if (unlikely(size == 0)) { + if (ptr != NULL) { + /* realloc(ptr, 0) is equivalent to free(ptr). */ + UTRACE(ptr, 0, 0); + tsd = tsd_fetch(); + ifree(tsd, ptr, tcache_get(tsd, false)); + return (NULL); + } + size = 1; + } + + if (likely(ptr != NULL)) { + assert(malloc_initialized() || IS_INITIALIZER); + malloc_thread_init(); + tsd = tsd_fetch(); + + old_usize = isalloc(ptr, config_prof); + if (config_valgrind && unlikely(in_valgrind)) + old_rzsize = config_prof ? p2rz(ptr) : u2rz(old_usize); + + if (config_prof && opt_prof) { + usize = s2u(size); + ret = unlikely(usize == 0) ? NULL : irealloc_prof(tsd, + ptr, old_usize, usize); + } else { + if (config_stats || (config_valgrind && + unlikely(in_valgrind))) + usize = s2u(size); + ret = iralloc(tsd, ptr, old_usize, size, 0, false); + } + } else { + /* realloc(NULL, size) is equivalent to malloc(size). */ + ret = imalloc_body(size, &tsd, &usize); + } + + if (unlikely(ret == NULL)) { + if (config_xmalloc && unlikely(opt_xmalloc)) { + malloc_write(": Error in realloc(): " + "out of memory\n"); + abort(); + } + set_errno(ENOMEM); + } + if (config_stats && likely(ret != NULL)) { + assert(usize == isalloc(ret, config_prof)); + *tsd_thread_allocatedp_get(tsd) += usize; + *tsd_thread_deallocatedp_get(tsd) += old_usize; + } + UTRACE(ptr, size, ret); + JEMALLOC_VALGRIND_REALLOC(true, ret, usize, true, ptr, old_usize, + old_rzsize, true, false); + return (ret); +} + +JEMALLOC_EXPORT void JEMALLOC_NOTHROW +je_free(void *ptr) +{ + + UTRACE(ptr, 0, 0); + if (likely(ptr != NULL)) { + tsd_t *tsd = tsd_fetch(); + ifree(tsd, ptr, tcache_get(tsd, false)); + } +} + +/* + * End malloc(3)-compatible functions. + */ +/******************************************************************************/ +/* + * Begin non-standard override functions. + */ + +#ifdef JEMALLOC_OVERRIDE_MEMALIGN +JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN +void JEMALLOC_NOTHROW * +JEMALLOC_ATTR(malloc) +je_memalign(size_t alignment, size_t size) +{ + void *ret JEMALLOC_CC_SILENCE_INIT(NULL); + if (unlikely(imemalign(&ret, alignment, size, 1) != 0)) + ret = NULL; + JEMALLOC_VALGRIND_MALLOC(ret != NULL, ret, size, false); + return (ret); +} +#endif + +#ifdef JEMALLOC_OVERRIDE_VALLOC +JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN +void JEMALLOC_NOTHROW * +JEMALLOC_ATTR(malloc) +je_valloc(size_t size) +{ + void *ret JEMALLOC_CC_SILENCE_INIT(NULL); + if (unlikely(imemalign(&ret, PAGE, size, 1) != 0)) + ret = NULL; + JEMALLOC_VALGRIND_MALLOC(ret != NULL, ret, size, false); + return (ret); +} +#endif + +/* + * is_malloc(je_malloc) is some macro magic to detect if jemalloc_defs.h has + * #define je_malloc malloc + */ +#define malloc_is_malloc 1 +#define is_malloc_(a) malloc_is_ ## a +#define is_malloc(a) is_malloc_(a) + +#if ((is_malloc(je_malloc) == 1) && defined(JEMALLOC_GLIBC_MALLOC_HOOK)) +/* + * glibc provides the RTLD_DEEPBIND flag for dlopen which can make it possible + * to inconsistently reference libc's malloc(3)-compatible functions + * (https://bugzilla.mozilla.org/show_bug.cgi?id=493541). + * + * These definitions interpose hooks in glibc. The functions are actually + * passed an extra argument for the caller return address, which will be + * ignored. + */ +JEMALLOC_EXPORT void (*__free_hook)(void *ptr) = je_free; +JEMALLOC_EXPORT void *(*__malloc_hook)(size_t size) = je_malloc; +JEMALLOC_EXPORT void *(*__realloc_hook)(void *ptr, size_t size) = je_realloc; +# ifdef JEMALLOC_GLIBC_MEMALIGN_HOOK +JEMALLOC_EXPORT void *(*__memalign_hook)(size_t alignment, size_t size) = + je_memalign; +# endif +#endif + +/* + * End non-standard override functions. + */ +/******************************************************************************/ +/* + * Begin non-standard functions. + */ + +JEMALLOC_ALWAYS_INLINE_C bool +imallocx_flags_decode_hard(tsd_t *tsd, size_t size, int flags, size_t *usize, + size_t *alignment, bool *zero, tcache_t **tcache, arena_t **arena) +{ + + if ((flags & MALLOCX_LG_ALIGN_MASK) == 0) { + *alignment = 0; + *usize = s2u(size); + } else { + *alignment = MALLOCX_ALIGN_GET_SPECIFIED(flags); + *usize = sa2u(size, *alignment); + } + assert(*usize != 0); + *zero = MALLOCX_ZERO_GET(flags); + if ((flags & MALLOCX_TCACHE_MASK) != 0) { + if ((flags & MALLOCX_TCACHE_MASK) == MALLOCX_TCACHE_NONE) + *tcache = NULL; + else + *tcache = tcaches_get(tsd, MALLOCX_TCACHE_GET(flags)); + } else + *tcache = tcache_get(tsd, true); + if ((flags & MALLOCX_ARENA_MASK) != 0) { + unsigned arena_ind = MALLOCX_ARENA_GET(flags); + *arena = arena_get(tsd, arena_ind, true, true); + if (unlikely(*arena == NULL)) + return (true); + } else + *arena = NULL; + return (false); +} + +JEMALLOC_ALWAYS_INLINE_C bool +imallocx_flags_decode(tsd_t *tsd, size_t size, int flags, size_t *usize, + size_t *alignment, bool *zero, tcache_t **tcache, arena_t **arena) +{ + + if (likely(flags == 0)) { + *usize = s2u(size); + assert(*usize != 0); + *alignment = 0; + *zero = false; + *tcache = tcache_get(tsd, true); + *arena = NULL; + return (false); + } else { + return (imallocx_flags_decode_hard(tsd, size, flags, usize, + alignment, zero, tcache, arena)); + } +} + +JEMALLOC_ALWAYS_INLINE_C void * +imallocx_flags(tsd_t *tsd, size_t usize, size_t alignment, bool zero, + tcache_t *tcache, arena_t *arena) +{ + + if (unlikely(alignment != 0)) + return (ipalloct(tsd, usize, alignment, zero, tcache, arena)); + if (unlikely(zero)) + return (icalloct(tsd, usize, tcache, arena)); + return (imalloct(tsd, usize, tcache, arena)); +} + +static void * +imallocx_prof_sample(tsd_t *tsd, size_t usize, size_t alignment, bool zero, + tcache_t *tcache, arena_t *arena) +{ + void *p; + + if (usize <= SMALL_MAXCLASS) { + assert(((alignment == 0) ? s2u(LARGE_MINCLASS) : + sa2u(LARGE_MINCLASS, alignment)) == LARGE_MINCLASS); + p = imallocx_flags(tsd, LARGE_MINCLASS, alignment, zero, tcache, + arena); + if (p == NULL) + return (NULL); + arena_prof_promoted(p, usize); + } else + p = imallocx_flags(tsd, usize, alignment, zero, tcache, arena); + + return (p); +} + +JEMALLOC_ALWAYS_INLINE_C void * +imallocx_prof(tsd_t *tsd, size_t size, int flags, size_t *usize) +{ + void *p; + size_t alignment; + bool zero; + tcache_t *tcache; + arena_t *arena; + prof_tctx_t *tctx; + + if (unlikely(imallocx_flags_decode(tsd, size, flags, usize, &alignment, + &zero, &tcache, &arena))) + return (NULL); + tctx = prof_alloc_prep(tsd, *usize, prof_active_get_unlocked(), true); + if (likely((uintptr_t)tctx == (uintptr_t)1U)) + p = imallocx_flags(tsd, *usize, alignment, zero, tcache, arena); + else if ((uintptr_t)tctx > (uintptr_t)1U) { + p = imallocx_prof_sample(tsd, *usize, alignment, zero, tcache, + arena); + } else + p = NULL; + if (unlikely(p == NULL)) { + prof_alloc_rollback(tsd, tctx, true); + return (NULL); + } + prof_malloc(p, *usize, tctx); + + assert(alignment == 0 || ((uintptr_t)p & (alignment - 1)) == ZU(0)); + return (p); +} + +JEMALLOC_ALWAYS_INLINE_C void * +imallocx_no_prof(tsd_t *tsd, size_t size, int flags, size_t *usize) +{ + void *p; + size_t alignment; + bool zero; + tcache_t *tcache; + arena_t *arena; + + if (likely(flags == 0)) { + if (config_stats || (config_valgrind && unlikely(in_valgrind))) + *usize = s2u(size); + return (imalloc(tsd, size)); + } + + if (unlikely(imallocx_flags_decode_hard(tsd, size, flags, usize, + &alignment, &zero, &tcache, &arena))) + return (NULL); + p = imallocx_flags(tsd, *usize, alignment, zero, tcache, arena); + assert(alignment == 0 || ((uintptr_t)p & (alignment - 1)) == ZU(0)); + return (p); +} + +JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN +void JEMALLOC_NOTHROW * +JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE(1) +je_mallocx(size_t size, int flags) +{ + tsd_t *tsd; + void *p; + size_t usize; + + assert(size != 0); + + if (unlikely(malloc_init())) + goto label_oom; + tsd = tsd_fetch(); + + if (config_prof && opt_prof) + p = imallocx_prof(tsd, size, flags, &usize); + else + p = imallocx_no_prof(tsd, size, flags, &usize); + if (unlikely(p == NULL)) + goto label_oom; + + if (config_stats) { + assert(usize == isalloc(p, config_prof)); + *tsd_thread_allocatedp_get(tsd) += usize; + } + UTRACE(0, size, p); + JEMALLOC_VALGRIND_MALLOC(true, p, usize, MALLOCX_ZERO_GET(flags)); + return (p); +label_oom: + if (config_xmalloc && unlikely(opt_xmalloc)) { + malloc_write(": Error in mallocx(): out of memory\n"); + abort(); + } + UTRACE(0, size, 0); + return (NULL); +} + +static void * +irallocx_prof_sample(tsd_t *tsd, void *old_ptr, size_t old_usize, + size_t usize, size_t alignment, bool zero, tcache_t *tcache, arena_t *arena, + prof_tctx_t *tctx) +{ + void *p; + + if (tctx == NULL) + return (NULL); + if (usize <= SMALL_MAXCLASS) { + p = iralloct(tsd, old_ptr, old_usize, LARGE_MINCLASS, alignment, + zero, tcache, arena); + if (p == NULL) + return (NULL); + arena_prof_promoted(p, usize); + } else { + p = iralloct(tsd, old_ptr, old_usize, usize, alignment, zero, + tcache, arena); + } + + return (p); +} + +JEMALLOC_ALWAYS_INLINE_C void * +irallocx_prof(tsd_t *tsd, void *old_ptr, size_t old_usize, size_t size, + size_t alignment, size_t *usize, bool zero, tcache_t *tcache, + arena_t *arena) +{ + void *p; + bool prof_active; + prof_tctx_t *old_tctx, *tctx; + + prof_active = prof_active_get_unlocked(); + old_tctx = prof_tctx_get(old_ptr); + tctx = prof_alloc_prep(tsd, *usize, prof_active, true); + if (unlikely((uintptr_t)tctx != (uintptr_t)1U)) { + p = irallocx_prof_sample(tsd, old_ptr, old_usize, *usize, + alignment, zero, tcache, arena, tctx); + } else { + p = iralloct(tsd, old_ptr, old_usize, size, alignment, zero, + tcache, arena); + } + if (unlikely(p == NULL)) { + prof_alloc_rollback(tsd, tctx, true); + return (NULL); + } + + if (p == old_ptr && alignment != 0) { + /* + * The allocation did not move, so it is possible that the size + * class is smaller than would guarantee the requested + * alignment, and that the alignment constraint was + * serendipitously satisfied. Additionally, old_usize may not + * be the same as the current usize because of in-place large + * reallocation. Therefore, query the actual value of usize. + */ + *usize = isalloc(p, config_prof); + } + prof_realloc(tsd, p, *usize, tctx, prof_active, true, old_ptr, + old_usize, old_tctx); + + return (p); +} + +JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN +void JEMALLOC_NOTHROW * +JEMALLOC_ALLOC_SIZE(2) +je_rallocx(void *ptr, size_t size, int flags) +{ + void *p; + tsd_t *tsd; + size_t usize; + size_t old_usize; + UNUSED size_t old_rzsize JEMALLOC_CC_SILENCE_INIT(0); + size_t alignment = MALLOCX_ALIGN_GET(flags); + bool zero = flags & MALLOCX_ZERO; + arena_t *arena; + tcache_t *tcache; + + assert(ptr != NULL); + assert(size != 0); + assert(malloc_initialized() || IS_INITIALIZER); + malloc_thread_init(); + tsd = tsd_fetch(); + + if (unlikely((flags & MALLOCX_ARENA_MASK) != 0)) { + unsigned arena_ind = MALLOCX_ARENA_GET(flags); + arena = arena_get(tsd, arena_ind, true, true); + if (unlikely(arena == NULL)) + goto label_oom; + } else + arena = NULL; + + if (unlikely((flags & MALLOCX_TCACHE_MASK) != 0)) { + if ((flags & MALLOCX_TCACHE_MASK) == MALLOCX_TCACHE_NONE) + tcache = NULL; + else + tcache = tcaches_get(tsd, MALLOCX_TCACHE_GET(flags)); + } else + tcache = tcache_get(tsd, true); + + old_usize = isalloc(ptr, config_prof); + if (config_valgrind && unlikely(in_valgrind)) + old_rzsize = u2rz(old_usize); + + if (config_prof && opt_prof) { + usize = (alignment == 0) ? s2u(size) : sa2u(size, alignment); + assert(usize != 0); + p = irallocx_prof(tsd, ptr, old_usize, size, alignment, &usize, + zero, tcache, arena); + if (unlikely(p == NULL)) + goto label_oom; + } else { + p = iralloct(tsd, ptr, old_usize, size, alignment, zero, + tcache, arena); + if (unlikely(p == NULL)) + goto label_oom; + if (config_stats || (config_valgrind && unlikely(in_valgrind))) + usize = isalloc(p, config_prof); + } + assert(alignment == 0 || ((uintptr_t)p & (alignment - 1)) == ZU(0)); + + if (config_stats) { + *tsd_thread_allocatedp_get(tsd) += usize; + *tsd_thread_deallocatedp_get(tsd) += old_usize; + } + UTRACE(ptr, size, p); + JEMALLOC_VALGRIND_REALLOC(true, p, usize, false, ptr, old_usize, + old_rzsize, false, zero); + return (p); +label_oom: + if (config_xmalloc && unlikely(opt_xmalloc)) { + malloc_write(": Error in rallocx(): out of memory\n"); + abort(); + } + UTRACE(ptr, size, 0); + return (NULL); +} + +JEMALLOC_ALWAYS_INLINE_C size_t +ixallocx_helper(void *ptr, size_t old_usize, size_t size, size_t extra, + size_t alignment, bool zero) +{ + size_t usize; + + if (ixalloc(ptr, old_usize, size, extra, alignment, zero)) + return (old_usize); + usize = isalloc(ptr, config_prof); + + return (usize); +} + +static size_t +ixallocx_prof_sample(void *ptr, size_t old_usize, size_t size, size_t extra, + size_t alignment, bool zero, prof_tctx_t *tctx) +{ + size_t usize; + + if (tctx == NULL) + return (old_usize); + usize = ixallocx_helper(ptr, old_usize, size, extra, alignment, zero); + + return (usize); +} + +JEMALLOC_ALWAYS_INLINE_C size_t +ixallocx_prof(tsd_t *tsd, void *ptr, size_t old_usize, size_t size, + size_t extra, size_t alignment, bool zero) +{ + size_t usize_max, usize; + bool prof_active; + prof_tctx_t *old_tctx, *tctx; + + prof_active = prof_active_get_unlocked(); + old_tctx = prof_tctx_get(ptr); + /* + * usize isn't knowable before ixalloc() returns when extra is non-zero. + * Therefore, compute its maximum possible value and use that in + * prof_alloc_prep() to decide whether to capture a backtrace. + * prof_realloc() will use the actual usize to decide whether to sample. + */ + usize_max = (alignment == 0) ? s2u(size+extra) : sa2u(size+extra, + alignment); + assert(usize_max != 0); + tctx = prof_alloc_prep(tsd, usize_max, prof_active, false); + if (unlikely((uintptr_t)tctx != (uintptr_t)1U)) { + usize = ixallocx_prof_sample(ptr, old_usize, size, extra, + alignment, zero, tctx); + } else { + usize = ixallocx_helper(ptr, old_usize, size, extra, alignment, + zero); + } + if (usize == old_usize) { + prof_alloc_rollback(tsd, tctx, false); + return (usize); + } + prof_realloc(tsd, ptr, usize, tctx, prof_active, false, ptr, old_usize, + old_tctx); + + return (usize); +} + +JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW +je_xallocx(void *ptr, size_t size, size_t extra, int flags) +{ + tsd_t *tsd; + size_t usize, old_usize; + UNUSED size_t old_rzsize JEMALLOC_CC_SILENCE_INIT(0); + size_t alignment = MALLOCX_ALIGN_GET(flags); + bool zero = flags & MALLOCX_ZERO; + + assert(ptr != NULL); + assert(size != 0); + assert(SIZE_T_MAX - size >= extra); + assert(malloc_initialized() || IS_INITIALIZER); + malloc_thread_init(); + tsd = tsd_fetch(); + + old_usize = isalloc(ptr, config_prof); + + /* Clamp extra if necessary to avoid (size + extra) overflow. */ + if (unlikely(size + extra > HUGE_MAXCLASS)) { + /* Check for size overflow. */ + if (unlikely(size > HUGE_MAXCLASS)) { + usize = old_usize; + goto label_not_resized; + } + extra = HUGE_MAXCLASS - size; + } + + if (config_valgrind && unlikely(in_valgrind)) + old_rzsize = u2rz(old_usize); + + if (config_prof && opt_prof) { + usize = ixallocx_prof(tsd, ptr, old_usize, size, extra, + alignment, zero); + } else { + usize = ixallocx_helper(ptr, old_usize, size, extra, alignment, + zero); + } + if (unlikely(usize == old_usize)) + goto label_not_resized; + + if (config_stats) { + *tsd_thread_allocatedp_get(tsd) += usize; + *tsd_thread_deallocatedp_get(tsd) += old_usize; + } + JEMALLOC_VALGRIND_REALLOC(false, ptr, usize, false, ptr, old_usize, + old_rzsize, false, zero); +label_not_resized: + UTRACE(ptr, size, ptr); + return (usize); +} + +JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW +JEMALLOC_ATTR(pure) +je_sallocx(const void *ptr, int flags) +{ + size_t usize; + + assert(malloc_initialized() || IS_INITIALIZER); + malloc_thread_init(); + + if (config_ivsalloc) + usize = ivsalloc(ptr, config_prof); + else + usize = isalloc(ptr, config_prof); + + return (usize); +} + +JEMALLOC_EXPORT void JEMALLOC_NOTHROW +je_dallocx(void *ptr, int flags) +{ + tsd_t *tsd; + tcache_t *tcache; + + assert(ptr != NULL); + assert(malloc_initialized() || IS_INITIALIZER); + + tsd = tsd_fetch(); + if (unlikely((flags & MALLOCX_TCACHE_MASK) != 0)) { + if ((flags & MALLOCX_TCACHE_MASK) == MALLOCX_TCACHE_NONE) + tcache = NULL; + else + tcache = tcaches_get(tsd, MALLOCX_TCACHE_GET(flags)); + } else + tcache = tcache_get(tsd, false); + + UTRACE(ptr, 0, 0); + ifree(tsd_fetch(), ptr, tcache); +} + +JEMALLOC_ALWAYS_INLINE_C size_t +inallocx(size_t size, int flags) +{ + size_t usize; + + if (likely((flags & MALLOCX_LG_ALIGN_MASK) == 0)) + usize = s2u(size); + else + usize = sa2u(size, MALLOCX_ALIGN_GET_SPECIFIED(flags)); + assert(usize != 0); + return (usize); +} + +JEMALLOC_EXPORT void JEMALLOC_NOTHROW +je_sdallocx(void *ptr, size_t size, int flags) +{ + tsd_t *tsd; + tcache_t *tcache; + size_t usize; + + assert(ptr != NULL); + assert(malloc_initialized() || IS_INITIALIZER); + usize = inallocx(size, flags); + assert(usize == isalloc(ptr, config_prof)); + + tsd = tsd_fetch(); + if (unlikely((flags & MALLOCX_TCACHE_MASK) != 0)) { + if ((flags & MALLOCX_TCACHE_MASK) == MALLOCX_TCACHE_NONE) + tcache = NULL; + else + tcache = tcaches_get(tsd, MALLOCX_TCACHE_GET(flags)); + } else + tcache = tcache_get(tsd, false); + + UTRACE(ptr, 0, 0); + isfree(tsd, ptr, usize, tcache); +} + +JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW +JEMALLOC_ATTR(pure) +je_nallocx(size_t size, int flags) +{ + + assert(size != 0); + + if (unlikely(malloc_init())) + return (0); + + return (inallocx(size, flags)); +} + +JEMALLOC_EXPORT int JEMALLOC_NOTHROW +je_mallctl(const char *name, void *oldp, size_t *oldlenp, void *newp, + size_t newlen) +{ + + if (unlikely(malloc_init())) + return (EAGAIN); + + return (ctl_byname(name, oldp, oldlenp, newp, newlen)); +} + +JEMALLOC_EXPORT int JEMALLOC_NOTHROW +je_mallctlnametomib(const char *name, size_t *mibp, size_t *miblenp) +{ + + if (unlikely(malloc_init())) + return (EAGAIN); + + return (ctl_nametomib(name, mibp, miblenp)); +} + +JEMALLOC_EXPORT int JEMALLOC_NOTHROW +je_mallctlbymib(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, + void *newp, size_t newlen) +{ + + if (unlikely(malloc_init())) + return (EAGAIN); + + return (ctl_bymib(mib, miblen, oldp, oldlenp, newp, newlen)); +} + +JEMALLOC_EXPORT void JEMALLOC_NOTHROW +je_malloc_stats_print(void (*write_cb)(void *, const char *), void *cbopaque, + const char *opts) +{ + + stats_print(write_cb, cbopaque, opts); +} + +JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW +je_malloc_usable_size(JEMALLOC_USABLE_SIZE_CONST void *ptr) +{ + size_t ret; + + assert(malloc_initialized() || IS_INITIALIZER); + malloc_thread_init(); + + if (config_ivsalloc) + ret = ivsalloc(ptr, config_prof); + else + ret = (ptr == NULL) ? 0 : isalloc(ptr, config_prof); + + return (ret); +} + +/* + * End non-standard functions. + */ +/******************************************************************************/ +/* + * The following functions are used by threading libraries for protection of + * malloc during fork(). + */ + +/* + * If an application creates a thread before doing any allocation in the main + * thread, then calls fork(2) in the main thread followed by memory allocation + * in the child process, a race can occur that results in deadlock within the + * child: the main thread may have forked while the created thread had + * partially initialized the allocator. Ordinarily jemalloc prevents + * fork/malloc races via the following functions it registers during + * initialization using pthread_atfork(), but of course that does no good if + * the allocator isn't fully initialized at fork time. The following library + * constructor is a partial solution to this problem. It may still be possible + * to trigger the deadlock described above, but doing so would involve forking + * via a library constructor that runs before jemalloc's runs. + */ +JEMALLOC_ATTR(constructor) +static void +jemalloc_constructor(void) +{ + + malloc_init(); +} + +#ifndef JEMALLOC_MUTEX_INIT_CB +void +jemalloc_prefork(void) +#else +JEMALLOC_EXPORT void +_malloc_prefork(void) +#endif +{ + unsigned i; + +#ifdef JEMALLOC_MUTEX_INIT_CB + if (!malloc_initialized()) + return; +#endif + assert(malloc_initialized()); + + /* Acquire all mutexes in a safe order. */ + ctl_prefork(); + prof_prefork(); + malloc_mutex_prefork(&arenas_lock); + for (i = 0; i < narenas_total; i++) { + if (arenas[i] != NULL) + arena_prefork(arenas[i]); + } + chunk_prefork(); + base_prefork(); +} + +#ifndef JEMALLOC_MUTEX_INIT_CB +void +jemalloc_postfork_parent(void) +#else +JEMALLOC_EXPORT void +_malloc_postfork(void) +#endif +{ + unsigned i; + +#ifdef JEMALLOC_MUTEX_INIT_CB + if (!malloc_initialized()) + return; +#endif + assert(malloc_initialized()); + + /* Release all mutexes, now that fork() has completed. */ + base_postfork_parent(); + chunk_postfork_parent(); + for (i = 0; i < narenas_total; i++) { + if (arenas[i] != NULL) + arena_postfork_parent(arenas[i]); + } + malloc_mutex_postfork_parent(&arenas_lock); + prof_postfork_parent(); + ctl_postfork_parent(); +} + +void +jemalloc_postfork_child(void) +{ + unsigned i; + + assert(malloc_initialized()); + + /* Release all mutexes, now that fork() has completed. */ + base_postfork_child(); + chunk_postfork_child(); + for (i = 0; i < narenas_total; i++) { + if (arenas[i] != NULL) + arena_postfork_child(arenas[i]); + } + malloc_mutex_postfork_child(&arenas_lock); + prof_postfork_child(); + ctl_postfork_child(); +} + +/******************************************************************************/ + +/* Helps the application decide if a pointer is worth re-allocating in order to reduce fragmentation. + * returns 0 if the allocation is in the currently active run, + * or when it is not causing any frag issue (large or huge bin) + * returns the bin utilization and run utilization both in fixed point 16:16. + * If the application decides to re-allocate it should use MALLOCX_TCACHE_NONE when doing so. */ +JEMALLOC_EXPORT int JEMALLOC_NOTHROW +je_get_defrag_hint(void* ptr, int *bin_util, int *run_util) { + int defrag = 0; + arena_chunk_t *chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr); + if (likely(chunk != ptr)) { /* indication that this is not a HUGE alloc */ + size_t pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> LG_PAGE; + size_t mapbits = arena_mapbits_get(chunk, pageind); + if (likely((mapbits & CHUNK_MAP_LARGE) == 0)) { /* indication that this is not a LARGE alloc */ + arena_t *arena = extent_node_arena_get(&chunk->node); + size_t rpages_ind = pageind - arena_mapbits_small_runind_get(chunk, pageind); + arena_run_t *run = &arena_miscelm_get(chunk, rpages_ind)->run; + arena_bin_t *bin = &arena->bins[run->binind]; + malloc_mutex_lock(&bin->lock); + /* runs that are in the same chunk in as the current chunk, are likely to be the next currun */ + if (chunk != (arena_chunk_t *)CHUNK_ADDR2BASE(bin->runcur)) { + arena_bin_info_t *bin_info = &arena_bin_info[run->binind]; + size_t availregs = bin_info->nregs * bin->stats.curruns; + *bin_util = (bin->stats.curregs<<16) / availregs; + *run_util = ((bin_info->nregs - run->nfree)<<16) / bin_info->nregs; + defrag = 1; + } + malloc_mutex_unlock(&bin->lock); + } + } + return defrag; +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/mb.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/mb.c new file mode 100644 index 0000000..dc2c0a2 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/mb.c @@ -0,0 +1,2 @@ +#define JEMALLOC_MB_C_ +#include "jemalloc/internal/jemalloc_internal.h" diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/mutex.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/mutex.c new file mode 100644 index 0000000..2d47af9 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/mutex.c @@ -0,0 +1,153 @@ +#define JEMALLOC_MUTEX_C_ +#include "jemalloc/internal/jemalloc_internal.h" + +#if defined(JEMALLOC_LAZY_LOCK) && !defined(_WIN32) +#include +#endif + +#ifndef _CRT_SPINCOUNT +#define _CRT_SPINCOUNT 4000 +#endif + +/******************************************************************************/ +/* Data. */ + +#ifdef JEMALLOC_LAZY_LOCK +bool isthreaded = false; +#endif +#ifdef JEMALLOC_MUTEX_INIT_CB +static bool postpone_init = true; +static malloc_mutex_t *postponed_mutexes = NULL; +#endif + +#if defined(JEMALLOC_LAZY_LOCK) && !defined(_WIN32) +static void pthread_create_once(void); +#endif + +/******************************************************************************/ +/* + * We intercept pthread_create() calls in order to toggle isthreaded if the + * process goes multi-threaded. + */ + +#if defined(JEMALLOC_LAZY_LOCK) && !defined(_WIN32) +static int (*pthread_create_fptr)(pthread_t *__restrict, const pthread_attr_t *, + void *(*)(void *), void *__restrict); + +static void +pthread_create_once(void) +{ + + pthread_create_fptr = dlsym(RTLD_NEXT, "pthread_create"); + if (pthread_create_fptr == NULL) { + malloc_write(": Error in dlsym(RTLD_NEXT, " + "\"pthread_create\")\n"); + abort(); + } + + isthreaded = true; +} + +JEMALLOC_EXPORT int +pthread_create(pthread_t *__restrict thread, + const pthread_attr_t *__restrict attr, void *(*start_routine)(void *), + void *__restrict arg) +{ + static pthread_once_t once_control = PTHREAD_ONCE_INIT; + + pthread_once(&once_control, pthread_create_once); + + return (pthread_create_fptr(thread, attr, start_routine, arg)); +} +#endif + +/******************************************************************************/ + +#ifdef JEMALLOC_MUTEX_INIT_CB +JEMALLOC_EXPORT int _pthread_mutex_init_calloc_cb(pthread_mutex_t *mutex, + void *(calloc_cb)(size_t, size_t)); +#endif + +bool +malloc_mutex_init(malloc_mutex_t *mutex) +{ + +#ifdef _WIN32 +# if _WIN32_WINNT >= 0x0600 + InitializeSRWLock(&mutex->lock); +# else + if (!InitializeCriticalSectionAndSpinCount(&mutex->lock, + _CRT_SPINCOUNT)) + return (true); +# endif +#elif (defined(JEMALLOC_OSSPIN)) + mutex->lock = 0; +#elif (defined(JEMALLOC_MUTEX_INIT_CB)) + if (postpone_init) { + mutex->postponed_next = postponed_mutexes; + postponed_mutexes = mutex; + } else { + if (_pthread_mutex_init_calloc_cb(&mutex->lock, + bootstrap_calloc) != 0) + return (true); + } +#else + pthread_mutexattr_t attr; + + if (pthread_mutexattr_init(&attr) != 0) + return (true); + pthread_mutexattr_settype(&attr, MALLOC_MUTEX_TYPE); + if (pthread_mutex_init(&mutex->lock, &attr) != 0) { + pthread_mutexattr_destroy(&attr); + return (true); + } + pthread_mutexattr_destroy(&attr); +#endif + return (false); +} + +void +malloc_mutex_prefork(malloc_mutex_t *mutex) +{ + + malloc_mutex_lock(mutex); +} + +void +malloc_mutex_postfork_parent(malloc_mutex_t *mutex) +{ + + malloc_mutex_unlock(mutex); +} + +void +malloc_mutex_postfork_child(malloc_mutex_t *mutex) +{ + +#ifdef JEMALLOC_MUTEX_INIT_CB + malloc_mutex_unlock(mutex); +#else + if (malloc_mutex_init(mutex)) { + malloc_printf(": Error re-initializing mutex in " + "child\n"); + if (opt_abort) + abort(); + } +#endif +} + +bool +mutex_boot(void) +{ + +#ifdef JEMALLOC_MUTEX_INIT_CB + postpone_init = false; + while (postponed_mutexes != NULL) { + if (_pthread_mutex_init_calloc_cb(&postponed_mutexes->lock, + bootstrap_calloc) != 0) + return (true); + postponed_mutexes = postponed_mutexes->postponed_next; + } +#endif + return (false); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/pages.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/pages.c new file mode 100644 index 0000000..83a167f --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/pages.c @@ -0,0 +1,173 @@ +#define JEMALLOC_PAGES_C_ +#include "jemalloc/internal/jemalloc_internal.h" + +/******************************************************************************/ + +void * +pages_map(void *addr, size_t size) +{ + void *ret; + + assert(size != 0); + +#ifdef _WIN32 + /* + * If VirtualAlloc can't allocate at the given address when one is + * given, it fails and returns NULL. + */ + ret = VirtualAlloc(addr, size, MEM_COMMIT | MEM_RESERVE, + PAGE_READWRITE); +#else + /* + * We don't use MAP_FIXED here, because it can cause the *replacement* + * of existing mappings, and we only want to create new mappings. + */ + ret = mmap(addr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, + -1, 0); + assert(ret != NULL); + + if (ret == MAP_FAILED) + ret = NULL; + else if (addr != NULL && ret != addr) { + /* + * We succeeded in mapping memory, but not in the right place. + */ + pages_unmap(ret, size); + ret = NULL; + } +#endif + assert(ret == NULL || (addr == NULL && ret != addr) + || (addr != NULL && ret == addr)); + return (ret); +} + +void +pages_unmap(void *addr, size_t size) +{ + +#ifdef _WIN32 + if (VirtualFree(addr, 0, MEM_RELEASE) == 0) +#else + if (munmap(addr, size) == -1) +#endif + { + char buf[BUFERROR_BUF]; + + buferror(get_errno(), buf, sizeof(buf)); + malloc_printf(": Error in " +#ifdef _WIN32 + "VirtualFree" +#else + "munmap" +#endif + "(): %s\n", buf); + if (opt_abort) + abort(); + } +} + +void * +pages_trim(void *addr, size_t alloc_size, size_t leadsize, size_t size) +{ + void *ret = (void *)((uintptr_t)addr + leadsize); + + assert(alloc_size >= leadsize + size); +#ifdef _WIN32 + { + void *new_addr; + + pages_unmap(addr, alloc_size); + new_addr = pages_map(ret, size); + if (new_addr == ret) + return (ret); + if (new_addr) + pages_unmap(new_addr, size); + return (NULL); + } +#else + { + size_t trailsize = alloc_size - leadsize - size; + + if (leadsize != 0) + pages_unmap(addr, leadsize); + if (trailsize != 0) + pages_unmap((void *)((uintptr_t)ret + size), trailsize); + return (ret); + } +#endif +} + +static bool +pages_commit_impl(void *addr, size_t size, bool commit) +{ + +#ifndef _WIN32 + /* + * The following decommit/commit implementation is functional, but + * always disabled because it doesn't add value beyong improved + * debugging (at the cost of extra system calls) on systems that + * overcommit. + */ + if (false) { + int prot = commit ? (PROT_READ | PROT_WRITE) : PROT_NONE; + void *result = mmap(addr, size, prot, MAP_PRIVATE | MAP_ANON | + MAP_FIXED, -1, 0); + if (result == MAP_FAILED) + return (true); + if (result != addr) { + /* + * We succeeded in mapping memory, but not in the right + * place. + */ + pages_unmap(result, size); + return (true); + } + return (false); + } +#endif + return (true); +} + +bool +pages_commit(void *addr, size_t size) +{ + + return (pages_commit_impl(addr, size, true)); +} + +bool +pages_decommit(void *addr, size_t size) +{ + + return (pages_commit_impl(addr, size, false)); +} + +bool +pages_purge(void *addr, size_t size) +{ + bool unzeroed; + +#ifdef _WIN32 + VirtualAlloc(addr, size, MEM_RESET, PAGE_READWRITE); + unzeroed = true; +#elif defined(JEMALLOC_HAVE_MADVISE) +# ifdef JEMALLOC_PURGE_MADVISE_DONTNEED +# define JEMALLOC_MADV_PURGE MADV_DONTNEED +# define JEMALLOC_MADV_ZEROS true +# elif defined(JEMALLOC_PURGE_MADVISE_FREE) +# define JEMALLOC_MADV_PURGE MADV_FREE +# define JEMALLOC_MADV_ZEROS false +# else +# error "No madvise(2) flag defined for purging unused dirty pages." +# endif + int err = madvise(addr, size, JEMALLOC_MADV_PURGE); + unzeroed = (!JEMALLOC_MADV_ZEROS || err != 0); +# undef JEMALLOC_MADV_PURGE +# undef JEMALLOC_MADV_ZEROS +#else + /* Last resort no-op. */ + unzeroed = true; +#endif + return (unzeroed); +} + diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/prof.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/prof.c new file mode 100644 index 0000000..5d2b959 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/prof.c @@ -0,0 +1,2237 @@ +#define JEMALLOC_PROF_C_ +#include "jemalloc/internal/jemalloc_internal.h" +/******************************************************************************/ + +#ifdef JEMALLOC_PROF_LIBUNWIND +#define UNW_LOCAL_ONLY +#include +#endif + +#ifdef JEMALLOC_PROF_LIBGCC +#include +#endif + +/******************************************************************************/ +/* Data. */ + +bool opt_prof = false; +bool opt_prof_active = true; +bool opt_prof_thread_active_init = true; +size_t opt_lg_prof_sample = LG_PROF_SAMPLE_DEFAULT; +ssize_t opt_lg_prof_interval = LG_PROF_INTERVAL_DEFAULT; +bool opt_prof_gdump = false; +bool opt_prof_final = false; +bool opt_prof_leak = false; +bool opt_prof_accum = false; +char opt_prof_prefix[ + /* Minimize memory bloat for non-prof builds. */ +#ifdef JEMALLOC_PROF + PATH_MAX + +#endif + 1]; + +/* + * Initialized as opt_prof_active, and accessed via + * prof_active_[gs]et{_unlocked,}(). + */ +bool prof_active; +static malloc_mutex_t prof_active_mtx; + +/* + * Initialized as opt_prof_thread_active_init, and accessed via + * prof_thread_active_init_[gs]et(). + */ +static bool prof_thread_active_init; +static malloc_mutex_t prof_thread_active_init_mtx; + +/* + * Initialized as opt_prof_gdump, and accessed via + * prof_gdump_[gs]et{_unlocked,}(). + */ +bool prof_gdump_val; +static malloc_mutex_t prof_gdump_mtx; + +uint64_t prof_interval = 0; + +size_t lg_prof_sample; + +/* + * Table of mutexes that are shared among gctx's. These are leaf locks, so + * there is no problem with using them for more than one gctx at the same time. + * The primary motivation for this sharing though is that gctx's are ephemeral, + * and destroying mutexes causes complications for systems that allocate when + * creating/destroying mutexes. + */ +static malloc_mutex_t *gctx_locks; +static unsigned cum_gctxs; /* Atomic counter. */ + +/* + * Table of mutexes that are shared among tdata's. No operations require + * holding multiple tdata locks, so there is no problem with using them for more + * than one tdata at the same time, even though a gctx lock may be acquired + * while holding a tdata lock. + */ +static malloc_mutex_t *tdata_locks; + +/* + * Global hash of (prof_bt_t *)-->(prof_gctx_t *). This is the master data + * structure that knows about all backtraces currently captured. + */ +static ckh_t bt2gctx; +static malloc_mutex_t bt2gctx_mtx; + +/* + * Tree of all extant prof_tdata_t structures, regardless of state, + * {attached,detached,expired}. + */ +static prof_tdata_tree_t tdatas; +static malloc_mutex_t tdatas_mtx; + +static uint64_t next_thr_uid; +static malloc_mutex_t next_thr_uid_mtx; + +static malloc_mutex_t prof_dump_seq_mtx; +static uint64_t prof_dump_seq; +static uint64_t prof_dump_iseq; +static uint64_t prof_dump_mseq; +static uint64_t prof_dump_useq; + +/* + * This buffer is rather large for stack allocation, so use a single buffer for + * all profile dumps. + */ +static malloc_mutex_t prof_dump_mtx; +static char prof_dump_buf[ + /* Minimize memory bloat for non-prof builds. */ +#ifdef JEMALLOC_PROF + PROF_DUMP_BUFSIZE +#else + 1 +#endif +]; +static unsigned prof_dump_buf_end; +static int prof_dump_fd; + +/* Do not dump any profiles until bootstrapping is complete. */ +static bool prof_booted = false; + +/******************************************************************************/ +/* + * Function prototypes for static functions that are referenced prior to + * definition. + */ + +static bool prof_tctx_should_destroy(prof_tctx_t *tctx); +static void prof_tctx_destroy(tsd_t *tsd, prof_tctx_t *tctx); +static bool prof_tdata_should_destroy(prof_tdata_t *tdata, + bool even_if_attached); +static void prof_tdata_destroy(tsd_t *tsd, prof_tdata_t *tdata, + bool even_if_attached); +static char *prof_thread_name_alloc(tsd_t *tsd, const char *thread_name); + +/******************************************************************************/ +/* Red-black trees. */ + +JEMALLOC_INLINE_C int +prof_tctx_comp(const prof_tctx_t *a, const prof_tctx_t *b) +{ + uint64_t a_thr_uid = a->thr_uid; + uint64_t b_thr_uid = b->thr_uid; + int ret = (a_thr_uid > b_thr_uid) - (a_thr_uid < b_thr_uid); + if (ret == 0) { + uint64_t a_thr_discrim = a->thr_discrim; + uint64_t b_thr_discrim = b->thr_discrim; + ret = (a_thr_discrim > b_thr_discrim) - (a_thr_discrim < + b_thr_discrim); + if (ret == 0) { + uint64_t a_tctx_uid = a->tctx_uid; + uint64_t b_tctx_uid = b->tctx_uid; + ret = (a_tctx_uid > b_tctx_uid) - (a_tctx_uid < + b_tctx_uid); + } + } + return (ret); +} + +rb_gen(static UNUSED, tctx_tree_, prof_tctx_tree_t, prof_tctx_t, + tctx_link, prof_tctx_comp) + +JEMALLOC_INLINE_C int +prof_gctx_comp(const prof_gctx_t *a, const prof_gctx_t *b) +{ + unsigned a_len = a->bt.len; + unsigned b_len = b->bt.len; + unsigned comp_len = (a_len < b_len) ? a_len : b_len; + int ret = memcmp(a->bt.vec, b->bt.vec, comp_len * sizeof(void *)); + if (ret == 0) + ret = (a_len > b_len) - (a_len < b_len); + return (ret); +} + +rb_gen(static UNUSED, gctx_tree_, prof_gctx_tree_t, prof_gctx_t, dump_link, + prof_gctx_comp) + +JEMALLOC_INLINE_C int +prof_tdata_comp(const prof_tdata_t *a, const prof_tdata_t *b) +{ + int ret; + uint64_t a_uid = a->thr_uid; + uint64_t b_uid = b->thr_uid; + + ret = ((a_uid > b_uid) - (a_uid < b_uid)); + if (ret == 0) { + uint64_t a_discrim = a->thr_discrim; + uint64_t b_discrim = b->thr_discrim; + + ret = ((a_discrim > b_discrim) - (a_discrim < b_discrim)); + } + return (ret); +} + +rb_gen(static UNUSED, tdata_tree_, prof_tdata_tree_t, prof_tdata_t, tdata_link, + prof_tdata_comp) + +/******************************************************************************/ + +void +prof_alloc_rollback(tsd_t *tsd, prof_tctx_t *tctx, bool updated) +{ + prof_tdata_t *tdata; + + cassert(config_prof); + + if (updated) { + /* + * Compute a new sample threshold. This isn't very important in + * practice, because this function is rarely executed, so the + * potential for sample bias is minimal except in contrived + * programs. + */ + tdata = prof_tdata_get(tsd, true); + if (tdata != NULL) + prof_sample_threshold_update(tdata); + } + + if ((uintptr_t)tctx > (uintptr_t)1U) { + malloc_mutex_lock(tctx->tdata->lock); + tctx->prepared = false; + if (prof_tctx_should_destroy(tctx)) + prof_tctx_destroy(tsd, tctx); + else + malloc_mutex_unlock(tctx->tdata->lock); + } +} + +void +prof_malloc_sample_object(const void *ptr, size_t usize, prof_tctx_t *tctx) +{ + + prof_tctx_set(ptr, usize, tctx); + + malloc_mutex_lock(tctx->tdata->lock); + tctx->cnts.curobjs++; + tctx->cnts.curbytes += usize; + if (opt_prof_accum) { + tctx->cnts.accumobjs++; + tctx->cnts.accumbytes += usize; + } + tctx->prepared = false; + malloc_mutex_unlock(tctx->tdata->lock); +} + +void +prof_free_sampled_object(tsd_t *tsd, size_t usize, prof_tctx_t *tctx) +{ + + malloc_mutex_lock(tctx->tdata->lock); + assert(tctx->cnts.curobjs > 0); + assert(tctx->cnts.curbytes >= usize); + tctx->cnts.curobjs--; + tctx->cnts.curbytes -= usize; + + if (prof_tctx_should_destroy(tctx)) + prof_tctx_destroy(tsd, tctx); + else + malloc_mutex_unlock(tctx->tdata->lock); +} + +void +bt_init(prof_bt_t *bt, void **vec) +{ + + cassert(config_prof); + + bt->vec = vec; + bt->len = 0; +} + +JEMALLOC_INLINE_C void +prof_enter(tsd_t *tsd, prof_tdata_t *tdata) +{ + + cassert(config_prof); + assert(tdata == prof_tdata_get(tsd, false)); + + if (tdata != NULL) { + assert(!tdata->enq); + tdata->enq = true; + } + + malloc_mutex_lock(&bt2gctx_mtx); +} + +JEMALLOC_INLINE_C void +prof_leave(tsd_t *tsd, prof_tdata_t *tdata) +{ + + cassert(config_prof); + assert(tdata == prof_tdata_get(tsd, false)); + + malloc_mutex_unlock(&bt2gctx_mtx); + + if (tdata != NULL) { + bool idump, gdump; + + assert(tdata->enq); + tdata->enq = false; + idump = tdata->enq_idump; + tdata->enq_idump = false; + gdump = tdata->enq_gdump; + tdata->enq_gdump = false; + + if (idump) + prof_idump(); + if (gdump) + prof_gdump(); + } +} + +#ifdef JEMALLOC_PROF_LIBUNWIND +void +prof_backtrace(prof_bt_t *bt) +{ + int nframes; + + cassert(config_prof); + assert(bt->len == 0); + assert(bt->vec != NULL); + + nframes = unw_backtrace(bt->vec, PROF_BT_MAX); + if (nframes <= 0) + return; + bt->len = nframes; +} +#elif (defined(JEMALLOC_PROF_LIBGCC)) +static _Unwind_Reason_Code +prof_unwind_init_callback(struct _Unwind_Context *context, void *arg) +{ + + cassert(config_prof); + + return (_URC_NO_REASON); +} + +static _Unwind_Reason_Code +prof_unwind_callback(struct _Unwind_Context *context, void *arg) +{ + prof_unwind_data_t *data = (prof_unwind_data_t *)arg; + void *ip; + + cassert(config_prof); + + ip = (void *)_Unwind_GetIP(context); + if (ip == NULL) + return (_URC_END_OF_STACK); + data->bt->vec[data->bt->len] = ip; + data->bt->len++; + if (data->bt->len == data->max) + return (_URC_END_OF_STACK); + + return (_URC_NO_REASON); +} + +void +prof_backtrace(prof_bt_t *bt) +{ + prof_unwind_data_t data = {bt, PROF_BT_MAX}; + + cassert(config_prof); + + _Unwind_Backtrace(prof_unwind_callback, &data); +} +#elif (defined(JEMALLOC_PROF_GCC)) +void +prof_backtrace(prof_bt_t *bt) +{ +#define BT_FRAME(i) \ + if ((i) < PROF_BT_MAX) { \ + void *p; \ + if (__builtin_frame_address(i) == 0) \ + return; \ + p = __builtin_return_address(i); \ + if (p == NULL) \ + return; \ + bt->vec[(i)] = p; \ + bt->len = (i) + 1; \ + } else \ + return; + + cassert(config_prof); + + BT_FRAME(0) + BT_FRAME(1) + BT_FRAME(2) + BT_FRAME(3) + BT_FRAME(4) + BT_FRAME(5) + BT_FRAME(6) + BT_FRAME(7) + BT_FRAME(8) + BT_FRAME(9) + + BT_FRAME(10) + BT_FRAME(11) + BT_FRAME(12) + BT_FRAME(13) + BT_FRAME(14) + BT_FRAME(15) + BT_FRAME(16) + BT_FRAME(17) + BT_FRAME(18) + BT_FRAME(19) + + BT_FRAME(20) + BT_FRAME(21) + BT_FRAME(22) + BT_FRAME(23) + BT_FRAME(24) + BT_FRAME(25) + BT_FRAME(26) + BT_FRAME(27) + BT_FRAME(28) + BT_FRAME(29) + + BT_FRAME(30) + BT_FRAME(31) + BT_FRAME(32) + BT_FRAME(33) + BT_FRAME(34) + BT_FRAME(35) + BT_FRAME(36) + BT_FRAME(37) + BT_FRAME(38) + BT_FRAME(39) + + BT_FRAME(40) + BT_FRAME(41) + BT_FRAME(42) + BT_FRAME(43) + BT_FRAME(44) + BT_FRAME(45) + BT_FRAME(46) + BT_FRAME(47) + BT_FRAME(48) + BT_FRAME(49) + + BT_FRAME(50) + BT_FRAME(51) + BT_FRAME(52) + BT_FRAME(53) + BT_FRAME(54) + BT_FRAME(55) + BT_FRAME(56) + BT_FRAME(57) + BT_FRAME(58) + BT_FRAME(59) + + BT_FRAME(60) + BT_FRAME(61) + BT_FRAME(62) + BT_FRAME(63) + BT_FRAME(64) + BT_FRAME(65) + BT_FRAME(66) + BT_FRAME(67) + BT_FRAME(68) + BT_FRAME(69) + + BT_FRAME(70) + BT_FRAME(71) + BT_FRAME(72) + BT_FRAME(73) + BT_FRAME(74) + BT_FRAME(75) + BT_FRAME(76) + BT_FRAME(77) + BT_FRAME(78) + BT_FRAME(79) + + BT_FRAME(80) + BT_FRAME(81) + BT_FRAME(82) + BT_FRAME(83) + BT_FRAME(84) + BT_FRAME(85) + BT_FRAME(86) + BT_FRAME(87) + BT_FRAME(88) + BT_FRAME(89) + + BT_FRAME(90) + BT_FRAME(91) + BT_FRAME(92) + BT_FRAME(93) + BT_FRAME(94) + BT_FRAME(95) + BT_FRAME(96) + BT_FRAME(97) + BT_FRAME(98) + BT_FRAME(99) + + BT_FRAME(100) + BT_FRAME(101) + BT_FRAME(102) + BT_FRAME(103) + BT_FRAME(104) + BT_FRAME(105) + BT_FRAME(106) + BT_FRAME(107) + BT_FRAME(108) + BT_FRAME(109) + + BT_FRAME(110) + BT_FRAME(111) + BT_FRAME(112) + BT_FRAME(113) + BT_FRAME(114) + BT_FRAME(115) + BT_FRAME(116) + BT_FRAME(117) + BT_FRAME(118) + BT_FRAME(119) + + BT_FRAME(120) + BT_FRAME(121) + BT_FRAME(122) + BT_FRAME(123) + BT_FRAME(124) + BT_FRAME(125) + BT_FRAME(126) + BT_FRAME(127) +#undef BT_FRAME +} +#else +void +prof_backtrace(prof_bt_t *bt) +{ + + cassert(config_prof); + not_reached(); +} +#endif + +static malloc_mutex_t * +prof_gctx_mutex_choose(void) +{ + unsigned ngctxs = atomic_add_u(&cum_gctxs, 1); + + return (&gctx_locks[(ngctxs - 1) % PROF_NCTX_LOCKS]); +} + +static malloc_mutex_t * +prof_tdata_mutex_choose(uint64_t thr_uid) +{ + + return (&tdata_locks[thr_uid % PROF_NTDATA_LOCKS]); +} + +static prof_gctx_t * +prof_gctx_create(tsd_t *tsd, prof_bt_t *bt) +{ + /* + * Create a single allocation that has space for vec of length bt->len. + */ + prof_gctx_t *gctx = (prof_gctx_t *)iallocztm(tsd, offsetof(prof_gctx_t, + vec) + (bt->len * sizeof(void *)), false, tcache_get(tsd, true), + true, NULL); + if (gctx == NULL) + return (NULL); + gctx->lock = prof_gctx_mutex_choose(); + /* + * Set nlimbo to 1, in order to avoid a race condition with + * prof_tctx_destroy()/prof_gctx_try_destroy(). + */ + gctx->nlimbo = 1; + tctx_tree_new(&gctx->tctxs); + /* Duplicate bt. */ + memcpy(gctx->vec, bt->vec, bt->len * sizeof(void *)); + gctx->bt.vec = gctx->vec; + gctx->bt.len = bt->len; + return (gctx); +} + +static void +prof_gctx_try_destroy(tsd_t *tsd, prof_tdata_t *tdata_self, prof_gctx_t *gctx, + prof_tdata_t *tdata) +{ + + cassert(config_prof); + + /* + * Check that gctx is still unused by any thread cache before destroying + * it. prof_lookup() increments gctx->nlimbo in order to avoid a race + * condition with this function, as does prof_tctx_destroy() in order to + * avoid a race between the main body of prof_tctx_destroy() and entry + * into this function. + */ + prof_enter(tsd, tdata_self); + malloc_mutex_lock(gctx->lock); + assert(gctx->nlimbo != 0); + if (tctx_tree_empty(&gctx->tctxs) && gctx->nlimbo == 1) { + /* Remove gctx from bt2gctx. */ + if (ckh_remove(tsd, &bt2gctx, &gctx->bt, NULL, NULL)) + not_reached(); + prof_leave(tsd, tdata_self); + /* Destroy gctx. */ + malloc_mutex_unlock(gctx->lock); + idalloctm(tsd, gctx, tcache_get(tsd, false), true); + } else { + /* + * Compensate for increment in prof_tctx_destroy() or + * prof_lookup(). + */ + gctx->nlimbo--; + malloc_mutex_unlock(gctx->lock); + prof_leave(tsd, tdata_self); + } +} + +/* tctx->tdata->lock must be held. */ +static bool +prof_tctx_should_destroy(prof_tctx_t *tctx) +{ + + if (opt_prof_accum) + return (false); + if (tctx->cnts.curobjs != 0) + return (false); + if (tctx->prepared) + return (false); + return (true); +} + +static bool +prof_gctx_should_destroy(prof_gctx_t *gctx) +{ + + if (opt_prof_accum) + return (false); + if (!tctx_tree_empty(&gctx->tctxs)) + return (false); + if (gctx->nlimbo != 0) + return (false); + return (true); +} + +/* tctx->tdata->lock is held upon entry, and released before return. */ +static void +prof_tctx_destroy(tsd_t *tsd, prof_tctx_t *tctx) +{ + prof_tdata_t *tdata = tctx->tdata; + prof_gctx_t *gctx = tctx->gctx; + bool destroy_tdata, destroy_tctx, destroy_gctx; + + assert(tctx->cnts.curobjs == 0); + assert(tctx->cnts.curbytes == 0); + assert(!opt_prof_accum); + assert(tctx->cnts.accumobjs == 0); + assert(tctx->cnts.accumbytes == 0); + + ckh_remove(tsd, &tdata->bt2tctx, &gctx->bt, NULL, NULL); + destroy_tdata = prof_tdata_should_destroy(tdata, false); + malloc_mutex_unlock(tdata->lock); + + malloc_mutex_lock(gctx->lock); + switch (tctx->state) { + case prof_tctx_state_nominal: + tctx_tree_remove(&gctx->tctxs, tctx); + destroy_tctx = true; + if (prof_gctx_should_destroy(gctx)) { + /* + * Increment gctx->nlimbo in order to keep another + * thread from winning the race to destroy gctx while + * this one has gctx->lock dropped. Without this, it + * would be possible for another thread to: + * + * 1) Sample an allocation associated with gctx. + * 2) Deallocate the sampled object. + * 3) Successfully prof_gctx_try_destroy(gctx). + * + * The result would be that gctx no longer exists by the + * time this thread accesses it in + * prof_gctx_try_destroy(). + */ + gctx->nlimbo++; + destroy_gctx = true; + } else + destroy_gctx = false; + break; + case prof_tctx_state_dumping: + /* + * A dumping thread needs tctx to remain valid until dumping + * has finished. Change state such that the dumping thread will + * complete destruction during a late dump iteration phase. + */ + tctx->state = prof_tctx_state_purgatory; + destroy_tctx = false; + destroy_gctx = false; + break; + default: + not_reached(); + destroy_tctx = false; + destroy_gctx = false; + } + malloc_mutex_unlock(gctx->lock); + if (destroy_gctx) { + prof_gctx_try_destroy(tsd, prof_tdata_get(tsd, false), gctx, + tdata); + } + + if (destroy_tdata) + prof_tdata_destroy(tsd, tdata, false); + + if (destroy_tctx) + idalloctm(tsd, tctx, tcache_get(tsd, false), true); +} + +static bool +prof_lookup_global(tsd_t *tsd, prof_bt_t *bt, prof_tdata_t *tdata, + void **p_btkey, prof_gctx_t **p_gctx, bool *p_new_gctx) +{ + union { + prof_gctx_t *p; + void *v; + } gctx; + union { + prof_bt_t *p; + void *v; + } btkey; + bool new_gctx; + + prof_enter(tsd, tdata); + if (ckh_search(&bt2gctx, bt, &btkey.v, &gctx.v)) { + /* bt has never been seen before. Insert it. */ + gctx.p = prof_gctx_create(tsd, bt); + if (gctx.v == NULL) { + prof_leave(tsd, tdata); + return (true); + } + btkey.p = &gctx.p->bt; + if (ckh_insert(tsd, &bt2gctx, btkey.v, gctx.v)) { + /* OOM. */ + prof_leave(tsd, tdata); + idalloctm(tsd, gctx.v, tcache_get(tsd, false), true); + return (true); + } + new_gctx = true; + } else { + /* + * Increment nlimbo, in order to avoid a race condition with + * prof_tctx_destroy()/prof_gctx_try_destroy(). + */ + malloc_mutex_lock(gctx.p->lock); + gctx.p->nlimbo++; + malloc_mutex_unlock(gctx.p->lock); + new_gctx = false; + } + prof_leave(tsd, tdata); + + *p_btkey = btkey.v; + *p_gctx = gctx.p; + *p_new_gctx = new_gctx; + return (false); +} + +prof_tctx_t * +prof_lookup(tsd_t *tsd, prof_bt_t *bt) +{ + union { + prof_tctx_t *p; + void *v; + } ret; + prof_tdata_t *tdata; + bool not_found; + + cassert(config_prof); + + tdata = prof_tdata_get(tsd, false); + if (tdata == NULL) + return (NULL); + + malloc_mutex_lock(tdata->lock); + not_found = ckh_search(&tdata->bt2tctx, bt, NULL, &ret.v); + if (!not_found) /* Note double negative! */ + ret.p->prepared = true; + malloc_mutex_unlock(tdata->lock); + if (not_found) { + tcache_t *tcache; + void *btkey; + prof_gctx_t *gctx; + bool new_gctx, error; + + /* + * This thread's cache lacks bt. Look for it in the global + * cache. + */ + if (prof_lookup_global(tsd, bt, tdata, &btkey, &gctx, + &new_gctx)) + return (NULL); + + /* Link a prof_tctx_t into gctx for this thread. */ + tcache = tcache_get(tsd, true); + ret.v = iallocztm(tsd, sizeof(prof_tctx_t), false, tcache, true, + NULL); + if (ret.p == NULL) { + if (new_gctx) + prof_gctx_try_destroy(tsd, tdata, gctx, tdata); + return (NULL); + } + ret.p->tdata = tdata; + ret.p->thr_uid = tdata->thr_uid; + ret.p->thr_discrim = tdata->thr_discrim; + memset(&ret.p->cnts, 0, sizeof(prof_cnt_t)); + ret.p->gctx = gctx; + ret.p->tctx_uid = tdata->tctx_uid_next++; + ret.p->prepared = true; + ret.p->state = prof_tctx_state_initializing; + malloc_mutex_lock(tdata->lock); + error = ckh_insert(tsd, &tdata->bt2tctx, btkey, ret.v); + malloc_mutex_unlock(tdata->lock); + if (error) { + if (new_gctx) + prof_gctx_try_destroy(tsd, tdata, gctx, tdata); + idalloctm(tsd, ret.v, tcache, true); + return (NULL); + } + malloc_mutex_lock(gctx->lock); + ret.p->state = prof_tctx_state_nominal; + tctx_tree_insert(&gctx->tctxs, ret.p); + gctx->nlimbo--; + malloc_mutex_unlock(gctx->lock); + } + + return (ret.p); +} + +void +prof_sample_threshold_update(prof_tdata_t *tdata) +{ + /* + * The body of this function is compiled out unless heap profiling is + * enabled, so that it is possible to compile jemalloc with floating + * point support completely disabled. Avoiding floating point code is + * important on memory-constrained systems, but it also enables a + * workaround for versions of glibc that don't properly save/restore + * floating point registers during dynamic lazy symbol loading (which + * internally calls into whatever malloc implementation happens to be + * integrated into the application). Note that some compilers (e.g. + * gcc 4.8) may use floating point registers for fast memory moves, so + * jemalloc must be compiled with such optimizations disabled (e.g. + * -mno-sse) in order for the workaround to be complete. + */ +#ifdef JEMALLOC_PROF + uint64_t r; + double u; + + if (!config_prof) + return; + + if (lg_prof_sample == 0) { + tdata->bytes_until_sample = 0; + return; + } + + /* + * Compute sample interval as a geometrically distributed random + * variable with mean (2^lg_prof_sample). + * + * __ __ + * | log(u) | 1 + * tdata->bytes_until_sample = | -------- |, where p = --------------- + * | log(1-p) | lg_prof_sample + * 2 + * + * For more information on the math, see: + * + * Non-Uniform Random Variate Generation + * Luc Devroye + * Springer-Verlag, New York, 1986 + * pp 500 + * (http://luc.devroye.org/rnbookindex.html) + */ + prng64(r, 53, tdata->prng_state, UINT64_C(6364136223846793005), + UINT64_C(1442695040888963407)); + u = (double)r * (1.0/9007199254740992.0L); + tdata->bytes_until_sample = (uint64_t)(log(u) / + log(1.0 - (1.0 / (double)((uint64_t)1U << lg_prof_sample)))) + + (uint64_t)1U; +#endif +} + +#ifdef JEMALLOC_JET +static prof_tdata_t * +prof_tdata_count_iter(prof_tdata_tree_t *tdatas, prof_tdata_t *tdata, void *arg) +{ + size_t *tdata_count = (size_t *)arg; + + (*tdata_count)++; + + return (NULL); +} + +size_t +prof_tdata_count(void) +{ + size_t tdata_count = 0; + + malloc_mutex_lock(&tdatas_mtx); + tdata_tree_iter(&tdatas, NULL, prof_tdata_count_iter, + (void *)&tdata_count); + malloc_mutex_unlock(&tdatas_mtx); + + return (tdata_count); +} +#endif + +#ifdef JEMALLOC_JET +size_t +prof_bt_count(void) +{ + size_t bt_count; + tsd_t *tsd; + prof_tdata_t *tdata; + + tsd = tsd_fetch(); + tdata = prof_tdata_get(tsd, false); + if (tdata == NULL) + return (0); + + malloc_mutex_lock(&bt2gctx_mtx); + bt_count = ckh_count(&bt2gctx); + malloc_mutex_unlock(&bt2gctx_mtx); + + return (bt_count); +} +#endif + +#ifdef JEMALLOC_JET +#undef prof_dump_open +#define prof_dump_open JEMALLOC_N(prof_dump_open_impl) +#endif +static int +prof_dump_open(bool propagate_err, const char *filename) +{ + int fd; + + fd = creat(filename, 0644); + if (fd == -1 && !propagate_err) { + malloc_printf(": creat(\"%s\"), 0644) failed\n", + filename); + if (opt_abort) + abort(); + } + + return (fd); +} +#ifdef JEMALLOC_JET +#undef prof_dump_open +#define prof_dump_open JEMALLOC_N(prof_dump_open) +prof_dump_open_t *prof_dump_open = JEMALLOC_N(prof_dump_open_impl); +#endif + +static bool +prof_dump_flush(bool propagate_err) +{ + bool ret = false; + ssize_t err; + + cassert(config_prof); + + err = write(prof_dump_fd, prof_dump_buf, prof_dump_buf_end); + if (err == -1) { + if (!propagate_err) { + malloc_write(": write() failed during heap " + "profile flush\n"); + if (opt_abort) + abort(); + } + ret = true; + } + prof_dump_buf_end = 0; + + return (ret); +} + +static bool +prof_dump_close(bool propagate_err) +{ + bool ret; + + assert(prof_dump_fd != -1); + ret = prof_dump_flush(propagate_err); + close(prof_dump_fd); + prof_dump_fd = -1; + + return (ret); +} + +static bool +prof_dump_write(bool propagate_err, const char *s) +{ + unsigned i, slen, n; + + cassert(config_prof); + + i = 0; + slen = strlen(s); + while (i < slen) { + /* Flush the buffer if it is full. */ + if (prof_dump_buf_end == PROF_DUMP_BUFSIZE) + if (prof_dump_flush(propagate_err) && propagate_err) + return (true); + + if (prof_dump_buf_end + slen <= PROF_DUMP_BUFSIZE) { + /* Finish writing. */ + n = slen - i; + } else { + /* Write as much of s as will fit. */ + n = PROF_DUMP_BUFSIZE - prof_dump_buf_end; + } + memcpy(&prof_dump_buf[prof_dump_buf_end], &s[i], n); + prof_dump_buf_end += n; + i += n; + } + + return (false); +} + +JEMALLOC_FORMAT_PRINTF(2, 3) +static bool +prof_dump_printf(bool propagate_err, const char *format, ...) +{ + bool ret; + va_list ap; + char buf[PROF_PRINTF_BUFSIZE]; + + va_start(ap, format); + malloc_vsnprintf(buf, sizeof(buf), format, ap); + va_end(ap); + ret = prof_dump_write(propagate_err, buf); + + return (ret); +} + +/* tctx->tdata->lock is held. */ +static void +prof_tctx_merge_tdata(prof_tctx_t *tctx, prof_tdata_t *tdata) +{ + + malloc_mutex_lock(tctx->gctx->lock); + + switch (tctx->state) { + case prof_tctx_state_initializing: + malloc_mutex_unlock(tctx->gctx->lock); + return; + case prof_tctx_state_nominal: + tctx->state = prof_tctx_state_dumping; + malloc_mutex_unlock(tctx->gctx->lock); + + memcpy(&tctx->dump_cnts, &tctx->cnts, sizeof(prof_cnt_t)); + + tdata->cnt_summed.curobjs += tctx->dump_cnts.curobjs; + tdata->cnt_summed.curbytes += tctx->dump_cnts.curbytes; + if (opt_prof_accum) { + tdata->cnt_summed.accumobjs += + tctx->dump_cnts.accumobjs; + tdata->cnt_summed.accumbytes += + tctx->dump_cnts.accumbytes; + } + break; + case prof_tctx_state_dumping: + case prof_tctx_state_purgatory: + not_reached(); + } +} + +/* gctx->lock is held. */ +static void +prof_tctx_merge_gctx(prof_tctx_t *tctx, prof_gctx_t *gctx) +{ + + gctx->cnt_summed.curobjs += tctx->dump_cnts.curobjs; + gctx->cnt_summed.curbytes += tctx->dump_cnts.curbytes; + if (opt_prof_accum) { + gctx->cnt_summed.accumobjs += tctx->dump_cnts.accumobjs; + gctx->cnt_summed.accumbytes += tctx->dump_cnts.accumbytes; + } +} + +/* tctx->gctx is held. */ +static prof_tctx_t * +prof_tctx_merge_iter(prof_tctx_tree_t *tctxs, prof_tctx_t *tctx, void *arg) +{ + + switch (tctx->state) { + case prof_tctx_state_nominal: + /* New since dumping started; ignore. */ + break; + case prof_tctx_state_dumping: + case prof_tctx_state_purgatory: + prof_tctx_merge_gctx(tctx, tctx->gctx); + break; + default: + not_reached(); + } + + return (NULL); +} + +/* gctx->lock is held. */ +static prof_tctx_t * +prof_tctx_dump_iter(prof_tctx_tree_t *tctxs, prof_tctx_t *tctx, void *arg) +{ + bool propagate_err = *(bool *)arg; + + switch (tctx->state) { + case prof_tctx_state_initializing: + case prof_tctx_state_nominal: + /* Not captured by this dump. */ + break; + case prof_tctx_state_dumping: + case prof_tctx_state_purgatory: + if (prof_dump_printf(propagate_err, + " t%"FMTu64": %"FMTu64": %"FMTu64" [%"FMTu64": " + "%"FMTu64"]\n", tctx->thr_uid, tctx->dump_cnts.curobjs, + tctx->dump_cnts.curbytes, tctx->dump_cnts.accumobjs, + tctx->dump_cnts.accumbytes)) + return (tctx); + break; + default: + not_reached(); + } + return (NULL); +} + +/* tctx->gctx is held. */ +static prof_tctx_t * +prof_tctx_finish_iter(prof_tctx_tree_t *tctxs, prof_tctx_t *tctx, void *arg) +{ + prof_tctx_t *ret; + + switch (tctx->state) { + case prof_tctx_state_nominal: + /* New since dumping started; ignore. */ + break; + case prof_tctx_state_dumping: + tctx->state = prof_tctx_state_nominal; + break; + case prof_tctx_state_purgatory: + ret = tctx; + goto label_return; + default: + not_reached(); + } + + ret = NULL; +label_return: + return (ret); +} + +static void +prof_dump_gctx_prep(prof_gctx_t *gctx, prof_gctx_tree_t *gctxs) +{ + + cassert(config_prof); + + malloc_mutex_lock(gctx->lock); + + /* + * Increment nlimbo so that gctx won't go away before dump. + * Additionally, link gctx into the dump list so that it is included in + * prof_dump()'s second pass. + */ + gctx->nlimbo++; + gctx_tree_insert(gctxs, gctx); + + memset(&gctx->cnt_summed, 0, sizeof(prof_cnt_t)); + + malloc_mutex_unlock(gctx->lock); +} + +static prof_gctx_t * +prof_gctx_merge_iter(prof_gctx_tree_t *gctxs, prof_gctx_t *gctx, void *arg) +{ + size_t *leak_ngctx = (size_t *)arg; + + malloc_mutex_lock(gctx->lock); + tctx_tree_iter(&gctx->tctxs, NULL, prof_tctx_merge_iter, NULL); + if (gctx->cnt_summed.curobjs != 0) + (*leak_ngctx)++; + malloc_mutex_unlock(gctx->lock); + + return (NULL); +} + +static void +prof_gctx_finish(tsd_t *tsd, prof_gctx_tree_t *gctxs) +{ + prof_tdata_t *tdata = prof_tdata_get(tsd, false); + prof_gctx_t *gctx; + + /* + * Standard tree iteration won't work here, because as soon as we + * decrement gctx->nlimbo and unlock gctx, another thread can + * concurrently destroy it, which will corrupt the tree. Therefore, + * tear down the tree one node at a time during iteration. + */ + while ((gctx = gctx_tree_first(gctxs)) != NULL) { + gctx_tree_remove(gctxs, gctx); + malloc_mutex_lock(gctx->lock); + { + prof_tctx_t *next; + + next = NULL; + do { + prof_tctx_t *to_destroy = + tctx_tree_iter(&gctx->tctxs, next, + prof_tctx_finish_iter, NULL); + if (to_destroy != NULL) { + next = tctx_tree_next(&gctx->tctxs, + to_destroy); + tctx_tree_remove(&gctx->tctxs, + to_destroy); + idalloctm(tsd, to_destroy, + tcache_get(tsd, false), true); + } else + next = NULL; + } while (next != NULL); + } + gctx->nlimbo--; + if (prof_gctx_should_destroy(gctx)) { + gctx->nlimbo++; + malloc_mutex_unlock(gctx->lock); + prof_gctx_try_destroy(tsd, tdata, gctx, tdata); + } else + malloc_mutex_unlock(gctx->lock); + } +} + +static prof_tdata_t * +prof_tdata_merge_iter(prof_tdata_tree_t *tdatas, prof_tdata_t *tdata, void *arg) +{ + prof_cnt_t *cnt_all = (prof_cnt_t *)arg; + + malloc_mutex_lock(tdata->lock); + if (!tdata->expired) { + size_t tabind; + union { + prof_tctx_t *p; + void *v; + } tctx; + + tdata->dumping = true; + memset(&tdata->cnt_summed, 0, sizeof(prof_cnt_t)); + for (tabind = 0; !ckh_iter(&tdata->bt2tctx, &tabind, NULL, + &tctx.v);) + prof_tctx_merge_tdata(tctx.p, tdata); + + cnt_all->curobjs += tdata->cnt_summed.curobjs; + cnt_all->curbytes += tdata->cnt_summed.curbytes; + if (opt_prof_accum) { + cnt_all->accumobjs += tdata->cnt_summed.accumobjs; + cnt_all->accumbytes += tdata->cnt_summed.accumbytes; + } + } else + tdata->dumping = false; + malloc_mutex_unlock(tdata->lock); + + return (NULL); +} + +static prof_tdata_t * +prof_tdata_dump_iter(prof_tdata_tree_t *tdatas, prof_tdata_t *tdata, void *arg) +{ + bool propagate_err = *(bool *)arg; + + if (!tdata->dumping) + return (NULL); + + if (prof_dump_printf(propagate_err, + " t%"FMTu64": %"FMTu64": %"FMTu64" [%"FMTu64": %"FMTu64"]%s%s\n", + tdata->thr_uid, tdata->cnt_summed.curobjs, + tdata->cnt_summed.curbytes, tdata->cnt_summed.accumobjs, + tdata->cnt_summed.accumbytes, + (tdata->thread_name != NULL) ? " " : "", + (tdata->thread_name != NULL) ? tdata->thread_name : "")) + return (tdata); + return (NULL); +} + +#ifdef JEMALLOC_JET +#undef prof_dump_header +#define prof_dump_header JEMALLOC_N(prof_dump_header_impl) +#endif +static bool +prof_dump_header(bool propagate_err, const prof_cnt_t *cnt_all) +{ + bool ret; + + if (prof_dump_printf(propagate_err, + "heap_v2/%"FMTu64"\n" + " t*: %"FMTu64": %"FMTu64" [%"FMTu64": %"FMTu64"]\n", + ((uint64_t)1U << lg_prof_sample), cnt_all->curobjs, + cnt_all->curbytes, cnt_all->accumobjs, cnt_all->accumbytes)) + return (true); + + malloc_mutex_lock(&tdatas_mtx); + ret = (tdata_tree_iter(&tdatas, NULL, prof_tdata_dump_iter, + (void *)&propagate_err) != NULL); + malloc_mutex_unlock(&tdatas_mtx); + return (ret); +} +#ifdef JEMALLOC_JET +#undef prof_dump_header +#define prof_dump_header JEMALLOC_N(prof_dump_header) +prof_dump_header_t *prof_dump_header = JEMALLOC_N(prof_dump_header_impl); +#endif + +/* gctx->lock is held. */ +static bool +prof_dump_gctx(bool propagate_err, prof_gctx_t *gctx, const prof_bt_t *bt, + prof_gctx_tree_t *gctxs) +{ + bool ret; + unsigned i; + + cassert(config_prof); + + /* Avoid dumping such gctx's that have no useful data. */ + if ((!opt_prof_accum && gctx->cnt_summed.curobjs == 0) || + (opt_prof_accum && gctx->cnt_summed.accumobjs == 0)) { + assert(gctx->cnt_summed.curobjs == 0); + assert(gctx->cnt_summed.curbytes == 0); + assert(gctx->cnt_summed.accumobjs == 0); + assert(gctx->cnt_summed.accumbytes == 0); + ret = false; + goto label_return; + } + + if (prof_dump_printf(propagate_err, "@")) { + ret = true; + goto label_return; + } + for (i = 0; i < bt->len; i++) { + if (prof_dump_printf(propagate_err, " %#"FMTxPTR, + (uintptr_t)bt->vec[i])) { + ret = true; + goto label_return; + } + } + + if (prof_dump_printf(propagate_err, + "\n" + " t*: %"FMTu64": %"FMTu64" [%"FMTu64": %"FMTu64"]\n", + gctx->cnt_summed.curobjs, gctx->cnt_summed.curbytes, + gctx->cnt_summed.accumobjs, gctx->cnt_summed.accumbytes)) { + ret = true; + goto label_return; + } + + if (tctx_tree_iter(&gctx->tctxs, NULL, prof_tctx_dump_iter, + (void *)&propagate_err) != NULL) { + ret = true; + goto label_return; + } + + ret = false; +label_return: + return (ret); +} + +JEMALLOC_FORMAT_PRINTF(1, 2) +static int +prof_open_maps(const char *format, ...) +{ + int mfd; + va_list ap; + char filename[PATH_MAX + 1]; + + va_start(ap, format); + malloc_vsnprintf(filename, sizeof(filename), format, ap); + va_end(ap); + mfd = open(filename, O_RDONLY); + + return (mfd); +} + +static bool +prof_dump_maps(bool propagate_err) +{ + bool ret; + int mfd; + + cassert(config_prof); +#ifdef __FreeBSD__ + mfd = prof_open_maps("/proc/curproc/map"); +#else + { + int pid = getpid(); + + mfd = prof_open_maps("/proc/%d/task/%d/maps", pid, pid); + if (mfd == -1) + mfd = prof_open_maps("/proc/%d/maps", pid); + } +#endif + if (mfd != -1) { + ssize_t nread; + + if (prof_dump_write(propagate_err, "\nMAPPED_LIBRARIES:\n") && + propagate_err) { + ret = true; + goto label_return; + } + nread = 0; + do { + prof_dump_buf_end += nread; + if (prof_dump_buf_end == PROF_DUMP_BUFSIZE) { + /* Make space in prof_dump_buf before read(). */ + if (prof_dump_flush(propagate_err) && + propagate_err) { + ret = true; + goto label_return; + } + } + nread = read(mfd, &prof_dump_buf[prof_dump_buf_end], + PROF_DUMP_BUFSIZE - prof_dump_buf_end); + } while (nread > 0); + } else { + ret = true; + goto label_return; + } + + ret = false; +label_return: + if (mfd != -1) + close(mfd); + return (ret); +} + +static void +prof_leakcheck(const prof_cnt_t *cnt_all, size_t leak_ngctx, + const char *filename) +{ + + if (cnt_all->curbytes != 0) { + malloc_printf(": Leak summary: %"FMTu64" byte%s, %" + FMTu64" object%s, %zu context%s\n", + cnt_all->curbytes, (cnt_all->curbytes != 1) ? "s" : "", + cnt_all->curobjs, (cnt_all->curobjs != 1) ? "s" : "", + leak_ngctx, (leak_ngctx != 1) ? "s" : ""); + malloc_printf( + ": Run jeprof on \"%s\" for leak detail\n", + filename); + } +} + +static prof_gctx_t * +prof_gctx_dump_iter(prof_gctx_tree_t *gctxs, prof_gctx_t *gctx, void *arg) +{ + prof_gctx_t *ret; + bool propagate_err = *(bool *)arg; + + malloc_mutex_lock(gctx->lock); + + if (prof_dump_gctx(propagate_err, gctx, &gctx->bt, gctxs)) { + ret = gctx; + goto label_return; + } + + ret = NULL; +label_return: + malloc_mutex_unlock(gctx->lock); + return (ret); +} + +static bool +prof_dump(tsd_t *tsd, bool propagate_err, const char *filename, bool leakcheck) +{ + prof_tdata_t *tdata; + prof_cnt_t cnt_all; + size_t tabind; + union { + prof_gctx_t *p; + void *v; + } gctx; + size_t leak_ngctx; + prof_gctx_tree_t gctxs; + + cassert(config_prof); + + tdata = prof_tdata_get(tsd, true); + if (tdata == NULL) + return (true); + + malloc_mutex_lock(&prof_dump_mtx); + prof_enter(tsd, tdata); + + /* + * Put gctx's in limbo and clear their counters in preparation for + * summing. + */ + gctx_tree_new(&gctxs); + for (tabind = 0; !ckh_iter(&bt2gctx, &tabind, NULL, &gctx.v);) + prof_dump_gctx_prep(gctx.p, &gctxs); + + /* + * Iterate over tdatas, and for the non-expired ones snapshot their tctx + * stats and merge them into the associated gctx's. + */ + memset(&cnt_all, 0, sizeof(prof_cnt_t)); + malloc_mutex_lock(&tdatas_mtx); + tdata_tree_iter(&tdatas, NULL, prof_tdata_merge_iter, (void *)&cnt_all); + malloc_mutex_unlock(&tdatas_mtx); + + /* Merge tctx stats into gctx's. */ + leak_ngctx = 0; + gctx_tree_iter(&gctxs, NULL, prof_gctx_merge_iter, (void *)&leak_ngctx); + + prof_leave(tsd, tdata); + + /* Create dump file. */ + if ((prof_dump_fd = prof_dump_open(propagate_err, filename)) == -1) + goto label_open_close_error; + + /* Dump profile header. */ + if (prof_dump_header(propagate_err, &cnt_all)) + goto label_write_error; + + /* Dump per gctx profile stats. */ + if (gctx_tree_iter(&gctxs, NULL, prof_gctx_dump_iter, + (void *)&propagate_err) != NULL) + goto label_write_error; + + /* Dump /proc//maps if possible. */ + if (prof_dump_maps(propagate_err)) + goto label_write_error; + + if (prof_dump_close(propagate_err)) + goto label_open_close_error; + + prof_gctx_finish(tsd, &gctxs); + malloc_mutex_unlock(&prof_dump_mtx); + + if (leakcheck) + prof_leakcheck(&cnt_all, leak_ngctx, filename); + + return (false); +label_write_error: + prof_dump_close(propagate_err); +label_open_close_error: + prof_gctx_finish(tsd, &gctxs); + malloc_mutex_unlock(&prof_dump_mtx); + return (true); +} + +#define DUMP_FILENAME_BUFSIZE (PATH_MAX + 1) +#define VSEQ_INVALID UINT64_C(0xffffffffffffffff) +static void +prof_dump_filename(char *filename, char v, uint64_t vseq) +{ + + cassert(config_prof); + + if (vseq != VSEQ_INVALID) { + /* "...v.heap" */ + malloc_snprintf(filename, DUMP_FILENAME_BUFSIZE, + "%s.%d.%"FMTu64".%c%"FMTu64".heap", + opt_prof_prefix, (int)getpid(), prof_dump_seq, v, vseq); + } else { + /* "....heap" */ + malloc_snprintf(filename, DUMP_FILENAME_BUFSIZE, + "%s.%d.%"FMTu64".%c.heap", + opt_prof_prefix, (int)getpid(), prof_dump_seq, v); + } + prof_dump_seq++; +} + +static void +prof_fdump(void) +{ + tsd_t *tsd; + char filename[DUMP_FILENAME_BUFSIZE]; + + cassert(config_prof); + assert(opt_prof_final); + assert(opt_prof_prefix[0] != '\0'); + + if (!prof_booted) + return; + tsd = tsd_fetch(); + + malloc_mutex_lock(&prof_dump_seq_mtx); + prof_dump_filename(filename, 'f', VSEQ_INVALID); + malloc_mutex_unlock(&prof_dump_seq_mtx); + prof_dump(tsd, false, filename, opt_prof_leak); +} + +void +prof_idump(void) +{ + tsd_t *tsd; + prof_tdata_t *tdata; + + cassert(config_prof); + + if (!prof_booted) + return; + tsd = tsd_fetch(); + tdata = prof_tdata_get(tsd, false); + if (tdata == NULL) + return; + if (tdata->enq) { + tdata->enq_idump = true; + return; + } + + if (opt_prof_prefix[0] != '\0') { + char filename[PATH_MAX + 1]; + malloc_mutex_lock(&prof_dump_seq_mtx); + prof_dump_filename(filename, 'i', prof_dump_iseq); + prof_dump_iseq++; + malloc_mutex_unlock(&prof_dump_seq_mtx); + prof_dump(tsd, false, filename, false); + } +} + +bool +prof_mdump(const char *filename) +{ + tsd_t *tsd; + char filename_buf[DUMP_FILENAME_BUFSIZE]; + + cassert(config_prof); + + if (!opt_prof || !prof_booted) + return (true); + tsd = tsd_fetch(); + + if (filename == NULL) { + /* No filename specified, so automatically generate one. */ + if (opt_prof_prefix[0] == '\0') + return (true); + malloc_mutex_lock(&prof_dump_seq_mtx); + prof_dump_filename(filename_buf, 'm', prof_dump_mseq); + prof_dump_mseq++; + malloc_mutex_unlock(&prof_dump_seq_mtx); + filename = filename_buf; + } + return (prof_dump(tsd, true, filename, false)); +} + +void +prof_gdump(void) +{ + tsd_t *tsd; + prof_tdata_t *tdata; + + cassert(config_prof); + + if (!prof_booted) + return; + tsd = tsd_fetch(); + tdata = prof_tdata_get(tsd, false); + if (tdata == NULL) + return; + if (tdata->enq) { + tdata->enq_gdump = true; + return; + } + + if (opt_prof_prefix[0] != '\0') { + char filename[DUMP_FILENAME_BUFSIZE]; + malloc_mutex_lock(&prof_dump_seq_mtx); + prof_dump_filename(filename, 'u', prof_dump_useq); + prof_dump_useq++; + malloc_mutex_unlock(&prof_dump_seq_mtx); + prof_dump(tsd, false, filename, false); + } +} + +static void +prof_bt_hash(const void *key, size_t r_hash[2]) +{ + prof_bt_t *bt = (prof_bt_t *)key; + + cassert(config_prof); + + hash(bt->vec, bt->len * sizeof(void *), 0x94122f33U, r_hash); +} + +static bool +prof_bt_keycomp(const void *k1, const void *k2) +{ + const prof_bt_t *bt1 = (prof_bt_t *)k1; + const prof_bt_t *bt2 = (prof_bt_t *)k2; + + cassert(config_prof); + + if (bt1->len != bt2->len) + return (false); + return (memcmp(bt1->vec, bt2->vec, bt1->len * sizeof(void *)) == 0); +} + +JEMALLOC_INLINE_C uint64_t +prof_thr_uid_alloc(void) +{ + uint64_t thr_uid; + + malloc_mutex_lock(&next_thr_uid_mtx); + thr_uid = next_thr_uid; + next_thr_uid++; + malloc_mutex_unlock(&next_thr_uid_mtx); + + return (thr_uid); +} + +static prof_tdata_t * +prof_tdata_init_impl(tsd_t *tsd, uint64_t thr_uid, uint64_t thr_discrim, + char *thread_name, bool active) +{ + prof_tdata_t *tdata; + tcache_t *tcache; + + cassert(config_prof); + + /* Initialize an empty cache for this thread. */ + tcache = tcache_get(tsd, true); + tdata = (prof_tdata_t *)iallocztm(tsd, sizeof(prof_tdata_t), false, + tcache, true, NULL); + if (tdata == NULL) + return (NULL); + + tdata->lock = prof_tdata_mutex_choose(thr_uid); + tdata->thr_uid = thr_uid; + tdata->thr_discrim = thr_discrim; + tdata->thread_name = thread_name; + tdata->attached = true; + tdata->expired = false; + tdata->tctx_uid_next = 0; + + if (ckh_new(tsd, &tdata->bt2tctx, PROF_CKH_MINITEMS, + prof_bt_hash, prof_bt_keycomp)) { + idalloctm(tsd, tdata, tcache, true); + return (NULL); + } + + tdata->prng_state = (uint64_t)(uintptr_t)tdata; + prof_sample_threshold_update(tdata); + + tdata->enq = false; + tdata->enq_idump = false; + tdata->enq_gdump = false; + + tdata->dumping = false; + tdata->active = active; + + malloc_mutex_lock(&tdatas_mtx); + tdata_tree_insert(&tdatas, tdata); + malloc_mutex_unlock(&tdatas_mtx); + + return (tdata); +} + +prof_tdata_t * +prof_tdata_init(tsd_t *tsd) +{ + + return (prof_tdata_init_impl(tsd, prof_thr_uid_alloc(), 0, NULL, + prof_thread_active_init_get())); +} + +/* tdata->lock must be held. */ +static bool +prof_tdata_should_destroy(prof_tdata_t *tdata, bool even_if_attached) +{ + + if (tdata->attached && !even_if_attached) + return (false); + if (ckh_count(&tdata->bt2tctx) != 0) + return (false); + return (true); +} + +/* tdatas_mtx must be held. */ +static void +prof_tdata_destroy_locked(tsd_t *tsd, prof_tdata_t *tdata, + bool even_if_attached) +{ + tcache_t *tcache; + + assert(prof_tdata_should_destroy(tdata, even_if_attached)); + assert(tsd_prof_tdata_get(tsd) != tdata); + + tdata_tree_remove(&tdatas, tdata); + + tcache = tcache_get(tsd, false); + if (tdata->thread_name != NULL) + idalloctm(tsd, tdata->thread_name, tcache, true); + ckh_delete(tsd, &tdata->bt2tctx); + idalloctm(tsd, tdata, tcache, true); +} + +static void +prof_tdata_destroy(tsd_t *tsd, prof_tdata_t *tdata, bool even_if_attached) +{ + + malloc_mutex_lock(&tdatas_mtx); + prof_tdata_destroy_locked(tsd, tdata, even_if_attached); + malloc_mutex_unlock(&tdatas_mtx); +} + +static void +prof_tdata_detach(tsd_t *tsd, prof_tdata_t *tdata) +{ + bool destroy_tdata; + + malloc_mutex_lock(tdata->lock); + if (tdata->attached) { + destroy_tdata = prof_tdata_should_destroy(tdata, true); + /* + * Only detach if !destroy_tdata, because detaching would allow + * another thread to win the race to destroy tdata. + */ + if (!destroy_tdata) + tdata->attached = false; + tsd_prof_tdata_set(tsd, NULL); + } else + destroy_tdata = false; + malloc_mutex_unlock(tdata->lock); + if (destroy_tdata) + prof_tdata_destroy(tsd, tdata, true); +} + +prof_tdata_t * +prof_tdata_reinit(tsd_t *tsd, prof_tdata_t *tdata) +{ + uint64_t thr_uid = tdata->thr_uid; + uint64_t thr_discrim = tdata->thr_discrim + 1; + char *thread_name = (tdata->thread_name != NULL) ? + prof_thread_name_alloc(tsd, tdata->thread_name) : NULL; + bool active = tdata->active; + + prof_tdata_detach(tsd, tdata); + return (prof_tdata_init_impl(tsd, thr_uid, thr_discrim, thread_name, + active)); +} + +static bool +prof_tdata_expire(prof_tdata_t *tdata) +{ + bool destroy_tdata; + + malloc_mutex_lock(tdata->lock); + if (!tdata->expired) { + tdata->expired = true; + destroy_tdata = tdata->attached ? false : + prof_tdata_should_destroy(tdata, false); + } else + destroy_tdata = false; + malloc_mutex_unlock(tdata->lock); + + return (destroy_tdata); +} + +static prof_tdata_t * +prof_tdata_reset_iter(prof_tdata_tree_t *tdatas, prof_tdata_t *tdata, void *arg) +{ + + return (prof_tdata_expire(tdata) ? tdata : NULL); +} + +void +prof_reset(tsd_t *tsd, size_t lg_sample) +{ + prof_tdata_t *next; + + assert(lg_sample < (sizeof(uint64_t) << 3)); + + malloc_mutex_lock(&prof_dump_mtx); + malloc_mutex_lock(&tdatas_mtx); + + lg_prof_sample = lg_sample; + + next = NULL; + do { + prof_tdata_t *to_destroy = tdata_tree_iter(&tdatas, next, + prof_tdata_reset_iter, NULL); + if (to_destroy != NULL) { + next = tdata_tree_next(&tdatas, to_destroy); + prof_tdata_destroy_locked(tsd, to_destroy, false); + } else + next = NULL; + } while (next != NULL); + + malloc_mutex_unlock(&tdatas_mtx); + malloc_mutex_unlock(&prof_dump_mtx); +} + +void +prof_tdata_cleanup(tsd_t *tsd) +{ + prof_tdata_t *tdata; + + if (!config_prof) + return; + + tdata = tsd_prof_tdata_get(tsd); + if (tdata != NULL) + prof_tdata_detach(tsd, tdata); +} + +bool +prof_active_get(void) +{ + bool prof_active_current; + + malloc_mutex_lock(&prof_active_mtx); + prof_active_current = prof_active; + malloc_mutex_unlock(&prof_active_mtx); + return (prof_active_current); +} + +bool +prof_active_set(bool active) +{ + bool prof_active_old; + + malloc_mutex_lock(&prof_active_mtx); + prof_active_old = prof_active; + prof_active = active; + malloc_mutex_unlock(&prof_active_mtx); + return (prof_active_old); +} + +const char * +prof_thread_name_get(void) +{ + tsd_t *tsd; + prof_tdata_t *tdata; + + tsd = tsd_fetch(); + tdata = prof_tdata_get(tsd, true); + if (tdata == NULL) + return (""); + return (tdata->thread_name != NULL ? tdata->thread_name : ""); +} + +static char * +prof_thread_name_alloc(tsd_t *tsd, const char *thread_name) +{ + char *ret; + size_t size; + + if (thread_name == NULL) + return (NULL); + + size = strlen(thread_name) + 1; + if (size == 1) + return (""); + + ret = iallocztm(tsd, size, false, tcache_get(tsd, true), true, NULL); + if (ret == NULL) + return (NULL); + memcpy(ret, thread_name, size); + return (ret); +} + +int +prof_thread_name_set(tsd_t *tsd, const char *thread_name) +{ + prof_tdata_t *tdata; + unsigned i; + char *s; + + tdata = prof_tdata_get(tsd, true); + if (tdata == NULL) + return (EAGAIN); + + /* Validate input. */ + if (thread_name == NULL) + return (EFAULT); + for (i = 0; thread_name[i] != '\0'; i++) { + char c = thread_name[i]; + if (!isgraph(c) && !isblank(c)) + return (EFAULT); + } + + s = prof_thread_name_alloc(tsd, thread_name); + if (s == NULL) + return (EAGAIN); + + if (tdata->thread_name != NULL) { + idalloctm(tsd, tdata->thread_name, tcache_get(tsd, false), + true); + tdata->thread_name = NULL; + } + if (strlen(s) > 0) + tdata->thread_name = s; + return (0); +} + +bool +prof_thread_active_get(void) +{ + tsd_t *tsd; + prof_tdata_t *tdata; + + tsd = tsd_fetch(); + tdata = prof_tdata_get(tsd, true); + if (tdata == NULL) + return (false); + return (tdata->active); +} + +bool +prof_thread_active_set(bool active) +{ + tsd_t *tsd; + prof_tdata_t *tdata; + + tsd = tsd_fetch(); + tdata = prof_tdata_get(tsd, true); + if (tdata == NULL) + return (true); + tdata->active = active; + return (false); +} + +bool +prof_thread_active_init_get(void) +{ + bool active_init; + + malloc_mutex_lock(&prof_thread_active_init_mtx); + active_init = prof_thread_active_init; + malloc_mutex_unlock(&prof_thread_active_init_mtx); + return (active_init); +} + +bool +prof_thread_active_init_set(bool active_init) +{ + bool active_init_old; + + malloc_mutex_lock(&prof_thread_active_init_mtx); + active_init_old = prof_thread_active_init; + prof_thread_active_init = active_init; + malloc_mutex_unlock(&prof_thread_active_init_mtx); + return (active_init_old); +} + +bool +prof_gdump_get(void) +{ + bool prof_gdump_current; + + malloc_mutex_lock(&prof_gdump_mtx); + prof_gdump_current = prof_gdump_val; + malloc_mutex_unlock(&prof_gdump_mtx); + return (prof_gdump_current); +} + +bool +prof_gdump_set(bool gdump) +{ + bool prof_gdump_old; + + malloc_mutex_lock(&prof_gdump_mtx); + prof_gdump_old = prof_gdump_val; + prof_gdump_val = gdump; + malloc_mutex_unlock(&prof_gdump_mtx); + return (prof_gdump_old); +} + +void +prof_boot0(void) +{ + + cassert(config_prof); + + memcpy(opt_prof_prefix, PROF_PREFIX_DEFAULT, + sizeof(PROF_PREFIX_DEFAULT)); +} + +void +prof_boot1(void) +{ + + cassert(config_prof); + + /* + * opt_prof must be in its final state before any arenas are + * initialized, so this function must be executed early. + */ + + if (opt_prof_leak && !opt_prof) { + /* + * Enable opt_prof, but in such a way that profiles are never + * automatically dumped. + */ + opt_prof = true; + opt_prof_gdump = false; + } else if (opt_prof) { + if (opt_lg_prof_interval >= 0) { + prof_interval = (((uint64_t)1U) << + opt_lg_prof_interval); + } + } +} + +bool +prof_boot2(void) +{ + + cassert(config_prof); + + if (opt_prof) { + tsd_t *tsd; + unsigned i; + + lg_prof_sample = opt_lg_prof_sample; + + prof_active = opt_prof_active; + if (malloc_mutex_init(&prof_active_mtx)) + return (true); + + prof_gdump_val = opt_prof_gdump; + if (malloc_mutex_init(&prof_gdump_mtx)) + return (true); + + prof_thread_active_init = opt_prof_thread_active_init; + if (malloc_mutex_init(&prof_thread_active_init_mtx)) + return (true); + + tsd = tsd_fetch(); + if (ckh_new(tsd, &bt2gctx, PROF_CKH_MINITEMS, prof_bt_hash, + prof_bt_keycomp)) + return (true); + if (malloc_mutex_init(&bt2gctx_mtx)) + return (true); + + tdata_tree_new(&tdatas); + if (malloc_mutex_init(&tdatas_mtx)) + return (true); + + next_thr_uid = 0; + if (malloc_mutex_init(&next_thr_uid_mtx)) + return (true); + + if (malloc_mutex_init(&prof_dump_seq_mtx)) + return (true); + if (malloc_mutex_init(&prof_dump_mtx)) + return (true); + + if (opt_prof_final && opt_prof_prefix[0] != '\0' && + atexit(prof_fdump) != 0) { + malloc_write(": Error in atexit()\n"); + if (opt_abort) + abort(); + } + + gctx_locks = (malloc_mutex_t *)base_alloc(PROF_NCTX_LOCKS * + sizeof(malloc_mutex_t)); + if (gctx_locks == NULL) + return (true); + for (i = 0; i < PROF_NCTX_LOCKS; i++) { + if (malloc_mutex_init(&gctx_locks[i])) + return (true); + } + + tdata_locks = (malloc_mutex_t *)base_alloc(PROF_NTDATA_LOCKS * + sizeof(malloc_mutex_t)); + if (tdata_locks == NULL) + return (true); + for (i = 0; i < PROF_NTDATA_LOCKS; i++) { + if (malloc_mutex_init(&tdata_locks[i])) + return (true); + } + } + +#ifdef JEMALLOC_PROF_LIBGCC + /* + * Cause the backtracing machinery to allocate its internal state + * before enabling profiling. + */ + _Unwind_Backtrace(prof_unwind_init_callback, NULL); +#endif + + prof_booted = true; + + return (false); +} + +void +prof_prefork(void) +{ + + if (opt_prof) { + unsigned i; + + malloc_mutex_prefork(&tdatas_mtx); + malloc_mutex_prefork(&bt2gctx_mtx); + malloc_mutex_prefork(&next_thr_uid_mtx); + malloc_mutex_prefork(&prof_dump_seq_mtx); + for (i = 0; i < PROF_NCTX_LOCKS; i++) + malloc_mutex_prefork(&gctx_locks[i]); + for (i = 0; i < PROF_NTDATA_LOCKS; i++) + malloc_mutex_prefork(&tdata_locks[i]); + } +} + +void +prof_postfork_parent(void) +{ + + if (opt_prof) { + unsigned i; + + for (i = 0; i < PROF_NTDATA_LOCKS; i++) + malloc_mutex_postfork_parent(&tdata_locks[i]); + for (i = 0; i < PROF_NCTX_LOCKS; i++) + malloc_mutex_postfork_parent(&gctx_locks[i]); + malloc_mutex_postfork_parent(&prof_dump_seq_mtx); + malloc_mutex_postfork_parent(&next_thr_uid_mtx); + malloc_mutex_postfork_parent(&bt2gctx_mtx); + malloc_mutex_postfork_parent(&tdatas_mtx); + } +} + +void +prof_postfork_child(void) +{ + + if (opt_prof) { + unsigned i; + + for (i = 0; i < PROF_NTDATA_LOCKS; i++) + malloc_mutex_postfork_child(&tdata_locks[i]); + for (i = 0; i < PROF_NCTX_LOCKS; i++) + malloc_mutex_postfork_child(&gctx_locks[i]); + malloc_mutex_postfork_child(&prof_dump_seq_mtx); + malloc_mutex_postfork_child(&next_thr_uid_mtx); + malloc_mutex_postfork_child(&bt2gctx_mtx); + malloc_mutex_postfork_child(&tdatas_mtx); + } +} + +/******************************************************************************/ diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/quarantine.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/quarantine.c new file mode 100644 index 0000000..6c43dfc --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/quarantine.c @@ -0,0 +1,183 @@ +#define JEMALLOC_QUARANTINE_C_ +#include "jemalloc/internal/jemalloc_internal.h" + +/* + * Quarantine pointers close to NULL are used to encode state information that + * is used for cleaning up during thread shutdown. + */ +#define QUARANTINE_STATE_REINCARNATED ((quarantine_t *)(uintptr_t)1) +#define QUARANTINE_STATE_PURGATORY ((quarantine_t *)(uintptr_t)2) +#define QUARANTINE_STATE_MAX QUARANTINE_STATE_PURGATORY + +/******************************************************************************/ +/* Function prototypes for non-inline static functions. */ + +static quarantine_t *quarantine_grow(tsd_t *tsd, quarantine_t *quarantine); +static void quarantine_drain_one(tsd_t *tsd, quarantine_t *quarantine); +static void quarantine_drain(tsd_t *tsd, quarantine_t *quarantine, + size_t upper_bound); + +/******************************************************************************/ + +static quarantine_t * +quarantine_init(tsd_t *tsd, size_t lg_maxobjs) +{ + quarantine_t *quarantine; + + assert(tsd_nominal(tsd)); + + quarantine = (quarantine_t *)iallocztm(tsd, offsetof(quarantine_t, objs) + + ((ZU(1) << lg_maxobjs) * sizeof(quarantine_obj_t)), false, + tcache_get(tsd, true), true, NULL); + if (quarantine == NULL) + return (NULL); + quarantine->curbytes = 0; + quarantine->curobjs = 0; + quarantine->first = 0; + quarantine->lg_maxobjs = lg_maxobjs; + + return (quarantine); +} + +void +quarantine_alloc_hook_work(tsd_t *tsd) +{ + quarantine_t *quarantine; + + if (!tsd_nominal(tsd)) + return; + + quarantine = quarantine_init(tsd, LG_MAXOBJS_INIT); + /* + * Check again whether quarantine has been initialized, because + * quarantine_init() may have triggered recursive initialization. + */ + if (tsd_quarantine_get(tsd) == NULL) + tsd_quarantine_set(tsd, quarantine); + else + idalloctm(tsd, quarantine, tcache_get(tsd, false), true); +} + +static quarantine_t * +quarantine_grow(tsd_t *tsd, quarantine_t *quarantine) +{ + quarantine_t *ret; + + ret = quarantine_init(tsd, quarantine->lg_maxobjs + 1); + if (ret == NULL) { + quarantine_drain_one(tsd, quarantine); + return (quarantine); + } + + ret->curbytes = quarantine->curbytes; + ret->curobjs = quarantine->curobjs; + if (quarantine->first + quarantine->curobjs <= (ZU(1) << + quarantine->lg_maxobjs)) { + /* objs ring buffer data are contiguous. */ + memcpy(ret->objs, &quarantine->objs[quarantine->first], + quarantine->curobjs * sizeof(quarantine_obj_t)); + } else { + /* objs ring buffer data wrap around. */ + size_t ncopy_a = (ZU(1) << quarantine->lg_maxobjs) - + quarantine->first; + size_t ncopy_b = quarantine->curobjs - ncopy_a; + + memcpy(ret->objs, &quarantine->objs[quarantine->first], ncopy_a + * sizeof(quarantine_obj_t)); + memcpy(&ret->objs[ncopy_a], quarantine->objs, ncopy_b * + sizeof(quarantine_obj_t)); + } + idalloctm(tsd, quarantine, tcache_get(tsd, false), true); + + tsd_quarantine_set(tsd, ret); + return (ret); +} + +static void +quarantine_drain_one(tsd_t *tsd, quarantine_t *quarantine) +{ + quarantine_obj_t *obj = &quarantine->objs[quarantine->first]; + assert(obj->usize == isalloc(obj->ptr, config_prof)); + idalloctm(tsd, obj->ptr, NULL, false); + quarantine->curbytes -= obj->usize; + quarantine->curobjs--; + quarantine->first = (quarantine->first + 1) & ((ZU(1) << + quarantine->lg_maxobjs) - 1); +} + +static void +quarantine_drain(tsd_t *tsd, quarantine_t *quarantine, size_t upper_bound) +{ + + while (quarantine->curbytes > upper_bound && quarantine->curobjs > 0) + quarantine_drain_one(tsd, quarantine); +} + +void +quarantine(tsd_t *tsd, void *ptr) +{ + quarantine_t *quarantine; + size_t usize = isalloc(ptr, config_prof); + + cassert(config_fill); + assert(opt_quarantine); + + if ((quarantine = tsd_quarantine_get(tsd)) == NULL) { + idalloctm(tsd, ptr, NULL, false); + return; + } + /* + * Drain one or more objects if the quarantine size limit would be + * exceeded by appending ptr. + */ + if (quarantine->curbytes + usize > opt_quarantine) { + size_t upper_bound = (opt_quarantine >= usize) ? opt_quarantine + - usize : 0; + quarantine_drain(tsd, quarantine, upper_bound); + } + /* Grow the quarantine ring buffer if it's full. */ + if (quarantine->curobjs == (ZU(1) << quarantine->lg_maxobjs)) + quarantine = quarantine_grow(tsd, quarantine); + /* quarantine_grow() must free a slot if it fails to grow. */ + assert(quarantine->curobjs < (ZU(1) << quarantine->lg_maxobjs)); + /* Append ptr if its size doesn't exceed the quarantine size. */ + if (quarantine->curbytes + usize <= opt_quarantine) { + size_t offset = (quarantine->first + quarantine->curobjs) & + ((ZU(1) << quarantine->lg_maxobjs) - 1); + quarantine_obj_t *obj = &quarantine->objs[offset]; + obj->ptr = ptr; + obj->usize = usize; + quarantine->curbytes += usize; + quarantine->curobjs++; + if (config_fill && unlikely(opt_junk_free)) { + /* + * Only do redzone validation if Valgrind isn't in + * operation. + */ + if ((!config_valgrind || likely(!in_valgrind)) + && usize <= SMALL_MAXCLASS) + arena_quarantine_junk_small(ptr, usize); + else + memset(ptr, 0x5a, usize); + } + } else { + assert(quarantine->curbytes == 0); + idalloctm(tsd, ptr, NULL, false); + } +} + +void +quarantine_cleanup(tsd_t *tsd) +{ + quarantine_t *quarantine; + + if (!config_fill) + return; + + quarantine = tsd_quarantine_get(tsd); + if (quarantine != NULL) { + quarantine_drain(tsd, quarantine, 0); + idalloctm(tsd, quarantine, tcache_get(tsd, false), true); + tsd_quarantine_set(tsd, NULL); + } +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/rtree.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/rtree.c new file mode 100644 index 0000000..af0d97e --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/rtree.c @@ -0,0 +1,127 @@ +#define JEMALLOC_RTREE_C_ +#include "jemalloc/internal/jemalloc_internal.h" + +static unsigned +hmin(unsigned ha, unsigned hb) +{ + + return (ha < hb ? ha : hb); +} + +/* Only the most significant bits of keys passed to rtree_[gs]et() are used. */ +bool +rtree_new(rtree_t *rtree, unsigned bits, rtree_node_alloc_t *alloc, + rtree_node_dalloc_t *dalloc) +{ + unsigned bits_in_leaf, height, i; + + assert(bits > 0 && bits <= (sizeof(uintptr_t) << 3)); + + bits_in_leaf = (bits % RTREE_BITS_PER_LEVEL) == 0 ? RTREE_BITS_PER_LEVEL + : (bits % RTREE_BITS_PER_LEVEL); + if (bits > bits_in_leaf) { + height = 1 + (bits - bits_in_leaf) / RTREE_BITS_PER_LEVEL; + if ((height-1) * RTREE_BITS_PER_LEVEL + bits_in_leaf != bits) + height++; + } else + height = 1; + assert((height-1) * RTREE_BITS_PER_LEVEL + bits_in_leaf == bits); + + rtree->alloc = alloc; + rtree->dalloc = dalloc; + rtree->height = height; + + /* Root level. */ + rtree->levels[0].subtree = NULL; + rtree->levels[0].bits = (height > 1) ? RTREE_BITS_PER_LEVEL : + bits_in_leaf; + rtree->levels[0].cumbits = rtree->levels[0].bits; + /* Interior levels. */ + for (i = 1; i < height-1; i++) { + rtree->levels[i].subtree = NULL; + rtree->levels[i].bits = RTREE_BITS_PER_LEVEL; + rtree->levels[i].cumbits = rtree->levels[i-1].cumbits + + RTREE_BITS_PER_LEVEL; + } + /* Leaf level. */ + if (height > 1) { + rtree->levels[height-1].subtree = NULL; + rtree->levels[height-1].bits = bits_in_leaf; + rtree->levels[height-1].cumbits = bits; + } + + /* Compute lookup table to be used by rtree_start_level(). */ + for (i = 0; i < RTREE_HEIGHT_MAX; i++) { + rtree->start_level[i] = hmin(RTREE_HEIGHT_MAX - 1 - i, height - + 1); + } + + return (false); +} + +static void +rtree_delete_subtree(rtree_t *rtree, rtree_node_elm_t *node, unsigned level) +{ + + if (level + 1 < rtree->height) { + size_t nchildren, i; + + nchildren = ZU(1) << rtree->levels[level].bits; + for (i = 0; i < nchildren; i++) { + rtree_node_elm_t *child = node[i].child; + if (child != NULL) + rtree_delete_subtree(rtree, child, level + 1); + } + } + rtree->dalloc(node); +} + +void +rtree_delete(rtree_t *rtree) +{ + unsigned i; + + for (i = 0; i < rtree->height; i++) { + rtree_node_elm_t *subtree = rtree->levels[i].subtree; + if (subtree != NULL) + rtree_delete_subtree(rtree, subtree, i); + } +} + +static rtree_node_elm_t * +rtree_node_init(rtree_t *rtree, unsigned level, rtree_node_elm_t **elmp) +{ + rtree_node_elm_t *node; + + if (atomic_cas_p((void **)elmp, NULL, RTREE_NODE_INITIALIZING)) { + /* + * Another thread is already in the process of initializing. + * Spin-wait until initialization is complete. + */ + do { + CPU_SPINWAIT; + node = atomic_read_p((void **)elmp); + } while (node == RTREE_NODE_INITIALIZING); + } else { + node = rtree->alloc(ZU(1) << rtree->levels[level].bits); + if (node == NULL) + return (NULL); + atomic_write_p((void **)elmp, node); + } + + return (node); +} + +rtree_node_elm_t * +rtree_subtree_read_hard(rtree_t *rtree, unsigned level) +{ + + return (rtree_node_init(rtree, level, &rtree->levels[level].subtree)); +} + +rtree_node_elm_t * +rtree_child_read_hard(rtree_t *rtree, rtree_node_elm_t *elm, unsigned level) +{ + + return (rtree_node_init(rtree, level, &elm->child)); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/stats.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/stats.c new file mode 100644 index 0000000..154c3e7 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/stats.c @@ -0,0 +1,640 @@ +#define JEMALLOC_STATS_C_ +#include "jemalloc/internal/jemalloc_internal.h" + +#define CTL_GET(n, v, t) do { \ + size_t sz = sizeof(t); \ + xmallctl(n, v, &sz, NULL, 0); \ +} while (0) + +#define CTL_M2_GET(n, i, v, t) do { \ + size_t mib[6]; \ + size_t miblen = sizeof(mib) / sizeof(size_t); \ + size_t sz = sizeof(t); \ + xmallctlnametomib(n, mib, &miblen); \ + mib[2] = (i); \ + xmallctlbymib(mib, miblen, v, &sz, NULL, 0); \ +} while (0) + +#define CTL_M2_M4_GET(n, i, j, v, t) do { \ + size_t mib[6]; \ + size_t miblen = sizeof(mib) / sizeof(size_t); \ + size_t sz = sizeof(t); \ + xmallctlnametomib(n, mib, &miblen); \ + mib[2] = (i); \ + mib[4] = (j); \ + xmallctlbymib(mib, miblen, v, &sz, NULL, 0); \ +} while (0) + +/******************************************************************************/ +/* Data. */ + +bool opt_stats_print = false; + +size_t stats_cactive = 0; + +/******************************************************************************/ +/* Function prototypes for non-inline static functions. */ + +static void stats_arena_bins_print(void (*write_cb)(void *, const char *), + void *cbopaque, unsigned i); +static void stats_arena_lruns_print(void (*write_cb)(void *, const char *), + void *cbopaque, unsigned i); +static void stats_arena_hchunks_print( + void (*write_cb)(void *, const char *), void *cbopaque, unsigned i); +static void stats_arena_print(void (*write_cb)(void *, const char *), + void *cbopaque, unsigned i, bool bins, bool large, bool huge); + +/******************************************************************************/ + +static void +stats_arena_bins_print(void (*write_cb)(void *, const char *), void *cbopaque, + unsigned i) +{ + size_t page; + bool config_tcache, in_gap; + unsigned nbins, j; + + CTL_GET("arenas.page", &page, size_t); + + CTL_GET("config.tcache", &config_tcache, bool); + if (config_tcache) { + malloc_cprintf(write_cb, cbopaque, + "bins: size ind allocated nmalloc" + " ndalloc nrequests curregs curruns regs" + " pgs util nfills nflushes newruns" + " reruns\n"); + } else { + malloc_cprintf(write_cb, cbopaque, + "bins: size ind allocated nmalloc" + " ndalloc nrequests curregs curruns regs" + " pgs util newruns reruns\n"); + } + CTL_GET("arenas.nbins", &nbins, unsigned); + for (j = 0, in_gap = false; j < nbins; j++) { + uint64_t nruns; + + CTL_M2_M4_GET("stats.arenas.0.bins.0.nruns", i, j, &nruns, + uint64_t); + if (nruns == 0) + in_gap = true; + else { + size_t reg_size, run_size, curregs, availregs, milli; + size_t curruns; + uint32_t nregs; + uint64_t nmalloc, ndalloc, nrequests, nfills, nflushes; + uint64_t reruns; + char util[6]; /* "x.yyy". */ + + if (in_gap) { + malloc_cprintf(write_cb, cbopaque, + " ---\n"); + in_gap = false; + } + CTL_M2_GET("arenas.bin.0.size", j, ®_size, size_t); + CTL_M2_GET("arenas.bin.0.nregs", j, &nregs, uint32_t); + CTL_M2_GET("arenas.bin.0.run_size", j, &run_size, + size_t); + CTL_M2_M4_GET("stats.arenas.0.bins.0.nmalloc", i, j, + &nmalloc, uint64_t); + CTL_M2_M4_GET("stats.arenas.0.bins.0.ndalloc", i, j, + &ndalloc, uint64_t); + CTL_M2_M4_GET("stats.arenas.0.bins.0.curregs", i, j, + &curregs, size_t); + CTL_M2_M4_GET("stats.arenas.0.bins.0.nrequests", i, j, + &nrequests, uint64_t); + if (config_tcache) { + CTL_M2_M4_GET("stats.arenas.0.bins.0.nfills", i, + j, &nfills, uint64_t); + CTL_M2_M4_GET("stats.arenas.0.bins.0.nflushes", + i, j, &nflushes, uint64_t); + } + CTL_M2_M4_GET("stats.arenas.0.bins.0.nreruns", i, j, + &reruns, uint64_t); + CTL_M2_M4_GET("stats.arenas.0.bins.0.curruns", i, j, + &curruns, size_t); + + availregs = nregs * curruns; + milli = (availregs != 0) ? (1000 * curregs) / availregs + : 1000; + assert(milli <= 1000); + if (milli < 10) { + malloc_snprintf(util, sizeof(util), + "0.00%zu", milli); + } else if (milli < 100) { + malloc_snprintf(util, sizeof(util), "0.0%zu", + milli); + } else if (milli < 1000) { + malloc_snprintf(util, sizeof(util), "0.%zu", + milli); + } else + malloc_snprintf(util, sizeof(util), "1"); + + if (config_tcache) { + malloc_cprintf(write_cb, cbopaque, + "%20zu %3u %12zu %12"FMTu64 + " %12"FMTu64" %12"FMTu64" %12zu" + " %12zu %4u %3zu %-5s %12"FMTu64 + " %12"FMTu64" %12"FMTu64" %12"FMTu64"\n", + reg_size, j, curregs * reg_size, nmalloc, + ndalloc, nrequests, curregs, curruns, nregs, + run_size / page, util, nfills, nflushes, + nruns, reruns); + } else { + malloc_cprintf(write_cb, cbopaque, + "%20zu %3u %12zu %12"FMTu64 + " %12"FMTu64" %12"FMTu64" %12zu" + " %12zu %4u %3zu %-5s %12"FMTu64 + " %12"FMTu64"\n", + reg_size, j, curregs * reg_size, nmalloc, + ndalloc, nrequests, curregs, curruns, nregs, + run_size / page, util, nruns, reruns); + } + } + } + if (in_gap) { + malloc_cprintf(write_cb, cbopaque, + " ---\n"); + } +} + +static void +stats_arena_lruns_print(void (*write_cb)(void *, const char *), void *cbopaque, + unsigned i) +{ + unsigned nbins, nlruns, j; + bool in_gap; + + malloc_cprintf(write_cb, cbopaque, + "large: size ind allocated nmalloc ndalloc" + " nrequests curruns\n"); + CTL_GET("arenas.nbins", &nbins, unsigned); + CTL_GET("arenas.nlruns", &nlruns, unsigned); + for (j = 0, in_gap = false; j < nlruns; j++) { + uint64_t nmalloc, ndalloc, nrequests; + size_t run_size, curruns; + + CTL_M2_M4_GET("stats.arenas.0.lruns.0.nmalloc", i, j, &nmalloc, + uint64_t); + CTL_M2_M4_GET("stats.arenas.0.lruns.0.ndalloc", i, j, &ndalloc, + uint64_t); + CTL_M2_M4_GET("stats.arenas.0.lruns.0.nrequests", i, j, + &nrequests, uint64_t); + if (nrequests == 0) + in_gap = true; + else { + CTL_M2_GET("arenas.lrun.0.size", j, &run_size, size_t); + CTL_M2_M4_GET("stats.arenas.0.lruns.0.curruns", i, j, + &curruns, size_t); + if (in_gap) { + malloc_cprintf(write_cb, cbopaque, + " ---\n"); + in_gap = false; + } + malloc_cprintf(write_cb, cbopaque, + "%20zu %3u %12zu %12"FMTu64" %12"FMTu64 + " %12"FMTu64" %12zu\n", + run_size, nbins + j, curruns * run_size, nmalloc, + ndalloc, nrequests, curruns); + } + } + if (in_gap) { + malloc_cprintf(write_cb, cbopaque, + " ---\n"); + } +} + +static void +stats_arena_hchunks_print(void (*write_cb)(void *, const char *), + void *cbopaque, unsigned i) +{ + unsigned nbins, nlruns, nhchunks, j; + bool in_gap; + + malloc_cprintf(write_cb, cbopaque, + "huge: size ind allocated nmalloc ndalloc" + " nrequests curhchunks\n"); + CTL_GET("arenas.nbins", &nbins, unsigned); + CTL_GET("arenas.nlruns", &nlruns, unsigned); + CTL_GET("arenas.nhchunks", &nhchunks, unsigned); + for (j = 0, in_gap = false; j < nhchunks; j++) { + uint64_t nmalloc, ndalloc, nrequests; + size_t hchunk_size, curhchunks; + + CTL_M2_M4_GET("stats.arenas.0.hchunks.0.nmalloc", i, j, + &nmalloc, uint64_t); + CTL_M2_M4_GET("stats.arenas.0.hchunks.0.ndalloc", i, j, + &ndalloc, uint64_t); + CTL_M2_M4_GET("stats.arenas.0.hchunks.0.nrequests", i, j, + &nrequests, uint64_t); + if (nrequests == 0) + in_gap = true; + else { + CTL_M2_GET("arenas.hchunk.0.size", j, &hchunk_size, + size_t); + CTL_M2_M4_GET("stats.arenas.0.hchunks.0.curhchunks", i, + j, &curhchunks, size_t); + if (in_gap) { + malloc_cprintf(write_cb, cbopaque, + " ---\n"); + in_gap = false; + } + malloc_cprintf(write_cb, cbopaque, + "%20zu %3u %12zu %12"FMTu64" %12"FMTu64 + " %12"FMTu64" %12zu\n", + hchunk_size, nbins + nlruns + j, + curhchunks * hchunk_size, nmalloc, ndalloc, + nrequests, curhchunks); + } + } + if (in_gap) { + malloc_cprintf(write_cb, cbopaque, + " ---\n"); + } +} + +static void +stats_arena_print(void (*write_cb)(void *, const char *), void *cbopaque, + unsigned i, bool bins, bool large, bool huge) +{ + unsigned nthreads; + const char *dss; + ssize_t lg_dirty_mult; + size_t page, pactive, pdirty, mapped; + size_t metadata_mapped, metadata_allocated; + uint64_t npurge, nmadvise, purged; + size_t small_allocated; + uint64_t small_nmalloc, small_ndalloc, small_nrequests; + size_t large_allocated; + uint64_t large_nmalloc, large_ndalloc, large_nrequests; + size_t huge_allocated; + uint64_t huge_nmalloc, huge_ndalloc, huge_nrequests; + + CTL_GET("arenas.page", &page, size_t); + + CTL_M2_GET("stats.arenas.0.nthreads", i, &nthreads, unsigned); + malloc_cprintf(write_cb, cbopaque, + "assigned threads: %u\n", nthreads); + CTL_M2_GET("stats.arenas.0.dss", i, &dss, const char *); + malloc_cprintf(write_cb, cbopaque, "dss allocation precedence: %s\n", + dss); + CTL_M2_GET("stats.arenas.0.lg_dirty_mult", i, &lg_dirty_mult, ssize_t); + if (lg_dirty_mult >= 0) { + malloc_cprintf(write_cb, cbopaque, + "min active:dirty page ratio: %u:1\n", + (1U << lg_dirty_mult)); + } else { + malloc_cprintf(write_cb, cbopaque, + "min active:dirty page ratio: N/A\n"); + } + CTL_M2_GET("stats.arenas.0.pactive", i, &pactive, size_t); + CTL_M2_GET("stats.arenas.0.pdirty", i, &pdirty, size_t); + CTL_M2_GET("stats.arenas.0.npurge", i, &npurge, uint64_t); + CTL_M2_GET("stats.arenas.0.nmadvise", i, &nmadvise, uint64_t); + CTL_M2_GET("stats.arenas.0.purged", i, &purged, uint64_t); + malloc_cprintf(write_cb, cbopaque, + "dirty pages: %zu:%zu active:dirty, %"FMTu64" sweep%s, %"FMTu64 + " madvise%s, %"FMTu64" purged\n", pactive, pdirty, npurge, npurge == + 1 ? "" : "s", nmadvise, nmadvise == 1 ? "" : "s", purged); + + malloc_cprintf(write_cb, cbopaque, + " allocated nmalloc ndalloc" + " nrequests\n"); + CTL_M2_GET("stats.arenas.0.small.allocated", i, &small_allocated, + size_t); + CTL_M2_GET("stats.arenas.0.small.nmalloc", i, &small_nmalloc, uint64_t); + CTL_M2_GET("stats.arenas.0.small.ndalloc", i, &small_ndalloc, uint64_t); + CTL_M2_GET("stats.arenas.0.small.nrequests", i, &small_nrequests, + uint64_t); + malloc_cprintf(write_cb, cbopaque, + "small: %12zu %12"FMTu64" %12"FMTu64 + " %12"FMTu64"\n", + small_allocated, small_nmalloc, small_ndalloc, small_nrequests); + CTL_M2_GET("stats.arenas.0.large.allocated", i, &large_allocated, + size_t); + CTL_M2_GET("stats.arenas.0.large.nmalloc", i, &large_nmalloc, uint64_t); + CTL_M2_GET("stats.arenas.0.large.ndalloc", i, &large_ndalloc, uint64_t); + CTL_M2_GET("stats.arenas.0.large.nrequests", i, &large_nrequests, + uint64_t); + malloc_cprintf(write_cb, cbopaque, + "large: %12zu %12"FMTu64" %12"FMTu64 + " %12"FMTu64"\n", + large_allocated, large_nmalloc, large_ndalloc, large_nrequests); + CTL_M2_GET("stats.arenas.0.huge.allocated", i, &huge_allocated, size_t); + CTL_M2_GET("stats.arenas.0.huge.nmalloc", i, &huge_nmalloc, uint64_t); + CTL_M2_GET("stats.arenas.0.huge.ndalloc", i, &huge_ndalloc, uint64_t); + CTL_M2_GET("stats.arenas.0.huge.nrequests", i, &huge_nrequests, + uint64_t); + malloc_cprintf(write_cb, cbopaque, + "huge: %12zu %12"FMTu64" %12"FMTu64 + " %12"FMTu64"\n", + huge_allocated, huge_nmalloc, huge_ndalloc, huge_nrequests); + malloc_cprintf(write_cb, cbopaque, + "total: %12zu %12"FMTu64" %12"FMTu64 + " %12"FMTu64"\n", + small_allocated + large_allocated + huge_allocated, + small_nmalloc + large_nmalloc + huge_nmalloc, + small_ndalloc + large_ndalloc + huge_ndalloc, + small_nrequests + large_nrequests + huge_nrequests); + malloc_cprintf(write_cb, cbopaque, + "active: %12zu\n", pactive * page); + CTL_M2_GET("stats.arenas.0.mapped", i, &mapped, size_t); + malloc_cprintf(write_cb, cbopaque, + "mapped: %12zu\n", mapped); + CTL_M2_GET("stats.arenas.0.metadata.mapped", i, &metadata_mapped, + size_t); + CTL_M2_GET("stats.arenas.0.metadata.allocated", i, &metadata_allocated, + size_t); + malloc_cprintf(write_cb, cbopaque, + "metadata: mapped: %zu, allocated: %zu\n", + metadata_mapped, metadata_allocated); + + if (bins) + stats_arena_bins_print(write_cb, cbopaque, i); + if (large) + stats_arena_lruns_print(write_cb, cbopaque, i); + if (huge) + stats_arena_hchunks_print(write_cb, cbopaque, i); +} + +void +stats_print(void (*write_cb)(void *, const char *), void *cbopaque, + const char *opts) +{ + int err; + uint64_t epoch; + size_t u64sz; + bool general = true; + bool merged = true; + bool unmerged = true; + bool bins = true; + bool large = true; + bool huge = true; + + /* + * Refresh stats, in case mallctl() was called by the application. + * + * Check for OOM here, since refreshing the ctl cache can trigger + * allocation. In practice, none of the subsequent mallctl()-related + * calls in this function will cause OOM if this one succeeds. + * */ + epoch = 1; + u64sz = sizeof(uint64_t); + err = je_mallctl("epoch", &epoch, &u64sz, &epoch, sizeof(uint64_t)); + if (err != 0) { + if (err == EAGAIN) { + malloc_write(": Memory allocation failure in " + "mallctl(\"epoch\", ...)\n"); + return; + } + malloc_write(": Failure in mallctl(\"epoch\", " + "...)\n"); + abort(); + } + + if (opts != NULL) { + unsigned i; + + for (i = 0; opts[i] != '\0'; i++) { + switch (opts[i]) { + case 'g': + general = false; + break; + case 'm': + merged = false; + break; + case 'a': + unmerged = false; + break; + case 'b': + bins = false; + break; + case 'l': + large = false; + break; + case 'h': + huge = false; + break; + default:; + } + } + } + + malloc_cprintf(write_cb, cbopaque, + "___ Begin jemalloc statistics ___\n"); + if (general) { + const char *cpv; + bool bv; + unsigned uv; + ssize_t ssv; + size_t sv, bsz, ssz, sssz, cpsz; + + bsz = sizeof(bool); + ssz = sizeof(size_t); + sssz = sizeof(ssize_t); + cpsz = sizeof(const char *); + + CTL_GET("version", &cpv, const char *); + malloc_cprintf(write_cb, cbopaque, "Version: %s\n", cpv); + CTL_GET("config.debug", &bv, bool); + malloc_cprintf(write_cb, cbopaque, "Assertions %s\n", + bv ? "enabled" : "disabled"); + +#define OPT_WRITE_BOOL(n) \ + if (je_mallctl("opt."#n, &bv, &bsz, NULL, 0) == 0) { \ + malloc_cprintf(write_cb, cbopaque, \ + " opt."#n": %s\n", bv ? "true" : "false"); \ + } +#define OPT_WRITE_BOOL_MUTABLE(n, m) { \ + bool bv2; \ + if (je_mallctl("opt."#n, &bv, &bsz, NULL, 0) == 0 && \ + je_mallctl(#m, &bv2, &bsz, NULL, 0) == 0) { \ + malloc_cprintf(write_cb, cbopaque, \ + " opt."#n": %s ("#m": %s)\n", bv ? "true" \ + : "false", bv2 ? "true" : "false"); \ + } \ +} +#define OPT_WRITE_SIZE_T(n) \ + if (je_mallctl("opt."#n, &sv, &ssz, NULL, 0) == 0) { \ + malloc_cprintf(write_cb, cbopaque, \ + " opt."#n": %zu\n", sv); \ + } +#define OPT_WRITE_SSIZE_T(n) \ + if (je_mallctl("opt."#n, &ssv, &sssz, NULL, 0) == 0) { \ + malloc_cprintf(write_cb, cbopaque, \ + " opt."#n": %zd\n", ssv); \ + } +#define OPT_WRITE_SSIZE_T_MUTABLE(n, m) { \ + ssize_t ssv2; \ + if (je_mallctl("opt."#n, &ssv, &sssz, NULL, 0) == 0 && \ + je_mallctl(#m, &ssv2, &sssz, NULL, 0) == 0) { \ + malloc_cprintf(write_cb, cbopaque, \ + " opt."#n": %zd ("#m": %zd)\n", \ + ssv, ssv2); \ + } \ +} +#define OPT_WRITE_CHAR_P(n) \ + if (je_mallctl("opt."#n, &cpv, &cpsz, NULL, 0) == 0) { \ + malloc_cprintf(write_cb, cbopaque, \ + " opt."#n": \"%s\"\n", cpv); \ + } + + malloc_cprintf(write_cb, cbopaque, + "Run-time option settings:\n"); + OPT_WRITE_BOOL(abort) + OPT_WRITE_SIZE_T(lg_chunk) + OPT_WRITE_CHAR_P(dss) + OPT_WRITE_SIZE_T(narenas) + OPT_WRITE_SSIZE_T_MUTABLE(lg_dirty_mult, arenas.lg_dirty_mult) + OPT_WRITE_BOOL(stats_print) + OPT_WRITE_CHAR_P(junk) + OPT_WRITE_SIZE_T(quarantine) + OPT_WRITE_BOOL(redzone) + OPT_WRITE_BOOL(zero) + OPT_WRITE_BOOL(utrace) + OPT_WRITE_BOOL(valgrind) + OPT_WRITE_BOOL(xmalloc) + OPT_WRITE_BOOL(tcache) + OPT_WRITE_SSIZE_T(lg_tcache_max) + OPT_WRITE_BOOL(prof) + OPT_WRITE_CHAR_P(prof_prefix) + OPT_WRITE_BOOL_MUTABLE(prof_active, prof.active) + OPT_WRITE_BOOL_MUTABLE(prof_thread_active_init, + prof.thread_active_init) + OPT_WRITE_SSIZE_T(lg_prof_sample) + OPT_WRITE_BOOL(prof_accum) + OPT_WRITE_SSIZE_T(lg_prof_interval) + OPT_WRITE_BOOL(prof_gdump) + OPT_WRITE_BOOL(prof_final) + OPT_WRITE_BOOL(prof_leak) + +#undef OPT_WRITE_BOOL +#undef OPT_WRITE_BOOL_MUTABLE +#undef OPT_WRITE_SIZE_T +#undef OPT_WRITE_SSIZE_T +#undef OPT_WRITE_CHAR_P + + malloc_cprintf(write_cb, cbopaque, "CPUs: %u\n", ncpus); + + CTL_GET("arenas.narenas", &uv, unsigned); + malloc_cprintf(write_cb, cbopaque, "Arenas: %u\n", uv); + + malloc_cprintf(write_cb, cbopaque, "Pointer size: %zu\n", + sizeof(void *)); + + CTL_GET("arenas.quantum", &sv, size_t); + malloc_cprintf(write_cb, cbopaque, "Quantum size: %zu\n", + sv); + + CTL_GET("arenas.page", &sv, size_t); + malloc_cprintf(write_cb, cbopaque, "Page size: %zu\n", sv); + + CTL_GET("arenas.lg_dirty_mult", &ssv, ssize_t); + if (ssv >= 0) { + malloc_cprintf(write_cb, cbopaque, + "Min active:dirty page ratio per arena: %u:1\n", + (1U << ssv)); + } else { + malloc_cprintf(write_cb, cbopaque, + "Min active:dirty page ratio per arena: N/A\n"); + } + if (je_mallctl("arenas.tcache_max", &sv, &ssz, NULL, 0) == 0) { + malloc_cprintf(write_cb, cbopaque, + "Maximum thread-cached size class: %zu\n", sv); + } + if (je_mallctl("opt.prof", &bv, &bsz, NULL, 0) == 0 && bv) { + CTL_GET("prof.lg_sample", &sv, size_t); + malloc_cprintf(write_cb, cbopaque, + "Average profile sample interval: %"FMTu64 + " (2^%zu)\n", (((uint64_t)1U) << sv), sv); + + CTL_GET("opt.lg_prof_interval", &ssv, ssize_t); + if (ssv >= 0) { + malloc_cprintf(write_cb, cbopaque, + "Average profile dump interval: %"FMTu64 + " (2^%zd)\n", + (((uint64_t)1U) << ssv), ssv); + } else { + malloc_cprintf(write_cb, cbopaque, + "Average profile dump interval: N/A\n"); + } + } + CTL_GET("opt.lg_chunk", &sv, size_t); + malloc_cprintf(write_cb, cbopaque, + "Chunk size: %zu (2^%zu)\n", (ZU(1) << sv), sv); + } + + if (config_stats) { + size_t *cactive; + size_t allocated, active, metadata, resident, mapped; + + CTL_GET("stats.cactive", &cactive, size_t *); + CTL_GET("stats.allocated", &allocated, size_t); + CTL_GET("stats.active", &active, size_t); + CTL_GET("stats.metadata", &metadata, size_t); + CTL_GET("stats.resident", &resident, size_t); + CTL_GET("stats.mapped", &mapped, size_t); + malloc_cprintf(write_cb, cbopaque, + "Allocated: %zu, active: %zu, metadata: %zu," + " resident: %zu, mapped: %zu\n", + allocated, active, metadata, resident, mapped); + malloc_cprintf(write_cb, cbopaque, + "Current active ceiling: %zu\n", + atomic_read_z(cactive)); + + if (merged) { + unsigned narenas; + + CTL_GET("arenas.narenas", &narenas, unsigned); + { + VARIABLE_ARRAY(bool, initialized, narenas); + size_t isz; + unsigned i, ninitialized; + + isz = sizeof(bool) * narenas; + xmallctl("arenas.initialized", initialized, + &isz, NULL, 0); + for (i = ninitialized = 0; i < narenas; i++) { + if (initialized[i]) + ninitialized++; + } + + if (ninitialized > 1 || !unmerged) { + /* Print merged arena stats. */ + malloc_cprintf(write_cb, cbopaque, + "\nMerged arenas stats:\n"); + stats_arena_print(write_cb, cbopaque, + narenas, bins, large, huge); + } + } + } + + if (unmerged) { + unsigned narenas; + + /* Print stats for each arena. */ + + CTL_GET("arenas.narenas", &narenas, unsigned); + { + VARIABLE_ARRAY(bool, initialized, narenas); + size_t isz; + unsigned i; + + isz = sizeof(bool) * narenas; + xmallctl("arenas.initialized", initialized, + &isz, NULL, 0); + + for (i = 0; i < narenas; i++) { + if (initialized[i]) { + malloc_cprintf(write_cb, + cbopaque, + "\narenas[%u]:\n", i); + stats_arena_print(write_cb, + cbopaque, i, bins, large, + huge); + } + } + } + } + } + malloc_cprintf(write_cb, cbopaque, "--- End jemalloc statistics ---\n"); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/tcache.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/tcache.c new file mode 100644 index 0000000..fdafd0c --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/tcache.c @@ -0,0 +1,537 @@ +#define JEMALLOC_TCACHE_C_ +#include "jemalloc/internal/jemalloc_internal.h" + +/******************************************************************************/ +/* Data. */ + +bool opt_tcache = true; +ssize_t opt_lg_tcache_max = LG_TCACHE_MAXCLASS_DEFAULT; + +tcache_bin_info_t *tcache_bin_info; +static unsigned stack_nelms; /* Total stack elms per tcache. */ + +size_t nhbins; +size_t tcache_maxclass; + +tcaches_t *tcaches; + +/* Index of first element within tcaches that has never been used. */ +static unsigned tcaches_past; + +/* Head of singly linked list tracking available tcaches elements. */ +static tcaches_t *tcaches_avail; + +/******************************************************************************/ + +size_t tcache_salloc(const void *ptr) +{ + + return (arena_salloc(ptr, false)); +} + +void +tcache_event_hard(tsd_t *tsd, tcache_t *tcache) +{ + szind_t binind = tcache->next_gc_bin; + tcache_bin_t *tbin = &tcache->tbins[binind]; + tcache_bin_info_t *tbin_info = &tcache_bin_info[binind]; + + if (tbin->low_water > 0) { + /* + * Flush (ceiling) 3/4 of the objects below the low water mark. + */ + if (binind < NBINS) { + tcache_bin_flush_small(tsd, tcache, tbin, binind, + tbin->ncached - tbin->low_water + (tbin->low_water + >> 2)); + } else { + tcache_bin_flush_large(tsd, tbin, binind, tbin->ncached + - tbin->low_water + (tbin->low_water >> 2), tcache); + } + /* + * Reduce fill count by 2X. Limit lg_fill_div such that the + * fill count is always at least 1. + */ + if ((tbin_info->ncached_max >> (tbin->lg_fill_div+1)) >= 1) + tbin->lg_fill_div++; + } else if (tbin->low_water < 0) { + /* + * Increase fill count by 2X. Make sure lg_fill_div stays + * greater than 0. + */ + if (tbin->lg_fill_div > 1) + tbin->lg_fill_div--; + } + tbin->low_water = tbin->ncached; + + tcache->next_gc_bin++; + if (tcache->next_gc_bin == nhbins) + tcache->next_gc_bin = 0; + tcache->ev_cnt = 0; +} + +void * +tcache_alloc_small_hard(tsd_t *tsd, arena_t *arena, tcache_t *tcache, + tcache_bin_t *tbin, szind_t binind) +{ + void *ret; + + arena_tcache_fill_small(arena, tbin, binind, config_prof ? + tcache->prof_accumbytes : 0); + if (config_prof) + tcache->prof_accumbytes = 0; + ret = tcache_alloc_easy(tbin); + + return (ret); +} + +void +tcache_bin_flush_small(tsd_t *tsd, tcache_t *tcache, tcache_bin_t *tbin, + szind_t binind, unsigned rem) +{ + arena_t *arena; + void *ptr; + unsigned i, nflush, ndeferred; + bool merged_stats = false; + + assert(binind < NBINS); + assert(rem <= tbin->ncached); + + arena = arena_choose(tsd, NULL); + assert(arena != NULL); + for (nflush = tbin->ncached - rem; nflush > 0; nflush = ndeferred) { + /* Lock the arena bin associated with the first object. */ + arena_chunk_t *chunk = (arena_chunk_t *)CHUNK_ADDR2BASE( + tbin->avail[0]); + arena_t *bin_arena = extent_node_arena_get(&chunk->node); + arena_bin_t *bin = &bin_arena->bins[binind]; + + if (config_prof && bin_arena == arena) { + if (arena_prof_accum(arena, tcache->prof_accumbytes)) + prof_idump(); + tcache->prof_accumbytes = 0; + } + + malloc_mutex_lock(&bin->lock); + if (config_stats && bin_arena == arena) { + assert(!merged_stats); + merged_stats = true; + bin->stats.nflushes++; + bin->stats.nrequests += tbin->tstats.nrequests; + tbin->tstats.nrequests = 0; + } + ndeferred = 0; + for (i = 0; i < nflush; i++) { + ptr = tbin->avail[i]; + assert(ptr != NULL); + chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr); + if (extent_node_arena_get(&chunk->node) == bin_arena) { + size_t pageind = ((uintptr_t)ptr - + (uintptr_t)chunk) >> LG_PAGE; + arena_chunk_map_bits_t *bitselm = + arena_bitselm_get(chunk, pageind); + arena_dalloc_bin_junked_locked(bin_arena, chunk, + ptr, bitselm); + } else { + /* + * This object was allocated via a different + * arena bin than the one that is currently + * locked. Stash the object, so that it can be + * handled in a future pass. + */ + tbin->avail[ndeferred] = ptr; + ndeferred++; + } + } + malloc_mutex_unlock(&bin->lock); + } + if (config_stats && !merged_stats) { + /* + * The flush loop didn't happen to flush to this thread's + * arena, so the stats didn't get merged. Manually do so now. + */ + arena_bin_t *bin = &arena->bins[binind]; + malloc_mutex_lock(&bin->lock); + bin->stats.nflushes++; + bin->stats.nrequests += tbin->tstats.nrequests; + tbin->tstats.nrequests = 0; + malloc_mutex_unlock(&bin->lock); + } + + memmove(tbin->avail, &tbin->avail[tbin->ncached - rem], + rem * sizeof(void *)); + tbin->ncached = rem; + if ((int)tbin->ncached < tbin->low_water) + tbin->low_water = tbin->ncached; +} + +void +tcache_bin_flush_large(tsd_t *tsd, tcache_bin_t *tbin, szind_t binind, + unsigned rem, tcache_t *tcache) +{ + arena_t *arena; + void *ptr; + unsigned i, nflush, ndeferred; + bool merged_stats = false; + + assert(binind < nhbins); + assert(rem <= tbin->ncached); + + arena = arena_choose(tsd, NULL); + assert(arena != NULL); + for (nflush = tbin->ncached - rem; nflush > 0; nflush = ndeferred) { + /* Lock the arena associated with the first object. */ + arena_chunk_t *chunk = (arena_chunk_t *)CHUNK_ADDR2BASE( + tbin->avail[0]); + arena_t *locked_arena = extent_node_arena_get(&chunk->node); + UNUSED bool idump; + + if (config_prof) + idump = false; + malloc_mutex_lock(&locked_arena->lock); + if ((config_prof || config_stats) && locked_arena == arena) { + if (config_prof) { + idump = arena_prof_accum_locked(arena, + tcache->prof_accumbytes); + tcache->prof_accumbytes = 0; + } + if (config_stats) { + merged_stats = true; + arena->stats.nrequests_large += + tbin->tstats.nrequests; + arena->stats.lstats[binind - NBINS].nrequests += + tbin->tstats.nrequests; + tbin->tstats.nrequests = 0; + } + } + ndeferred = 0; + for (i = 0; i < nflush; i++) { + ptr = tbin->avail[i]; + assert(ptr != NULL); + chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr); + if (extent_node_arena_get(&chunk->node) == + locked_arena) { + arena_dalloc_large_junked_locked(locked_arena, + chunk, ptr); + } else { + /* + * This object was allocated via a different + * arena than the one that is currently locked. + * Stash the object, so that it can be handled + * in a future pass. + */ + tbin->avail[ndeferred] = ptr; + ndeferred++; + } + } + malloc_mutex_unlock(&locked_arena->lock); + if (config_prof && idump) + prof_idump(); + } + if (config_stats && !merged_stats) { + /* + * The flush loop didn't happen to flush to this thread's + * arena, so the stats didn't get merged. Manually do so now. + */ + malloc_mutex_lock(&arena->lock); + arena->stats.nrequests_large += tbin->tstats.nrequests; + arena->stats.lstats[binind - NBINS].nrequests += + tbin->tstats.nrequests; + tbin->tstats.nrequests = 0; + malloc_mutex_unlock(&arena->lock); + } + + memmove(tbin->avail, &tbin->avail[tbin->ncached - rem], + rem * sizeof(void *)); + tbin->ncached = rem; + if ((int)tbin->ncached < tbin->low_water) + tbin->low_water = tbin->ncached; +} + +void +tcache_arena_associate(tcache_t *tcache, arena_t *arena) +{ + + if (config_stats) { + /* Link into list of extant tcaches. */ + malloc_mutex_lock(&arena->lock); + ql_elm_new(tcache, link); + ql_tail_insert(&arena->tcache_ql, tcache, link); + malloc_mutex_unlock(&arena->lock); + } +} + +void +tcache_arena_reassociate(tcache_t *tcache, arena_t *oldarena, arena_t *newarena) +{ + + tcache_arena_dissociate(tcache, oldarena); + tcache_arena_associate(tcache, newarena); +} + +void +tcache_arena_dissociate(tcache_t *tcache, arena_t *arena) +{ + + if (config_stats) { + /* Unlink from list of extant tcaches. */ + malloc_mutex_lock(&arena->lock); + if (config_debug) { + bool in_ql = false; + tcache_t *iter; + ql_foreach(iter, &arena->tcache_ql, link) { + if (iter == tcache) { + in_ql = true; + break; + } + } + assert(in_ql); + } + ql_remove(&arena->tcache_ql, tcache, link); + tcache_stats_merge(tcache, arena); + malloc_mutex_unlock(&arena->lock); + } +} + +tcache_t * +tcache_get_hard(tsd_t *tsd) +{ + arena_t *arena; + + if (!tcache_enabled_get()) { + if (tsd_nominal(tsd)) + tcache_enabled_set(false); /* Memoize. */ + return (NULL); + } + arena = arena_choose(tsd, NULL); + if (unlikely(arena == NULL)) + return (NULL); + return (tcache_create(tsd, arena)); +} + +tcache_t * +tcache_create(tsd_t *tsd, arena_t *arena) +{ + tcache_t *tcache; + size_t size, stack_offset; + unsigned i; + + size = offsetof(tcache_t, tbins) + (sizeof(tcache_bin_t) * nhbins); + /* Naturally align the pointer stacks. */ + size = PTR_CEILING(size); + stack_offset = size; + size += stack_nelms * sizeof(void *); + /* Avoid false cacheline sharing. */ + size = sa2u(size, CACHELINE); + + tcache = ipallocztm(tsd, size, CACHELINE, true, false, true, a0get()); + if (tcache == NULL) + return (NULL); + + tcache_arena_associate(tcache, arena); + + assert((TCACHE_NSLOTS_SMALL_MAX & 1U) == 0); + for (i = 0; i < nhbins; i++) { + tcache->tbins[i].lg_fill_div = 1; + tcache->tbins[i].avail = (void **)((uintptr_t)tcache + + (uintptr_t)stack_offset); + stack_offset += tcache_bin_info[i].ncached_max * sizeof(void *); + } + + return (tcache); +} + +static void +tcache_destroy(tsd_t *tsd, tcache_t *tcache) +{ + arena_t *arena; + unsigned i; + + arena = arena_choose(tsd, NULL); + tcache_arena_dissociate(tcache, arena); + + for (i = 0; i < NBINS; i++) { + tcache_bin_t *tbin = &tcache->tbins[i]; + tcache_bin_flush_small(tsd, tcache, tbin, i, 0); + + if (config_stats && tbin->tstats.nrequests != 0) { + arena_bin_t *bin = &arena->bins[i]; + malloc_mutex_lock(&bin->lock); + bin->stats.nrequests += tbin->tstats.nrequests; + malloc_mutex_unlock(&bin->lock); + } + } + + for (; i < nhbins; i++) { + tcache_bin_t *tbin = &tcache->tbins[i]; + tcache_bin_flush_large(tsd, tbin, i, 0, tcache); + + if (config_stats && tbin->tstats.nrequests != 0) { + malloc_mutex_lock(&arena->lock); + arena->stats.nrequests_large += tbin->tstats.nrequests; + arena->stats.lstats[i - NBINS].nrequests += + tbin->tstats.nrequests; + malloc_mutex_unlock(&arena->lock); + } + } + + if (config_prof && tcache->prof_accumbytes > 0 && + arena_prof_accum(arena, tcache->prof_accumbytes)) + prof_idump(); + + idalloctm(tsd, tcache, false, true); +} + +void +tcache_cleanup(tsd_t *tsd) +{ + tcache_t *tcache; + + if (!config_tcache) + return; + + if ((tcache = tsd_tcache_get(tsd)) != NULL) { + tcache_destroy(tsd, tcache); + tsd_tcache_set(tsd, NULL); + } +} + +void +tcache_enabled_cleanup(tsd_t *tsd) +{ + + /* Do nothing. */ +} + +/* Caller must own arena->lock. */ +void +tcache_stats_merge(tcache_t *tcache, arena_t *arena) +{ + unsigned i; + + cassert(config_stats); + + /* Merge and reset tcache stats. */ + for (i = 0; i < NBINS; i++) { + arena_bin_t *bin = &arena->bins[i]; + tcache_bin_t *tbin = &tcache->tbins[i]; + malloc_mutex_lock(&bin->lock); + bin->stats.nrequests += tbin->tstats.nrequests; + malloc_mutex_unlock(&bin->lock); + tbin->tstats.nrequests = 0; + } + + for (; i < nhbins; i++) { + malloc_large_stats_t *lstats = &arena->stats.lstats[i - NBINS]; + tcache_bin_t *tbin = &tcache->tbins[i]; + arena->stats.nrequests_large += tbin->tstats.nrequests; + lstats->nrequests += tbin->tstats.nrequests; + tbin->tstats.nrequests = 0; + } +} + +bool +tcaches_create(tsd_t *tsd, unsigned *r_ind) +{ + tcache_t *tcache; + tcaches_t *elm; + + if (tcaches == NULL) { + tcaches = base_alloc(sizeof(tcache_t *) * + (MALLOCX_TCACHE_MAX+1)); + if (tcaches == NULL) + return (true); + } + + if (tcaches_avail == NULL && tcaches_past > MALLOCX_TCACHE_MAX) + return (true); + tcache = tcache_create(tsd, a0get()); + if (tcache == NULL) + return (true); + + if (tcaches_avail != NULL) { + elm = tcaches_avail; + tcaches_avail = tcaches_avail->next; + elm->tcache = tcache; + *r_ind = elm - tcaches; + } else { + elm = &tcaches[tcaches_past]; + elm->tcache = tcache; + *r_ind = tcaches_past; + tcaches_past++; + } + + return (false); +} + +static void +tcaches_elm_flush(tsd_t *tsd, tcaches_t *elm) +{ + + if (elm->tcache == NULL) + return; + tcache_destroy(tsd, elm->tcache); + elm->tcache = NULL; +} + +void +tcaches_flush(tsd_t *tsd, unsigned ind) +{ + + tcaches_elm_flush(tsd, &tcaches[ind]); +} + +void +tcaches_destroy(tsd_t *tsd, unsigned ind) +{ + tcaches_t *elm = &tcaches[ind]; + tcaches_elm_flush(tsd, elm); + elm->next = tcaches_avail; + tcaches_avail = elm; +} + +bool +tcache_boot(void) +{ + unsigned i; + + /* + * If necessary, clamp opt_lg_tcache_max, now that large_maxclass is + * known. + */ + if (opt_lg_tcache_max < 0 || (1U << opt_lg_tcache_max) < SMALL_MAXCLASS) + tcache_maxclass = SMALL_MAXCLASS; + else if ((1U << opt_lg_tcache_max) > large_maxclass) + tcache_maxclass = large_maxclass; + else + tcache_maxclass = (1U << opt_lg_tcache_max); + + nhbins = size2index(tcache_maxclass) + 1; + + /* Initialize tcache_bin_info. */ + tcache_bin_info = (tcache_bin_info_t *)base_alloc(nhbins * + sizeof(tcache_bin_info_t)); + if (tcache_bin_info == NULL) + return (true); + stack_nelms = 0; + for (i = 0; i < NBINS; i++) { + if ((arena_bin_info[i].nregs << 1) <= TCACHE_NSLOTS_SMALL_MIN) { + tcache_bin_info[i].ncached_max = + TCACHE_NSLOTS_SMALL_MIN; + } else if ((arena_bin_info[i].nregs << 1) <= + TCACHE_NSLOTS_SMALL_MAX) { + tcache_bin_info[i].ncached_max = + (arena_bin_info[i].nregs << 1); + } else { + tcache_bin_info[i].ncached_max = + TCACHE_NSLOTS_SMALL_MAX; + } + stack_nelms += tcache_bin_info[i].ncached_max; + } + for (; i < nhbins; i++) { + tcache_bin_info[i].ncached_max = TCACHE_NSLOTS_LARGE; + stack_nelms += tcache_bin_info[i].ncached_max; + } + + return (false); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/tsd.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/tsd.c new file mode 100644 index 0000000..9ffe9af --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/tsd.c @@ -0,0 +1,193 @@ +#define JEMALLOC_TSD_C_ +#include "jemalloc/internal/jemalloc_internal.h" + +/******************************************************************************/ +/* Data. */ + +static unsigned ncleanups; +static malloc_tsd_cleanup_t cleanups[MALLOC_TSD_CLEANUPS_MAX]; + +malloc_tsd_data(, , tsd_t, TSD_INITIALIZER) + +/******************************************************************************/ + +void * +malloc_tsd_malloc(size_t size) +{ + + return (a0malloc(CACHELINE_CEILING(size))); +} + +void +malloc_tsd_dalloc(void *wrapper) +{ + + a0dalloc(wrapper); +} + +void +malloc_tsd_no_cleanup(void *arg) +{ + + not_reached(); +} + +#if defined(JEMALLOC_MALLOC_THREAD_CLEANUP) || defined(_WIN32) +#ifndef _WIN32 +JEMALLOC_EXPORT +#endif +void +_malloc_thread_cleanup(void) +{ + bool pending[MALLOC_TSD_CLEANUPS_MAX], again; + unsigned i; + + for (i = 0; i < ncleanups; i++) + pending[i] = true; + + do { + again = false; + for (i = 0; i < ncleanups; i++) { + if (pending[i]) { + pending[i] = cleanups[i](); + if (pending[i]) + again = true; + } + } + } while (again); +} +#endif + +void +malloc_tsd_cleanup_register(bool (*f)(void)) +{ + + assert(ncleanups < MALLOC_TSD_CLEANUPS_MAX); + cleanups[ncleanups] = f; + ncleanups++; +} + +void +tsd_cleanup(void *arg) +{ + tsd_t *tsd = (tsd_t *)arg; + + switch (tsd->state) { + case tsd_state_uninitialized: + /* Do nothing. */ + break; + case tsd_state_nominal: +#define O(n, t) \ + n##_cleanup(tsd); +MALLOC_TSD +#undef O + tsd->state = tsd_state_purgatory; + tsd_set(tsd); + break; + case tsd_state_purgatory: + /* + * The previous time this destructor was called, we set the + * state to tsd_state_purgatory so that other destructors + * wouldn't cause re-creation of the tsd. This time, do + * nothing, and do not request another callback. + */ + break; + case tsd_state_reincarnated: + /* + * Another destructor deallocated memory after this destructor + * was called. Reset state to tsd_state_purgatory and request + * another callback. + */ + tsd->state = tsd_state_purgatory; + tsd_set(tsd); + break; + default: + not_reached(); + } +} + +bool +malloc_tsd_boot0(void) +{ + + ncleanups = 0; + if (tsd_boot0()) + return (true); + *tsd_arenas_cache_bypassp_get(tsd_fetch()) = true; + return (false); +} + +void +malloc_tsd_boot1(void) +{ + + tsd_boot1(); + *tsd_arenas_cache_bypassp_get(tsd_fetch()) = false; +} + +#ifdef _WIN32 +static BOOL WINAPI +_tls_callback(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + + switch (fdwReason) { +#ifdef JEMALLOC_LAZY_LOCK + case DLL_THREAD_ATTACH: + isthreaded = true; + break; +#endif + case DLL_THREAD_DETACH: + _malloc_thread_cleanup(); + break; + default: + break; + } + return (true); +} + +#ifdef _MSC_VER +# ifdef _M_IX86 +# pragma comment(linker, "/INCLUDE:__tls_used") +# else +# pragma comment(linker, "/INCLUDE:_tls_used") +# endif +# pragma section(".CRT$XLY",long,read) +#endif +JEMALLOC_SECTION(".CRT$XLY") JEMALLOC_ATTR(used) +static BOOL (WINAPI *const tls_callback)(HINSTANCE hinstDLL, + DWORD fdwReason, LPVOID lpvReserved) = _tls_callback; +#endif + +#if (!defined(JEMALLOC_MALLOC_THREAD_CLEANUP) && !defined(JEMALLOC_TLS) && \ + !defined(_WIN32)) +void * +tsd_init_check_recursion(tsd_init_head_t *head, tsd_init_block_t *block) +{ + pthread_t self = pthread_self(); + tsd_init_block_t *iter; + + /* Check whether this thread has already inserted into the list. */ + malloc_mutex_lock(&head->lock); + ql_foreach(iter, &head->blocks, link) { + if (iter->thread == self) { + malloc_mutex_unlock(&head->lock); + return (iter->data); + } + } + /* Insert block into list. */ + ql_elm_new(block, link); + block->thread = self; + ql_tail_insert(&head->blocks, block, link); + malloc_mutex_unlock(&head->lock); + return (NULL); +} + +void +tsd_init_finish(tsd_init_head_t *head, tsd_init_block_t *block) +{ + + malloc_mutex_lock(&head->lock); + ql_remove(&head->blocks, block, link); + malloc_mutex_unlock(&head->lock); +} +#endif diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/util.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/util.c new file mode 100644 index 0000000..4cb0d6c --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/util.c @@ -0,0 +1,650 @@ +#define assert(e) do { \ + if (config_debug && !(e)) { \ + malloc_write(": Failed assertion\n"); \ + abort(); \ + } \ +} while (0) + +#define not_reached() do { \ + if (config_debug) { \ + malloc_write(": Unreachable code reached\n"); \ + abort(); \ + } \ +} while (0) + +#define not_implemented() do { \ + if (config_debug) { \ + malloc_write(": Not implemented\n"); \ + abort(); \ + } \ +} while (0) + +#define JEMALLOC_UTIL_C_ +#include "jemalloc/internal/jemalloc_internal.h" + +/******************************************************************************/ +/* Function prototypes for non-inline static functions. */ + +static void wrtmessage(void *cbopaque, const char *s); +#define U2S_BUFSIZE ((1U << (LG_SIZEOF_INTMAX_T + 3)) + 1) +static char *u2s(uintmax_t x, unsigned base, bool uppercase, char *s, + size_t *slen_p); +#define D2S_BUFSIZE (1 + U2S_BUFSIZE) +static char *d2s(intmax_t x, char sign, char *s, size_t *slen_p); +#define O2S_BUFSIZE (1 + U2S_BUFSIZE) +static char *o2s(uintmax_t x, bool alt_form, char *s, size_t *slen_p); +#define X2S_BUFSIZE (2 + U2S_BUFSIZE) +static char *x2s(uintmax_t x, bool alt_form, bool uppercase, char *s, + size_t *slen_p); + +/******************************************************************************/ + +/* malloc_message() setup. */ +static void +wrtmessage(void *cbopaque, const char *s) +{ + +#ifdef SYS_write + /* + * Use syscall(2) rather than write(2) when possible in order to avoid + * the possibility of memory allocation within libc. This is necessary + * on FreeBSD; most operating systems do not have this problem though. + */ + UNUSED int result = syscall(SYS_write, STDERR_FILENO, s, strlen(s)); +#else + UNUSED int result = write(STDERR_FILENO, s, strlen(s)); +#endif +} + +JEMALLOC_EXPORT void (*je_malloc_message)(void *, const char *s); + +/* + * Wrapper around malloc_message() that avoids the need for + * je_malloc_message(...) throughout the code. + */ +void +malloc_write(const char *s) +{ + + if (je_malloc_message != NULL) + je_malloc_message(NULL, s); + else + wrtmessage(NULL, s); +} + +/* + * glibc provides a non-standard strerror_r() when _GNU_SOURCE is defined, so + * provide a wrapper. + */ +int +buferror(int err, char *buf, size_t buflen) +{ + +#ifdef _WIN32 + FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, + (LPSTR)buf, buflen, NULL); + return (0); +#elif defined(__GLIBC__) && defined(_GNU_SOURCE) + char *b = strerror_r(err, buf, buflen); + if (b != buf) { + strncpy(buf, b, buflen); + buf[buflen-1] = '\0'; + } + return (0); +#else + return (strerror_r(err, buf, buflen)); +#endif +} + +uintmax_t +malloc_strtoumax(const char *restrict nptr, char **restrict endptr, int base) +{ + uintmax_t ret, digit; + unsigned b; + bool neg; + const char *p, *ns; + + p = nptr; + if (base < 0 || base == 1 || base > 36) { + ns = p; + set_errno(EINVAL); + ret = UINTMAX_MAX; + goto label_return; + } + b = base; + + /* Swallow leading whitespace and get sign, if any. */ + neg = false; + while (true) { + switch (*p) { + case '\t': case '\n': case '\v': case '\f': case '\r': case ' ': + p++; + break; + case '-': + neg = true; + /* Fall through. */ + case '+': + p++; + /* Fall through. */ + default: + goto label_prefix; + } + } + + /* Get prefix, if any. */ + label_prefix: + /* + * Note where the first non-whitespace/sign character is so that it is + * possible to tell whether any digits are consumed (e.g., " 0" vs. + * " -x"). + */ + ns = p; + if (*p == '0') { + switch (p[1]) { + case '0': case '1': case '2': case '3': case '4': case '5': + case '6': case '7': + if (b == 0) + b = 8; + if (b == 8) + p++; + break; + case 'X': case 'x': + switch (p[2]) { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + case 'A': case 'B': case 'C': case 'D': case 'E': + case 'F': + case 'a': case 'b': case 'c': case 'd': case 'e': + case 'f': + if (b == 0) + b = 16; + if (b == 16) + p += 2; + break; + default: + break; + } + break; + default: + p++; + ret = 0; + goto label_return; + } + } + if (b == 0) + b = 10; + + /* Convert. */ + ret = 0; + while ((*p >= '0' && *p <= '9' && (digit = *p - '0') < b) + || (*p >= 'A' && *p <= 'Z' && (digit = 10 + *p - 'A') < b) + || (*p >= 'a' && *p <= 'z' && (digit = 10 + *p - 'a') < b)) { + uintmax_t pret = ret; + ret *= b; + ret += digit; + if (ret < pret) { + /* Overflow. */ + set_errno(ERANGE); + ret = UINTMAX_MAX; + goto label_return; + } + p++; + } + if (neg) + ret = -ret; + + if (p == ns) { + /* No conversion performed. */ + set_errno(EINVAL); + ret = UINTMAX_MAX; + goto label_return; + } + +label_return: + if (endptr != NULL) { + if (p == ns) { + /* No characters were converted. */ + *endptr = (char *)nptr; + } else + *endptr = (char *)p; + } + return (ret); +} + +static char * +u2s(uintmax_t x, unsigned base, bool uppercase, char *s, size_t *slen_p) +{ + unsigned i; + + i = U2S_BUFSIZE - 1; + s[i] = '\0'; + switch (base) { + case 10: + do { + i--; + s[i] = "0123456789"[x % (uint64_t)10]; + x /= (uint64_t)10; + } while (x > 0); + break; + case 16: { + const char *digits = (uppercase) + ? "0123456789ABCDEF" + : "0123456789abcdef"; + + do { + i--; + s[i] = digits[x & 0xf]; + x >>= 4; + } while (x > 0); + break; + } default: { + const char *digits = (uppercase) + ? "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + : "0123456789abcdefghijklmnopqrstuvwxyz"; + + assert(base >= 2 && base <= 36); + do { + i--; + s[i] = digits[x % (uint64_t)base]; + x /= (uint64_t)base; + } while (x > 0); + }} + + *slen_p = U2S_BUFSIZE - 1 - i; + return (&s[i]); +} + +static char * +d2s(intmax_t x, char sign, char *s, size_t *slen_p) +{ + bool neg; + + if ((neg = (x < 0))) + x = -x; + s = u2s(x, 10, false, s, slen_p); + if (neg) + sign = '-'; + switch (sign) { + case '-': + if (!neg) + break; + /* Fall through. */ + case ' ': + case '+': + s--; + (*slen_p)++; + *s = sign; + break; + default: not_reached(); + } + return (s); +} + +static char * +o2s(uintmax_t x, bool alt_form, char *s, size_t *slen_p) +{ + + s = u2s(x, 8, false, s, slen_p); + if (alt_form && *s != '0') { + s--; + (*slen_p)++; + *s = '0'; + } + return (s); +} + +static char * +x2s(uintmax_t x, bool alt_form, bool uppercase, char *s, size_t *slen_p) +{ + + s = u2s(x, 16, uppercase, s, slen_p); + if (alt_form) { + s -= 2; + (*slen_p) += 2; + memcpy(s, uppercase ? "0X" : "0x", 2); + } + return (s); +} + +int +malloc_vsnprintf(char *str, size_t size, const char *format, va_list ap) +{ + int ret; + size_t i; + const char *f; + +#define APPEND_C(c) do { \ + if (i < size) \ + str[i] = (c); \ + i++; \ +} while (0) +#define APPEND_S(s, slen) do { \ + if (i < size) { \ + size_t cpylen = (slen <= size - i) ? slen : size - i; \ + memcpy(&str[i], s, cpylen); \ + } \ + i += slen; \ +} while (0) +#define APPEND_PADDED_S(s, slen, width, left_justify) do { \ + /* Left padding. */ \ + size_t pad_len = (width == -1) ? 0 : ((slen < (size_t)width) ? \ + (size_t)width - slen : 0); \ + if (!left_justify && pad_len != 0) { \ + size_t j; \ + for (j = 0; j < pad_len; j++) \ + APPEND_C(' '); \ + } \ + /* Value. */ \ + APPEND_S(s, slen); \ + /* Right padding. */ \ + if (left_justify && pad_len != 0) { \ + size_t j; \ + for (j = 0; j < pad_len; j++) \ + APPEND_C(' '); \ + } \ +} while (0) +#define GET_ARG_NUMERIC(val, len) do { \ + switch (len) { \ + case '?': \ + val = va_arg(ap, int); \ + break; \ + case '?' | 0x80: \ + val = va_arg(ap, unsigned int); \ + break; \ + case 'l': \ + val = va_arg(ap, long); \ + break; \ + case 'l' | 0x80: \ + val = va_arg(ap, unsigned long); \ + break; \ + case 'q': \ + val = va_arg(ap, long long); \ + break; \ + case 'q' | 0x80: \ + val = va_arg(ap, unsigned long long); \ + break; \ + case 'j': \ + val = va_arg(ap, intmax_t); \ + break; \ + case 'j' | 0x80: \ + val = va_arg(ap, uintmax_t); \ + break; \ + case 't': \ + val = va_arg(ap, ptrdiff_t); \ + break; \ + case 'z': \ + val = va_arg(ap, ssize_t); \ + break; \ + case 'z' | 0x80: \ + val = va_arg(ap, size_t); \ + break; \ + case 'p': /* Synthetic; used for %p. */ \ + val = va_arg(ap, uintptr_t); \ + break; \ + default: \ + not_reached(); \ + val = 0; \ + } \ +} while (0) + + i = 0; + f = format; + while (true) { + switch (*f) { + case '\0': goto label_out; + case '%': { + bool alt_form = false; + bool left_justify = false; + bool plus_space = false; + bool plus_plus = false; + int prec = -1; + int width = -1; + unsigned char len = '?'; + + f++; + /* Flags. */ + while (true) { + switch (*f) { + case '#': + assert(!alt_form); + alt_form = true; + break; + case '-': + assert(!left_justify); + left_justify = true; + break; + case ' ': + assert(!plus_space); + plus_space = true; + break; + case '+': + assert(!plus_plus); + plus_plus = true; + break; + default: goto label_width; + } + f++; + } + /* Width. */ + label_width: + switch (*f) { + case '*': + width = va_arg(ap, int); + f++; + if (width < 0) { + left_justify = true; + width = -width; + } + break; + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': { + uintmax_t uwidth; + set_errno(0); + uwidth = malloc_strtoumax(f, (char **)&f, 10); + assert(uwidth != UINTMAX_MAX || get_errno() != + ERANGE); + width = (int)uwidth; + break; + } default: + break; + } + /* Width/precision separator. */ + if (*f == '.') + f++; + else + goto label_length; + /* Precision. */ + switch (*f) { + case '*': + prec = va_arg(ap, int); + f++; + break; + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': { + uintmax_t uprec; + set_errno(0); + uprec = malloc_strtoumax(f, (char **)&f, 10); + assert(uprec != UINTMAX_MAX || get_errno() != + ERANGE); + prec = (int)uprec; + break; + } + default: break; + } + /* Length. */ + label_length: + switch (*f) { + case 'l': + f++; + if (*f == 'l') { + len = 'q'; + f++; + } else + len = 'l'; + break; + case 'q': case 'j': case 't': case 'z': + len = *f; + f++; + break; + default: break; + } + /* Conversion specifier. */ + switch (*f) { + char *s; + size_t slen; + case '%': + /* %% */ + APPEND_C(*f); + f++; + break; + case 'd': case 'i': { + intmax_t val JEMALLOC_CC_SILENCE_INIT(0); + char buf[D2S_BUFSIZE]; + + GET_ARG_NUMERIC(val, len); + s = d2s(val, (plus_plus ? '+' : (plus_space ? + ' ' : '-')), buf, &slen); + APPEND_PADDED_S(s, slen, width, left_justify); + f++; + break; + } case 'o': { + uintmax_t val JEMALLOC_CC_SILENCE_INIT(0); + char buf[O2S_BUFSIZE]; + + GET_ARG_NUMERIC(val, len | 0x80); + s = o2s(val, alt_form, buf, &slen); + APPEND_PADDED_S(s, slen, width, left_justify); + f++; + break; + } case 'u': { + uintmax_t val JEMALLOC_CC_SILENCE_INIT(0); + char buf[U2S_BUFSIZE]; + + GET_ARG_NUMERIC(val, len | 0x80); + s = u2s(val, 10, false, buf, &slen); + APPEND_PADDED_S(s, slen, width, left_justify); + f++; + break; + } case 'x': case 'X': { + uintmax_t val JEMALLOC_CC_SILENCE_INIT(0); + char buf[X2S_BUFSIZE]; + + GET_ARG_NUMERIC(val, len | 0x80); + s = x2s(val, alt_form, *f == 'X', buf, &slen); + APPEND_PADDED_S(s, slen, width, left_justify); + f++; + break; + } case 'c': { + unsigned char val; + char buf[2]; + + assert(len == '?' || len == 'l'); + assert_not_implemented(len != 'l'); + val = va_arg(ap, int); + buf[0] = val; + buf[1] = '\0'; + APPEND_PADDED_S(buf, 1, width, left_justify); + f++; + break; + } case 's': + assert(len == '?' || len == 'l'); + assert_not_implemented(len != 'l'); + s = va_arg(ap, char *); + slen = (prec < 0) ? strlen(s) : (size_t)prec; + APPEND_PADDED_S(s, slen, width, left_justify); + f++; + break; + case 'p': { + uintmax_t val; + char buf[X2S_BUFSIZE]; + + GET_ARG_NUMERIC(val, 'p'); + s = x2s(val, true, false, buf, &slen); + APPEND_PADDED_S(s, slen, width, left_justify); + f++; + break; + } default: not_reached(); + } + break; + } default: { + APPEND_C(*f); + f++; + break; + }} + } + label_out: + if (i < size) + str[i] = '\0'; + else + str[size - 1] = '\0'; + ret = i; + +#undef APPEND_C +#undef APPEND_S +#undef APPEND_PADDED_S +#undef GET_ARG_NUMERIC + return (ret); +} + +JEMALLOC_FORMAT_PRINTF(3, 4) +int +malloc_snprintf(char *str, size_t size, const char *format, ...) +{ + int ret; + va_list ap; + + va_start(ap, format); + ret = malloc_vsnprintf(str, size, format, ap); + va_end(ap); + + return (ret); +} + +void +malloc_vcprintf(void (*write_cb)(void *, const char *), void *cbopaque, + const char *format, va_list ap) +{ + char buf[MALLOC_PRINTF_BUFSIZE]; + + if (write_cb == NULL) { + /* + * The caller did not provide an alternate write_cb callback + * function, so use the default one. malloc_write() is an + * inline function, so use malloc_message() directly here. + */ + write_cb = (je_malloc_message != NULL) ? je_malloc_message : + wrtmessage; + cbopaque = NULL; + } + + malloc_vsnprintf(buf, sizeof(buf), format, ap); + write_cb(cbopaque, buf); +} + +/* + * Print to a callback function in such a way as to (hopefully) avoid memory + * allocation. + */ +JEMALLOC_FORMAT_PRINTF(3, 4) +void +malloc_cprintf(void (*write_cb)(void *, const char *), void *cbopaque, + const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + malloc_vcprintf(write_cb, cbopaque, format, ap); + va_end(ap); +} + +/* Print to stderr in such a way as to avoid memory allocation. */ +JEMALLOC_FORMAT_PRINTF(1, 2) +void +malloc_printf(const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + malloc_vcprintf(NULL, NULL, format, ap); + va_end(ap); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/valgrind.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/valgrind.c new file mode 100644 index 0000000..8e7ef3a --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/valgrind.c @@ -0,0 +1,34 @@ +#include "jemalloc/internal/jemalloc_internal.h" +#ifndef JEMALLOC_VALGRIND +# error "This source file is for Valgrind integration." +#endif + +#include + +void +valgrind_make_mem_noaccess(void *ptr, size_t usize) +{ + + VALGRIND_MAKE_MEM_NOACCESS(ptr, usize); +} + +void +valgrind_make_mem_undefined(void *ptr, size_t usize) +{ + + VALGRIND_MAKE_MEM_UNDEFINED(ptr, usize); +} + +void +valgrind_make_mem_defined(void *ptr, size_t usize) +{ + + VALGRIND_MAKE_MEM_DEFINED(ptr, usize); +} + +void +valgrind_freelike_block(void *ptr, size_t usize) +{ + + VALGRIND_FREELIKE_BLOCK(ptr, usize); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/zone.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/zone.c new file mode 100644 index 0000000..12e1734 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/src/zone.c @@ -0,0 +1,274 @@ +#include "jemalloc/internal/jemalloc_internal.h" +#ifndef JEMALLOC_ZONE +# error "This source file is for zones on Darwin (OS X)." +#endif + +/* + * The malloc_default_purgeable_zone function is only available on >= 10.6. + * We need to check whether it is present at runtime, thus the weak_import. + */ +extern malloc_zone_t *malloc_default_purgeable_zone(void) +JEMALLOC_ATTR(weak_import); + +/******************************************************************************/ +/* Data. */ + +static malloc_zone_t zone; +static struct malloc_introspection_t zone_introspect; + +/******************************************************************************/ +/* Function prototypes for non-inline static functions. */ + +static size_t zone_size(malloc_zone_t *zone, void *ptr); +static void *zone_malloc(malloc_zone_t *zone, size_t size); +static void *zone_calloc(malloc_zone_t *zone, size_t num, size_t size); +static void *zone_valloc(malloc_zone_t *zone, size_t size); +static void zone_free(malloc_zone_t *zone, void *ptr); +static void *zone_realloc(malloc_zone_t *zone, void *ptr, size_t size); +#if (JEMALLOC_ZONE_VERSION >= 5) +static void *zone_memalign(malloc_zone_t *zone, size_t alignment, +#endif +#if (JEMALLOC_ZONE_VERSION >= 6) + size_t size); +static void zone_free_definite_size(malloc_zone_t *zone, void *ptr, + size_t size); +#endif +static void *zone_destroy(malloc_zone_t *zone); +static size_t zone_good_size(malloc_zone_t *zone, size_t size); +static void zone_force_lock(malloc_zone_t *zone); +static void zone_force_unlock(malloc_zone_t *zone); + +/******************************************************************************/ +/* + * Functions. + */ + +static size_t +zone_size(malloc_zone_t *zone, void *ptr) +{ + + /* + * There appear to be places within Darwin (such as setenv(3)) that + * cause calls to this function with pointers that *no* zone owns. If + * we knew that all pointers were owned by *some* zone, we could split + * our zone into two parts, and use one as the default allocator and + * the other as the default deallocator/reallocator. Since that will + * not work in practice, we must check all pointers to assure that they + * reside within a mapped chunk before determining size. + */ + return (ivsalloc(ptr, config_prof)); +} + +static void * +zone_malloc(malloc_zone_t *zone, size_t size) +{ + + return (je_malloc(size)); +} + +static void * +zone_calloc(malloc_zone_t *zone, size_t num, size_t size) +{ + + return (je_calloc(num, size)); +} + +static void * +zone_valloc(malloc_zone_t *zone, size_t size) +{ + void *ret = NULL; /* Assignment avoids useless compiler warning. */ + + je_posix_memalign(&ret, PAGE, size); + + return (ret); +} + +static void +zone_free(malloc_zone_t *zone, void *ptr) +{ + + if (ivsalloc(ptr, config_prof) != 0) { + je_free(ptr); + return; + } + + free(ptr); +} + +static void * +zone_realloc(malloc_zone_t *zone, void *ptr, size_t size) +{ + + if (ivsalloc(ptr, config_prof) != 0) + return (je_realloc(ptr, size)); + + return (realloc(ptr, size)); +} + +#if (JEMALLOC_ZONE_VERSION >= 5) +static void * +zone_memalign(malloc_zone_t *zone, size_t alignment, size_t size) +{ + void *ret = NULL; /* Assignment avoids useless compiler warning. */ + + je_posix_memalign(&ret, alignment, size); + + return (ret); +} +#endif + +#if (JEMALLOC_ZONE_VERSION >= 6) +static void +zone_free_definite_size(malloc_zone_t *zone, void *ptr, size_t size) +{ + + if (ivsalloc(ptr, config_prof) != 0) { + assert(ivsalloc(ptr, config_prof) == size); + je_free(ptr); + return; + } + + free(ptr); +} +#endif + +static void * +zone_destroy(malloc_zone_t *zone) +{ + + /* This function should never be called. */ + not_reached(); + return (NULL); +} + +static size_t +zone_good_size(malloc_zone_t *zone, size_t size) +{ + + if (size == 0) + size = 1; + return (s2u(size)); +} + +static void +zone_force_lock(malloc_zone_t *zone) +{ + + if (isthreaded) + jemalloc_prefork(); +} + +static void +zone_force_unlock(malloc_zone_t *zone) +{ + + if (isthreaded) + jemalloc_postfork_parent(); +} + +JEMALLOC_ATTR(constructor) +void +register_zone(void) +{ + + /* + * If something else replaced the system default zone allocator, don't + * register jemalloc's. + */ + malloc_zone_t *default_zone = malloc_default_zone(); + malloc_zone_t *purgeable_zone = NULL; + if (!default_zone->zone_name || + strcmp(default_zone->zone_name, "DefaultMallocZone") != 0) { + return; + } + + zone.size = (void *)zone_size; + zone.malloc = (void *)zone_malloc; + zone.calloc = (void *)zone_calloc; + zone.valloc = (void *)zone_valloc; + zone.free = (void *)zone_free; + zone.realloc = (void *)zone_realloc; + zone.destroy = (void *)zone_destroy; + zone.zone_name = "jemalloc_zone"; + zone.batch_malloc = NULL; + zone.batch_free = NULL; + zone.introspect = &zone_introspect; + zone.version = JEMALLOC_ZONE_VERSION; +#if (JEMALLOC_ZONE_VERSION >= 5) + zone.memalign = zone_memalign; +#endif +#if (JEMALLOC_ZONE_VERSION >= 6) + zone.free_definite_size = zone_free_definite_size; +#endif +#if (JEMALLOC_ZONE_VERSION >= 8) + zone.pressure_relief = NULL; +#endif + + zone_introspect.enumerator = NULL; + zone_introspect.good_size = (void *)zone_good_size; + zone_introspect.check = NULL; + zone_introspect.print = NULL; + zone_introspect.log = NULL; + zone_introspect.force_lock = (void *)zone_force_lock; + zone_introspect.force_unlock = (void *)zone_force_unlock; + zone_introspect.statistics = NULL; +#if (JEMALLOC_ZONE_VERSION >= 6) + zone_introspect.zone_locked = NULL; +#endif +#if (JEMALLOC_ZONE_VERSION >= 7) + zone_introspect.enable_discharge_checking = NULL; + zone_introspect.disable_discharge_checking = NULL; + zone_introspect.discharge = NULL; +#ifdef __BLOCKS__ + zone_introspect.enumerate_discharged_pointers = NULL; +#else + zone_introspect.enumerate_unavailable_without_blocks = NULL; +#endif +#endif + + /* + * The default purgeable zone is created lazily by OSX's libc. It uses + * the default zone when it is created for "small" allocations + * (< 15 KiB), but assumes the default zone is a scalable_zone. This + * obviously fails when the default zone is the jemalloc zone, so + * malloc_default_purgeable_zone is called beforehand so that the + * default purgeable zone is created when the default zone is still + * a scalable_zone. As purgeable zones only exist on >= 10.6, we need + * to check for the existence of malloc_default_purgeable_zone() at + * run time. + */ + if (malloc_default_purgeable_zone != NULL) + purgeable_zone = malloc_default_purgeable_zone(); + + /* Register the custom zone. At this point it won't be the default. */ + malloc_zone_register(&zone); + + do { + default_zone = malloc_default_zone(); + /* + * Unregister and reregister the default zone. On OSX >= 10.6, + * unregistering takes the last registered zone and places it + * at the location of the specified zone. Unregistering the + * default zone thus makes the last registered one the default. + * On OSX < 10.6, unregistering shifts all registered zones. + * The first registered zone then becomes the default. + */ + malloc_zone_unregister(default_zone); + malloc_zone_register(default_zone); + /* + * On OSX 10.6, having the default purgeable zone appear before + * the default zone makes some things crash because it thinks it + * owns the default zone allocated pointers. We thus + * unregister/re-register it in order to ensure it's always + * after the default zone. On OSX < 10.6, there is no purgeable + * zone, so this does nothing. On OSX >= 10.6, unregistering + * replaces the purgeable zone with the last registered zone + * above, i.e. the default zone. Registering it again then puts + * it at the end, obviously after the default zone. + */ + if (purgeable_zone) { + malloc_zone_unregister(purgeable_zone); + malloc_zone_register(purgeable_zone); + } + } while (malloc_default_zone() != &zone); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-alti.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-alti.h new file mode 100644 index 0000000..0005df6 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-alti.h @@ -0,0 +1,186 @@ +/* + * This file derives from SFMT 1.3.3 + * (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was + * released under the terms of the following license: + * + * Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima + * University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the Hiroshima University nor the names of + * its contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/** + * @file SFMT-alti.h + * + * @brief SIMD oriented Fast Mersenne Twister(SFMT) + * pseudorandom number generator + * + * @author Mutsuo Saito (Hiroshima University) + * @author Makoto Matsumoto (Hiroshima University) + * + * Copyright (C) 2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima + * University. All rights reserved. + * + * The new BSD License is applied to this software. + * see LICENSE.txt + */ + +#ifndef SFMT_ALTI_H +#define SFMT_ALTI_H + +/** + * This function represents the recursion formula in AltiVec and BIG ENDIAN. + * @param a a 128-bit part of the interal state array + * @param b a 128-bit part of the interal state array + * @param c a 128-bit part of the interal state array + * @param d a 128-bit part of the interal state array + * @return output + */ +JEMALLOC_ALWAYS_INLINE +vector unsigned int vec_recursion(vector unsigned int a, + vector unsigned int b, + vector unsigned int c, + vector unsigned int d) { + + const vector unsigned int sl1 = ALTI_SL1; + const vector unsigned int sr1 = ALTI_SR1; +#ifdef ONLY64 + const vector unsigned int mask = ALTI_MSK64; + const vector unsigned char perm_sl = ALTI_SL2_PERM64; + const vector unsigned char perm_sr = ALTI_SR2_PERM64; +#else + const vector unsigned int mask = ALTI_MSK; + const vector unsigned char perm_sl = ALTI_SL2_PERM; + const vector unsigned char perm_sr = ALTI_SR2_PERM; +#endif + vector unsigned int v, w, x, y, z; + x = vec_perm(a, (vector unsigned int)perm_sl, perm_sl); + v = a; + y = vec_sr(b, sr1); + z = vec_perm(c, (vector unsigned int)perm_sr, perm_sr); + w = vec_sl(d, sl1); + z = vec_xor(z, w); + y = vec_and(y, mask); + v = vec_xor(v, x); + z = vec_xor(z, y); + z = vec_xor(z, v); + return z; +} + +/** + * This function fills the internal state array with pseudorandom + * integers. + */ +JEMALLOC_INLINE void gen_rand_all(sfmt_t *ctx) { + int i; + vector unsigned int r, r1, r2; + + r1 = ctx->sfmt[N - 2].s; + r2 = ctx->sfmt[N - 1].s; + for (i = 0; i < N - POS1; i++) { + r = vec_recursion(ctx->sfmt[i].s, ctx->sfmt[i + POS1].s, r1, r2); + ctx->sfmt[i].s = r; + r1 = r2; + r2 = r; + } + for (; i < N; i++) { + r = vec_recursion(ctx->sfmt[i].s, ctx->sfmt[i + POS1 - N].s, r1, r2); + ctx->sfmt[i].s = r; + r1 = r2; + r2 = r; + } +} + +/** + * This function fills the user-specified array with pseudorandom + * integers. + * + * @param array an 128-bit array to be filled by pseudorandom numbers. + * @param size number of 128-bit pesudorandom numbers to be generated. + */ +JEMALLOC_INLINE void gen_rand_array(sfmt_t *ctx, w128_t *array, int size) { + int i, j; + vector unsigned int r, r1, r2; + + r1 = ctx->sfmt[N - 2].s; + r2 = ctx->sfmt[N - 1].s; + for (i = 0; i < N - POS1; i++) { + r = vec_recursion(ctx->sfmt[i].s, ctx->sfmt[i + POS1].s, r1, r2); + array[i].s = r; + r1 = r2; + r2 = r; + } + for (; i < N; i++) { + r = vec_recursion(ctx->sfmt[i].s, array[i + POS1 - N].s, r1, r2); + array[i].s = r; + r1 = r2; + r2 = r; + } + /* main loop */ + for (; i < size - N; i++) { + r = vec_recursion(array[i - N].s, array[i + POS1 - N].s, r1, r2); + array[i].s = r; + r1 = r2; + r2 = r; + } + for (j = 0; j < 2 * N - size; j++) { + ctx->sfmt[j].s = array[j + size - N].s; + } + for (; i < size; i++) { + r = vec_recursion(array[i - N].s, array[i + POS1 - N].s, r1, r2); + array[i].s = r; + ctx->sfmt[j++].s = r; + r1 = r2; + r2 = r; + } +} + +#ifndef ONLY64 +#if defined(__APPLE__) +#define ALTI_SWAP (vector unsigned char) \ + (4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11) +#else +#define ALTI_SWAP {4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11} +#endif +/** + * This function swaps high and low 32-bit of 64-bit integers in user + * specified array. + * + * @param array an 128-bit array to be swaped. + * @param size size of 128-bit array. + */ +JEMALLOC_INLINE void swap(w128_t *array, int size) { + int i; + const vector unsigned char perm = ALTI_SWAP; + + for (i = 0; i < size; i++) { + array[i].s = vec_perm(array[i].s, (vector unsigned int)perm, perm); + } +} +#endif + +#endif diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params.h new file mode 100644 index 0000000..ade6622 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params.h @@ -0,0 +1,132 @@ +/* + * This file derives from SFMT 1.3.3 + * (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was + * released under the terms of the following license: + * + * Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima + * University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the Hiroshima University nor the names of + * its contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef SFMT_PARAMS_H +#define SFMT_PARAMS_H + +#if !defined(MEXP) +#ifdef __GNUC__ + #warning "MEXP is not defined. I assume MEXP is 19937." +#endif + #define MEXP 19937 +#endif +/*----------------- + BASIC DEFINITIONS + -----------------*/ +/** Mersenne Exponent. The period of the sequence + * is a multiple of 2^MEXP-1. + * #define MEXP 19937 */ +/** SFMT generator has an internal state array of 128-bit integers, + * and N is its size. */ +#define N (MEXP / 128 + 1) +/** N32 is the size of internal state array when regarded as an array + * of 32-bit integers.*/ +#define N32 (N * 4) +/** N64 is the size of internal state array when regarded as an array + * of 64-bit integers.*/ +#define N64 (N * 2) + +/*---------------------- + the parameters of SFMT + following definitions are in paramsXXXX.h file. + ----------------------*/ +/** the pick up position of the array. +#define POS1 122 +*/ + +/** the parameter of shift left as four 32-bit registers. +#define SL1 18 + */ + +/** the parameter of shift left as one 128-bit register. + * The 128-bit integer is shifted by (SL2 * 8) bits. +#define SL2 1 +*/ + +/** the parameter of shift right as four 32-bit registers. +#define SR1 11 +*/ + +/** the parameter of shift right as one 128-bit register. + * The 128-bit integer is shifted by (SL2 * 8) bits. +#define SR2 1 +*/ + +/** A bitmask, used in the recursion. These parameters are introduced + * to break symmetry of SIMD. +#define MSK1 0xdfffffefU +#define MSK2 0xddfecb7fU +#define MSK3 0xbffaffffU +#define MSK4 0xbffffff6U +*/ + +/** These definitions are part of a 128-bit period certification vector. +#define PARITY1 0x00000001U +#define PARITY2 0x00000000U +#define PARITY3 0x00000000U +#define PARITY4 0xc98e126aU +*/ + +#if MEXP == 607 + #include "test/SFMT-params607.h" +#elif MEXP == 1279 + #include "test/SFMT-params1279.h" +#elif MEXP == 2281 + #include "test/SFMT-params2281.h" +#elif MEXP == 4253 + #include "test/SFMT-params4253.h" +#elif MEXP == 11213 + #include "test/SFMT-params11213.h" +#elif MEXP == 19937 + #include "test/SFMT-params19937.h" +#elif MEXP == 44497 + #include "test/SFMT-params44497.h" +#elif MEXP == 86243 + #include "test/SFMT-params86243.h" +#elif MEXP == 132049 + #include "test/SFMT-params132049.h" +#elif MEXP == 216091 + #include "test/SFMT-params216091.h" +#else +#ifdef __GNUC__ + #error "MEXP is not valid." + #undef MEXP +#else + #undef MEXP +#endif + +#endif + +#endif /* SFMT_PARAMS_H */ diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params11213.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params11213.h new file mode 100644 index 0000000..2994bd2 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params11213.h @@ -0,0 +1,81 @@ +/* + * This file derives from SFMT 1.3.3 + * (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was + * released under the terms of the following license: + * + * Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima + * University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the Hiroshima University nor the names of + * its contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef SFMT_PARAMS11213_H +#define SFMT_PARAMS11213_H + +#define POS1 68 +#define SL1 14 +#define SL2 3 +#define SR1 7 +#define SR2 3 +#define MSK1 0xeffff7fbU +#define MSK2 0xffffffefU +#define MSK3 0xdfdfbfffU +#define MSK4 0x7fffdbfdU +#define PARITY1 0x00000001U +#define PARITY2 0x00000000U +#define PARITY3 0xe8148000U +#define PARITY4 0xd0c7afa3U + + +/* PARAMETERS FOR ALTIVEC */ +#if defined(__APPLE__) /* For OSX */ + #define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1) + #define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1) + #define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4) + #define ALTI_MSK64 \ + (vector unsigned int)(MSK2, MSK1, MSK4, MSK3) + #define ALTI_SL2_PERM \ + (vector unsigned char)(3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10) + #define ALTI_SL2_PERM64 \ + (vector unsigned char)(3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2) + #define ALTI_SR2_PERM \ + (vector unsigned char)(5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12) + #define ALTI_SR2_PERM64 \ + (vector unsigned char)(13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12) +#else /* For OTHER OSs(Linux?) */ + #define ALTI_SL1 {SL1, SL1, SL1, SL1} + #define ALTI_SR1 {SR1, SR1, SR1, SR1} + #define ALTI_MSK {MSK1, MSK2, MSK3, MSK4} + #define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3} + #define ALTI_SL2_PERM {3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10} + #define ALTI_SL2_PERM64 {3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2} + #define ALTI_SR2_PERM {5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12} + #define ALTI_SR2_PERM64 {13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12} +#endif /* For OSX */ +#define IDSTR "SFMT-11213:68-14-3-7-3:effff7fb-ffffffef-dfdfbfff-7fffdbfd" + +#endif /* SFMT_PARAMS11213_H */ diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params1279.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params1279.h new file mode 100644 index 0000000..d7959f9 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params1279.h @@ -0,0 +1,81 @@ +/* + * This file derives from SFMT 1.3.3 + * (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was + * released under the terms of the following license: + * + * Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima + * University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the Hiroshima University nor the names of + * its contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef SFMT_PARAMS1279_H +#define SFMT_PARAMS1279_H + +#define POS1 7 +#define SL1 14 +#define SL2 3 +#define SR1 5 +#define SR2 1 +#define MSK1 0xf7fefffdU +#define MSK2 0x7fefcfffU +#define MSK3 0xaff3ef3fU +#define MSK4 0xb5ffff7fU +#define PARITY1 0x00000001U +#define PARITY2 0x00000000U +#define PARITY3 0x00000000U +#define PARITY4 0x20000000U + + +/* PARAMETERS FOR ALTIVEC */ +#if defined(__APPLE__) /* For OSX */ + #define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1) + #define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1) + #define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4) + #define ALTI_MSK64 \ + (vector unsigned int)(MSK2, MSK1, MSK4, MSK3) + #define ALTI_SL2_PERM \ + (vector unsigned char)(3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10) + #define ALTI_SL2_PERM64 \ + (vector unsigned char)(3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2) + #define ALTI_SR2_PERM \ + (vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14) + #define ALTI_SR2_PERM64 \ + (vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14) +#else /* For OTHER OSs(Linux?) */ + #define ALTI_SL1 {SL1, SL1, SL1, SL1} + #define ALTI_SR1 {SR1, SR1, SR1, SR1} + #define ALTI_MSK {MSK1, MSK2, MSK3, MSK4} + #define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3} + #define ALTI_SL2_PERM {3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10} + #define ALTI_SL2_PERM64 {3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2} + #define ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14} + #define ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14} +#endif /* For OSX */ +#define IDSTR "SFMT-1279:7-14-3-5-1:f7fefffd-7fefcfff-aff3ef3f-b5ffff7f" + +#endif /* SFMT_PARAMS1279_H */ diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params132049.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params132049.h new file mode 100644 index 0000000..a1dcec3 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params132049.h @@ -0,0 +1,81 @@ +/* + * This file derives from SFMT 1.3.3 + * (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was + * released under the terms of the following license: + * + * Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima + * University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the Hiroshima University nor the names of + * its contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef SFMT_PARAMS132049_H +#define SFMT_PARAMS132049_H + +#define POS1 110 +#define SL1 19 +#define SL2 1 +#define SR1 21 +#define SR2 1 +#define MSK1 0xffffbb5fU +#define MSK2 0xfb6ebf95U +#define MSK3 0xfffefffaU +#define MSK4 0xcff77fffU +#define PARITY1 0x00000001U +#define PARITY2 0x00000000U +#define PARITY3 0xcb520000U +#define PARITY4 0xc7e91c7dU + + +/* PARAMETERS FOR ALTIVEC */ +#if defined(__APPLE__) /* For OSX */ + #define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1) + #define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1) + #define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4) + #define ALTI_MSK64 \ + (vector unsigned int)(MSK2, MSK1, MSK4, MSK3) + #define ALTI_SL2_PERM \ + (vector unsigned char)(1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8) + #define ALTI_SL2_PERM64 \ + (vector unsigned char)(1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0) + #define ALTI_SR2_PERM \ + (vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14) + #define ALTI_SR2_PERM64 \ + (vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14) +#else /* For OTHER OSs(Linux?) */ + #define ALTI_SL1 {SL1, SL1, SL1, SL1} + #define ALTI_SR1 {SR1, SR1, SR1, SR1} + #define ALTI_MSK {MSK1, MSK2, MSK3, MSK4} + #define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3} + #define ALTI_SL2_PERM {1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8} + #define ALTI_SL2_PERM64 {1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0} + #define ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14} + #define ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14} +#endif /* For OSX */ +#define IDSTR "SFMT-132049:110-19-1-21-1:ffffbb5f-fb6ebf95-fffefffa-cff77fff" + +#endif /* SFMT_PARAMS132049_H */ diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params19937.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params19937.h new file mode 100644 index 0000000..fb92b4c --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params19937.h @@ -0,0 +1,81 @@ +/* + * This file derives from SFMT 1.3.3 + * (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was + * released under the terms of the following license: + * + * Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima + * University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the Hiroshima University nor the names of + * its contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef SFMT_PARAMS19937_H +#define SFMT_PARAMS19937_H + +#define POS1 122 +#define SL1 18 +#define SL2 1 +#define SR1 11 +#define SR2 1 +#define MSK1 0xdfffffefU +#define MSK2 0xddfecb7fU +#define MSK3 0xbffaffffU +#define MSK4 0xbffffff6U +#define PARITY1 0x00000001U +#define PARITY2 0x00000000U +#define PARITY3 0x00000000U +#define PARITY4 0x13c9e684U + + +/* PARAMETERS FOR ALTIVEC */ +#if defined(__APPLE__) /* For OSX */ + #define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1) + #define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1) + #define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4) + #define ALTI_MSK64 \ + (vector unsigned int)(MSK2, MSK1, MSK4, MSK3) + #define ALTI_SL2_PERM \ + (vector unsigned char)(1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8) + #define ALTI_SL2_PERM64 \ + (vector unsigned char)(1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0) + #define ALTI_SR2_PERM \ + (vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14) + #define ALTI_SR2_PERM64 \ + (vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14) +#else /* For OTHER OSs(Linux?) */ + #define ALTI_SL1 {SL1, SL1, SL1, SL1} + #define ALTI_SR1 {SR1, SR1, SR1, SR1} + #define ALTI_MSK {MSK1, MSK2, MSK3, MSK4} + #define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3} + #define ALTI_SL2_PERM {1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8} + #define ALTI_SL2_PERM64 {1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0} + #define ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14} + #define ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14} +#endif /* For OSX */ +#define IDSTR "SFMT-19937:122-18-1-11-1:dfffffef-ddfecb7f-bffaffff-bffffff6" + +#endif /* SFMT_PARAMS19937_H */ diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params216091.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params216091.h new file mode 100644 index 0000000..125ce28 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params216091.h @@ -0,0 +1,81 @@ +/* + * This file derives from SFMT 1.3.3 + * (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was + * released under the terms of the following license: + * + * Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima + * University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the Hiroshima University nor the names of + * its contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef SFMT_PARAMS216091_H +#define SFMT_PARAMS216091_H + +#define POS1 627 +#define SL1 11 +#define SL2 3 +#define SR1 10 +#define SR2 1 +#define MSK1 0xbff7bff7U +#define MSK2 0xbfffffffU +#define MSK3 0xbffffa7fU +#define MSK4 0xffddfbfbU +#define PARITY1 0xf8000001U +#define PARITY2 0x89e80709U +#define PARITY3 0x3bd2b64bU +#define PARITY4 0x0c64b1e4U + + +/* PARAMETERS FOR ALTIVEC */ +#if defined(__APPLE__) /* For OSX */ + #define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1) + #define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1) + #define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4) + #define ALTI_MSK64 \ + (vector unsigned int)(MSK2, MSK1, MSK4, MSK3) + #define ALTI_SL2_PERM \ + (vector unsigned char)(3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10) + #define ALTI_SL2_PERM64 \ + (vector unsigned char)(3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2) + #define ALTI_SR2_PERM \ + (vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14) + #define ALTI_SR2_PERM64 \ + (vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14) +#else /* For OTHER OSs(Linux?) */ + #define ALTI_SL1 {SL1, SL1, SL1, SL1} + #define ALTI_SR1 {SR1, SR1, SR1, SR1} + #define ALTI_MSK {MSK1, MSK2, MSK3, MSK4} + #define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3} + #define ALTI_SL2_PERM {3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10} + #define ALTI_SL2_PERM64 {3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2} + #define ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14} + #define ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14} +#endif /* For OSX */ +#define IDSTR "SFMT-216091:627-11-3-10-1:bff7bff7-bfffffff-bffffa7f-ffddfbfb" + +#endif /* SFMT_PARAMS216091_H */ diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params2281.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params2281.h new file mode 100644 index 0000000..0ef85c4 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params2281.h @@ -0,0 +1,81 @@ +/* + * This file derives from SFMT 1.3.3 + * (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was + * released under the terms of the following license: + * + * Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima + * University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the Hiroshima University nor the names of + * its contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef SFMT_PARAMS2281_H +#define SFMT_PARAMS2281_H + +#define POS1 12 +#define SL1 19 +#define SL2 1 +#define SR1 5 +#define SR2 1 +#define MSK1 0xbff7ffbfU +#define MSK2 0xfdfffffeU +#define MSK3 0xf7ffef7fU +#define MSK4 0xf2f7cbbfU +#define PARITY1 0x00000001U +#define PARITY2 0x00000000U +#define PARITY3 0x00000000U +#define PARITY4 0x41dfa600U + + +/* PARAMETERS FOR ALTIVEC */ +#if defined(__APPLE__) /* For OSX */ + #define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1) + #define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1) + #define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4) + #define ALTI_MSK64 \ + (vector unsigned int)(MSK2, MSK1, MSK4, MSK3) + #define ALTI_SL2_PERM \ + (vector unsigned char)(1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8) + #define ALTI_SL2_PERM64 \ + (vector unsigned char)(1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0) + #define ALTI_SR2_PERM \ + (vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14) + #define ALTI_SR2_PERM64 \ + (vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14) +#else /* For OTHER OSs(Linux?) */ + #define ALTI_SL1 {SL1, SL1, SL1, SL1} + #define ALTI_SR1 {SR1, SR1, SR1, SR1} + #define ALTI_MSK {MSK1, MSK2, MSK3, MSK4} + #define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3} + #define ALTI_SL2_PERM {1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8} + #define ALTI_SL2_PERM64 {1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0} + #define ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14} + #define ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14} +#endif /* For OSX */ +#define IDSTR "SFMT-2281:12-19-1-5-1:bff7ffbf-fdfffffe-f7ffef7f-f2f7cbbf" + +#endif /* SFMT_PARAMS2281_H */ diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params4253.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params4253.h new file mode 100644 index 0000000..9f07bc6 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params4253.h @@ -0,0 +1,81 @@ +/* + * This file derives from SFMT 1.3.3 + * (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was + * released under the terms of the following license: + * + * Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima + * University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the Hiroshima University nor the names of + * its contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef SFMT_PARAMS4253_H +#define SFMT_PARAMS4253_H + +#define POS1 17 +#define SL1 20 +#define SL2 1 +#define SR1 7 +#define SR2 1 +#define MSK1 0x9f7bffffU +#define MSK2 0x9fffff5fU +#define MSK3 0x3efffffbU +#define MSK4 0xfffff7bbU +#define PARITY1 0xa8000001U +#define PARITY2 0xaf5390a3U +#define PARITY3 0xb740b3f8U +#define PARITY4 0x6c11486dU + + +/* PARAMETERS FOR ALTIVEC */ +#if defined(__APPLE__) /* For OSX */ + #define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1) + #define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1) + #define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4) + #define ALTI_MSK64 \ + (vector unsigned int)(MSK2, MSK1, MSK4, MSK3) + #define ALTI_SL2_PERM \ + (vector unsigned char)(1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8) + #define ALTI_SL2_PERM64 \ + (vector unsigned char)(1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0) + #define ALTI_SR2_PERM \ + (vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14) + #define ALTI_SR2_PERM64 \ + (vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14) +#else /* For OTHER OSs(Linux?) */ + #define ALTI_SL1 {SL1, SL1, SL1, SL1} + #define ALTI_SR1 {SR1, SR1, SR1, SR1} + #define ALTI_MSK {MSK1, MSK2, MSK3, MSK4} + #define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3} + #define ALTI_SL2_PERM {1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8} + #define ALTI_SL2_PERM64 {1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0} + #define ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14} + #define ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14} +#endif /* For OSX */ +#define IDSTR "SFMT-4253:17-20-1-7-1:9f7bffff-9fffff5f-3efffffb-fffff7bb" + +#endif /* SFMT_PARAMS4253_H */ diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params44497.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params44497.h new file mode 100644 index 0000000..85598fe --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params44497.h @@ -0,0 +1,81 @@ +/* + * This file derives from SFMT 1.3.3 + * (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was + * released under the terms of the following license: + * + * Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima + * University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the Hiroshima University nor the names of + * its contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef SFMT_PARAMS44497_H +#define SFMT_PARAMS44497_H + +#define POS1 330 +#define SL1 5 +#define SL2 3 +#define SR1 9 +#define SR2 3 +#define MSK1 0xeffffffbU +#define MSK2 0xdfbebfffU +#define MSK3 0xbfbf7befU +#define MSK4 0x9ffd7bffU +#define PARITY1 0x00000001U +#define PARITY2 0x00000000U +#define PARITY3 0xa3ac4000U +#define PARITY4 0xecc1327aU + + +/* PARAMETERS FOR ALTIVEC */ +#if defined(__APPLE__) /* For OSX */ + #define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1) + #define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1) + #define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4) + #define ALTI_MSK64 \ + (vector unsigned int)(MSK2, MSK1, MSK4, MSK3) + #define ALTI_SL2_PERM \ + (vector unsigned char)(3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10) + #define ALTI_SL2_PERM64 \ + (vector unsigned char)(3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2) + #define ALTI_SR2_PERM \ + (vector unsigned char)(5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12) + #define ALTI_SR2_PERM64 \ + (vector unsigned char)(13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12) +#else /* For OTHER OSs(Linux?) */ + #define ALTI_SL1 {SL1, SL1, SL1, SL1} + #define ALTI_SR1 {SR1, SR1, SR1, SR1} + #define ALTI_MSK {MSK1, MSK2, MSK3, MSK4} + #define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3} + #define ALTI_SL2_PERM {3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10} + #define ALTI_SL2_PERM64 {3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2} + #define ALTI_SR2_PERM {5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12} + #define ALTI_SR2_PERM64 {13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12} +#endif /* For OSX */ +#define IDSTR "SFMT-44497:330-5-3-9-3:effffffb-dfbebfff-bfbf7bef-9ffd7bff" + +#endif /* SFMT_PARAMS44497_H */ diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params607.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params607.h new file mode 100644 index 0000000..bc76485 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params607.h @@ -0,0 +1,81 @@ +/* + * This file derives from SFMT 1.3.3 + * (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was + * released under the terms of the following license: + * + * Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima + * University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the Hiroshima University nor the names of + * its contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef SFMT_PARAMS607_H +#define SFMT_PARAMS607_H + +#define POS1 2 +#define SL1 15 +#define SL2 3 +#define SR1 13 +#define SR2 3 +#define MSK1 0xfdff37ffU +#define MSK2 0xef7f3f7dU +#define MSK3 0xff777b7dU +#define MSK4 0x7ff7fb2fU +#define PARITY1 0x00000001U +#define PARITY2 0x00000000U +#define PARITY3 0x00000000U +#define PARITY4 0x5986f054U + + +/* PARAMETERS FOR ALTIVEC */ +#if defined(__APPLE__) /* For OSX */ + #define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1) + #define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1) + #define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4) + #define ALTI_MSK64 \ + (vector unsigned int)(MSK2, MSK1, MSK4, MSK3) + #define ALTI_SL2_PERM \ + (vector unsigned char)(3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10) + #define ALTI_SL2_PERM64 \ + (vector unsigned char)(3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2) + #define ALTI_SR2_PERM \ + (vector unsigned char)(5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12) + #define ALTI_SR2_PERM64 \ + (vector unsigned char)(13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12) +#else /* For OTHER OSs(Linux?) */ + #define ALTI_SL1 {SL1, SL1, SL1, SL1} + #define ALTI_SR1 {SR1, SR1, SR1, SR1} + #define ALTI_MSK {MSK1, MSK2, MSK3, MSK4} + #define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3} + #define ALTI_SL2_PERM {3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10} + #define ALTI_SL2_PERM64 {3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2} + #define ALTI_SR2_PERM {5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12} + #define ALTI_SR2_PERM64 {13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12} +#endif /* For OSX */ +#define IDSTR "SFMT-607:2-15-3-13-3:fdff37ff-ef7f3f7d-ff777b7d-7ff7fb2f" + +#endif /* SFMT_PARAMS607_H */ diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params86243.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params86243.h new file mode 100644 index 0000000..5e4d783 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-params86243.h @@ -0,0 +1,81 @@ +/* + * This file derives from SFMT 1.3.3 + * (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was + * released under the terms of the following license: + * + * Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima + * University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the Hiroshima University nor the names of + * its contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef SFMT_PARAMS86243_H +#define SFMT_PARAMS86243_H + +#define POS1 366 +#define SL1 6 +#define SL2 7 +#define SR1 19 +#define SR2 1 +#define MSK1 0xfdbffbffU +#define MSK2 0xbff7ff3fU +#define MSK3 0xfd77efffU +#define MSK4 0xbf9ff3ffU +#define PARITY1 0x00000001U +#define PARITY2 0x00000000U +#define PARITY3 0x00000000U +#define PARITY4 0xe9528d85U + + +/* PARAMETERS FOR ALTIVEC */ +#if defined(__APPLE__) /* For OSX */ + #define ALTI_SL1 (vector unsigned int)(SL1, SL1, SL1, SL1) + #define ALTI_SR1 (vector unsigned int)(SR1, SR1, SR1, SR1) + #define ALTI_MSK (vector unsigned int)(MSK1, MSK2, MSK3, MSK4) + #define ALTI_MSK64 \ + (vector unsigned int)(MSK2, MSK1, MSK4, MSK3) + #define ALTI_SL2_PERM \ + (vector unsigned char)(25,25,25,25,3,25,25,25,7,0,1,2,11,4,5,6) + #define ALTI_SL2_PERM64 \ + (vector unsigned char)(7,25,25,25,25,25,25,25,15,0,1,2,3,4,5,6) + #define ALTI_SR2_PERM \ + (vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14) + #define ALTI_SR2_PERM64 \ + (vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14) +#else /* For OTHER OSs(Linux?) */ + #define ALTI_SL1 {SL1, SL1, SL1, SL1} + #define ALTI_SR1 {SR1, SR1, SR1, SR1} + #define ALTI_MSK {MSK1, MSK2, MSK3, MSK4} + #define ALTI_MSK64 {MSK2, MSK1, MSK4, MSK3} + #define ALTI_SL2_PERM {25,25,25,25,3,25,25,25,7,0,1,2,11,4,5,6} + #define ALTI_SL2_PERM64 {7,25,25,25,25,25,25,25,15,0,1,2,3,4,5,6} + #define ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14} + #define ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14} +#endif /* For OSX */ +#define IDSTR "SFMT-86243:366-6-7-19-1:fdbffbff-bff7ff3f-fd77efff-bf9ff3ff" + +#endif /* SFMT_PARAMS86243_H */ diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-sse2.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-sse2.h new file mode 100644 index 0000000..0314a16 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT-sse2.h @@ -0,0 +1,157 @@ +/* + * This file derives from SFMT 1.3.3 + * (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was + * released under the terms of the following license: + * + * Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima + * University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the Hiroshima University nor the names of + * its contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/** + * @file SFMT-sse2.h + * @brief SIMD oriented Fast Mersenne Twister(SFMT) for Intel SSE2 + * + * @author Mutsuo Saito (Hiroshima University) + * @author Makoto Matsumoto (Hiroshima University) + * + * @note We assume LITTLE ENDIAN in this file + * + * Copyright (C) 2006, 2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima + * University. All rights reserved. + * + * The new BSD License is applied to this software, see LICENSE.txt + */ + +#ifndef SFMT_SSE2_H +#define SFMT_SSE2_H + +/** + * This function represents the recursion formula. + * @param a a 128-bit part of the interal state array + * @param b a 128-bit part of the interal state array + * @param c a 128-bit part of the interal state array + * @param d a 128-bit part of the interal state array + * @param mask 128-bit mask + * @return output + */ +JEMALLOC_ALWAYS_INLINE __m128i mm_recursion(__m128i *a, __m128i *b, + __m128i c, __m128i d, __m128i mask) { + __m128i v, x, y, z; + + x = _mm_load_si128(a); + y = _mm_srli_epi32(*b, SR1); + z = _mm_srli_si128(c, SR2); + v = _mm_slli_epi32(d, SL1); + z = _mm_xor_si128(z, x); + z = _mm_xor_si128(z, v); + x = _mm_slli_si128(x, SL2); + y = _mm_and_si128(y, mask); + z = _mm_xor_si128(z, x); + z = _mm_xor_si128(z, y); + return z; +} + +/** + * This function fills the internal state array with pseudorandom + * integers. + */ +JEMALLOC_INLINE void gen_rand_all(sfmt_t *ctx) { + int i; + __m128i r, r1, r2, mask; + mask = _mm_set_epi32(MSK4, MSK3, MSK2, MSK1); + + r1 = _mm_load_si128(&ctx->sfmt[N - 2].si); + r2 = _mm_load_si128(&ctx->sfmt[N - 1].si); + for (i = 0; i < N - POS1; i++) { + r = mm_recursion(&ctx->sfmt[i].si, &ctx->sfmt[i + POS1].si, r1, r2, + mask); + _mm_store_si128(&ctx->sfmt[i].si, r); + r1 = r2; + r2 = r; + } + for (; i < N; i++) { + r = mm_recursion(&ctx->sfmt[i].si, &ctx->sfmt[i + POS1 - N].si, r1, r2, + mask); + _mm_store_si128(&ctx->sfmt[i].si, r); + r1 = r2; + r2 = r; + } +} + +/** + * This function fills the user-specified array with pseudorandom + * integers. + * + * @param array an 128-bit array to be filled by pseudorandom numbers. + * @param size number of 128-bit pesudorandom numbers to be generated. + */ +JEMALLOC_INLINE void gen_rand_array(sfmt_t *ctx, w128_t *array, int size) { + int i, j; + __m128i r, r1, r2, mask; + mask = _mm_set_epi32(MSK4, MSK3, MSK2, MSK1); + + r1 = _mm_load_si128(&ctx->sfmt[N - 2].si); + r2 = _mm_load_si128(&ctx->sfmt[N - 1].si); + for (i = 0; i < N - POS1; i++) { + r = mm_recursion(&ctx->sfmt[i].si, &ctx->sfmt[i + POS1].si, r1, r2, + mask); + _mm_store_si128(&array[i].si, r); + r1 = r2; + r2 = r; + } + for (; i < N; i++) { + r = mm_recursion(&ctx->sfmt[i].si, &array[i + POS1 - N].si, r1, r2, + mask); + _mm_store_si128(&array[i].si, r); + r1 = r2; + r2 = r; + } + /* main loop */ + for (; i < size - N; i++) { + r = mm_recursion(&array[i - N].si, &array[i + POS1 - N].si, r1, r2, + mask); + _mm_store_si128(&array[i].si, r); + r1 = r2; + r2 = r; + } + for (j = 0; j < 2 * N - size; j++) { + r = _mm_load_si128(&array[j + size - N].si); + _mm_store_si128(&ctx->sfmt[j].si, r); + } + for (; i < size; i++) { + r = mm_recursion(&array[i - N].si, &array[i + POS1 - N].si, r1, r2, + mask); + _mm_store_si128(&array[i].si, r); + _mm_store_si128(&ctx->sfmt[j++].si, r); + r1 = r2; + r2 = r; + } +} + +#endif diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT.h new file mode 100644 index 0000000..09c1607 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/SFMT.h @@ -0,0 +1,171 @@ +/* + * This file derives from SFMT 1.3.3 + * (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was + * released under the terms of the following license: + * + * Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima + * University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the Hiroshima University nor the names of + * its contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/** + * @file SFMT.h + * + * @brief SIMD oriented Fast Mersenne Twister(SFMT) pseudorandom + * number generator + * + * @author Mutsuo Saito (Hiroshima University) + * @author Makoto Matsumoto (Hiroshima University) + * + * Copyright (C) 2006, 2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima + * University. All rights reserved. + * + * The new BSD License is applied to this software. + * see LICENSE.txt + * + * @note We assume that your system has inttypes.h. If your system + * doesn't have inttypes.h, you have to typedef uint32_t and uint64_t, + * and you have to define PRIu64 and PRIx64 in this file as follows: + * @verbatim + typedef unsigned int uint32_t + typedef unsigned long long uint64_t + #define PRIu64 "llu" + #define PRIx64 "llx" +@endverbatim + * uint32_t must be exactly 32-bit unsigned integer type (no more, no + * less), and uint64_t must be exactly 64-bit unsigned integer type. + * PRIu64 and PRIx64 are used for printf function to print 64-bit + * unsigned int and 64-bit unsigned int in hexadecimal format. + */ + +#ifndef SFMT_H +#define SFMT_H + +typedef struct sfmt_s sfmt_t; + +uint32_t gen_rand32(sfmt_t *ctx); +uint32_t gen_rand32_range(sfmt_t *ctx, uint32_t limit); +uint64_t gen_rand64(sfmt_t *ctx); +uint64_t gen_rand64_range(sfmt_t *ctx, uint64_t limit); +void fill_array32(sfmt_t *ctx, uint32_t *array, int size); +void fill_array64(sfmt_t *ctx, uint64_t *array, int size); +sfmt_t *init_gen_rand(uint32_t seed); +sfmt_t *init_by_array(uint32_t *init_key, int key_length); +void fini_gen_rand(sfmt_t *ctx); +const char *get_idstring(void); +int get_min_array_size32(void); +int get_min_array_size64(void); + +#ifndef JEMALLOC_ENABLE_INLINE +double to_real1(uint32_t v); +double genrand_real1(sfmt_t *ctx); +double to_real2(uint32_t v); +double genrand_real2(sfmt_t *ctx); +double to_real3(uint32_t v); +double genrand_real3(sfmt_t *ctx); +double to_res53(uint64_t v); +double to_res53_mix(uint32_t x, uint32_t y); +double genrand_res53(sfmt_t *ctx); +double genrand_res53_mix(sfmt_t *ctx); +#endif + +#if (defined(JEMALLOC_ENABLE_INLINE) || defined(SFMT_C_)) +/* These real versions are due to Isaku Wada */ +/** generates a random number on [0,1]-real-interval */ +JEMALLOC_INLINE double to_real1(uint32_t v) +{ + return v * (1.0/4294967295.0); + /* divided by 2^32-1 */ +} + +/** generates a random number on [0,1]-real-interval */ +JEMALLOC_INLINE double genrand_real1(sfmt_t *ctx) +{ + return to_real1(gen_rand32(ctx)); +} + +/** generates a random number on [0,1)-real-interval */ +JEMALLOC_INLINE double to_real2(uint32_t v) +{ + return v * (1.0/4294967296.0); + /* divided by 2^32 */ +} + +/** generates a random number on [0,1)-real-interval */ +JEMALLOC_INLINE double genrand_real2(sfmt_t *ctx) +{ + return to_real2(gen_rand32(ctx)); +} + +/** generates a random number on (0,1)-real-interval */ +JEMALLOC_INLINE double to_real3(uint32_t v) +{ + return (((double)v) + 0.5)*(1.0/4294967296.0); + /* divided by 2^32 */ +} + +/** generates a random number on (0,1)-real-interval */ +JEMALLOC_INLINE double genrand_real3(sfmt_t *ctx) +{ + return to_real3(gen_rand32(ctx)); +} +/** These real versions are due to Isaku Wada */ + +/** generates a random number on [0,1) with 53-bit resolution*/ +JEMALLOC_INLINE double to_res53(uint64_t v) +{ + return v * (1.0/18446744073709551616.0L); +} + +/** generates a random number on [0,1) with 53-bit resolution from two + * 32 bit integers */ +JEMALLOC_INLINE double to_res53_mix(uint32_t x, uint32_t y) +{ + return to_res53(x | ((uint64_t)y << 32)); +} + +/** generates a random number on [0,1) with 53-bit resolution + */ +JEMALLOC_INLINE double genrand_res53(sfmt_t *ctx) +{ + return to_res53(gen_rand64(ctx)); +} + +/** generates a random number on [0,1) with 53-bit resolution + using 32bit integer. + */ +JEMALLOC_INLINE double genrand_res53_mix(sfmt_t *ctx) +{ + uint32_t x, y; + + x = gen_rand32(ctx); + y = gen_rand32(ctx); + return to_res53_mix(x, y); +} +#endif +#endif diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/btalloc.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/btalloc.h new file mode 100644 index 0000000..c3f9d4d --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/btalloc.h @@ -0,0 +1,31 @@ +/* btalloc() provides a mechanism for allocating via permuted backtraces. */ +void *btalloc(size_t size, unsigned bits); + +#define btalloc_n_proto(n) \ +void *btalloc_##n(size_t size, unsigned bits); +btalloc_n_proto(0) +btalloc_n_proto(1) + +#define btalloc_n_gen(n) \ +void * \ +btalloc_##n(size_t size, unsigned bits) \ +{ \ + void *p; \ + \ + if (bits == 0) \ + p = mallocx(size, 0); \ + else { \ + switch (bits & 0x1U) { \ + case 0: \ + p = (btalloc_0(size, bits >> 1)); \ + break; \ + case 1: \ + p = (btalloc_1(size, bits >> 1)); \ + break; \ + default: not_reached(); \ + } \ + } \ + /* Intentionally sabotage tail call optimization. */ \ + assert_ptr_not_null(p, "Unexpected mallocx() failure"); \ + return (p); \ +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/jemalloc_test.h.in b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/jemalloc_test.h.in new file mode 100644 index 0000000..455569d --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/jemalloc_test.h.in @@ -0,0 +1,151 @@ +#include +#ifndef SIZE_T_MAX +# define SIZE_T_MAX SIZE_MAX +#endif +#include +#include +#include +#include +#include +#include +#ifdef _WIN32 +# include "msvc_compat/strings.h" +#endif +#include + +#ifdef _WIN32 +# include +# include "msvc_compat/windows_extra.h" +#else +# include +#endif + +/******************************************************************************/ +/* + * Define always-enabled assertion macros, so that test assertions execute even + * if assertions are disabled in the library code. These definitions must + * exist prior to including "jemalloc/internal/util.h". + */ +#define assert(e) do { \ + if (!(e)) { \ + malloc_printf( \ + ": %s:%d: Failed assertion: \"%s\"\n", \ + __FILE__, __LINE__, #e); \ + abort(); \ + } \ +} while (0) + +#define not_reached() do { \ + malloc_printf( \ + ": %s:%d: Unreachable code reached\n", \ + __FILE__, __LINE__); \ + abort(); \ +} while (0) + +#define not_implemented() do { \ + malloc_printf(": %s:%d: Not implemented\n", \ + __FILE__, __LINE__); \ + abort(); \ +} while (0) + +#define assert_not_implemented(e) do { \ + if (!(e)) \ + not_implemented(); \ +} while (0) + +#include "test/jemalloc_test_defs.h" + +#ifdef JEMALLOC_OSSPIN +# include +#endif + +#if defined(HAVE_ALTIVEC) && !defined(__APPLE__) +# include +#endif +#ifdef HAVE_SSE2 +# include +#endif + +/******************************************************************************/ +/* + * For unit tests, expose all public and private interfaces. + */ +#ifdef JEMALLOC_UNIT_TEST +# define JEMALLOC_JET +# define JEMALLOC_MANGLE +# include "jemalloc/internal/jemalloc_internal.h" + +/******************************************************************************/ +/* + * For integration tests, expose the public jemalloc interfaces, but only + * expose the minimum necessary internal utility code (to avoid re-implementing + * essentially identical code within the test infrastructure). + */ +#elif defined(JEMALLOC_INTEGRATION_TEST) +# define JEMALLOC_MANGLE +# include "jemalloc/jemalloc@install_suffix@.h" +# include "jemalloc/internal/jemalloc_internal_defs.h" +# include "jemalloc/internal/jemalloc_internal_macros.h" + +# define JEMALLOC_N(n) @private_namespace@##n +# include "jemalloc/internal/private_namespace.h" + +# define JEMALLOC_H_TYPES +# define JEMALLOC_H_STRUCTS +# define JEMALLOC_H_EXTERNS +# define JEMALLOC_H_INLINES +# include "jemalloc/internal/util.h" +# include "jemalloc/internal/qr.h" +# include "jemalloc/internal/ql.h" +# undef JEMALLOC_H_TYPES +# undef JEMALLOC_H_STRUCTS +# undef JEMALLOC_H_EXTERNS +# undef JEMALLOC_H_INLINES + +/******************************************************************************/ +/* + * For stress tests, expose the public jemalloc interfaces with name mangling + * so that they can be tested as e.g. malloc() and free(). Also expose the + * public jemalloc interfaces with jet_ prefixes, so that stress tests can use + * a separate allocator for their internal data structures. + */ +#elif defined(JEMALLOC_STRESS_TEST) +# include "jemalloc/jemalloc@install_suffix@.h" + +# include "jemalloc/jemalloc_protos_jet.h" + +# define JEMALLOC_JET +# include "jemalloc/internal/jemalloc_internal.h" +# include "jemalloc/internal/public_unnamespace.h" +# undef JEMALLOC_JET + +# include "jemalloc/jemalloc_rename.h" +# define JEMALLOC_MANGLE +# ifdef JEMALLOC_STRESS_TESTLIB +# include "jemalloc/jemalloc_mangle_jet.h" +# else +# include "jemalloc/jemalloc_mangle.h" +# endif + +/******************************************************************************/ +/* + * This header does dangerous things, the effects of which only test code + * should be subject to. + */ +#else +# error "This header cannot be included outside a testing context" +#endif + +/******************************************************************************/ +/* + * Common test utilities. + */ +#include "test/btalloc.h" +#include "test/math.h" +#include "test/mtx.h" +#include "test/mq.h" +#include "test/test.h" +#include "test/timer.h" +#include "test/thd.h" +#define MEXP 19937 +#include "test/SFMT.h" diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/jemalloc_test_defs.h.in b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/jemalloc_test_defs.h.in new file mode 100644 index 0000000..5cc8532 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/jemalloc_test_defs.h.in @@ -0,0 +1,9 @@ +#include "jemalloc/internal/jemalloc_internal_defs.h" +#include "jemalloc/internal/jemalloc_internal_decls.h" + +/* + * For use by SFMT. configure.ac doesn't actually define HAVE_SSE2 because its + * dependencies are notoriously unportable in practice. + */ +#undef HAVE_SSE2 +#undef HAVE_ALTIVEC diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/math.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/math.h new file mode 100644 index 0000000..b057b29 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/math.h @@ -0,0 +1,311 @@ +#ifndef JEMALLOC_ENABLE_INLINE +double ln_gamma(double x); +double i_gamma(double x, double p, double ln_gamma_p); +double pt_norm(double p); +double pt_chi2(double p, double df, double ln_gamma_df_2); +double pt_gamma(double p, double shape, double scale, double ln_gamma_shape); +#endif + +#if (defined(JEMALLOC_ENABLE_INLINE) || defined(MATH_C_)) +/* + * Compute the natural log of Gamma(x), accurate to 10 decimal places. + * + * This implementation is based on: + * + * Pike, M.C., I.D. Hill (1966) Algorithm 291: Logarithm of Gamma function + * [S14]. Communications of the ACM 9(9):684. + */ +JEMALLOC_INLINE double +ln_gamma(double x) +{ + double f, z; + + assert(x > 0.0); + + if (x < 7.0) { + f = 1.0; + z = x; + while (z < 7.0) { + f *= z; + z += 1.0; + } + x = z; + f = -log(f); + } else + f = 0.0; + + z = 1.0 / (x * x); + + return (f + (x-0.5) * log(x) - x + 0.918938533204673 + + (((-0.000595238095238 * z + 0.000793650793651) * z - + 0.002777777777778) * z + 0.083333333333333) / x); +} + +/* + * Compute the incomplete Gamma ratio for [0..x], where p is the shape + * parameter, and ln_gamma_p is ln_gamma(p). + * + * This implementation is based on: + * + * Bhattacharjee, G.P. (1970) Algorithm AS 32: The incomplete Gamma integral. + * Applied Statistics 19:285-287. + */ +JEMALLOC_INLINE double +i_gamma(double x, double p, double ln_gamma_p) +{ + double acu, factor, oflo, gin, term, rn, a, b, an, dif; + double pn[6]; + unsigned i; + + assert(p > 0.0); + assert(x >= 0.0); + + if (x == 0.0) + return (0.0); + + acu = 1.0e-10; + oflo = 1.0e30; + gin = 0.0; + factor = exp(p * log(x) - x - ln_gamma_p); + + if (x <= 1.0 || x < p) { + /* Calculation by series expansion. */ + gin = 1.0; + term = 1.0; + rn = p; + + while (true) { + rn += 1.0; + term *= x / rn; + gin += term; + if (term <= acu) { + gin *= factor / p; + return (gin); + } + } + } else { + /* Calculation by continued fraction. */ + a = 1.0 - p; + b = a + x + 1.0; + term = 0.0; + pn[0] = 1.0; + pn[1] = x; + pn[2] = x + 1.0; + pn[3] = x * b; + gin = pn[2] / pn[3]; + + while (true) { + a += 1.0; + b += 2.0; + term += 1.0; + an = a * term; + for (i = 0; i < 2; i++) + pn[i+4] = b * pn[i+2] - an * pn[i]; + if (pn[5] != 0.0) { + rn = pn[4] / pn[5]; + dif = fabs(gin - rn); + if (dif <= acu && dif <= acu * rn) { + gin = 1.0 - factor * gin; + return (gin); + } + gin = rn; + } + for (i = 0; i < 4; i++) + pn[i] = pn[i+2]; + + if (fabs(pn[4]) >= oflo) { + for (i = 0; i < 4; i++) + pn[i] /= oflo; + } + } + } +} + +/* + * Given a value p in [0..1] of the lower tail area of the normal distribution, + * compute the limit on the definite integral from [-inf..z] that satisfies p, + * accurate to 16 decimal places. + * + * This implementation is based on: + * + * Wichura, M.J. (1988) Algorithm AS 241: The percentage points of the normal + * distribution. Applied Statistics 37(3):477-484. + */ +JEMALLOC_INLINE double +pt_norm(double p) +{ + double q, r, ret; + + assert(p > 0.0 && p < 1.0); + + q = p - 0.5; + if (fabs(q) <= 0.425) { + /* p close to 1/2. */ + r = 0.180625 - q * q; + return (q * (((((((2.5090809287301226727e3 * r + + 3.3430575583588128105e4) * r + 6.7265770927008700853e4) * r + + 4.5921953931549871457e4) * r + 1.3731693765509461125e4) * + r + 1.9715909503065514427e3) * r + 1.3314166789178437745e2) + * r + 3.3871328727963666080e0) / + (((((((5.2264952788528545610e3 * r + + 2.8729085735721942674e4) * r + 3.9307895800092710610e4) * r + + 2.1213794301586595867e4) * r + 5.3941960214247511077e3) * + r + 6.8718700749205790830e2) * r + 4.2313330701600911252e1) + * r + 1.0)); + } else { + if (q < 0.0) + r = p; + else + r = 1.0 - p; + assert(r > 0.0); + + r = sqrt(-log(r)); + if (r <= 5.0) { + /* p neither close to 1/2 nor 0 or 1. */ + r -= 1.6; + ret = ((((((((7.74545014278341407640e-4 * r + + 2.27238449892691845833e-2) * r + + 2.41780725177450611770e-1) * r + + 1.27045825245236838258e0) * r + + 3.64784832476320460504e0) * r + + 5.76949722146069140550e0) * r + + 4.63033784615654529590e0) * r + + 1.42343711074968357734e0) / + (((((((1.05075007164441684324e-9 * r + + 5.47593808499534494600e-4) * r + + 1.51986665636164571966e-2) + * r + 1.48103976427480074590e-1) * r + + 6.89767334985100004550e-1) * r + + 1.67638483018380384940e0) * r + + 2.05319162663775882187e0) * r + 1.0)); + } else { + /* p near 0 or 1. */ + r -= 5.0; + ret = ((((((((2.01033439929228813265e-7 * r + + 2.71155556874348757815e-5) * r + + 1.24266094738807843860e-3) * r + + 2.65321895265761230930e-2) * r + + 2.96560571828504891230e-1) * r + + 1.78482653991729133580e0) * r + + 5.46378491116411436990e0) * r + + 6.65790464350110377720e0) / + (((((((2.04426310338993978564e-15 * r + + 1.42151175831644588870e-7) * r + + 1.84631831751005468180e-5) * r + + 7.86869131145613259100e-4) * r + + 1.48753612908506148525e-2) * r + + 1.36929880922735805310e-1) * r + + 5.99832206555887937690e-1) + * r + 1.0)); + } + if (q < 0.0) + ret = -ret; + return (ret); + } +} + +/* + * Given a value p in [0..1] of the lower tail area of the Chi^2 distribution + * with df degrees of freedom, where ln_gamma_df_2 is ln_gamma(df/2.0), compute + * the upper limit on the definite integral from [0..z] that satisfies p, + * accurate to 12 decimal places. + * + * This implementation is based on: + * + * Best, D.J., D.E. Roberts (1975) Algorithm AS 91: The percentage points of + * the Chi^2 distribution. Applied Statistics 24(3):385-388. + * + * Shea, B.L. (1991) Algorithm AS R85: A remark on AS 91: The percentage + * points of the Chi^2 distribution. Applied Statistics 40(1):233-235. + */ +JEMALLOC_INLINE double +pt_chi2(double p, double df, double ln_gamma_df_2) +{ + double e, aa, xx, c, ch, a, q, p1, p2, t, x, b, s1, s2, s3, s4, s5, s6; + unsigned i; + + assert(p >= 0.0 && p < 1.0); + assert(df > 0.0); + + e = 5.0e-7; + aa = 0.6931471805; + + xx = 0.5 * df; + c = xx - 1.0; + + if (df < -1.24 * log(p)) { + /* Starting approximation for small Chi^2. */ + ch = pow(p * xx * exp(ln_gamma_df_2 + xx * aa), 1.0 / xx); + if (ch - e < 0.0) + return (ch); + } else { + if (df > 0.32) { + x = pt_norm(p); + /* + * Starting approximation using Wilson and Hilferty + * estimate. + */ + p1 = 0.222222 / df; + ch = df * pow(x * sqrt(p1) + 1.0 - p1, 3.0); + /* Starting approximation for p tending to 1. */ + if (ch > 2.2 * df + 6.0) { + ch = -2.0 * (log(1.0 - p) - c * log(0.5 * ch) + + ln_gamma_df_2); + } + } else { + ch = 0.4; + a = log(1.0 - p); + while (true) { + q = ch; + p1 = 1.0 + ch * (4.67 + ch); + p2 = ch * (6.73 + ch * (6.66 + ch)); + t = -0.5 + (4.67 + 2.0 * ch) / p1 - (6.73 + ch + * (13.32 + 3.0 * ch)) / p2; + ch -= (1.0 - exp(a + ln_gamma_df_2 + 0.5 * ch + + c * aa) * p2 / p1) / t; + if (fabs(q / ch - 1.0) - 0.01 <= 0.0) + break; + } + } + } + + for (i = 0; i < 20; i++) { + /* Calculation of seven-term Taylor series. */ + q = ch; + p1 = 0.5 * ch; + if (p1 < 0.0) + return (-1.0); + p2 = p - i_gamma(p1, xx, ln_gamma_df_2); + t = p2 * exp(xx * aa + ln_gamma_df_2 + p1 - c * log(ch)); + b = t / ch; + a = 0.5 * t - b * c; + s1 = (210.0 + a * (140.0 + a * (105.0 + a * (84.0 + a * (70.0 + + 60.0 * a))))) / 420.0; + s2 = (420.0 + a * (735.0 + a * (966.0 + a * (1141.0 + 1278.0 * + a)))) / 2520.0; + s3 = (210.0 + a * (462.0 + a * (707.0 + 932.0 * a))) / 2520.0; + s4 = (252.0 + a * (672.0 + 1182.0 * a) + c * (294.0 + a * + (889.0 + 1740.0 * a))) / 5040.0; + s5 = (84.0 + 264.0 * a + c * (175.0 + 606.0 * a)) / 2520.0; + s6 = (120.0 + c * (346.0 + 127.0 * c)) / 5040.0; + ch += t * (1.0 + 0.5 * t * s1 - b * c * (s1 - b * (s2 - b * (s3 + - b * (s4 - b * (s5 - b * s6)))))); + if (fabs(q / ch - 1.0) <= e) + break; + } + + return (ch); +} + +/* + * Given a value p in [0..1] and Gamma distribution shape and scale parameters, + * compute the upper limit on the definite integral from [0..z] that satisfies + * p. + */ +JEMALLOC_INLINE double +pt_gamma(double p, double shape, double scale, double ln_gamma_shape) +{ + + return (pt_chi2(p, shape * 2.0, ln_gamma_shape) * 0.5 * scale); +} +#endif diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/mq.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/mq.h new file mode 100644 index 0000000..7c4df49 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/mq.h @@ -0,0 +1,109 @@ +void mq_nanosleep(unsigned ns); + +/* + * Simple templated message queue implementation that relies on only mutexes for + * synchronization (which reduces portability issues). Given the following + * setup: + * + * typedef struct mq_msg_s mq_msg_t; + * struct mq_msg_s { + * mq_msg(mq_msg_t) link; + * [message data] + * }; + * mq_gen(, mq_, mq_t, mq_msg_t, link) + * + * The API is as follows: + * + * bool mq_init(mq_t *mq); + * void mq_fini(mq_t *mq); + * unsigned mq_count(mq_t *mq); + * mq_msg_t *mq_tryget(mq_t *mq); + * mq_msg_t *mq_get(mq_t *mq); + * void mq_put(mq_t *mq, mq_msg_t *msg); + * + * The message queue linkage embedded in each message is to be treated as + * externally opaque (no need to initialize or clean up externally). mq_fini() + * does not perform any cleanup of messages, since it knows nothing of their + * payloads. + */ +#define mq_msg(a_mq_msg_type) ql_elm(a_mq_msg_type) + +#define mq_gen(a_attr, a_prefix, a_mq_type, a_mq_msg_type, a_field) \ +typedef struct { \ + mtx_t lock; \ + ql_head(a_mq_msg_type) msgs; \ + unsigned count; \ +} a_mq_type; \ +a_attr bool \ +a_prefix##init(a_mq_type *mq) { \ + \ + if (mtx_init(&mq->lock)) \ + return (true); \ + ql_new(&mq->msgs); \ + mq->count = 0; \ + return (false); \ +} \ +a_attr void \ +a_prefix##fini(a_mq_type *mq) \ +{ \ + \ + mtx_fini(&mq->lock); \ +} \ +a_attr unsigned \ +a_prefix##count(a_mq_type *mq) \ +{ \ + unsigned count; \ + \ + mtx_lock(&mq->lock); \ + count = mq->count; \ + mtx_unlock(&mq->lock); \ + return (count); \ +} \ +a_attr a_mq_msg_type * \ +a_prefix##tryget(a_mq_type *mq) \ +{ \ + a_mq_msg_type *msg; \ + \ + mtx_lock(&mq->lock); \ + msg = ql_first(&mq->msgs); \ + if (msg != NULL) { \ + ql_head_remove(&mq->msgs, a_mq_msg_type, a_field); \ + mq->count--; \ + } \ + mtx_unlock(&mq->lock); \ + return (msg); \ +} \ +a_attr a_mq_msg_type * \ +a_prefix##get(a_mq_type *mq) \ +{ \ + a_mq_msg_type *msg; \ + unsigned ns; \ + \ + msg = a_prefix##tryget(mq); \ + if (msg != NULL) \ + return (msg); \ + \ + ns = 1; \ + while (true) { \ + mq_nanosleep(ns); \ + msg = a_prefix##tryget(mq); \ + if (msg != NULL) \ + return (msg); \ + if (ns < 1000*1000*1000) { \ + /* Double sleep time, up to max 1 second. */ \ + ns <<= 1; \ + if (ns > 1000*1000*1000) \ + ns = 1000*1000*1000; \ + } \ + } \ +} \ +a_attr void \ +a_prefix##put(a_mq_type *mq, a_mq_msg_type *msg) \ +{ \ + \ + mtx_lock(&mq->lock); \ + ql_elm_new(msg, a_field); \ + ql_tail_insert(&mq->msgs, msg, a_field); \ + mq->count++; \ + mtx_unlock(&mq->lock); \ +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/mtx.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/mtx.h new file mode 100644 index 0000000..bbe822f --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/mtx.h @@ -0,0 +1,21 @@ +/* + * mtx is a slightly simplified version of malloc_mutex. This code duplication + * is unfortunate, but there are allocator bootstrapping considerations that + * would leak into the test infrastructure if malloc_mutex were used directly + * in tests. + */ + +typedef struct { +#ifdef _WIN32 + CRITICAL_SECTION lock; +#elif (defined(JEMALLOC_OSSPIN)) + OSSpinLock lock; +#else + pthread_mutex_t lock; +#endif +} mtx_t; + +bool mtx_init(mtx_t *mtx); +void mtx_fini(mtx_t *mtx); +void mtx_lock(mtx_t *mtx); +void mtx_unlock(mtx_t *mtx); diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/test.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/test.h new file mode 100644 index 0000000..3cf901f --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/test.h @@ -0,0 +1,329 @@ +#define ASSERT_BUFSIZE 256 + +#define assert_cmp(t, a, b, cmp, neg_cmp, pri, ...) do { \ + t a_ = (a); \ + t b_ = (b); \ + if (!(a_ cmp b_)) { \ + char prefix[ASSERT_BUFSIZE]; \ + char message[ASSERT_BUFSIZE]; \ + malloc_snprintf(prefix, sizeof(prefix), \ + "%s:%s:%d: Failed assertion: " \ + "(%s) "#cmp" (%s) --> " \ + "%"pri" "#neg_cmp" %"pri": ", \ + __func__, __FILE__, __LINE__, \ + #a, #b, a_, b_); \ + malloc_snprintf(message, sizeof(message), __VA_ARGS__); \ + p_test_fail(prefix, message); \ + } \ +} while (0) + +#define assert_ptr_eq(a, b, ...) assert_cmp(void *, a, b, ==, \ + !=, "p", __VA_ARGS__) +#define assert_ptr_ne(a, b, ...) assert_cmp(void *, a, b, !=, \ + ==, "p", __VA_ARGS__) +#define assert_ptr_null(a, ...) assert_cmp(void *, a, NULL, ==, \ + !=, "p", __VA_ARGS__) +#define assert_ptr_not_null(a, ...) assert_cmp(void *, a, NULL, !=, \ + ==, "p", __VA_ARGS__) + +#define assert_c_eq(a, b, ...) assert_cmp(char, a, b, ==, !=, "c", __VA_ARGS__) +#define assert_c_ne(a, b, ...) assert_cmp(char, a, b, !=, ==, "c", __VA_ARGS__) +#define assert_c_lt(a, b, ...) assert_cmp(char, a, b, <, >=, "c", __VA_ARGS__) +#define assert_c_le(a, b, ...) assert_cmp(char, a, b, <=, >, "c", __VA_ARGS__) +#define assert_c_ge(a, b, ...) assert_cmp(char, a, b, >=, <, "c", __VA_ARGS__) +#define assert_c_gt(a, b, ...) assert_cmp(char, a, b, >, <=, "c", __VA_ARGS__) + +#define assert_x_eq(a, b, ...) assert_cmp(int, a, b, ==, !=, "#x", __VA_ARGS__) +#define assert_x_ne(a, b, ...) assert_cmp(int, a, b, !=, ==, "#x", __VA_ARGS__) +#define assert_x_lt(a, b, ...) assert_cmp(int, a, b, <, >=, "#x", __VA_ARGS__) +#define assert_x_le(a, b, ...) assert_cmp(int, a, b, <=, >, "#x", __VA_ARGS__) +#define assert_x_ge(a, b, ...) assert_cmp(int, a, b, >=, <, "#x", __VA_ARGS__) +#define assert_x_gt(a, b, ...) assert_cmp(int, a, b, >, <=, "#x", __VA_ARGS__) + +#define assert_d_eq(a, b, ...) assert_cmp(int, a, b, ==, !=, "d", __VA_ARGS__) +#define assert_d_ne(a, b, ...) assert_cmp(int, a, b, !=, ==, "d", __VA_ARGS__) +#define assert_d_lt(a, b, ...) assert_cmp(int, a, b, <, >=, "d", __VA_ARGS__) +#define assert_d_le(a, b, ...) assert_cmp(int, a, b, <=, >, "d", __VA_ARGS__) +#define assert_d_ge(a, b, ...) assert_cmp(int, a, b, >=, <, "d", __VA_ARGS__) +#define assert_d_gt(a, b, ...) assert_cmp(int, a, b, >, <=, "d", __VA_ARGS__) + +#define assert_u_eq(a, b, ...) assert_cmp(int, a, b, ==, !=, "u", __VA_ARGS__) +#define assert_u_ne(a, b, ...) assert_cmp(int, a, b, !=, ==, "u", __VA_ARGS__) +#define assert_u_lt(a, b, ...) assert_cmp(int, a, b, <, >=, "u", __VA_ARGS__) +#define assert_u_le(a, b, ...) assert_cmp(int, a, b, <=, >, "u", __VA_ARGS__) +#define assert_u_ge(a, b, ...) assert_cmp(int, a, b, >=, <, "u", __VA_ARGS__) +#define assert_u_gt(a, b, ...) assert_cmp(int, a, b, >, <=, "u", __VA_ARGS__) + +#define assert_ld_eq(a, b, ...) assert_cmp(long, a, b, ==, \ + !=, "ld", __VA_ARGS__) +#define assert_ld_ne(a, b, ...) assert_cmp(long, a, b, !=, \ + ==, "ld", __VA_ARGS__) +#define assert_ld_lt(a, b, ...) assert_cmp(long, a, b, <, \ + >=, "ld", __VA_ARGS__) +#define assert_ld_le(a, b, ...) assert_cmp(long, a, b, <=, \ + >, "ld", __VA_ARGS__) +#define assert_ld_ge(a, b, ...) assert_cmp(long, a, b, >=, \ + <, "ld", __VA_ARGS__) +#define assert_ld_gt(a, b, ...) assert_cmp(long, a, b, >, \ + <=, "ld", __VA_ARGS__) + +#define assert_lu_eq(a, b, ...) assert_cmp(unsigned long, \ + a, b, ==, !=, "lu", __VA_ARGS__) +#define assert_lu_ne(a, b, ...) assert_cmp(unsigned long, \ + a, b, !=, ==, "lu", __VA_ARGS__) +#define assert_lu_lt(a, b, ...) assert_cmp(unsigned long, \ + a, b, <, >=, "lu", __VA_ARGS__) +#define assert_lu_le(a, b, ...) assert_cmp(unsigned long, \ + a, b, <=, >, "lu", __VA_ARGS__) +#define assert_lu_ge(a, b, ...) assert_cmp(unsigned long, \ + a, b, >=, <, "lu", __VA_ARGS__) +#define assert_lu_gt(a, b, ...) assert_cmp(unsigned long, \ + a, b, >, <=, "lu", __VA_ARGS__) + +#define assert_qd_eq(a, b, ...) assert_cmp(long long, a, b, ==, \ + !=, "qd", __VA_ARGS__) +#define assert_qd_ne(a, b, ...) assert_cmp(long long, a, b, !=, \ + ==, "qd", __VA_ARGS__) +#define assert_qd_lt(a, b, ...) assert_cmp(long long, a, b, <, \ + >=, "qd", __VA_ARGS__) +#define assert_qd_le(a, b, ...) assert_cmp(long long, a, b, <=, \ + >, "qd", __VA_ARGS__) +#define assert_qd_ge(a, b, ...) assert_cmp(long long, a, b, >=, \ + <, "qd", __VA_ARGS__) +#define assert_qd_gt(a, b, ...) assert_cmp(long long, a, b, >, \ + <=, "qd", __VA_ARGS__) + +#define assert_qu_eq(a, b, ...) assert_cmp(unsigned long long, \ + a, b, ==, !=, "qu", __VA_ARGS__) +#define assert_qu_ne(a, b, ...) assert_cmp(unsigned long long, \ + a, b, !=, ==, "qu", __VA_ARGS__) +#define assert_qu_lt(a, b, ...) assert_cmp(unsigned long long, \ + a, b, <, >=, "qu", __VA_ARGS__) +#define assert_qu_le(a, b, ...) assert_cmp(unsigned long long, \ + a, b, <=, >, "qu", __VA_ARGS__) +#define assert_qu_ge(a, b, ...) assert_cmp(unsigned long long, \ + a, b, >=, <, "qu", __VA_ARGS__) +#define assert_qu_gt(a, b, ...) assert_cmp(unsigned long long, \ + a, b, >, <=, "qu", __VA_ARGS__) + +#define assert_jd_eq(a, b, ...) assert_cmp(intmax_t, a, b, ==, \ + !=, "jd", __VA_ARGS__) +#define assert_jd_ne(a, b, ...) assert_cmp(intmax_t, a, b, !=, \ + ==, "jd", __VA_ARGS__) +#define assert_jd_lt(a, b, ...) assert_cmp(intmax_t, a, b, <, \ + >=, "jd", __VA_ARGS__) +#define assert_jd_le(a, b, ...) assert_cmp(intmax_t, a, b, <=, \ + >, "jd", __VA_ARGS__) +#define assert_jd_ge(a, b, ...) assert_cmp(intmax_t, a, b, >=, \ + <, "jd", __VA_ARGS__) +#define assert_jd_gt(a, b, ...) assert_cmp(intmax_t, a, b, >, \ + <=, "jd", __VA_ARGS__) + +#define assert_ju_eq(a, b, ...) assert_cmp(uintmax_t, a, b, ==, \ + !=, "ju", __VA_ARGS__) +#define assert_ju_ne(a, b, ...) assert_cmp(uintmax_t, a, b, !=, \ + ==, "ju", __VA_ARGS__) +#define assert_ju_lt(a, b, ...) assert_cmp(uintmax_t, a, b, <, \ + >=, "ju", __VA_ARGS__) +#define assert_ju_le(a, b, ...) assert_cmp(uintmax_t, a, b, <=, \ + >, "ju", __VA_ARGS__) +#define assert_ju_ge(a, b, ...) assert_cmp(uintmax_t, a, b, >=, \ + <, "ju", __VA_ARGS__) +#define assert_ju_gt(a, b, ...) assert_cmp(uintmax_t, a, b, >, \ + <=, "ju", __VA_ARGS__) + +#define assert_zd_eq(a, b, ...) assert_cmp(ssize_t, a, b, ==, \ + !=, "zd", __VA_ARGS__) +#define assert_zd_ne(a, b, ...) assert_cmp(ssize_t, a, b, !=, \ + ==, "zd", __VA_ARGS__) +#define assert_zd_lt(a, b, ...) assert_cmp(ssize_t, a, b, <, \ + >=, "zd", __VA_ARGS__) +#define assert_zd_le(a, b, ...) assert_cmp(ssize_t, a, b, <=, \ + >, "zd", __VA_ARGS__) +#define assert_zd_ge(a, b, ...) assert_cmp(ssize_t, a, b, >=, \ + <, "zd", __VA_ARGS__) +#define assert_zd_gt(a, b, ...) assert_cmp(ssize_t, a, b, >, \ + <=, "zd", __VA_ARGS__) + +#define assert_zu_eq(a, b, ...) assert_cmp(size_t, a, b, ==, \ + !=, "zu", __VA_ARGS__) +#define assert_zu_ne(a, b, ...) assert_cmp(size_t, a, b, !=, \ + ==, "zu", __VA_ARGS__) +#define assert_zu_lt(a, b, ...) assert_cmp(size_t, a, b, <, \ + >=, "zu", __VA_ARGS__) +#define assert_zu_le(a, b, ...) assert_cmp(size_t, a, b, <=, \ + >, "zu", __VA_ARGS__) +#define assert_zu_ge(a, b, ...) assert_cmp(size_t, a, b, >=, \ + <, "zu", __VA_ARGS__) +#define assert_zu_gt(a, b, ...) assert_cmp(size_t, a, b, >, \ + <=, "zu", __VA_ARGS__) + +#define assert_d32_eq(a, b, ...) assert_cmp(int32_t, a, b, ==, \ + !=, FMTd32, __VA_ARGS__) +#define assert_d32_ne(a, b, ...) assert_cmp(int32_t, a, b, !=, \ + ==, FMTd32, __VA_ARGS__) +#define assert_d32_lt(a, b, ...) assert_cmp(int32_t, a, b, <, \ + >=, FMTd32, __VA_ARGS__) +#define assert_d32_le(a, b, ...) assert_cmp(int32_t, a, b, <=, \ + >, FMTd32, __VA_ARGS__) +#define assert_d32_ge(a, b, ...) assert_cmp(int32_t, a, b, >=, \ + <, FMTd32, __VA_ARGS__) +#define assert_d32_gt(a, b, ...) assert_cmp(int32_t, a, b, >, \ + <=, FMTd32, __VA_ARGS__) + +#define assert_u32_eq(a, b, ...) assert_cmp(uint32_t, a, b, ==, \ + !=, FMTu32, __VA_ARGS__) +#define assert_u32_ne(a, b, ...) assert_cmp(uint32_t, a, b, !=, \ + ==, FMTu32, __VA_ARGS__) +#define assert_u32_lt(a, b, ...) assert_cmp(uint32_t, a, b, <, \ + >=, FMTu32, __VA_ARGS__) +#define assert_u32_le(a, b, ...) assert_cmp(uint32_t, a, b, <=, \ + >, FMTu32, __VA_ARGS__) +#define assert_u32_ge(a, b, ...) assert_cmp(uint32_t, a, b, >=, \ + <, FMTu32, __VA_ARGS__) +#define assert_u32_gt(a, b, ...) assert_cmp(uint32_t, a, b, >, \ + <=, FMTu32, __VA_ARGS__) + +#define assert_d64_eq(a, b, ...) assert_cmp(int64_t, a, b, ==, \ + !=, FMTd64, __VA_ARGS__) +#define assert_d64_ne(a, b, ...) assert_cmp(int64_t, a, b, !=, \ + ==, FMTd64, __VA_ARGS__) +#define assert_d64_lt(a, b, ...) assert_cmp(int64_t, a, b, <, \ + >=, FMTd64, __VA_ARGS__) +#define assert_d64_le(a, b, ...) assert_cmp(int64_t, a, b, <=, \ + >, FMTd64, __VA_ARGS__) +#define assert_d64_ge(a, b, ...) assert_cmp(int64_t, a, b, >=, \ + <, FMTd64, __VA_ARGS__) +#define assert_d64_gt(a, b, ...) assert_cmp(int64_t, a, b, >, \ + <=, FMTd64, __VA_ARGS__) + +#define assert_u64_eq(a, b, ...) assert_cmp(uint64_t, a, b, ==, \ + !=, FMTu64, __VA_ARGS__) +#define assert_u64_ne(a, b, ...) assert_cmp(uint64_t, a, b, !=, \ + ==, FMTu64, __VA_ARGS__) +#define assert_u64_lt(a, b, ...) assert_cmp(uint64_t, a, b, <, \ + >=, FMTu64, __VA_ARGS__) +#define assert_u64_le(a, b, ...) assert_cmp(uint64_t, a, b, <=, \ + >, FMTu64, __VA_ARGS__) +#define assert_u64_ge(a, b, ...) assert_cmp(uint64_t, a, b, >=, \ + <, FMTu64, __VA_ARGS__) +#define assert_u64_gt(a, b, ...) assert_cmp(uint64_t, a, b, >, \ + <=, FMTu64, __VA_ARGS__) + +#define assert_b_eq(a, b, ...) do { \ + bool a_ = (a); \ + bool b_ = (b); \ + if (!(a_ == b_)) { \ + char prefix[ASSERT_BUFSIZE]; \ + char message[ASSERT_BUFSIZE]; \ + malloc_snprintf(prefix, sizeof(prefix), \ + "%s:%s:%d: Failed assertion: " \ + "(%s) == (%s) --> %s != %s: ", \ + __func__, __FILE__, __LINE__, \ + #a, #b, a_ ? "true" : "false", \ + b_ ? "true" : "false"); \ + malloc_snprintf(message, sizeof(message), __VA_ARGS__); \ + p_test_fail(prefix, message); \ + } \ +} while (0) +#define assert_b_ne(a, b, ...) do { \ + bool a_ = (a); \ + bool b_ = (b); \ + if (!(a_ != b_)) { \ + char prefix[ASSERT_BUFSIZE]; \ + char message[ASSERT_BUFSIZE]; \ + malloc_snprintf(prefix, sizeof(prefix), \ + "%s:%s:%d: Failed assertion: " \ + "(%s) != (%s) --> %s == %s: ", \ + __func__, __FILE__, __LINE__, \ + #a, #b, a_ ? "true" : "false", \ + b_ ? "true" : "false"); \ + malloc_snprintf(message, sizeof(message), __VA_ARGS__); \ + p_test_fail(prefix, message); \ + } \ +} while (0) +#define assert_true(a, ...) assert_b_eq(a, true, __VA_ARGS__) +#define assert_false(a, ...) assert_b_eq(a, false, __VA_ARGS__) + +#define assert_str_eq(a, b, ...) do { \ + if (strcmp((a), (b))) { \ + char prefix[ASSERT_BUFSIZE]; \ + char message[ASSERT_BUFSIZE]; \ + malloc_snprintf(prefix, sizeof(prefix), \ + "%s:%s:%d: Failed assertion: " \ + "(%s) same as (%s) --> " \ + "\"%s\" differs from \"%s\": ", \ + __func__, __FILE__, __LINE__, #a, #b, a, b); \ + malloc_snprintf(message, sizeof(message), __VA_ARGS__); \ + p_test_fail(prefix, message); \ + } \ +} while (0) +#define assert_str_ne(a, b, ...) do { \ + if (!strcmp((a), (b))) { \ + char prefix[ASSERT_BUFSIZE]; \ + char message[ASSERT_BUFSIZE]; \ + malloc_snprintf(prefix, sizeof(prefix), \ + "%s:%s:%d: Failed assertion: " \ + "(%s) differs from (%s) --> " \ + "\"%s\" same as \"%s\": ", \ + __func__, __FILE__, __LINE__, #a, #b, a, b); \ + malloc_snprintf(message, sizeof(message), __VA_ARGS__); \ + p_test_fail(prefix, message); \ + } \ +} while (0) + +#define assert_not_reached(...) do { \ + char prefix[ASSERT_BUFSIZE]; \ + char message[ASSERT_BUFSIZE]; \ + malloc_snprintf(prefix, sizeof(prefix), \ + "%s:%s:%d: Unreachable code reached: ", \ + __func__, __FILE__, __LINE__); \ + malloc_snprintf(message, sizeof(message), __VA_ARGS__); \ + p_test_fail(prefix, message); \ +} while (0) + +/* + * If this enum changes, corresponding changes in test/test.sh.in are also + * necessary. + */ +typedef enum { + test_status_pass = 0, + test_status_skip = 1, + test_status_fail = 2, + + test_status_count = 3 +} test_status_t; + +typedef void (test_t)(void); + +#define TEST_BEGIN(f) \ +static void \ +f(void) \ +{ \ + p_test_init(#f); + +#define TEST_END \ + goto label_test_end; \ +label_test_end: \ + p_test_fini(); \ +} + +#define test(...) \ + p_test(__VA_ARGS__, NULL) + +#define test_skip_if(e) do { \ + if (e) { \ + test_skip("%s:%s:%d: Test skipped: (%s)", \ + __func__, __FILE__, __LINE__, #e); \ + goto label_test_end; \ + } \ +} while (0) + +void test_skip(const char *format, ...) JEMALLOC_FORMAT_PRINTF(1, 2); +void test_fail(const char *format, ...) JEMALLOC_FORMAT_PRINTF(1, 2); + +/* For private use by macros. */ +test_status_t p_test(test_t *t, ...); +void p_test_init(const char *name); +void p_test_fini(void); +void p_test_fail(const char *prefix, const char *message); diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/thd.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/thd.h new file mode 100644 index 0000000..47a5126 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/thd.h @@ -0,0 +1,9 @@ +/* Abstraction layer for threading in tests. */ +#ifdef _WIN32 +typedef HANDLE thd_t; +#else +typedef pthread_t thd_t; +#endif + +void thd_create(thd_t *thd, void *(*proc)(void *), void *arg); +void thd_join(thd_t thd, void **ret); diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/timer.h b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/timer.h new file mode 100644 index 0000000..a7fefdf --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/include/test/timer.h @@ -0,0 +1,26 @@ +/* Simple timer, for use in benchmark reporting. */ + +#include +#include + +#define JEMALLOC_CLOCK_GETTIME defined(_POSIX_MONOTONIC_CLOCK) \ + && _POSIX_MONOTONIC_CLOCK >= 0 + +typedef struct { +#ifdef _WIN32 + FILETIME ft0; + FILETIME ft1; +#elif JEMALLOC_CLOCK_GETTIME + struct timespec ts0; + struct timespec ts1; + int clock_id; +#else + struct timeval tv0; + struct timeval tv1; +#endif +} timedelta_t; + +void timer_start(timedelta_t *timer); +void timer_stop(timedelta_t *timer); +uint64_t timer_usec(const timedelta_t *timer); +void timer_ratio(timedelta_t *a, timedelta_t *b, char *buf, size_t buflen); diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/MALLOCX_ARENA.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/MALLOCX_ARENA.c new file mode 100644 index 0000000..30c203a --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/MALLOCX_ARENA.c @@ -0,0 +1,69 @@ +#include "test/jemalloc_test.h" + +#define NTHREADS 10 + +static bool have_dss = +#ifdef JEMALLOC_DSS + true +#else + false +#endif + ; + +void * +thd_start(void *arg) +{ + unsigned thread_ind = (unsigned)(uintptr_t)arg; + unsigned arena_ind; + void *p; + size_t sz; + + sz = sizeof(arena_ind); + assert_d_eq(mallctl("arenas.extend", &arena_ind, &sz, NULL, 0), 0, + "Error in arenas.extend"); + + if (thread_ind % 4 != 3) { + size_t mib[3]; + size_t miblen = sizeof(mib) / sizeof(size_t); + const char *dss_precs[] = {"disabled", "primary", "secondary"}; + unsigned prec_ind = thread_ind % + (sizeof(dss_precs)/sizeof(char*)); + const char *dss = dss_precs[prec_ind]; + int expected_err = (have_dss || prec_ind == 0) ? 0 : EFAULT; + assert_d_eq(mallctlnametomib("arena.0.dss", mib, &miblen), 0, + "Error in mallctlnametomib()"); + mib[1] = arena_ind; + assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, (void *)&dss, + sizeof(const char *)), expected_err, + "Error in mallctlbymib()"); + } + + p = mallocx(1, MALLOCX_ARENA(arena_ind)); + assert_ptr_not_null(p, "Unexpected mallocx() error"); + dallocx(p, 0); + + return (NULL); +} + +TEST_BEGIN(test_MALLOCX_ARENA) +{ + thd_t thds[NTHREADS]; + unsigned i; + + for (i = 0; i < NTHREADS; i++) { + thd_create(&thds[i], thd_start, + (void *)(uintptr_t)i); + } + + for (i = 0; i < NTHREADS; i++) + thd_join(thds[i], NULL); +} +TEST_END + +int +main(void) +{ + + return (test( + test_MALLOCX_ARENA)); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/aligned_alloc.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/aligned_alloc.c new file mode 100644 index 0000000..6090014 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/aligned_alloc.c @@ -0,0 +1,125 @@ +#include "test/jemalloc_test.h" + +#define CHUNK 0x400000 +/* #define MAXALIGN ((size_t)UINT64_C(0x80000000000)) */ +#define MAXALIGN ((size_t)0x2000000LU) +#define NITER 4 + +TEST_BEGIN(test_alignment_errors) +{ + size_t alignment; + void *p; + + alignment = 0; + set_errno(0); + p = aligned_alloc(alignment, 1); + assert_false(p != NULL || get_errno() != EINVAL, + "Expected error for invalid alignment %zu", alignment); + + for (alignment = sizeof(size_t); alignment < MAXALIGN; + alignment <<= 1) { + set_errno(0); + p = aligned_alloc(alignment + 1, 1); + assert_false(p != NULL || get_errno() != EINVAL, + "Expected error for invalid alignment %zu", + alignment + 1); + } +} +TEST_END + +TEST_BEGIN(test_oom_errors) +{ + size_t alignment, size; + void *p; + +#if LG_SIZEOF_PTR == 3 + alignment = UINT64_C(0x8000000000000000); + size = UINT64_C(0x8000000000000000); +#else + alignment = 0x80000000LU; + size = 0x80000000LU; +#endif + set_errno(0); + p = aligned_alloc(alignment, size); + assert_false(p != NULL || get_errno() != ENOMEM, + "Expected error for aligned_alloc(%zu, %zu)", + alignment, size); + +#if LG_SIZEOF_PTR == 3 + alignment = UINT64_C(0x4000000000000000); + size = UINT64_C(0xc000000000000001); +#else + alignment = 0x40000000LU; + size = 0xc0000001LU; +#endif + set_errno(0); + p = aligned_alloc(alignment, size); + assert_false(p != NULL || get_errno() != ENOMEM, + "Expected error for aligned_alloc(%zu, %zu)", + alignment, size); + + alignment = 0x10LU; +#if LG_SIZEOF_PTR == 3 + size = UINT64_C(0xfffffffffffffff0); +#else + size = 0xfffffff0LU; +#endif + set_errno(0); + p = aligned_alloc(alignment, size); + assert_false(p != NULL || get_errno() != ENOMEM, + "Expected error for aligned_alloc(&p, %zu, %zu)", + alignment, size); +} +TEST_END + +TEST_BEGIN(test_alignment_and_size) +{ + size_t alignment, size, total; + unsigned i; + void *ps[NITER]; + + for (i = 0; i < NITER; i++) + ps[i] = NULL; + + for (alignment = 8; + alignment <= MAXALIGN; + alignment <<= 1) { + total = 0; + for (size = 1; + size < 3 * alignment && size < (1U << 31); + size += (alignment >> (LG_SIZEOF_PTR-1)) - 1) { + for (i = 0; i < NITER; i++) { + ps[i] = aligned_alloc(alignment, size); + if (ps[i] == NULL) { + char buf[BUFERROR_BUF]; + + buferror(get_errno(), buf, sizeof(buf)); + test_fail( + "Error for alignment=%zu, " + "size=%zu (%#zx): %s", + alignment, size, size, buf); + } + total += malloc_usable_size(ps[i]); + if (total >= (MAXALIGN << 1)) + break; + } + for (i = 0; i < NITER; i++) { + if (ps[i] != NULL) { + free(ps[i]); + ps[i] = NULL; + } + } + } + } +} +TEST_END + +int +main(void) +{ + + return (test( + test_alignment_errors, + test_oom_errors, + test_alignment_and_size)); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/allocated.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/allocated.c new file mode 100644 index 0000000..3630e80 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/allocated.c @@ -0,0 +1,125 @@ +#include "test/jemalloc_test.h" + +static const bool config_stats = +#ifdef JEMALLOC_STATS + true +#else + false +#endif + ; + +void * +thd_start(void *arg) +{ + int err; + void *p; + uint64_t a0, a1, d0, d1; + uint64_t *ap0, *ap1, *dp0, *dp1; + size_t sz, usize; + + sz = sizeof(a0); + if ((err = mallctl("thread.allocated", &a0, &sz, NULL, 0))) { + if (err == ENOENT) + goto label_ENOENT; + test_fail("%s(): Error in mallctl(): %s", __func__, + strerror(err)); + } + sz = sizeof(ap0); + if ((err = mallctl("thread.allocatedp", &ap0, &sz, NULL, 0))) { + if (err == ENOENT) + goto label_ENOENT; + test_fail("%s(): Error in mallctl(): %s", __func__, + strerror(err)); + } + assert_u64_eq(*ap0, a0, + "\"thread.allocatedp\" should provide a pointer to internal " + "storage"); + + sz = sizeof(d0); + if ((err = mallctl("thread.deallocated", &d0, &sz, NULL, 0))) { + if (err == ENOENT) + goto label_ENOENT; + test_fail("%s(): Error in mallctl(): %s", __func__, + strerror(err)); + } + sz = sizeof(dp0); + if ((err = mallctl("thread.deallocatedp", &dp0, &sz, NULL, 0))) { + if (err == ENOENT) + goto label_ENOENT; + test_fail("%s(): Error in mallctl(): %s", __func__, + strerror(err)); + } + assert_u64_eq(*dp0, d0, + "\"thread.deallocatedp\" should provide a pointer to internal " + "storage"); + + p = malloc(1); + assert_ptr_not_null(p, "Unexpected malloc() error"); + + sz = sizeof(a1); + mallctl("thread.allocated", &a1, &sz, NULL, 0); + sz = sizeof(ap1); + mallctl("thread.allocatedp", &ap1, &sz, NULL, 0); + assert_u64_eq(*ap1, a1, + "Dereferenced \"thread.allocatedp\" value should equal " + "\"thread.allocated\" value"); + assert_ptr_eq(ap0, ap1, + "Pointer returned by \"thread.allocatedp\" should not change"); + + usize = malloc_usable_size(p); + assert_u64_le(a0 + usize, a1, + "Allocated memory counter should increase by at least the amount " + "explicitly allocated"); + + free(p); + + sz = sizeof(d1); + mallctl("thread.deallocated", &d1, &sz, NULL, 0); + sz = sizeof(dp1); + mallctl("thread.deallocatedp", &dp1, &sz, NULL, 0); + assert_u64_eq(*dp1, d1, + "Dereferenced \"thread.deallocatedp\" value should equal " + "\"thread.deallocated\" value"); + assert_ptr_eq(dp0, dp1, + "Pointer returned by \"thread.deallocatedp\" should not change"); + + assert_u64_le(d0 + usize, d1, + "Deallocated memory counter should increase by at least the amount " + "explicitly deallocated"); + + return (NULL); +label_ENOENT: + assert_false(config_stats, + "ENOENT should only be returned if stats are disabled"); + test_skip("\"thread.allocated\" mallctl not available"); + return (NULL); +} + +TEST_BEGIN(test_main_thread) +{ + + thd_start(NULL); +} +TEST_END + +TEST_BEGIN(test_subthread) +{ + thd_t thd; + + thd_create(&thd, thd_start, NULL); + thd_join(thd, NULL); +} +TEST_END + +int +main(void) +{ + + /* Run tests multiple times to check for bad interactions. */ + return (test( + test_main_thread, + test_subthread, + test_main_thread, + test_subthread, + test_main_thread)); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/chunk.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/chunk.c new file mode 100644 index 0000000..af1c9a5 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/chunk.c @@ -0,0 +1,276 @@ +#include "test/jemalloc_test.h" + +#ifdef JEMALLOC_FILL +const char *malloc_conf = "junk:false"; +#endif + +static chunk_hooks_t orig_hooks; +static chunk_hooks_t old_hooks; + +static bool do_dalloc = true; +static bool do_decommit; + +static bool did_alloc; +static bool did_dalloc; +static bool did_commit; +static bool did_decommit; +static bool did_purge; +static bool did_split; +static bool did_merge; + +#if 0 +# define TRACE_HOOK(fmt, ...) malloc_printf(fmt, __VA_ARGS__) +#else +# define TRACE_HOOK(fmt, ...) +#endif + +void * +chunk_alloc(void *new_addr, size_t size, size_t alignment, bool *zero, + bool *commit, unsigned arena_ind) +{ + + TRACE_HOOK("%s(new_addr=%p, size=%zu, alignment=%zu, *zero=%s, " + "*commit=%s, arena_ind=%u)\n", __func__, new_addr, size, alignment, + *zero ? "true" : "false", *commit ? "true" : "false", arena_ind); + did_alloc = true; + return (old_hooks.alloc(new_addr, size, alignment, zero, commit, + arena_ind)); +} + +bool +chunk_dalloc(void *chunk, size_t size, bool committed, unsigned arena_ind) +{ + + TRACE_HOOK("%s(chunk=%p, size=%zu, committed=%s, arena_ind=%u)\n", + __func__, chunk, size, committed ? "true" : "false", arena_ind); + did_dalloc = true; + if (!do_dalloc) + return (true); + return (old_hooks.dalloc(chunk, size, committed, arena_ind)); +} + +bool +chunk_commit(void *chunk, size_t size, size_t offset, size_t length, + unsigned arena_ind) +{ + bool err; + + TRACE_HOOK("%s(chunk=%p, size=%zu, offset=%zu, length=%zu, " + "arena_ind=%u)\n", __func__, chunk, size, offset, length, + arena_ind); + err = old_hooks.commit(chunk, size, offset, length, arena_ind); + did_commit = !err; + return (err); +} + +bool +chunk_decommit(void *chunk, size_t size, size_t offset, size_t length, + unsigned arena_ind) +{ + bool err; + + TRACE_HOOK("%s(chunk=%p, size=%zu, offset=%zu, length=%zu, " + "arena_ind=%u)\n", __func__, chunk, size, offset, length, + arena_ind); + if (!do_decommit) + return (true); + err = old_hooks.decommit(chunk, size, offset, length, arena_ind); + did_decommit = !err; + return (err); +} + +bool +chunk_purge(void *chunk, size_t size, size_t offset, size_t length, + unsigned arena_ind) +{ + + TRACE_HOOK("%s(chunk=%p, size=%zu, offset=%zu, length=%zu " + "arena_ind=%u)\n", __func__, chunk, size, offset, length, + arena_ind); + did_purge = true; + return (old_hooks.purge(chunk, size, offset, length, arena_ind)); +} + +bool +chunk_split(void *chunk, size_t size, size_t size_a, size_t size_b, + bool committed, unsigned arena_ind) +{ + + TRACE_HOOK("%s(chunk=%p, size=%zu, size_a=%zu, size_b=%zu, " + "committed=%s, arena_ind=%u)\n", __func__, chunk, size, size_a, + size_b, committed ? "true" : "false", arena_ind); + did_split = true; + return (old_hooks.split(chunk, size, size_a, size_b, committed, + arena_ind)); +} + +bool +chunk_merge(void *chunk_a, size_t size_a, void *chunk_b, size_t size_b, + bool committed, unsigned arena_ind) +{ + + TRACE_HOOK("%s(chunk_a=%p, size_a=%zu, chunk_b=%p size_b=%zu, " + "committed=%s, arena_ind=%u)\n", __func__, chunk_a, size_a, chunk_b, + size_b, committed ? "true" : "false", arena_ind); + did_merge = true; + return (old_hooks.merge(chunk_a, size_a, chunk_b, size_b, + committed, arena_ind)); +} + +TEST_BEGIN(test_chunk) +{ + void *p; + size_t old_size, new_size, large0, large1, huge0, huge1, huge2, sz; + chunk_hooks_t new_hooks = { + chunk_alloc, + chunk_dalloc, + chunk_commit, + chunk_decommit, + chunk_purge, + chunk_split, + chunk_merge + }; + bool xallocx_success_a, xallocx_success_b, xallocx_success_c; + + /* Install custom chunk hooks. */ + old_size = sizeof(chunk_hooks_t); + new_size = sizeof(chunk_hooks_t); + assert_d_eq(mallctl("arena.0.chunk_hooks", &old_hooks, &old_size, + &new_hooks, new_size), 0, "Unexpected chunk_hooks error"); + orig_hooks = old_hooks; + assert_ptr_ne(old_hooks.alloc, chunk_alloc, "Unexpected alloc error"); + assert_ptr_ne(old_hooks.dalloc, chunk_dalloc, + "Unexpected dalloc error"); + assert_ptr_ne(old_hooks.commit, chunk_commit, + "Unexpected commit error"); + assert_ptr_ne(old_hooks.decommit, chunk_decommit, + "Unexpected decommit error"); + assert_ptr_ne(old_hooks.purge, chunk_purge, "Unexpected purge error"); + assert_ptr_ne(old_hooks.split, chunk_split, "Unexpected split error"); + assert_ptr_ne(old_hooks.merge, chunk_merge, "Unexpected merge error"); + + /* Get large size classes. */ + sz = sizeof(size_t); + assert_d_eq(mallctl("arenas.lrun.0.size", &large0, &sz, NULL, 0), 0, + "Unexpected arenas.lrun.0.size failure"); + assert_d_eq(mallctl("arenas.lrun.1.size", &large1, &sz, NULL, 0), 0, + "Unexpected arenas.lrun.1.size failure"); + + /* Get huge size classes. */ + assert_d_eq(mallctl("arenas.hchunk.0.size", &huge0, &sz, NULL, 0), 0, + "Unexpected arenas.hchunk.0.size failure"); + assert_d_eq(mallctl("arenas.hchunk.1.size", &huge1, &sz, NULL, 0), 0, + "Unexpected arenas.hchunk.1.size failure"); + assert_d_eq(mallctl("arenas.hchunk.2.size", &huge2, &sz, NULL, 0), 0, + "Unexpected arenas.hchunk.2.size failure"); + + /* Test dalloc/decommit/purge cascade. */ + do_dalloc = false; + do_decommit = false; + p = mallocx(huge0 * 2, 0); + assert_ptr_not_null(p, "Unexpected mallocx() error"); + did_dalloc = false; + did_decommit = false; + did_purge = false; + did_split = false; + xallocx_success_a = (xallocx(p, huge0, 0, 0) == huge0); + assert_d_eq(mallctl("arena.0.purge", NULL, NULL, NULL, 0), 0, + "Unexpected arena.0.purge error"); + if (xallocx_success_a) { + assert_true(did_dalloc, "Expected dalloc"); + assert_false(did_decommit, "Unexpected decommit"); + assert_true(did_purge, "Expected purge"); + } + assert_true(did_split, "Expected split"); + dallocx(p, 0); + do_dalloc = true; + + /* Test decommit/commit and observe split/merge. */ + do_dalloc = false; + do_decommit = true; + p = mallocx(huge0 * 2, 0); + assert_ptr_not_null(p, "Unexpected mallocx() error"); + did_decommit = false; + did_commit = false; + did_split = false; + did_merge = false; + xallocx_success_b = (xallocx(p, huge0, 0, 0) == huge0); + assert_d_eq(mallctl("arena.0.purge", NULL, NULL, NULL, 0), 0, + "Unexpected arena.0.purge error"); + if (xallocx_success_b) + assert_true(did_split, "Expected split"); + xallocx_success_c = (xallocx(p, huge0 * 2, 0, 0) == huge0 * 2); + assert_b_eq(did_decommit, did_commit, "Expected decommit/commit match"); + if (xallocx_success_b && xallocx_success_c) + assert_true(did_merge, "Expected merge"); + dallocx(p, 0); + do_dalloc = true; + do_decommit = false; + + /* Test purge for partial-chunk huge allocations. */ + if (huge0 * 2 > huge2) { + /* + * There are at least four size classes per doubling, so a + * successful xallocx() from size=huge2 to size=huge1 is + * guaranteed to leave trailing purgeable memory. + */ + p = mallocx(huge2, 0); + assert_ptr_not_null(p, "Unexpected mallocx() error"); + did_purge = false; + assert_zu_eq(xallocx(p, huge1, 0, 0), huge1, + "Unexpected xallocx() failure"); + assert_true(did_purge, "Expected purge"); + dallocx(p, 0); + } + + /* Test decommit for large allocations. */ + do_decommit = true; + p = mallocx(large1, 0); + assert_ptr_not_null(p, "Unexpected mallocx() error"); + assert_d_eq(mallctl("arena.0.purge", NULL, NULL, NULL, 0), 0, + "Unexpected arena.0.purge error"); + did_decommit = false; + assert_zu_eq(xallocx(p, large0, 0, 0), large0, + "Unexpected xallocx() failure"); + assert_d_eq(mallctl("arena.0.purge", NULL, NULL, NULL, 0), 0, + "Unexpected arena.0.purge error"); + did_commit = false; + assert_zu_eq(xallocx(p, large1, 0, 0), large1, + "Unexpected xallocx() failure"); + assert_b_eq(did_decommit, did_commit, "Expected decommit/commit match"); + dallocx(p, 0); + do_decommit = false; + + /* Make sure non-huge allocation succeeds. */ + p = mallocx(42, 0); + assert_ptr_not_null(p, "Unexpected mallocx() error"); + dallocx(p, 0); + + /* Restore chunk hooks. */ + assert_d_eq(mallctl("arena.0.chunk_hooks", NULL, NULL, &old_hooks, + new_size), 0, "Unexpected chunk_hooks error"); + assert_d_eq(mallctl("arena.0.chunk_hooks", &old_hooks, &old_size, + NULL, 0), 0, "Unexpected chunk_hooks error"); + assert_ptr_eq(old_hooks.alloc, orig_hooks.alloc, + "Unexpected alloc error"); + assert_ptr_eq(old_hooks.dalloc, orig_hooks.dalloc, + "Unexpected dalloc error"); + assert_ptr_eq(old_hooks.commit, orig_hooks.commit, + "Unexpected commit error"); + assert_ptr_eq(old_hooks.decommit, orig_hooks.decommit, + "Unexpected decommit error"); + assert_ptr_eq(old_hooks.purge, orig_hooks.purge, + "Unexpected purge error"); + assert_ptr_eq(old_hooks.split, orig_hooks.split, + "Unexpected split error"); + assert_ptr_eq(old_hooks.merge, orig_hooks.merge, + "Unexpected merge error"); +} +TEST_END + +int +main(void) +{ + + return (test(test_chunk)); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/mallocx.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/mallocx.c new file mode 100644 index 0000000..6253175 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/mallocx.c @@ -0,0 +1,182 @@ +#include "test/jemalloc_test.h" + +static unsigned +get_nsizes_impl(const char *cmd) +{ + unsigned ret; + size_t z; + + z = sizeof(unsigned); + assert_d_eq(mallctl(cmd, &ret, &z, NULL, 0), 0, + "Unexpected mallctl(\"%s\", ...) failure", cmd); + + return (ret); +} + +static unsigned +get_nhuge(void) +{ + + return (get_nsizes_impl("arenas.nhchunks")); +} + +static size_t +get_size_impl(const char *cmd, size_t ind) +{ + size_t ret; + size_t z; + size_t mib[4]; + size_t miblen = 4; + + z = sizeof(size_t); + assert_d_eq(mallctlnametomib(cmd, mib, &miblen), + 0, "Unexpected mallctlnametomib(\"%s\", ...) failure", cmd); + mib[2] = ind; + z = sizeof(size_t); + assert_d_eq(mallctlbymib(mib, miblen, &ret, &z, NULL, 0), + 0, "Unexpected mallctlbymib([\"%s\", %zu], ...) failure", cmd, ind); + + return (ret); +} + +static size_t +get_huge_size(size_t ind) +{ + + return (get_size_impl("arenas.hchunk.0.size", ind)); +} + +TEST_BEGIN(test_oom) +{ + size_t hugemax, size, alignment; + + hugemax = get_huge_size(get_nhuge()-1); + + /* + * It should be impossible to allocate two objects that each consume + * more than half the virtual address space. + */ + { + void *p; + + p = mallocx(hugemax, 0); + if (p != NULL) { + assert_ptr_null(mallocx(hugemax, 0), + "Expected OOM for mallocx(size=%#zx, 0)", hugemax); + dallocx(p, 0); + } + } + +#if LG_SIZEOF_PTR == 3 + size = ZU(0x8000000000000000); + alignment = ZU(0x8000000000000000); +#else + size = ZU(0x80000000); + alignment = ZU(0x80000000); +#endif + assert_ptr_null(mallocx(size, MALLOCX_ALIGN(alignment)), + "Expected OOM for mallocx(size=%#zx, MALLOCX_ALIGN(%#zx)", size, + alignment); +} +TEST_END + +TEST_BEGIN(test_basic) +{ +#define MAXSZ (((size_t)1) << 26) + size_t sz; + + for (sz = 1; sz < MAXSZ; sz = nallocx(sz, 0) + 1) { + size_t nsz, rsz; + void *p; + nsz = nallocx(sz, 0); + assert_zu_ne(nsz, 0, "Unexpected nallocx() error"); + p = mallocx(sz, 0); + assert_ptr_not_null(p, "Unexpected mallocx() error"); + rsz = sallocx(p, 0); + assert_zu_ge(rsz, sz, "Real size smaller than expected"); + assert_zu_eq(nsz, rsz, "nallocx()/sallocx() size mismatch"); + dallocx(p, 0); + + p = mallocx(sz, 0); + assert_ptr_not_null(p, "Unexpected mallocx() error"); + dallocx(p, 0); + + nsz = nallocx(sz, MALLOCX_ZERO); + assert_zu_ne(nsz, 0, "Unexpected nallocx() error"); + p = mallocx(sz, MALLOCX_ZERO); + assert_ptr_not_null(p, "Unexpected mallocx() error"); + rsz = sallocx(p, 0); + assert_zu_eq(nsz, rsz, "nallocx()/sallocx() rsize mismatch"); + dallocx(p, 0); + } +#undef MAXSZ +} +TEST_END + +TEST_BEGIN(test_alignment_and_size) +{ +#define MAXALIGN (((size_t)1) << 25) +#define NITER 4 + size_t nsz, rsz, sz, alignment, total; + unsigned i; + void *ps[NITER]; + + for (i = 0; i < NITER; i++) + ps[i] = NULL; + + for (alignment = 8; + alignment <= MAXALIGN; + alignment <<= 1) { + total = 0; + for (sz = 1; + sz < 3 * alignment && sz < (1U << 31); + sz += (alignment >> (LG_SIZEOF_PTR-1)) - 1) { + for (i = 0; i < NITER; i++) { + nsz = nallocx(sz, MALLOCX_ALIGN(alignment) | + MALLOCX_ZERO); + assert_zu_ne(nsz, 0, + "nallocx() error for alignment=%zu, " + "size=%zu (%#zx)", alignment, sz, sz); + ps[i] = mallocx(sz, MALLOCX_ALIGN(alignment) | + MALLOCX_ZERO); + assert_ptr_not_null(ps[i], + "mallocx() error for alignment=%zu, " + "size=%zu (%#zx)", alignment, sz, sz); + rsz = sallocx(ps[i], 0); + assert_zu_ge(rsz, sz, + "Real size smaller than expected for " + "alignment=%zu, size=%zu", alignment, sz); + assert_zu_eq(nsz, rsz, + "nallocx()/sallocx() size mismatch for " + "alignment=%zu, size=%zu", alignment, sz); + assert_ptr_null( + (void *)((uintptr_t)ps[i] & (alignment-1)), + "%p inadequately aligned for" + " alignment=%zu, size=%zu", ps[i], + alignment, sz); + total += rsz; + if (total >= (MAXALIGN << 1)) + break; + } + for (i = 0; i < NITER; i++) { + if (ps[i] != NULL) { + dallocx(ps[i], 0); + ps[i] = NULL; + } + } + } + } +#undef MAXALIGN +#undef NITER +} +TEST_END + +int +main(void) +{ + + return (test( + test_oom, + test_basic, + test_alignment_and_size)); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/overflow.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/overflow.c new file mode 100644 index 0000000..303d9b2 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/overflow.c @@ -0,0 +1,49 @@ +#include "test/jemalloc_test.h" + +TEST_BEGIN(test_overflow) +{ + unsigned nhchunks; + size_t mib[4]; + size_t sz, miblen, max_size_class; + void *p; + + sz = sizeof(unsigned); + assert_d_eq(mallctl("arenas.nhchunks", &nhchunks, &sz, NULL, 0), 0, + "Unexpected mallctl() error"); + + miblen = sizeof(mib) / sizeof(size_t); + assert_d_eq(mallctlnametomib("arenas.hchunk.0.size", mib, &miblen), 0, + "Unexpected mallctlnametomib() error"); + mib[2] = nhchunks - 1; + + sz = sizeof(size_t); + assert_d_eq(mallctlbymib(mib, miblen, &max_size_class, &sz, NULL, 0), 0, + "Unexpected mallctlbymib() error"); + + assert_ptr_null(malloc(max_size_class + 1), + "Expected OOM due to over-sized allocation request"); + assert_ptr_null(malloc(SIZE_T_MAX), + "Expected OOM due to over-sized allocation request"); + + assert_ptr_null(calloc(1, max_size_class + 1), + "Expected OOM due to over-sized allocation request"); + assert_ptr_null(calloc(1, SIZE_T_MAX), + "Expected OOM due to over-sized allocation request"); + + p = malloc(1); + assert_ptr_not_null(p, "Unexpected malloc() OOM"); + assert_ptr_null(realloc(p, max_size_class + 1), + "Expected OOM due to over-sized allocation request"); + assert_ptr_null(realloc(p, SIZE_T_MAX), + "Expected OOM due to over-sized allocation request"); + free(p); +} +TEST_END + +int +main(void) +{ + + return (test( + test_overflow)); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/posix_memalign.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/posix_memalign.c new file mode 100644 index 0000000..19741c6 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/posix_memalign.c @@ -0,0 +1,119 @@ +#include "test/jemalloc_test.h" + +#define CHUNK 0x400000 +/* #define MAXALIGN ((size_t)UINT64_C(0x80000000000)) */ +#define MAXALIGN ((size_t)0x2000000LU) +#define NITER 4 + +TEST_BEGIN(test_alignment_errors) +{ + size_t alignment; + void *p; + + for (alignment = 0; alignment < sizeof(void *); alignment++) { + assert_d_eq(posix_memalign(&p, alignment, 1), EINVAL, + "Expected error for invalid alignment %zu", + alignment); + } + + for (alignment = sizeof(size_t); alignment < MAXALIGN; + alignment <<= 1) { + assert_d_ne(posix_memalign(&p, alignment + 1, 1), 0, + "Expected error for invalid alignment %zu", + alignment + 1); + } +} +TEST_END + +TEST_BEGIN(test_oom_errors) +{ + size_t alignment, size; + void *p; + +#if LG_SIZEOF_PTR == 3 + alignment = UINT64_C(0x8000000000000000); + size = UINT64_C(0x8000000000000000); +#else + alignment = 0x80000000LU; + size = 0x80000000LU; +#endif + assert_d_ne(posix_memalign(&p, alignment, size), 0, + "Expected error for posix_memalign(&p, %zu, %zu)", + alignment, size); + +#if LG_SIZEOF_PTR == 3 + alignment = UINT64_C(0x4000000000000000); + size = UINT64_C(0xc000000000000001); +#else + alignment = 0x40000000LU; + size = 0xc0000001LU; +#endif + assert_d_ne(posix_memalign(&p, alignment, size), 0, + "Expected error for posix_memalign(&p, %zu, %zu)", + alignment, size); + + alignment = 0x10LU; +#if LG_SIZEOF_PTR == 3 + size = UINT64_C(0xfffffffffffffff0); +#else + size = 0xfffffff0LU; +#endif + assert_d_ne(posix_memalign(&p, alignment, size), 0, + "Expected error for posix_memalign(&p, %zu, %zu)", + alignment, size); +} +TEST_END + +TEST_BEGIN(test_alignment_and_size) +{ + size_t alignment, size, total; + unsigned i; + int err; + void *ps[NITER]; + + for (i = 0; i < NITER; i++) + ps[i] = NULL; + + for (alignment = 8; + alignment <= MAXALIGN; + alignment <<= 1) { + total = 0; + for (size = 1; + size < 3 * alignment && size < (1U << 31); + size += (alignment >> (LG_SIZEOF_PTR-1)) - 1) { + for (i = 0; i < NITER; i++) { + err = posix_memalign(&ps[i], + alignment, size); + if (err) { + char buf[BUFERROR_BUF]; + + buferror(get_errno(), buf, sizeof(buf)); + test_fail( + "Error for alignment=%zu, " + "size=%zu (%#zx): %s", + alignment, size, size, buf); + } + total += malloc_usable_size(ps[i]); + if (total >= (MAXALIGN << 1)) + break; + } + for (i = 0; i < NITER; i++) { + if (ps[i] != NULL) { + free(ps[i]); + ps[i] = NULL; + } + } + } + } +} +TEST_END + +int +main(void) +{ + + return (test( + test_alignment_errors, + test_oom_errors, + test_alignment_and_size)); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/rallocx.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/rallocx.c new file mode 100644 index 0000000..be1b27b --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/rallocx.c @@ -0,0 +1,185 @@ +#include "test/jemalloc_test.h" + +TEST_BEGIN(test_grow_and_shrink) +{ + void *p, *q; + size_t tsz; +#define NCYCLES 3 + unsigned i, j; +#define NSZS 2500 + size_t szs[NSZS]; +#define MAXSZ ZU(12 * 1024 * 1024) + + p = mallocx(1, 0); + assert_ptr_not_null(p, "Unexpected mallocx() error"); + szs[0] = sallocx(p, 0); + + for (i = 0; i < NCYCLES; i++) { + for (j = 1; j < NSZS && szs[j-1] < MAXSZ; j++) { + q = rallocx(p, szs[j-1]+1, 0); + assert_ptr_not_null(q, + "Unexpected rallocx() error for size=%zu-->%zu", + szs[j-1], szs[j-1]+1); + szs[j] = sallocx(q, 0); + assert_zu_ne(szs[j], szs[j-1]+1, + "Expected size to be at least: %zu", szs[j-1]+1); + p = q; + } + + for (j--; j > 0; j--) { + q = rallocx(p, szs[j-1], 0); + assert_ptr_not_null(q, + "Unexpected rallocx() error for size=%zu-->%zu", + szs[j], szs[j-1]); + tsz = sallocx(q, 0); + assert_zu_eq(tsz, szs[j-1], + "Expected size=%zu, got size=%zu", szs[j-1], tsz); + p = q; + } + } + + dallocx(p, 0); +#undef MAXSZ +#undef NSZS +#undef NCYCLES +} +TEST_END + +static bool +validate_fill(const void *p, uint8_t c, size_t offset, size_t len) +{ + bool ret = false; + const uint8_t *buf = (const uint8_t *)p; + size_t i; + + for (i = 0; i < len; i++) { + uint8_t b = buf[offset+i]; + if (b != c) { + test_fail("Allocation at %p (len=%zu) contains %#x " + "rather than %#x at offset %zu", p, len, b, c, + offset+i); + ret = true; + } + } + + return (ret); +} + +TEST_BEGIN(test_zero) +{ + void *p, *q; + size_t psz, qsz, i, j; + size_t start_sizes[] = {1, 3*1024, 63*1024, 4095*1024}; +#define FILL_BYTE 0xaaU +#define RANGE 2048 + + for (i = 0; i < sizeof(start_sizes)/sizeof(size_t); i++) { + size_t start_size = start_sizes[i]; + p = mallocx(start_size, MALLOCX_ZERO); + assert_ptr_not_null(p, "Unexpected mallocx() error"); + psz = sallocx(p, 0); + + assert_false(validate_fill(p, 0, 0, psz), + "Expected zeroed memory"); + memset(p, FILL_BYTE, psz); + assert_false(validate_fill(p, FILL_BYTE, 0, psz), + "Expected filled memory"); + + for (j = 1; j < RANGE; j++) { + q = rallocx(p, start_size+j, MALLOCX_ZERO); + assert_ptr_not_null(q, "Unexpected rallocx() error"); + qsz = sallocx(q, 0); + if (q != p || qsz != psz) { + assert_false(validate_fill(q, FILL_BYTE, 0, + psz), "Expected filled memory"); + assert_false(validate_fill(q, 0, psz, qsz-psz), + "Expected zeroed memory"); + } + if (psz != qsz) { + memset((void *)((uintptr_t)q+psz), FILL_BYTE, + qsz-psz); + psz = qsz; + } + p = q; + } + assert_false(validate_fill(p, FILL_BYTE, 0, psz), + "Expected filled memory"); + dallocx(p, 0); + } +#undef FILL_BYTE +} +TEST_END + +TEST_BEGIN(test_align) +{ + void *p, *q; + size_t align; +#define MAX_ALIGN (ZU(1) << 25) + + align = ZU(1); + p = mallocx(1, MALLOCX_ALIGN(align)); + assert_ptr_not_null(p, "Unexpected mallocx() error"); + + for (align <<= 1; align <= MAX_ALIGN; align <<= 1) { + q = rallocx(p, 1, MALLOCX_ALIGN(align)); + assert_ptr_not_null(q, + "Unexpected rallocx() error for align=%zu", align); + assert_ptr_null( + (void *)((uintptr_t)q & (align-1)), + "%p inadequately aligned for align=%zu", + q, align); + p = q; + } + dallocx(p, 0); +#undef MAX_ALIGN +} +TEST_END + +TEST_BEGIN(test_lg_align_and_zero) +{ + void *p, *q; + size_t lg_align, sz; +#define MAX_LG_ALIGN 25 +#define MAX_VALIDATE (ZU(1) << 22) + + lg_align = ZU(0); + p = mallocx(1, MALLOCX_LG_ALIGN(lg_align)|MALLOCX_ZERO); + assert_ptr_not_null(p, "Unexpected mallocx() error"); + + for (lg_align++; lg_align <= MAX_LG_ALIGN; lg_align++) { + q = rallocx(p, 1, MALLOCX_LG_ALIGN(lg_align)|MALLOCX_ZERO); + assert_ptr_not_null(q, + "Unexpected rallocx() error for lg_align=%zu", lg_align); + assert_ptr_null( + (void *)((uintptr_t)q & ((ZU(1) << lg_align)-1)), + "%p inadequately aligned for lg_align=%zu", + q, lg_align); + sz = sallocx(q, 0); + if ((sz << 1) <= MAX_VALIDATE) { + assert_false(validate_fill(q, 0, 0, sz), + "Expected zeroed memory"); + } else { + assert_false(validate_fill(q, 0, 0, MAX_VALIDATE), + "Expected zeroed memory"); + assert_false(validate_fill( + (void *)((uintptr_t)q+sz-MAX_VALIDATE), + 0, 0, MAX_VALIDATE), "Expected zeroed memory"); + } + p = q; + } + dallocx(p, 0); +#undef MAX_VALIDATE +#undef MAX_LG_ALIGN +} +TEST_END + +int +main(void) +{ + + return (test( + test_grow_and_shrink, + test_zero, + test_align, + test_lg_align_and_zero)); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/sdallocx.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/sdallocx.c new file mode 100644 index 0000000..b84817d --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/sdallocx.c @@ -0,0 +1,57 @@ +#include "test/jemalloc_test.h" + +#define MAXALIGN (((size_t)1) << 25) +#define NITER 4 + +TEST_BEGIN(test_basic) +{ + void *ptr = mallocx(64, 0); + sdallocx(ptr, 64, 0); +} +TEST_END + +TEST_BEGIN(test_alignment_and_size) +{ + size_t nsz, sz, alignment, total; + unsigned i; + void *ps[NITER]; + + for (i = 0; i < NITER; i++) + ps[i] = NULL; + + for (alignment = 8; + alignment <= MAXALIGN; + alignment <<= 1) { + total = 0; + for (sz = 1; + sz < 3 * alignment && sz < (1U << 31); + sz += (alignment >> (LG_SIZEOF_PTR-1)) - 1) { + for (i = 0; i < NITER; i++) { + nsz = nallocx(sz, MALLOCX_ALIGN(alignment) | + MALLOCX_ZERO); + ps[i] = mallocx(sz, MALLOCX_ALIGN(alignment) | + MALLOCX_ZERO); + total += nsz; + if (total >= (MAXALIGN << 1)) + break; + } + for (i = 0; i < NITER; i++) { + if (ps[i] != NULL) { + sdallocx(ps[i], sz, + MALLOCX_ALIGN(alignment)); + ps[i] = NULL; + } + } + } + } +} +TEST_END + +int +main(void) +{ + + return (test( + test_basic, + test_alignment_and_size)); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/thread_arena.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/thread_arena.c new file mode 100644 index 0000000..67be535 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/thread_arena.c @@ -0,0 +1,79 @@ +#include "test/jemalloc_test.h" + +#define NTHREADS 10 + +void * +thd_start(void *arg) +{ + unsigned main_arena_ind = *(unsigned *)arg; + void *p; + unsigned arena_ind; + size_t size; + int err; + + p = malloc(1); + assert_ptr_not_null(p, "Error in malloc()"); + free(p); + + size = sizeof(arena_ind); + if ((err = mallctl("thread.arena", &arena_ind, &size, &main_arena_ind, + sizeof(main_arena_ind)))) { + char buf[BUFERROR_BUF]; + + buferror(err, buf, sizeof(buf)); + test_fail("Error in mallctl(): %s", buf); + } + + size = sizeof(arena_ind); + if ((err = mallctl("thread.arena", &arena_ind, &size, NULL, 0))) { + char buf[BUFERROR_BUF]; + + buferror(err, buf, sizeof(buf)); + test_fail("Error in mallctl(): %s", buf); + } + assert_u_eq(arena_ind, main_arena_ind, + "Arena index should be same as for main thread"); + + return (NULL); +} + +TEST_BEGIN(test_thread_arena) +{ + void *p; + unsigned arena_ind; + size_t size; + int err; + thd_t thds[NTHREADS]; + unsigned i; + + p = malloc(1); + assert_ptr_not_null(p, "Error in malloc()"); + + size = sizeof(arena_ind); + if ((err = mallctl("thread.arena", &arena_ind, &size, NULL, 0))) { + char buf[BUFERROR_BUF]; + + buferror(err, buf, sizeof(buf)); + test_fail("Error in mallctl(): %s", buf); + } + + for (i = 0; i < NTHREADS; i++) { + thd_create(&thds[i], thd_start, + (void *)&arena_ind); + } + + for (i = 0; i < NTHREADS; i++) { + intptr_t join_ret; + thd_join(thds[i], (void *)&join_ret); + assert_zd_eq(join_ret, 0, "Unexpected thread join error"); + } +} +TEST_END + +int +main(void) +{ + + return (test( + test_thread_arena)); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/thread_tcache_enabled.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/thread_tcache_enabled.c new file mode 100644 index 0000000..f4e89c6 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/thread_tcache_enabled.c @@ -0,0 +1,113 @@ +#include "test/jemalloc_test.h" + +static const bool config_tcache = +#ifdef JEMALLOC_TCACHE + true +#else + false +#endif + ; + +void * +thd_start(void *arg) +{ + int err; + size_t sz; + bool e0, e1; + + sz = sizeof(bool); + if ((err = mallctl("thread.tcache.enabled", &e0, &sz, NULL, 0))) { + if (err == ENOENT) { + assert_false(config_tcache, + "ENOENT should only be returned if tcache is " + "disabled"); + } + goto label_ENOENT; + } + + if (e0) { + e1 = false; + assert_d_eq(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz), + 0, "Unexpected mallctl() error"); + assert_true(e0, "tcache should be enabled"); + } + + e1 = true; + assert_d_eq(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz), 0, + "Unexpected mallctl() error"); + assert_false(e0, "tcache should be disabled"); + + e1 = true; + assert_d_eq(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz), 0, + "Unexpected mallctl() error"); + assert_true(e0, "tcache should be enabled"); + + e1 = false; + assert_d_eq(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz), 0, + "Unexpected mallctl() error"); + assert_true(e0, "tcache should be enabled"); + + e1 = false; + assert_d_eq(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz), 0, + "Unexpected mallctl() error"); + assert_false(e0, "tcache should be disabled"); + + free(malloc(1)); + e1 = true; + assert_d_eq(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz), 0, + "Unexpected mallctl() error"); + assert_false(e0, "tcache should be disabled"); + + free(malloc(1)); + e1 = true; + assert_d_eq(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz), 0, + "Unexpected mallctl() error"); + assert_true(e0, "tcache should be enabled"); + + free(malloc(1)); + e1 = false; + assert_d_eq(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz), 0, + "Unexpected mallctl() error"); + assert_true(e0, "tcache should be enabled"); + + free(malloc(1)); + e1 = false; + assert_d_eq(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz), 0, + "Unexpected mallctl() error"); + assert_false(e0, "tcache should be disabled"); + + free(malloc(1)); + return (NULL); +label_ENOENT: + test_skip("\"thread.tcache.enabled\" mallctl not available"); + return (NULL); +} + +TEST_BEGIN(test_main_thread) +{ + + thd_start(NULL); +} +TEST_END + +TEST_BEGIN(test_subthread) +{ + thd_t thd; + + thd_create(&thd, thd_start, NULL); + thd_join(thd, NULL); +} +TEST_END + +int +main(void) +{ + + /* Run tests multiple times to check for bad interactions. */ + return (test( + test_main_thread, + test_subthread, + test_main_thread, + test_subthread, + test_main_thread)); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/xallocx.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/xallocx.c new file mode 100644 index 0000000..3736252 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/integration/xallocx.c @@ -0,0 +1,471 @@ +#include "test/jemalloc_test.h" + +TEST_BEGIN(test_same_size) +{ + void *p; + size_t sz, tsz; + + p = mallocx(42, 0); + assert_ptr_not_null(p, "Unexpected mallocx() error"); + sz = sallocx(p, 0); + + tsz = xallocx(p, sz, 0, 0); + assert_zu_eq(tsz, sz, "Unexpected size change: %zu --> %zu", sz, tsz); + + dallocx(p, 0); +} +TEST_END + +TEST_BEGIN(test_extra_no_move) +{ + void *p; + size_t sz, tsz; + + p = mallocx(42, 0); + assert_ptr_not_null(p, "Unexpected mallocx() error"); + sz = sallocx(p, 0); + + tsz = xallocx(p, sz, sz-42, 0); + assert_zu_eq(tsz, sz, "Unexpected size change: %zu --> %zu", sz, tsz); + + dallocx(p, 0); +} +TEST_END + +TEST_BEGIN(test_no_move_fail) +{ + void *p; + size_t sz, tsz; + + p = mallocx(42, 0); + assert_ptr_not_null(p, "Unexpected mallocx() error"); + sz = sallocx(p, 0); + + tsz = xallocx(p, sz + 5, 0, 0); + assert_zu_eq(tsz, sz, "Unexpected size change: %zu --> %zu", sz, tsz); + + dallocx(p, 0); +} +TEST_END + +static unsigned +get_nsizes_impl(const char *cmd) +{ + unsigned ret; + size_t z; + + z = sizeof(unsigned); + assert_d_eq(mallctl(cmd, &ret, &z, NULL, 0), 0, + "Unexpected mallctl(\"%s\", ...) failure", cmd); + + return (ret); +} + +static unsigned +get_nsmall(void) +{ + + return (get_nsizes_impl("arenas.nbins")); +} + +static unsigned +get_nlarge(void) +{ + + return (get_nsizes_impl("arenas.nlruns")); +} + +static unsigned +get_nhuge(void) +{ + + return (get_nsizes_impl("arenas.nhchunks")); +} + +static size_t +get_size_impl(const char *cmd, size_t ind) +{ + size_t ret; + size_t z; + size_t mib[4]; + size_t miblen = 4; + + z = sizeof(size_t); + assert_d_eq(mallctlnametomib(cmd, mib, &miblen), + 0, "Unexpected mallctlnametomib(\"%s\", ...) failure", cmd); + mib[2] = ind; + z = sizeof(size_t); + assert_d_eq(mallctlbymib(mib, miblen, &ret, &z, NULL, 0), + 0, "Unexpected mallctlbymib([\"%s\", %zu], ...) failure", cmd, ind); + + return (ret); +} + +static size_t +get_small_size(size_t ind) +{ + + return (get_size_impl("arenas.bin.0.size", ind)); +} + +static size_t +get_large_size(size_t ind) +{ + + return (get_size_impl("arenas.lrun.0.size", ind)); +} + +static size_t +get_huge_size(size_t ind) +{ + + return (get_size_impl("arenas.hchunk.0.size", ind)); +} + +TEST_BEGIN(test_size) +{ + size_t small0, hugemax; + void *p; + + /* Get size classes. */ + small0 = get_small_size(0); + hugemax = get_huge_size(get_nhuge()-1); + + p = mallocx(small0, 0); + assert_ptr_not_null(p, "Unexpected mallocx() error"); + + /* Test smallest supported size. */ + assert_zu_eq(xallocx(p, 1, 0, 0), small0, + "Unexpected xallocx() behavior"); + + /* Test largest supported size. */ + assert_zu_le(xallocx(p, hugemax, 0, 0), hugemax, + "Unexpected xallocx() behavior"); + + /* Test size overflow. */ + assert_zu_le(xallocx(p, hugemax+1, 0, 0), hugemax, + "Unexpected xallocx() behavior"); + assert_zu_le(xallocx(p, SIZE_T_MAX, 0, 0), hugemax, + "Unexpected xallocx() behavior"); + + dallocx(p, 0); +} +TEST_END + +TEST_BEGIN(test_size_extra_overflow) +{ + size_t small0, hugemax; + void *p; + + /* Get size classes. */ + small0 = get_small_size(0); + hugemax = get_huge_size(get_nhuge()-1); + + p = mallocx(small0, 0); + assert_ptr_not_null(p, "Unexpected mallocx() error"); + + /* Test overflows that can be resolved by clamping extra. */ + assert_zu_le(xallocx(p, hugemax-1, 2, 0), hugemax, + "Unexpected xallocx() behavior"); + assert_zu_le(xallocx(p, hugemax, 1, 0), hugemax, + "Unexpected xallocx() behavior"); + + /* Test overflow such that hugemax-size underflows. */ + assert_zu_le(xallocx(p, hugemax+1, 2, 0), hugemax, + "Unexpected xallocx() behavior"); + assert_zu_le(xallocx(p, hugemax+2, 3, 0), hugemax, + "Unexpected xallocx() behavior"); + assert_zu_le(xallocx(p, SIZE_T_MAX-2, 2, 0), hugemax, + "Unexpected xallocx() behavior"); + assert_zu_le(xallocx(p, SIZE_T_MAX-1, 1, 0), hugemax, + "Unexpected xallocx() behavior"); + + dallocx(p, 0); +} +TEST_END + +TEST_BEGIN(test_extra_small) +{ + size_t small0, small1, hugemax; + void *p; + + /* Get size classes. */ + small0 = get_small_size(0); + small1 = get_small_size(1); + hugemax = get_huge_size(get_nhuge()-1); + + p = mallocx(small0, 0); + assert_ptr_not_null(p, "Unexpected mallocx() error"); + + assert_zu_eq(xallocx(p, small1, 0, 0), small0, + "Unexpected xallocx() behavior"); + + assert_zu_eq(xallocx(p, small1, 0, 0), small0, + "Unexpected xallocx() behavior"); + + assert_zu_eq(xallocx(p, small0, small1 - small0, 0), small0, + "Unexpected xallocx() behavior"); + + /* Test size+extra overflow. */ + assert_zu_eq(xallocx(p, small0, hugemax - small0 + 1, 0), small0, + "Unexpected xallocx() behavior"); + assert_zu_eq(xallocx(p, small0, SIZE_T_MAX - small0, 0), small0, + "Unexpected xallocx() behavior"); + + dallocx(p, 0); +} +TEST_END + +TEST_BEGIN(test_extra_large) +{ + size_t smallmax, large0, large1, large2, huge0, hugemax; + void *p; + + /* Get size classes. */ + smallmax = get_small_size(get_nsmall()-1); + large0 = get_large_size(0); + large1 = get_large_size(1); + large2 = get_large_size(2); + huge0 = get_huge_size(0); + hugemax = get_huge_size(get_nhuge()-1); + + p = mallocx(large2, 0); + assert_ptr_not_null(p, "Unexpected mallocx() error"); + + assert_zu_eq(xallocx(p, large2, 0, 0), large2, + "Unexpected xallocx() behavior"); + /* Test size decrease with zero extra. */ + assert_zu_eq(xallocx(p, large0, 0, 0), large0, + "Unexpected xallocx() behavior"); + assert_zu_eq(xallocx(p, smallmax, 0, 0), large0, + "Unexpected xallocx() behavior"); + + assert_zu_eq(xallocx(p, large2, 0, 0), large2, + "Unexpected xallocx() behavior"); + /* Test size decrease with non-zero extra. */ + assert_zu_eq(xallocx(p, large0, large2 - large0, 0), large2, + "Unexpected xallocx() behavior"); + assert_zu_eq(xallocx(p, large1, large2 - large1, 0), large2, + "Unexpected xallocx() behavior"); + assert_zu_eq(xallocx(p, large0, large1 - large0, 0), large1, + "Unexpected xallocx() behavior"); + assert_zu_eq(xallocx(p, smallmax, large0 - smallmax, 0), large0, + "Unexpected xallocx() behavior"); + + assert_zu_eq(xallocx(p, large0, 0, 0), large0, + "Unexpected xallocx() behavior"); + /* Test size increase with zero extra. */ + assert_zu_eq(xallocx(p, large2, 0, 0), large2, + "Unexpected xallocx() behavior"); + assert_zu_eq(xallocx(p, huge0, 0, 0), large2, + "Unexpected xallocx() behavior"); + + assert_zu_eq(xallocx(p, large0, 0, 0), large0, + "Unexpected xallocx() behavior"); + /* Test size increase with non-zero extra. */ + assert_zu_lt(xallocx(p, large0, huge0 - large0, 0), huge0, + "Unexpected xallocx() behavior"); + + assert_zu_eq(xallocx(p, large0, 0, 0), large0, + "Unexpected xallocx() behavior"); + /* Test size increase with non-zero extra. */ + assert_zu_eq(xallocx(p, large0, large2 - large0, 0), large2, + "Unexpected xallocx() behavior"); + + assert_zu_eq(xallocx(p, large2, 0, 0), large2, + "Unexpected xallocx() behavior"); + /* Test size+extra overflow. */ + assert_zu_lt(xallocx(p, large2, hugemax - large2 + 1, 0), huge0, + "Unexpected xallocx() behavior"); + + dallocx(p, 0); +} +TEST_END + +TEST_BEGIN(test_extra_huge) +{ + size_t largemax, huge0, huge1, huge2, hugemax; + void *p; + + /* Get size classes. */ + largemax = get_large_size(get_nlarge()-1); + huge0 = get_huge_size(0); + huge1 = get_huge_size(1); + huge2 = get_huge_size(2); + hugemax = get_huge_size(get_nhuge()-1); + + p = mallocx(huge2, 0); + assert_ptr_not_null(p, "Unexpected mallocx() error"); + + assert_zu_eq(xallocx(p, huge2, 0, 0), huge2, + "Unexpected xallocx() behavior"); + /* Test size decrease with zero extra. */ + assert_zu_ge(xallocx(p, huge0, 0, 0), huge0, + "Unexpected xallocx() behavior"); + assert_zu_ge(xallocx(p, largemax, 0, 0), huge0, + "Unexpected xallocx() behavior"); + + assert_zu_eq(xallocx(p, huge2, 0, 0), huge2, + "Unexpected xallocx() behavior"); + /* Test size decrease with non-zero extra. */ + assert_zu_eq(xallocx(p, huge0, huge2 - huge0, 0), huge2, + "Unexpected xallocx() behavior"); + assert_zu_eq(xallocx(p, huge1, huge2 - huge1, 0), huge2, + "Unexpected xallocx() behavior"); + assert_zu_eq(xallocx(p, huge0, huge1 - huge0, 0), huge1, + "Unexpected xallocx() behavior"); + assert_zu_ge(xallocx(p, largemax, huge0 - largemax, 0), huge0, + "Unexpected xallocx() behavior"); + + assert_zu_ge(xallocx(p, huge0, 0, 0), huge0, + "Unexpected xallocx() behavior"); + /* Test size increase with zero extra. */ + assert_zu_le(xallocx(p, huge2, 0, 0), huge2, + "Unexpected xallocx() behavior"); + assert_zu_le(xallocx(p, hugemax+1, 0, 0), huge2, + "Unexpected xallocx() behavior"); + + assert_zu_ge(xallocx(p, huge0, 0, 0), huge0, + "Unexpected xallocx() behavior"); + /* Test size increase with non-zero extra. */ + assert_zu_le(xallocx(p, huge0, SIZE_T_MAX - huge0, 0), hugemax, + "Unexpected xallocx() behavior"); + + assert_zu_ge(xallocx(p, huge0, 0, 0), huge0, + "Unexpected xallocx() behavior"); + /* Test size increase with non-zero extra. */ + assert_zu_le(xallocx(p, huge0, huge2 - huge0, 0), huge2, + "Unexpected xallocx() behavior"); + + assert_zu_eq(xallocx(p, huge2, 0, 0), huge2, + "Unexpected xallocx() behavior"); + /* Test size+extra overflow. */ + assert_zu_le(xallocx(p, huge2, hugemax - huge2 + 1, 0), hugemax, + "Unexpected xallocx() behavior"); + + dallocx(p, 0); +} +TEST_END + +static void +print_filled_extents(const void *p, uint8_t c, size_t len) +{ + const uint8_t *pc = (const uint8_t *)p; + size_t i, range0; + uint8_t c0; + + malloc_printf(" p=%p, c=%#x, len=%zu:", p, c, len); + range0 = 0; + c0 = pc[0]; + for (i = 0; i < len; i++) { + if (pc[i] != c0) { + malloc_printf(" %#x[%zu..%zu)", c0, range0, i); + range0 = i; + c0 = pc[i]; + } + } + malloc_printf(" %#x[%zu..%zu)\n", c0, range0, i); +} + +static bool +validate_fill(const void *p, uint8_t c, size_t offset, size_t len) +{ + const uint8_t *pc = (const uint8_t *)p; + bool err; + size_t i; + + for (i = offset, err = false; i < offset+len; i++) { + if (pc[i] != c) + err = true; + } + + if (err) + print_filled_extents(p, c, offset + len); + + return (err); +} + +static void +test_zero(size_t szmin, size_t szmax) +{ + size_t sz, nsz; + void *p; +#define FILL_BYTE 0x7aU + + sz = szmax; + p = mallocx(sz, MALLOCX_ZERO); + assert_ptr_not_null(p, "Unexpected mallocx() error"); + assert_false(validate_fill(p, 0x00, 0, sz), "Memory not filled: sz=%zu", + sz); + + /* + * Fill with non-zero so that non-debug builds are more likely to detect + * errors. + */ + memset(p, FILL_BYTE, sz); + assert_false(validate_fill(p, FILL_BYTE, 0, sz), + "Memory not filled: sz=%zu", sz); + + /* Shrink in place so that we can expect growing in place to succeed. */ + sz = szmin; + assert_zu_eq(xallocx(p, sz, 0, MALLOCX_ZERO), sz, + "Unexpected xallocx() error"); + assert_false(validate_fill(p, FILL_BYTE, 0, sz), + "Memory not filled: sz=%zu", sz); + + for (sz = szmin; sz < szmax; sz = nsz) { + nsz = nallocx(sz+1, MALLOCX_ZERO); + assert_zu_eq(xallocx(p, sz+1, 0, MALLOCX_ZERO), nsz, + "Unexpected xallocx() failure"); + assert_false(validate_fill(p, FILL_BYTE, 0, sz), + "Memory not filled: sz=%zu", sz); + assert_false(validate_fill(p, 0x00, sz, nsz-sz), + "Memory not filled: sz=%zu, nsz-sz=%zu", sz, nsz-sz); + memset((void *)((uintptr_t)p + sz), FILL_BYTE, nsz-sz); + assert_false(validate_fill(p, FILL_BYTE, 0, nsz), + "Memory not filled: nsz=%zu", nsz); + } + + dallocx(p, 0); +} + +TEST_BEGIN(test_zero_large) +{ + size_t large0, largemax; + + /* Get size classes. */ + large0 = get_large_size(0); + largemax = get_large_size(get_nlarge()-1); + + test_zero(large0, largemax); +} +TEST_END + +TEST_BEGIN(test_zero_huge) +{ + size_t huge0, huge1; + + /* Get size classes. */ + huge0 = get_huge_size(0); + huge1 = get_huge_size(1); + + test_zero(huge1, huge0 * 2); +} +TEST_END + +int +main(void) +{ + + return (test( + test_same_size, + test_extra_no_move, + test_no_move_fail, + test_size, + test_size_extra_overflow, + test_extra_small, + test_extra_large, + test_extra_huge, + test_zero_large, + test_zero_huge)); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/src/SFMT.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/src/SFMT.c new file mode 100644 index 0000000..80cabe0 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/src/SFMT.c @@ -0,0 +1,719 @@ +/* + * This file derives from SFMT 1.3.3 + * (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was + * released under the terms of the following license: + * + * Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima + * University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the Hiroshima University nor the names of + * its contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/** + * @file SFMT.c + * @brief SIMD oriented Fast Mersenne Twister(SFMT) + * + * @author Mutsuo Saito (Hiroshima University) + * @author Makoto Matsumoto (Hiroshima University) + * + * Copyright (C) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima + * University. All rights reserved. + * + * The new BSD License is applied to this software, see LICENSE.txt + */ +#define SFMT_C_ +#include "test/jemalloc_test.h" +#include "test/SFMT-params.h" + +#if defined(JEMALLOC_BIG_ENDIAN) && !defined(BIG_ENDIAN64) +#define BIG_ENDIAN64 1 +#endif +#if defined(__BIG_ENDIAN__) && !defined(__amd64) && !defined(BIG_ENDIAN64) +#define BIG_ENDIAN64 1 +#endif +#if defined(HAVE_ALTIVEC) && !defined(BIG_ENDIAN64) +#define BIG_ENDIAN64 1 +#endif +#if defined(ONLY64) && !defined(BIG_ENDIAN64) + #if defined(__GNUC__) + #error "-DONLY64 must be specified with -DBIG_ENDIAN64" + #endif +#undef ONLY64 +#endif +/*------------------------------------------------------ + 128-bit SIMD data type for Altivec, SSE2 or standard C + ------------------------------------------------------*/ +#if defined(HAVE_ALTIVEC) +/** 128-bit data structure */ +union W128_T { + vector unsigned int s; + uint32_t u[4]; +}; +/** 128-bit data type */ +typedef union W128_T w128_t; + +#elif defined(HAVE_SSE2) +/** 128-bit data structure */ +union W128_T { + __m128i si; + uint32_t u[4]; +}; +/** 128-bit data type */ +typedef union W128_T w128_t; + +#else + +/** 128-bit data structure */ +struct W128_T { + uint32_t u[4]; +}; +/** 128-bit data type */ +typedef struct W128_T w128_t; + +#endif + +struct sfmt_s { + /** the 128-bit internal state array */ + w128_t sfmt[N]; + /** index counter to the 32-bit internal state array */ + int idx; + /** a flag: it is 0 if and only if the internal state is not yet + * initialized. */ + int initialized; +}; + +/*-------------------------------------- + FILE GLOBAL VARIABLES + internal state, index counter and flag + --------------------------------------*/ + +/** a parity check vector which certificate the period of 2^{MEXP} */ +static uint32_t parity[4] = {PARITY1, PARITY2, PARITY3, PARITY4}; + +/*---------------- + STATIC FUNCTIONS + ----------------*/ +JEMALLOC_INLINE_C int idxof(int i); +#if (!defined(HAVE_ALTIVEC)) && (!defined(HAVE_SSE2)) +JEMALLOC_INLINE_C void rshift128(w128_t *out, w128_t const *in, int shift); +JEMALLOC_INLINE_C void lshift128(w128_t *out, w128_t const *in, int shift); +#endif +JEMALLOC_INLINE_C void gen_rand_all(sfmt_t *ctx); +JEMALLOC_INLINE_C void gen_rand_array(sfmt_t *ctx, w128_t *array, int size); +JEMALLOC_INLINE_C uint32_t func1(uint32_t x); +JEMALLOC_INLINE_C uint32_t func2(uint32_t x); +static void period_certification(sfmt_t *ctx); +#if defined(BIG_ENDIAN64) && !defined(ONLY64) +JEMALLOC_INLINE_C void swap(w128_t *array, int size); +#endif + +#if defined(HAVE_ALTIVEC) + #include "test/SFMT-alti.h" +#elif defined(HAVE_SSE2) + #include "test/SFMT-sse2.h" +#endif + +/** + * This function simulate a 64-bit index of LITTLE ENDIAN + * in BIG ENDIAN machine. + */ +#ifdef ONLY64 +JEMALLOC_INLINE_C int idxof(int i) { + return i ^ 1; +} +#else +JEMALLOC_INLINE_C int idxof(int i) { + return i; +} +#endif +/** + * This function simulates SIMD 128-bit right shift by the standard C. + * The 128-bit integer given in in is shifted by (shift * 8) bits. + * This function simulates the LITTLE ENDIAN SIMD. + * @param out the output of this function + * @param in the 128-bit data to be shifted + * @param shift the shift value + */ +#if (!defined(HAVE_ALTIVEC)) && (!defined(HAVE_SSE2)) +#ifdef ONLY64 +JEMALLOC_INLINE_C void rshift128(w128_t *out, w128_t const *in, int shift) { + uint64_t th, tl, oh, ol; + + th = ((uint64_t)in->u[2] << 32) | ((uint64_t)in->u[3]); + tl = ((uint64_t)in->u[0] << 32) | ((uint64_t)in->u[1]); + + oh = th >> (shift * 8); + ol = tl >> (shift * 8); + ol |= th << (64 - shift * 8); + out->u[0] = (uint32_t)(ol >> 32); + out->u[1] = (uint32_t)ol; + out->u[2] = (uint32_t)(oh >> 32); + out->u[3] = (uint32_t)oh; +} +#else +JEMALLOC_INLINE_C void rshift128(w128_t *out, w128_t const *in, int shift) { + uint64_t th, tl, oh, ol; + + th = ((uint64_t)in->u[3] << 32) | ((uint64_t)in->u[2]); + tl = ((uint64_t)in->u[1] << 32) | ((uint64_t)in->u[0]); + + oh = th >> (shift * 8); + ol = tl >> (shift * 8); + ol |= th << (64 - shift * 8); + out->u[1] = (uint32_t)(ol >> 32); + out->u[0] = (uint32_t)ol; + out->u[3] = (uint32_t)(oh >> 32); + out->u[2] = (uint32_t)oh; +} +#endif +/** + * This function simulates SIMD 128-bit left shift by the standard C. + * The 128-bit integer given in in is shifted by (shift * 8) bits. + * This function simulates the LITTLE ENDIAN SIMD. + * @param out the output of this function + * @param in the 128-bit data to be shifted + * @param shift the shift value + */ +#ifdef ONLY64 +JEMALLOC_INLINE_C void lshift128(w128_t *out, w128_t const *in, int shift) { + uint64_t th, tl, oh, ol; + + th = ((uint64_t)in->u[2] << 32) | ((uint64_t)in->u[3]); + tl = ((uint64_t)in->u[0] << 32) | ((uint64_t)in->u[1]); + + oh = th << (shift * 8); + ol = tl << (shift * 8); + oh |= tl >> (64 - shift * 8); + out->u[0] = (uint32_t)(ol >> 32); + out->u[1] = (uint32_t)ol; + out->u[2] = (uint32_t)(oh >> 32); + out->u[3] = (uint32_t)oh; +} +#else +JEMALLOC_INLINE_C void lshift128(w128_t *out, w128_t const *in, int shift) { + uint64_t th, tl, oh, ol; + + th = ((uint64_t)in->u[3] << 32) | ((uint64_t)in->u[2]); + tl = ((uint64_t)in->u[1] << 32) | ((uint64_t)in->u[0]); + + oh = th << (shift * 8); + ol = tl << (shift * 8); + oh |= tl >> (64 - shift * 8); + out->u[1] = (uint32_t)(ol >> 32); + out->u[0] = (uint32_t)ol; + out->u[3] = (uint32_t)(oh >> 32); + out->u[2] = (uint32_t)oh; +} +#endif +#endif + +/** + * This function represents the recursion formula. + * @param r output + * @param a a 128-bit part of the internal state array + * @param b a 128-bit part of the internal state array + * @param c a 128-bit part of the internal state array + * @param d a 128-bit part of the internal state array + */ +#if (!defined(HAVE_ALTIVEC)) && (!defined(HAVE_SSE2)) +#ifdef ONLY64 +JEMALLOC_INLINE_C void do_recursion(w128_t *r, w128_t *a, w128_t *b, w128_t *c, + w128_t *d) { + w128_t x; + w128_t y; + + lshift128(&x, a, SL2); + rshift128(&y, c, SR2); + r->u[0] = a->u[0] ^ x.u[0] ^ ((b->u[0] >> SR1) & MSK2) ^ y.u[0] + ^ (d->u[0] << SL1); + r->u[1] = a->u[1] ^ x.u[1] ^ ((b->u[1] >> SR1) & MSK1) ^ y.u[1] + ^ (d->u[1] << SL1); + r->u[2] = a->u[2] ^ x.u[2] ^ ((b->u[2] >> SR1) & MSK4) ^ y.u[2] + ^ (d->u[2] << SL1); + r->u[3] = a->u[3] ^ x.u[3] ^ ((b->u[3] >> SR1) & MSK3) ^ y.u[3] + ^ (d->u[3] << SL1); +} +#else +JEMALLOC_INLINE_C void do_recursion(w128_t *r, w128_t *a, w128_t *b, w128_t *c, + w128_t *d) { + w128_t x; + w128_t y; + + lshift128(&x, a, SL2); + rshift128(&y, c, SR2); + r->u[0] = a->u[0] ^ x.u[0] ^ ((b->u[0] >> SR1) & MSK1) ^ y.u[0] + ^ (d->u[0] << SL1); + r->u[1] = a->u[1] ^ x.u[1] ^ ((b->u[1] >> SR1) & MSK2) ^ y.u[1] + ^ (d->u[1] << SL1); + r->u[2] = a->u[2] ^ x.u[2] ^ ((b->u[2] >> SR1) & MSK3) ^ y.u[2] + ^ (d->u[2] << SL1); + r->u[3] = a->u[3] ^ x.u[3] ^ ((b->u[3] >> SR1) & MSK4) ^ y.u[3] + ^ (d->u[3] << SL1); +} +#endif +#endif + +#if (!defined(HAVE_ALTIVEC)) && (!defined(HAVE_SSE2)) +/** + * This function fills the internal state array with pseudorandom + * integers. + */ +JEMALLOC_INLINE_C void gen_rand_all(sfmt_t *ctx) { + int i; + w128_t *r1, *r2; + + r1 = &ctx->sfmt[N - 2]; + r2 = &ctx->sfmt[N - 1]; + for (i = 0; i < N - POS1; i++) { + do_recursion(&ctx->sfmt[i], &ctx->sfmt[i], &ctx->sfmt[i + POS1], r1, + r2); + r1 = r2; + r2 = &ctx->sfmt[i]; + } + for (; i < N; i++) { + do_recursion(&ctx->sfmt[i], &ctx->sfmt[i], &ctx->sfmt[i + POS1 - N], r1, + r2); + r1 = r2; + r2 = &ctx->sfmt[i]; + } +} + +/** + * This function fills the user-specified array with pseudorandom + * integers. + * + * @param array an 128-bit array to be filled by pseudorandom numbers. + * @param size number of 128-bit pseudorandom numbers to be generated. + */ +JEMALLOC_INLINE_C void gen_rand_array(sfmt_t *ctx, w128_t *array, int size) { + int i, j; + w128_t *r1, *r2; + + r1 = &ctx->sfmt[N - 2]; + r2 = &ctx->sfmt[N - 1]; + for (i = 0; i < N - POS1; i++) { + do_recursion(&array[i], &ctx->sfmt[i], &ctx->sfmt[i + POS1], r1, r2); + r1 = r2; + r2 = &array[i]; + } + for (; i < N; i++) { + do_recursion(&array[i], &ctx->sfmt[i], &array[i + POS1 - N], r1, r2); + r1 = r2; + r2 = &array[i]; + } + for (; i < size - N; i++) { + do_recursion(&array[i], &array[i - N], &array[i + POS1 - N], r1, r2); + r1 = r2; + r2 = &array[i]; + } + for (j = 0; j < 2 * N - size; j++) { + ctx->sfmt[j] = array[j + size - N]; + } + for (; i < size; i++, j++) { + do_recursion(&array[i], &array[i - N], &array[i + POS1 - N], r1, r2); + r1 = r2; + r2 = &array[i]; + ctx->sfmt[j] = array[i]; + } +} +#endif + +#if defined(BIG_ENDIAN64) && !defined(ONLY64) && !defined(HAVE_ALTIVEC) +JEMALLOC_INLINE_C void swap(w128_t *array, int size) { + int i; + uint32_t x, y; + + for (i = 0; i < size; i++) { + x = array[i].u[0]; + y = array[i].u[2]; + array[i].u[0] = array[i].u[1]; + array[i].u[2] = array[i].u[3]; + array[i].u[1] = x; + array[i].u[3] = y; + } +} +#endif +/** + * This function represents a function used in the initialization + * by init_by_array + * @param x 32-bit integer + * @return 32-bit integer + */ +static uint32_t func1(uint32_t x) { + return (x ^ (x >> 27)) * (uint32_t)1664525UL; +} + +/** + * This function represents a function used in the initialization + * by init_by_array + * @param x 32-bit integer + * @return 32-bit integer + */ +static uint32_t func2(uint32_t x) { + return (x ^ (x >> 27)) * (uint32_t)1566083941UL; +} + +/** + * This function certificate the period of 2^{MEXP} + */ +static void period_certification(sfmt_t *ctx) { + int inner = 0; + int i, j; + uint32_t work; + uint32_t *psfmt32 = &ctx->sfmt[0].u[0]; + + for (i = 0; i < 4; i++) + inner ^= psfmt32[idxof(i)] & parity[i]; + for (i = 16; i > 0; i >>= 1) + inner ^= inner >> i; + inner &= 1; + /* check OK */ + if (inner == 1) { + return; + } + /* check NG, and modification */ + for (i = 0; i < 4; i++) { + work = 1; + for (j = 0; j < 32; j++) { + if ((work & parity[i]) != 0) { + psfmt32[idxof(i)] ^= work; + return; + } + work = work << 1; + } + } +} + +/*---------------- + PUBLIC FUNCTIONS + ----------------*/ +/** + * This function returns the identification string. + * The string shows the word size, the Mersenne exponent, + * and all parameters of this generator. + */ +const char *get_idstring(void) { + return IDSTR; +} + +/** + * This function returns the minimum size of array used for \b + * fill_array32() function. + * @return minimum size of array used for fill_array32() function. + */ +int get_min_array_size32(void) { + return N32; +} + +/** + * This function returns the minimum size of array used for \b + * fill_array64() function. + * @return minimum size of array used for fill_array64() function. + */ +int get_min_array_size64(void) { + return N64; +} + +#ifndef ONLY64 +/** + * This function generates and returns 32-bit pseudorandom number. + * init_gen_rand or init_by_array must be called before this function. + * @return 32-bit pseudorandom number + */ +uint32_t gen_rand32(sfmt_t *ctx) { + uint32_t r; + uint32_t *psfmt32 = &ctx->sfmt[0].u[0]; + + assert(ctx->initialized); + if (ctx->idx >= N32) { + gen_rand_all(ctx); + ctx->idx = 0; + } + r = psfmt32[ctx->idx++]; + return r; +} + +/* Generate a random integer in [0..limit). */ +uint32_t gen_rand32_range(sfmt_t *ctx, uint32_t limit) { + uint32_t ret, above; + + above = 0xffffffffU - (0xffffffffU % limit); + while (1) { + ret = gen_rand32(ctx); + if (ret < above) { + ret %= limit; + break; + } + } + return ret; +} +#endif +/** + * This function generates and returns 64-bit pseudorandom number. + * init_gen_rand or init_by_array must be called before this function. + * The function gen_rand64 should not be called after gen_rand32, + * unless an initialization is again executed. + * @return 64-bit pseudorandom number + */ +uint64_t gen_rand64(sfmt_t *ctx) { +#if defined(BIG_ENDIAN64) && !defined(ONLY64) + uint32_t r1, r2; + uint32_t *psfmt32 = &ctx->sfmt[0].u[0]; +#else + uint64_t r; + uint64_t *psfmt64 = (uint64_t *)&ctx->sfmt[0].u[0]; +#endif + + assert(ctx->initialized); + assert(ctx->idx % 2 == 0); + + if (ctx->idx >= N32) { + gen_rand_all(ctx); + ctx->idx = 0; + } +#if defined(BIG_ENDIAN64) && !defined(ONLY64) + r1 = psfmt32[ctx->idx]; + r2 = psfmt32[ctx->idx + 1]; + ctx->idx += 2; + return ((uint64_t)r2 << 32) | r1; +#else + r = psfmt64[ctx->idx / 2]; + ctx->idx += 2; + return r; +#endif +} + +/* Generate a random integer in [0..limit). */ +uint64_t gen_rand64_range(sfmt_t *ctx, uint64_t limit) { + uint64_t ret, above; + + above = KQU(0xffffffffffffffff) - (KQU(0xffffffffffffffff) % limit); + while (1) { + ret = gen_rand64(ctx); + if (ret < above) { + ret %= limit; + break; + } + } + return ret; +} + +#ifndef ONLY64 +/** + * This function generates pseudorandom 32-bit integers in the + * specified array[] by one call. The number of pseudorandom integers + * is specified by the argument size, which must be at least 624 and a + * multiple of four. The generation by this function is much faster + * than the following gen_rand function. + * + * For initialization, init_gen_rand or init_by_array must be called + * before the first call of this function. This function can not be + * used after calling gen_rand function, without initialization. + * + * @param array an array where pseudorandom 32-bit integers are filled + * by this function. The pointer to the array must be \b "aligned" + * (namely, must be a multiple of 16) in the SIMD version, since it + * refers to the address of a 128-bit integer. In the standard C + * version, the pointer is arbitrary. + * + * @param size the number of 32-bit pseudorandom integers to be + * generated. size must be a multiple of 4, and greater than or equal + * to (MEXP / 128 + 1) * 4. + * + * @note \b memalign or \b posix_memalign is available to get aligned + * memory. Mac OSX doesn't have these functions, but \b malloc of OSX + * returns the pointer to the aligned memory block. + */ +void fill_array32(sfmt_t *ctx, uint32_t *array, int size) { + assert(ctx->initialized); + assert(ctx->idx == N32); + assert(size % 4 == 0); + assert(size >= N32); + + gen_rand_array(ctx, (w128_t *)array, size / 4); + ctx->idx = N32; +} +#endif + +/** + * This function generates pseudorandom 64-bit integers in the + * specified array[] by one call. The number of pseudorandom integers + * is specified by the argument size, which must be at least 312 and a + * multiple of two. The generation by this function is much faster + * than the following gen_rand function. + * + * For initialization, init_gen_rand or init_by_array must be called + * before the first call of this function. This function can not be + * used after calling gen_rand function, without initialization. + * + * @param array an array where pseudorandom 64-bit integers are filled + * by this function. The pointer to the array must be "aligned" + * (namely, must be a multiple of 16) in the SIMD version, since it + * refers to the address of a 128-bit integer. In the standard C + * version, the pointer is arbitrary. + * + * @param size the number of 64-bit pseudorandom integers to be + * generated. size must be a multiple of 2, and greater than or equal + * to (MEXP / 128 + 1) * 2 + * + * @note \b memalign or \b posix_memalign is available to get aligned + * memory. Mac OSX doesn't have these functions, but \b malloc of OSX + * returns the pointer to the aligned memory block. + */ +void fill_array64(sfmt_t *ctx, uint64_t *array, int size) { + assert(ctx->initialized); + assert(ctx->idx == N32); + assert(size % 2 == 0); + assert(size >= N64); + + gen_rand_array(ctx, (w128_t *)array, size / 2); + ctx->idx = N32; + +#if defined(BIG_ENDIAN64) && !defined(ONLY64) + swap((w128_t *)array, size /2); +#endif +} + +/** + * This function initializes the internal state array with a 32-bit + * integer seed. + * + * @param seed a 32-bit integer used as the seed. + */ +sfmt_t *init_gen_rand(uint32_t seed) { + void *p; + sfmt_t *ctx; + int i; + uint32_t *psfmt32; + + if (posix_memalign(&p, sizeof(w128_t), sizeof(sfmt_t)) != 0) { + return NULL; + } + ctx = (sfmt_t *)p; + psfmt32 = &ctx->sfmt[0].u[0]; + + psfmt32[idxof(0)] = seed; + for (i = 1; i < N32; i++) { + psfmt32[idxof(i)] = 1812433253UL * (psfmt32[idxof(i - 1)] + ^ (psfmt32[idxof(i - 1)] >> 30)) + + i; + } + ctx->idx = N32; + period_certification(ctx); + ctx->initialized = 1; + + return ctx; +} + +/** + * This function initializes the internal state array, + * with an array of 32-bit integers used as the seeds + * @param init_key the array of 32-bit integers, used as a seed. + * @param key_length the length of init_key. + */ +sfmt_t *init_by_array(uint32_t *init_key, int key_length) { + void *p; + sfmt_t *ctx; + int i, j, count; + uint32_t r; + int lag; + int mid; + int size = N * 4; + uint32_t *psfmt32; + + if (posix_memalign(&p, sizeof(w128_t), sizeof(sfmt_t)) != 0) { + return NULL; + } + ctx = (sfmt_t *)p; + psfmt32 = &ctx->sfmt[0].u[0]; + + if (size >= 623) { + lag = 11; + } else if (size >= 68) { + lag = 7; + } else if (size >= 39) { + lag = 5; + } else { + lag = 3; + } + mid = (size - lag) / 2; + + memset(ctx->sfmt, 0x8b, sizeof(ctx->sfmt)); + if (key_length + 1 > N32) { + count = key_length + 1; + } else { + count = N32; + } + r = func1(psfmt32[idxof(0)] ^ psfmt32[idxof(mid)] + ^ psfmt32[idxof(N32 - 1)]); + psfmt32[idxof(mid)] += r; + r += key_length; + psfmt32[idxof(mid + lag)] += r; + psfmt32[idxof(0)] = r; + + count--; + for (i = 1, j = 0; (j < count) && (j < key_length); j++) { + r = func1(psfmt32[idxof(i)] ^ psfmt32[idxof((i + mid) % N32)] + ^ psfmt32[idxof((i + N32 - 1) % N32)]); + psfmt32[idxof((i + mid) % N32)] += r; + r += init_key[j] + i; + psfmt32[idxof((i + mid + lag) % N32)] += r; + psfmt32[idxof(i)] = r; + i = (i + 1) % N32; + } + for (; j < count; j++) { + r = func1(psfmt32[idxof(i)] ^ psfmt32[idxof((i + mid) % N32)] + ^ psfmt32[idxof((i + N32 - 1) % N32)]); + psfmt32[idxof((i + mid) % N32)] += r; + r += i; + psfmt32[idxof((i + mid + lag) % N32)] += r; + psfmt32[idxof(i)] = r; + i = (i + 1) % N32; + } + for (j = 0; j < N32; j++) { + r = func2(psfmt32[idxof(i)] + psfmt32[idxof((i + mid) % N32)] + + psfmt32[idxof((i + N32 - 1) % N32)]); + psfmt32[idxof((i + mid) % N32)] ^= r; + r -= i; + psfmt32[idxof((i + mid + lag) % N32)] ^= r; + psfmt32[idxof(i)] = r; + i = (i + 1) % N32; + } + + ctx->idx = N32; + period_certification(ctx); + ctx->initialized = 1; + + return ctx; +} + +void fini_gen_rand(sfmt_t *ctx) { + assert(ctx != NULL); + + ctx->initialized = 0; + free(ctx); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/src/btalloc.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/src/btalloc.c new file mode 100644 index 0000000..9a253d9 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/src/btalloc.c @@ -0,0 +1,8 @@ +#include "test/jemalloc_test.h" + +void * +btalloc(size_t size, unsigned bits) +{ + + return (btalloc_0(size, bits)); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/src/btalloc_0.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/src/btalloc_0.c new file mode 100644 index 0000000..77d8904 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/src/btalloc_0.c @@ -0,0 +1,3 @@ +#include "test/jemalloc_test.h" + +btalloc_n_gen(0) diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/src/btalloc_1.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/src/btalloc_1.c new file mode 100644 index 0000000..4c126c3 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/src/btalloc_1.c @@ -0,0 +1,3 @@ +#include "test/jemalloc_test.h" + +btalloc_n_gen(1) diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/src/math.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/src/math.c new file mode 100644 index 0000000..887a363 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/src/math.c @@ -0,0 +1,2 @@ +#define MATH_C_ +#include "test/jemalloc_test.h" diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/src/mq.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/src/mq.c new file mode 100644 index 0000000..40b31c1 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/src/mq.c @@ -0,0 +1,29 @@ +#include "test/jemalloc_test.h" + +/* + * Sleep for approximately ns nanoseconds. No lower *nor* upper bound on sleep + * time is guaranteed. + */ +void +mq_nanosleep(unsigned ns) +{ + + assert(ns <= 1000*1000*1000); + +#ifdef _WIN32 + Sleep(ns / 1000); +#else + { + struct timespec timeout; + + if (ns < 1000*1000*1000) { + timeout.tv_sec = 0; + timeout.tv_nsec = ns; + } else { + timeout.tv_sec = 1; + timeout.tv_nsec = 0; + } + nanosleep(&timeout, NULL); + } +#endif +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/src/mtx.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/src/mtx.c new file mode 100644 index 0000000..73bd02f --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/src/mtx.c @@ -0,0 +1,66 @@ +#include "test/jemalloc_test.h" + +#ifndef _CRT_SPINCOUNT +#define _CRT_SPINCOUNT 4000 +#endif + +bool +mtx_init(mtx_t *mtx) +{ + +#ifdef _WIN32 + if (!InitializeCriticalSectionAndSpinCount(&mtx->lock, _CRT_SPINCOUNT)) + return (true); +#elif (defined(JEMALLOC_OSSPIN)) + mtx->lock = 0; +#else + pthread_mutexattr_t attr; + + if (pthread_mutexattr_init(&attr) != 0) + return (true); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_DEFAULT); + if (pthread_mutex_init(&mtx->lock, &attr) != 0) { + pthread_mutexattr_destroy(&attr); + return (true); + } + pthread_mutexattr_destroy(&attr); +#endif + return (false); +} + +void +mtx_fini(mtx_t *mtx) +{ + +#ifdef _WIN32 +#elif (defined(JEMALLOC_OSSPIN)) +#else + pthread_mutex_destroy(&mtx->lock); +#endif +} + +void +mtx_lock(mtx_t *mtx) +{ + +#ifdef _WIN32 + EnterCriticalSection(&mtx->lock); +#elif (defined(JEMALLOC_OSSPIN)) + OSSpinLockLock(&mtx->lock); +#else + pthread_mutex_lock(&mtx->lock); +#endif +} + +void +mtx_unlock(mtx_t *mtx) +{ + +#ifdef _WIN32 + LeaveCriticalSection(&mtx->lock); +#elif (defined(JEMALLOC_OSSPIN)) + OSSpinLockUnlock(&mtx->lock); +#else + pthread_mutex_unlock(&mtx->lock); +#endif +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/src/test.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/src/test.c new file mode 100644 index 0000000..8173614 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/src/test.c @@ -0,0 +1,107 @@ +#include "test/jemalloc_test.h" + +static unsigned test_count = 0; +static test_status_t test_counts[test_status_count] = {0, 0, 0}; +static test_status_t test_status = test_status_pass; +static const char * test_name = ""; + +JEMALLOC_FORMAT_PRINTF(1, 2) +void +test_skip(const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + malloc_vcprintf(NULL, NULL, format, ap); + va_end(ap); + malloc_printf("\n"); + test_status = test_status_skip; +} + +JEMALLOC_FORMAT_PRINTF(1, 2) +void +test_fail(const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + malloc_vcprintf(NULL, NULL, format, ap); + va_end(ap); + malloc_printf("\n"); + test_status = test_status_fail; +} + +static const char * +test_status_string(test_status_t test_status) +{ + + switch (test_status) { + case test_status_pass: return "pass"; + case test_status_skip: return "skip"; + case test_status_fail: return "fail"; + default: not_reached(); + } +} + +void +p_test_init(const char *name) +{ + + test_count++; + test_status = test_status_pass; + test_name = name; +} + +void +p_test_fini(void) +{ + + test_counts[test_status]++; + malloc_printf("%s: %s\n", test_name, test_status_string(test_status)); +} + +test_status_t +p_test(test_t *t, ...) +{ + test_status_t ret; + va_list ap; + + /* + * Make sure initialization occurs prior to running tests. Tests are + * special because they may use internal facilities prior to triggering + * initialization as a side effect of calling into the public API. This + * is a final safety that works even if jemalloc_constructor() doesn't + * run, as for MSVC builds. + */ + if (nallocx(1, 0) == 0) { + malloc_printf("Initialization error"); + return (test_status_fail); + } + + ret = test_status_pass; + va_start(ap, t); + for (; t != NULL; t = va_arg(ap, test_t *)) { + t(); + if (test_status > ret) + ret = test_status; + } + va_end(ap); + + malloc_printf("--- %s: %u/%u, %s: %u/%u, %s: %u/%u ---\n", + test_status_string(test_status_pass), + test_counts[test_status_pass], test_count, + test_status_string(test_status_skip), + test_counts[test_status_skip], test_count, + test_status_string(test_status_fail), + test_counts[test_status_fail], test_count); + + return (ret); +} + +void +p_test_fail(const char *prefix, const char *message) +{ + + malloc_cprintf(NULL, NULL, "%s%s\n", prefix, message); + test_status = test_status_fail; +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/src/thd.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/src/thd.c new file mode 100644 index 0000000..c9d0065 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/src/thd.c @@ -0,0 +1,39 @@ +#include "test/jemalloc_test.h" + +#ifdef _WIN32 +void +thd_create(thd_t *thd, void *(*proc)(void *), void *arg) +{ + LPTHREAD_START_ROUTINE routine = (LPTHREAD_START_ROUTINE)proc; + *thd = CreateThread(NULL, 0, routine, arg, 0, NULL); + if (*thd == NULL) + test_fail("Error in CreateThread()\n"); +} + +void +thd_join(thd_t thd, void **ret) +{ + + if (WaitForSingleObject(thd, INFINITE) == WAIT_OBJECT_0 && ret) { + DWORD exit_code; + GetExitCodeThread(thd, (LPDWORD) &exit_code); + *ret = (void *)(uintptr_t)exit_code; + } +} + +#else +void +thd_create(thd_t *thd, void *(*proc)(void *), void *arg) +{ + + if (pthread_create(thd, NULL, proc, arg) != 0) + test_fail("Error in pthread_create()\n"); +} + +void +thd_join(thd_t thd, void **ret) +{ + + pthread_join(thd, ret); +} +#endif diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/src/timer.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/src/timer.c new file mode 100644 index 0000000..0c93aba --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/src/timer.c @@ -0,0 +1,85 @@ +#include "test/jemalloc_test.h" + +void +timer_start(timedelta_t *timer) +{ + +#ifdef _WIN32 + GetSystemTimeAsFileTime(&timer->ft0); +#elif JEMALLOC_CLOCK_GETTIME + if (sysconf(_SC_MONOTONIC_CLOCK) <= 0) + timer->clock_id = CLOCK_REALTIME; + else + timer->clock_id = CLOCK_MONOTONIC; + clock_gettime(timer->clock_id, &timer->ts0); +#else + gettimeofday(&timer->tv0, NULL); +#endif +} + +void +timer_stop(timedelta_t *timer) +{ + +#ifdef _WIN32 + GetSystemTimeAsFileTime(&timer->ft0); +#elif JEMALLOC_CLOCK_GETTIME + clock_gettime(timer->clock_id, &timer->ts1); +#else + gettimeofday(&timer->tv1, NULL); +#endif +} + +uint64_t +timer_usec(const timedelta_t *timer) +{ + +#ifdef _WIN32 + uint64_t t0, t1; + t0 = (((uint64_t)timer->ft0.dwHighDateTime) << 32) | + timer->ft0.dwLowDateTime; + t1 = (((uint64_t)timer->ft1.dwHighDateTime) << 32) | + timer->ft1.dwLowDateTime; + return ((t1 - t0) / 10); +#elif JEMALLOC_CLOCK_GETTIME + return (((timer->ts1.tv_sec - timer->ts0.tv_sec) * 1000000) + + (timer->ts1.tv_nsec - timer->ts0.tv_nsec) / 1000); +#else + return (((timer->tv1.tv_sec - timer->tv0.tv_sec) * 1000000) + + timer->tv1.tv_usec - timer->tv0.tv_usec); +#endif +} + +void +timer_ratio(timedelta_t *a, timedelta_t *b, char *buf, size_t buflen) +{ + uint64_t t0 = timer_usec(a); + uint64_t t1 = timer_usec(b); + uint64_t mult; + unsigned i = 0; + unsigned j; + int n; + + /* Whole. */ + n = malloc_snprintf(&buf[i], buflen-i, "%"FMTu64, t0 / t1); + i += n; + if (i >= buflen) + return; + mult = 1; + for (j = 0; j < n; j++) + mult *= 10; + + /* Decimal. */ + n = malloc_snprintf(&buf[i], buflen-i, "."); + i += n; + + /* Fraction. */ + while (i < buflen-1) { + uint64_t round = (i+1 == buflen-1 && ((t0 * mult * 10 / t1) % 10 + >= 5)) ? 1 : 0; + n = malloc_snprintf(&buf[i], buflen-i, + "%"FMTu64, (t0 * mult / t1) % 10 + round); + i += n; + mult *= 10; + } +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/stress/microbench.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/stress/microbench.c new file mode 100644 index 0000000..ee39fea --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/stress/microbench.c @@ -0,0 +1,181 @@ +#include "test/jemalloc_test.h" + +JEMALLOC_INLINE_C void +time_func(timedelta_t *timer, uint64_t nwarmup, uint64_t niter, void (*func)(void)) +{ + uint64_t i; + + for (i = 0; i < nwarmup; i++) + func(); + timer_start(timer); + for (i = 0; i < niter; i++) + func(); + timer_stop(timer); +} + +void +compare_funcs(uint64_t nwarmup, uint64_t niter, const char *name_a, + void (*func_a), const char *name_b, void (*func_b)) +{ + timedelta_t timer_a, timer_b; + char ratio_buf[6]; + void *p; + + p = mallocx(1, 0); + if (p == NULL) { + test_fail("Unexpected mallocx() failure"); + return; + } + + time_func(&timer_a, nwarmup, niter, func_a); + time_func(&timer_b, nwarmup, niter, func_b); + + timer_ratio(&timer_a, &timer_b, ratio_buf, sizeof(ratio_buf)); + malloc_printf("%"FMTu64" iterations, %s=%"FMTu64"us, " + "%s=%"FMTu64"us, ratio=1:%s\n", + niter, name_a, timer_usec(&timer_a), name_b, timer_usec(&timer_b), + ratio_buf); + + dallocx(p, 0); +} + +static void +malloc_free(void) +{ + /* The compiler can optimize away free(malloc(1))! */ + void *p = malloc(1); + if (p == NULL) { + test_fail("Unexpected malloc() failure"); + return; + } + free(p); +} + +static void +mallocx_free(void) +{ + void *p = mallocx(1, 0); + if (p == NULL) { + test_fail("Unexpected mallocx() failure"); + return; + } + free(p); +} + +TEST_BEGIN(test_malloc_vs_mallocx) +{ + + compare_funcs(10*1000*1000, 100*1000*1000, "malloc", + malloc_free, "mallocx", mallocx_free); +} +TEST_END + +static void +malloc_dallocx(void) +{ + void *p = malloc(1); + if (p == NULL) { + test_fail("Unexpected malloc() failure"); + return; + } + dallocx(p, 0); +} + +static void +malloc_sdallocx(void) +{ + void *p = malloc(1); + if (p == NULL) { + test_fail("Unexpected malloc() failure"); + return; + } + sdallocx(p, 1, 0); +} + +TEST_BEGIN(test_free_vs_dallocx) +{ + + compare_funcs(10*1000*1000, 100*1000*1000, "free", malloc_free, + "dallocx", malloc_dallocx); +} +TEST_END + +TEST_BEGIN(test_dallocx_vs_sdallocx) +{ + + compare_funcs(10*1000*1000, 100*1000*1000, "dallocx", malloc_dallocx, + "sdallocx", malloc_sdallocx); +} +TEST_END + +static void +malloc_mus_free(void) +{ + void *p; + + p = malloc(1); + if (p == NULL) { + test_fail("Unexpected malloc() failure"); + return; + } + malloc_usable_size(p); + free(p); +} + +static void +malloc_sallocx_free(void) +{ + void *p; + + p = malloc(1); + if (p == NULL) { + test_fail("Unexpected malloc() failure"); + return; + } + if (sallocx(p, 0) < 1) + test_fail("Unexpected sallocx() failure"); + free(p); +} + +TEST_BEGIN(test_mus_vs_sallocx) +{ + + compare_funcs(10*1000*1000, 100*1000*1000, "malloc_usable_size", + malloc_mus_free, "sallocx", malloc_sallocx_free); +} +TEST_END + +static void +malloc_nallocx_free(void) +{ + void *p; + + p = malloc(1); + if (p == NULL) { + test_fail("Unexpected malloc() failure"); + return; + } + if (nallocx(1, 0) < 1) + test_fail("Unexpected nallocx() failure"); + free(p); +} + +TEST_BEGIN(test_sallocx_vs_nallocx) +{ + + compare_funcs(10*1000*1000, 100*1000*1000, "sallocx", + malloc_sallocx_free, "nallocx", malloc_nallocx_free); +} +TEST_END + +int +main(void) +{ + + return (test( + test_malloc_vs_mallocx, + test_free_vs_dallocx, + test_dallocx_vs_sdallocx, + test_mus_vs_sallocx, + test_sallocx_vs_nallocx)); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/test.sh.in b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/test.sh.in new file mode 100644 index 0000000..a39f99f --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/test.sh.in @@ -0,0 +1,53 @@ +#!/bin/sh + +case @abi@ in + macho) + export DYLD_FALLBACK_LIBRARY_PATH="@objroot@lib" + ;; + pecoff) + export PATH="${PATH}:@objroot@lib" + ;; + *) + ;; +esac + +# Corresponds to test_status_t. +pass_code=0 +skip_code=1 +fail_code=2 + +pass_count=0 +skip_count=0 +fail_count=0 +for t in $@; do + if [ $pass_count -ne 0 -o $skip_count -ne 0 -o $fail_count != 0 ] ; then + echo + fi + echo "=== ${t} ===" + ${t}@exe@ @abs_srcroot@ @abs_objroot@ + result_code=$? + case ${result_code} in + ${pass_code}) + pass_count=$((pass_count+1)) + ;; + ${skip_code}) + skip_count=$((skip_count+1)) + ;; + ${fail_code}) + fail_count=$((fail_count+1)) + ;; + *) + echo "Test harness error" 1>&2 + exit 1 + esac +done + +total_count=`expr ${pass_count} + ${skip_count} + ${fail_count}` +echo +echo "Test suite summary: pass: ${pass_count}/${total_count}, skip: ${skip_count}/${total_count}, fail: ${fail_count}/${total_count}" + +if [ ${fail_count} -eq 0 ] ; then + exit 0 +else + exit 1 +fi diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/SFMT.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/SFMT.c new file mode 100644 index 0000000..ba4be87 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/SFMT.c @@ -0,0 +1,1605 @@ +/* + * This file derives from SFMT 1.3.3 + * (http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html), which was + * released under the terms of the following license: + * + * Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima + * University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of the Hiroshima University nor the names of + * its contributors may be used to endorse or promote products + * derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "test/jemalloc_test.h" + +#define BLOCK_SIZE 10000 +#define BLOCK_SIZE64 (BLOCK_SIZE / 2) +#define COUNT_1 1000 +#define COUNT_2 700 + +static const uint32_t init_gen_rand_32_expected[] = { + 3440181298U, 1564997079U, 1510669302U, 2930277156U, 1452439940U, + 3796268453U, 423124208U, 2143818589U, 3827219408U, 2987036003U, + 2674978610U, 1536842514U, 2027035537U, 2534897563U, 1686527725U, + 545368292U, 1489013321U, 1370534252U, 4231012796U, 3994803019U, + 1764869045U, 824597505U, 862581900U, 2469764249U, 812862514U, + 359318673U, 116957936U, 3367389672U, 2327178354U, 1898245200U, + 3206507879U, 2378925033U, 1040214787U, 2524778605U, 3088428700U, + 1417665896U, 964324147U, 2282797708U, 2456269299U, 313400376U, + 2245093271U, 1015729427U, 2694465011U, 3246975184U, 1992793635U, + 463679346U, 3721104591U, 3475064196U, 856141236U, 1499559719U, + 3522818941U, 3721533109U, 1954826617U, 1282044024U, 1543279136U, + 1301863085U, 2669145051U, 4221477354U, 3896016841U, 3392740262U, + 462466863U, 1037679449U, 1228140306U, 922298197U, 1205109853U, + 1872938061U, 3102547608U, 2742766808U, 1888626088U, 4028039414U, + 157593879U, 1136901695U, 4038377686U, 3572517236U, 4231706728U, + 2997311961U, 1189931652U, 3981543765U, 2826166703U, 87159245U, + 1721379072U, 3897926942U, 1790395498U, 2569178939U, 1047368729U, + 2340259131U, 3144212906U, 2301169789U, 2442885464U, 3034046771U, + 3667880593U, 3935928400U, 2372805237U, 1666397115U, 2460584504U, + 513866770U, 3810869743U, 2147400037U, 2792078025U, 2941761810U, + 3212265810U, 984692259U, 346590253U, 1804179199U, 3298543443U, + 750108141U, 2880257022U, 243310542U, 1869036465U, 1588062513U, + 2983949551U, 1931450364U, 4034505847U, 2735030199U, 1628461061U, + 2539522841U, 127965585U, 3992448871U, 913388237U, 559130076U, + 1202933193U, 4087643167U, 2590021067U, 2256240196U, 1746697293U, + 1013913783U, 1155864921U, 2715773730U, 915061862U, 1948766573U, + 2322882854U, 3761119102U, 1343405684U, 3078711943U, 3067431651U, + 3245156316U, 3588354584U, 3484623306U, 3899621563U, 4156689741U, + 3237090058U, 3880063844U, 862416318U, 4039923869U, 2303788317U, + 3073590536U, 701653667U, 2131530884U, 3169309950U, 2028486980U, + 747196777U, 3620218225U, 432016035U, 1449580595U, 2772266392U, + 444224948U, 1662832057U, 3184055582U, 3028331792U, 1861686254U, + 1104864179U, 342430307U, 1350510923U, 3024656237U, 1028417492U, + 2870772950U, 290847558U, 3675663500U, 508431529U, 4264340390U, + 2263569913U, 1669302976U, 519511383U, 2706411211U, 3764615828U, + 3883162495U, 4051445305U, 2412729798U, 3299405164U, 3991911166U, + 2348767304U, 2664054906U, 3763609282U, 593943581U, 3757090046U, + 2075338894U, 2020550814U, 4287452920U, 4290140003U, 1422957317U, + 2512716667U, 2003485045U, 2307520103U, 2288472169U, 3940751663U, + 4204638664U, 2892583423U, 1710068300U, 3904755993U, 2363243951U, + 3038334120U, 547099465U, 771105860U, 3199983734U, 4282046461U, + 2298388363U, 934810218U, 2837827901U, 3952500708U, 2095130248U, + 3083335297U, 26885281U, 3932155283U, 1531751116U, 1425227133U, + 495654159U, 3279634176U, 3855562207U, 3957195338U, 4159985527U, + 893375062U, 1875515536U, 1327247422U, 3754140693U, 1028923197U, + 1729880440U, 805571298U, 448971099U, 2726757106U, 2749436461U, + 2485987104U, 175337042U, 3235477922U, 3882114302U, 2020970972U, + 943926109U, 2762587195U, 1904195558U, 3452650564U, 108432281U, + 3893463573U, 3977583081U, 2636504348U, 1110673525U, 3548479841U, + 4258854744U, 980047703U, 4057175418U, 3890008292U, 145653646U, + 3141868989U, 3293216228U, 1194331837U, 1254570642U, 3049934521U, + 2868313360U, 2886032750U, 1110873820U, 279553524U, 3007258565U, + 1104807822U, 3186961098U, 315764646U, 2163680838U, 3574508994U, + 3099755655U, 191957684U, 3642656737U, 3317946149U, 3522087636U, + 444526410U, 779157624U, 1088229627U, 1092460223U, 1856013765U, + 3659877367U, 368270451U, 503570716U, 3000984671U, 2742789647U, + 928097709U, 2914109539U, 308843566U, 2816161253U, 3667192079U, + 2762679057U, 3395240989U, 2928925038U, 1491465914U, 3458702834U, + 3787782576U, 2894104823U, 1296880455U, 1253636503U, 989959407U, + 2291560361U, 2776790436U, 1913178042U, 1584677829U, 689637520U, + 1898406878U, 688391508U, 3385234998U, 845493284U, 1943591856U, + 2720472050U, 222695101U, 1653320868U, 2904632120U, 4084936008U, + 1080720688U, 3938032556U, 387896427U, 2650839632U, 99042991U, + 1720913794U, 1047186003U, 1877048040U, 2090457659U, 517087501U, + 4172014665U, 2129713163U, 2413533132U, 2760285054U, 4129272496U, + 1317737175U, 2309566414U, 2228873332U, 3889671280U, 1110864630U, + 3576797776U, 2074552772U, 832002644U, 3097122623U, 2464859298U, + 2679603822U, 1667489885U, 3237652716U, 1478413938U, 1719340335U, + 2306631119U, 639727358U, 3369698270U, 226902796U, 2099920751U, + 1892289957U, 2201594097U, 3508197013U, 3495811856U, 3900381493U, + 841660320U, 3974501451U, 3360949056U, 1676829340U, 728899254U, + 2047809627U, 2390948962U, 670165943U, 3412951831U, 4189320049U, + 1911595255U, 2055363086U, 507170575U, 418219594U, 4141495280U, + 2692088692U, 4203630654U, 3540093932U, 791986533U, 2237921051U, + 2526864324U, 2956616642U, 1394958700U, 1983768223U, 1893373266U, + 591653646U, 228432437U, 1611046598U, 3007736357U, 1040040725U, + 2726180733U, 2789804360U, 4263568405U, 829098158U, 3847722805U, + 1123578029U, 1804276347U, 997971319U, 4203797076U, 4185199713U, + 2811733626U, 2343642194U, 2985262313U, 1417930827U, 3759587724U, + 1967077982U, 1585223204U, 1097475516U, 1903944948U, 740382444U, + 1114142065U, 1541796065U, 1718384172U, 1544076191U, 1134682254U, + 3519754455U, 2866243923U, 341865437U, 645498576U, 2690735853U, + 1046963033U, 2493178460U, 1187604696U, 1619577821U, 488503634U, + 3255768161U, 2306666149U, 1630514044U, 2377698367U, 2751503746U, + 3794467088U, 1796415981U, 3657173746U, 409136296U, 1387122342U, + 1297726519U, 219544855U, 4270285558U, 437578827U, 1444698679U, + 2258519491U, 963109892U, 3982244073U, 3351535275U, 385328496U, + 1804784013U, 698059346U, 3920535147U, 708331212U, 784338163U, + 785678147U, 1238376158U, 1557298846U, 2037809321U, 271576218U, + 4145155269U, 1913481602U, 2763691931U, 588981080U, 1201098051U, + 3717640232U, 1509206239U, 662536967U, 3180523616U, 1133105435U, + 2963500837U, 2253971215U, 3153642623U, 1066925709U, 2582781958U, + 3034720222U, 1090798544U, 2942170004U, 4036187520U, 686972531U, + 2610990302U, 2641437026U, 1837562420U, 722096247U, 1315333033U, + 2102231203U, 3402389208U, 3403698140U, 1312402831U, 2898426558U, + 814384596U, 385649582U, 1916643285U, 1924625106U, 2512905582U, + 2501170304U, 4275223366U, 2841225246U, 1467663688U, 3563567847U, + 2969208552U, 884750901U, 102992576U, 227844301U, 3681442994U, + 3502881894U, 4034693299U, 1166727018U, 1697460687U, 1737778332U, + 1787161139U, 1053003655U, 1215024478U, 2791616766U, 2525841204U, + 1629323443U, 3233815U, 2003823032U, 3083834263U, 2379264872U, + 3752392312U, 1287475550U, 3770904171U, 3004244617U, 1502117784U, + 918698423U, 2419857538U, 3864502062U, 1751322107U, 2188775056U, + 4018728324U, 983712955U, 440071928U, 3710838677U, 2001027698U, + 3994702151U, 22493119U, 3584400918U, 3446253670U, 4254789085U, + 1405447860U, 1240245579U, 1800644159U, 1661363424U, 3278326132U, + 3403623451U, 67092802U, 2609352193U, 3914150340U, 1814842761U, + 3610830847U, 591531412U, 3880232807U, 1673505890U, 2585326991U, + 1678544474U, 3148435887U, 3457217359U, 1193226330U, 2816576908U, + 154025329U, 121678860U, 1164915738U, 973873761U, 269116100U, + 52087970U, 744015362U, 498556057U, 94298882U, 1563271621U, + 2383059628U, 4197367290U, 3958472990U, 2592083636U, 2906408439U, + 1097742433U, 3924840517U, 264557272U, 2292287003U, 3203307984U, + 4047038857U, 3820609705U, 2333416067U, 1839206046U, 3600944252U, + 3412254904U, 583538222U, 2390557166U, 4140459427U, 2810357445U, + 226777499U, 2496151295U, 2207301712U, 3283683112U, 611630281U, + 1933218215U, 3315610954U, 3889441987U, 3719454256U, 3957190521U, + 1313998161U, 2365383016U, 3146941060U, 1801206260U, 796124080U, + 2076248581U, 1747472464U, 3254365145U, 595543130U, 3573909503U, + 3758250204U, 2020768540U, 2439254210U, 93368951U, 3155792250U, + 2600232980U, 3709198295U, 3894900440U, 2971850836U, 1578909644U, + 1443493395U, 2581621665U, 3086506297U, 2443465861U, 558107211U, + 1519367835U, 249149686U, 908102264U, 2588765675U, 1232743965U, + 1001330373U, 3561331654U, 2259301289U, 1564977624U, 3835077093U, + 727244906U, 4255738067U, 1214133513U, 2570786021U, 3899704621U, + 1633861986U, 1636979509U, 1438500431U, 58463278U, 2823485629U, + 2297430187U, 2926781924U, 3371352948U, 1864009023U, 2722267973U, + 1444292075U, 437703973U, 1060414512U, 189705863U, 910018135U, + 4077357964U, 884213423U, 2644986052U, 3973488374U, 1187906116U, + 2331207875U, 780463700U, 3713351662U, 3854611290U, 412805574U, + 2978462572U, 2176222820U, 829424696U, 2790788332U, 2750819108U, + 1594611657U, 3899878394U, 3032870364U, 1702887682U, 1948167778U, + 14130042U, 192292500U, 947227076U, 90719497U, 3854230320U, + 784028434U, 2142399787U, 1563449646U, 2844400217U, 819143172U, + 2883302356U, 2328055304U, 1328532246U, 2603885363U, 3375188924U, + 933941291U, 3627039714U, 2129697284U, 2167253953U, 2506905438U, + 1412424497U, 2981395985U, 1418359660U, 2925902456U, 52752784U, + 3713667988U, 3924669405U, 648975707U, 1145520213U, 4018650664U, + 3805915440U, 2380542088U, 2013260958U, 3262572197U, 2465078101U, + 1114540067U, 3728768081U, 2396958768U, 590672271U, 904818725U, + 4263660715U, 700754408U, 1042601829U, 4094111823U, 4274838909U, + 2512692617U, 2774300207U, 2057306915U, 3470942453U, 99333088U, + 1142661026U, 2889931380U, 14316674U, 2201179167U, 415289459U, + 448265759U, 3515142743U, 3254903683U, 246633281U, 1184307224U, + 2418347830U, 2092967314U, 2682072314U, 2558750234U, 2000352263U, + 1544150531U, 399010405U, 1513946097U, 499682937U, 461167460U, + 3045570638U, 1633669705U, 851492362U, 4052801922U, 2055266765U, + 635556996U, 368266356U, 2385737383U, 3218202352U, 2603772408U, + 349178792U, 226482567U, 3102426060U, 3575998268U, 2103001871U, + 3243137071U, 225500688U, 1634718593U, 4283311431U, 4292122923U, + 3842802787U, 811735523U, 105712518U, 663434053U, 1855889273U, + 2847972595U, 1196355421U, 2552150115U, 4254510614U, 3752181265U, + 3430721819U, 3828705396U, 3436287905U, 3441964937U, 4123670631U, + 353001539U, 459496439U, 3799690868U, 1293777660U, 2761079737U, + 498096339U, 3398433374U, 4080378380U, 2304691596U, 2995729055U, + 4134660419U, 3903444024U, 3576494993U, 203682175U, 3321164857U, + 2747963611U, 79749085U, 2992890370U, 1240278549U, 1772175713U, + 2111331972U, 2655023449U, 1683896345U, 2836027212U, 3482868021U, + 2489884874U, 756853961U, 2298874501U, 4013448667U, 4143996022U, + 2948306858U, 4132920035U, 1283299272U, 995592228U, 3450508595U, + 1027845759U, 1766942720U, 3861411826U, 1446861231U, 95974993U, + 3502263554U, 1487532194U, 601502472U, 4129619129U, 250131773U, + 2050079547U, 3198903947U, 3105589778U, 4066481316U, 3026383978U, + 2276901713U, 365637751U, 2260718426U, 1394775634U, 1791172338U, + 2690503163U, 2952737846U, 1568710462U, 732623190U, 2980358000U, + 1053631832U, 1432426951U, 3229149635U, 1854113985U, 3719733532U, + 3204031934U, 735775531U, 107468620U, 3734611984U, 631009402U, + 3083622457U, 4109580626U, 159373458U, 1301970201U, 4132389302U, + 1293255004U, 847182752U, 4170022737U, 96712900U, 2641406755U, + 1381727755U, 405608287U, 4287919625U, 1703554290U, 3589580244U, + 2911403488U, 2166565U, 2647306451U, 2330535117U, 1200815358U, + 1165916754U, 245060911U, 4040679071U, 3684908771U, 2452834126U, + 2486872773U, 2318678365U, 2940627908U, 1837837240U, 3447897409U, + 4270484676U, 1495388728U, 3754288477U, 4204167884U, 1386977705U, + 2692224733U, 3076249689U, 4109568048U, 4170955115U, 4167531356U, + 4020189950U, 4261855038U, 3036907575U, 3410399885U, 3076395737U, + 1046178638U, 144496770U, 230725846U, 3349637149U, 17065717U, + 2809932048U, 2054581785U, 3608424964U, 3259628808U, 134897388U, + 3743067463U, 257685904U, 3795656590U, 1562468719U, 3589103904U, + 3120404710U, 254684547U, 2653661580U, 3663904795U, 2631942758U, + 1063234347U, 2609732900U, 2332080715U, 3521125233U, 1180599599U, + 1935868586U, 4110970440U, 296706371U, 2128666368U, 1319875791U, + 1570900197U, 3096025483U, 1799882517U, 1928302007U, 1163707758U, + 1244491489U, 3533770203U, 567496053U, 2757924305U, 2781639343U, + 2818420107U, 560404889U, 2619609724U, 4176035430U, 2511289753U, + 2521842019U, 3910553502U, 2926149387U, 3302078172U, 4237118867U, + 330725126U, 367400677U, 888239854U, 545570454U, 4259590525U, + 134343617U, 1102169784U, 1647463719U, 3260979784U, 1518840883U, + 3631537963U, 3342671457U, 1301549147U, 2083739356U, 146593792U, + 3217959080U, 652755743U, 2032187193U, 3898758414U, 1021358093U, + 4037409230U, 2176407931U, 3427391950U, 2883553603U, 985613827U, + 3105265092U, 3423168427U, 3387507672U, 467170288U, 2141266163U, + 3723870208U, 916410914U, 1293987799U, 2652584950U, 769160137U, + 3205292896U, 1561287359U, 1684510084U, 3136055621U, 3765171391U, + 639683232U, 2639569327U, 1218546948U, 4263586685U, 3058215773U, + 2352279820U, 401870217U, 2625822463U, 1529125296U, 2981801895U, + 1191285226U, 4027725437U, 3432700217U, 4098835661U, 971182783U, + 2443861173U, 3881457123U, 3874386651U, 457276199U, 2638294160U, + 4002809368U, 421169044U, 1112642589U, 3076213779U, 3387033971U, + 2499610950U, 3057240914U, 1662679783U, 461224431U, 1168395933U +}; +static const uint32_t init_by_array_32_expected[] = { + 2920711183U, 3885745737U, 3501893680U, 856470934U, 1421864068U, + 277361036U, 1518638004U, 2328404353U, 3355513634U, 64329189U, + 1624587673U, 3508467182U, 2481792141U, 3706480799U, 1925859037U, + 2913275699U, 882658412U, 384641219U, 422202002U, 1873384891U, + 2006084383U, 3924929912U, 1636718106U, 3108838742U, 1245465724U, + 4195470535U, 779207191U, 1577721373U, 1390469554U, 2928648150U, + 121399709U, 3170839019U, 4044347501U, 953953814U, 3821710850U, + 3085591323U, 3666535579U, 3577837737U, 2012008410U, 3565417471U, + 4044408017U, 433600965U, 1637785608U, 1798509764U, 860770589U, + 3081466273U, 3982393409U, 2451928325U, 3437124742U, 4093828739U, + 3357389386U, 2154596123U, 496568176U, 2650035164U, 2472361850U, + 3438299U, 2150366101U, 1577256676U, 3802546413U, 1787774626U, + 4078331588U, 3706103141U, 170391138U, 3806085154U, 1680970100U, + 1961637521U, 3316029766U, 890610272U, 1453751581U, 1430283664U, + 3051057411U, 3597003186U, 542563954U, 3796490244U, 1690016688U, + 3448752238U, 440702173U, 347290497U, 1121336647U, 2540588620U, + 280881896U, 2495136428U, 213707396U, 15104824U, 2946180358U, + 659000016U, 566379385U, 2614030979U, 2855760170U, 334526548U, + 2315569495U, 2729518615U, 564745877U, 1263517638U, 3157185798U, + 1604852056U, 1011639885U, 2950579535U, 2524219188U, 312951012U, + 1528896652U, 1327861054U, 2846910138U, 3966855905U, 2536721582U, + 855353911U, 1685434729U, 3303978929U, 1624872055U, 4020329649U, + 3164802143U, 1642802700U, 1957727869U, 1792352426U, 3334618929U, + 2631577923U, 3027156164U, 842334259U, 3353446843U, 1226432104U, + 1742801369U, 3552852535U, 3471698828U, 1653910186U, 3380330939U, + 2313782701U, 3351007196U, 2129839995U, 1800682418U, 4085884420U, + 1625156629U, 3669701987U, 615211810U, 3294791649U, 4131143784U, + 2590843588U, 3207422808U, 3275066464U, 561592872U, 3957205738U, + 3396578098U, 48410678U, 3505556445U, 1005764855U, 3920606528U, + 2936980473U, 2378918600U, 2404449845U, 1649515163U, 701203563U, + 3705256349U, 83714199U, 3586854132U, 922978446U, 2863406304U, + 3523398907U, 2606864832U, 2385399361U, 3171757816U, 4262841009U, + 3645837721U, 1169579486U, 3666433897U, 3174689479U, 1457866976U, + 3803895110U, 3346639145U, 1907224409U, 1978473712U, 1036712794U, + 980754888U, 1302782359U, 1765252468U, 459245755U, 3728923860U, + 1512894209U, 2046491914U, 207860527U, 514188684U, 2288713615U, + 1597354672U, 3349636117U, 2357291114U, 3995796221U, 945364213U, + 1893326518U, 3770814016U, 1691552714U, 2397527410U, 967486361U, + 776416472U, 4197661421U, 951150819U, 1852770983U, 4044624181U, + 1399439738U, 4194455275U, 2284037669U, 1550734958U, 3321078108U, + 1865235926U, 2912129961U, 2664980877U, 1357572033U, 2600196436U, + 2486728200U, 2372668724U, 1567316966U, 2374111491U, 1839843570U, + 20815612U, 3727008608U, 3871996229U, 824061249U, 1932503978U, + 3404541726U, 758428924U, 2609331364U, 1223966026U, 1299179808U, + 648499352U, 2180134401U, 880821170U, 3781130950U, 113491270U, + 1032413764U, 4185884695U, 2490396037U, 1201932817U, 4060951446U, + 4165586898U, 1629813212U, 2887821158U, 415045333U, 628926856U, + 2193466079U, 3391843445U, 2227540681U, 1907099846U, 2848448395U, + 1717828221U, 1372704537U, 1707549841U, 2294058813U, 2101214437U, + 2052479531U, 1695809164U, 3176587306U, 2632770465U, 81634404U, + 1603220563U, 644238487U, 302857763U, 897352968U, 2613146653U, + 1391730149U, 4245717312U, 4191828749U, 1948492526U, 2618174230U, + 3992984522U, 2178852787U, 3596044509U, 3445573503U, 2026614616U, + 915763564U, 3415689334U, 2532153403U, 3879661562U, 2215027417U, + 3111154986U, 2929478371U, 668346391U, 1152241381U, 2632029711U, + 3004150659U, 2135025926U, 948690501U, 2799119116U, 4228829406U, + 1981197489U, 4209064138U, 684318751U, 3459397845U, 201790843U, + 4022541136U, 3043635877U, 492509624U, 3263466772U, 1509148086U, + 921459029U, 3198857146U, 705479721U, 3835966910U, 3603356465U, + 576159741U, 1742849431U, 594214882U, 2055294343U, 3634861861U, + 449571793U, 3246390646U, 3868232151U, 1479156585U, 2900125656U, + 2464815318U, 3960178104U, 1784261920U, 18311476U, 3627135050U, + 644609697U, 424968996U, 919890700U, 2986824110U, 816423214U, + 4003562844U, 1392714305U, 1757384428U, 2569030598U, 995949559U, + 3875659880U, 2933807823U, 2752536860U, 2993858466U, 4030558899U, + 2770783427U, 2775406005U, 2777781742U, 1931292655U, 472147933U, + 3865853827U, 2726470545U, 2668412860U, 2887008249U, 408979190U, + 3578063323U, 3242082049U, 1778193530U, 27981909U, 2362826515U, + 389875677U, 1043878156U, 581653903U, 3830568952U, 389535942U, + 3713523185U, 2768373359U, 2526101582U, 1998618197U, 1160859704U, + 3951172488U, 1098005003U, 906275699U, 3446228002U, 2220677963U, + 2059306445U, 132199571U, 476838790U, 1868039399U, 3097344807U, + 857300945U, 396345050U, 2835919916U, 1782168828U, 1419519470U, + 4288137521U, 819087232U, 596301494U, 872823172U, 1526888217U, + 805161465U, 1116186205U, 2829002754U, 2352620120U, 620121516U, + 354159268U, 3601949785U, 209568138U, 1352371732U, 2145977349U, + 4236871834U, 1539414078U, 3558126206U, 3224857093U, 4164166682U, + 3817553440U, 3301780278U, 2682696837U, 3734994768U, 1370950260U, + 1477421202U, 2521315749U, 1330148125U, 1261554731U, 2769143688U, + 3554756293U, 4235882678U, 3254686059U, 3530579953U, 1215452615U, + 3574970923U, 4057131421U, 589224178U, 1000098193U, 171190718U, + 2521852045U, 2351447494U, 2284441580U, 2646685513U, 3486933563U, + 3789864960U, 1190528160U, 1702536782U, 1534105589U, 4262946827U, + 2726686826U, 3584544841U, 2348270128U, 2145092281U, 2502718509U, + 1027832411U, 3571171153U, 1287361161U, 4011474411U, 3241215351U, + 2419700818U, 971242709U, 1361975763U, 1096842482U, 3271045537U, + 81165449U, 612438025U, 3912966678U, 1356929810U, 733545735U, + 537003843U, 1282953084U, 884458241U, 588930090U, 3930269801U, + 2961472450U, 1219535534U, 3632251943U, 268183903U, 1441240533U, + 3653903360U, 3854473319U, 2259087390U, 2548293048U, 2022641195U, + 2105543911U, 1764085217U, 3246183186U, 482438805U, 888317895U, + 2628314765U, 2466219854U, 717546004U, 2322237039U, 416725234U, + 1544049923U, 1797944973U, 3398652364U, 3111909456U, 485742908U, + 2277491072U, 1056355088U, 3181001278U, 129695079U, 2693624550U, + 1764438564U, 3797785470U, 195503713U, 3266519725U, 2053389444U, + 1961527818U, 3400226523U, 3777903038U, 2597274307U, 4235851091U, + 4094406648U, 2171410785U, 1781151386U, 1378577117U, 654643266U, + 3424024173U, 3385813322U, 679385799U, 479380913U, 681715441U, + 3096225905U, 276813409U, 3854398070U, 2721105350U, 831263315U, + 3276280337U, 2628301522U, 3984868494U, 1466099834U, 2104922114U, + 1412672743U, 820330404U, 3491501010U, 942735832U, 710652807U, + 3972652090U, 679881088U, 40577009U, 3705286397U, 2815423480U, + 3566262429U, 663396513U, 3777887429U, 4016670678U, 404539370U, + 1142712925U, 1140173408U, 2913248352U, 2872321286U, 263751841U, + 3175196073U, 3162557581U, 2878996619U, 75498548U, 3836833140U, + 3284664959U, 1157523805U, 112847376U, 207855609U, 1337979698U, + 1222578451U, 157107174U, 901174378U, 3883717063U, 1618632639U, + 1767889440U, 4264698824U, 1582999313U, 884471997U, 2508825098U, + 3756370771U, 2457213553U, 3565776881U, 3709583214U, 915609601U, + 460833524U, 1091049576U, 85522880U, 2553251U, 132102809U, + 2429882442U, 2562084610U, 1386507633U, 4112471229U, 21965213U, + 1981516006U, 2418435617U, 3054872091U, 4251511224U, 2025783543U, + 1916911512U, 2454491136U, 3938440891U, 3825869115U, 1121698605U, + 3463052265U, 802340101U, 1912886800U, 4031997367U, 3550640406U, + 1596096923U, 610150600U, 431464457U, 2541325046U, 486478003U, + 739704936U, 2862696430U, 3037903166U, 1129749694U, 2611481261U, + 1228993498U, 510075548U, 3424962587U, 2458689681U, 818934833U, + 4233309125U, 1608196251U, 3419476016U, 1858543939U, 2682166524U, + 3317854285U, 631986188U, 3008214764U, 613826412U, 3567358221U, + 3512343882U, 1552467474U, 3316162670U, 1275841024U, 4142173454U, + 565267881U, 768644821U, 198310105U, 2396688616U, 1837659011U, + 203429334U, 854539004U, 4235811518U, 3338304926U, 3730418692U, + 3852254981U, 3032046452U, 2329811860U, 2303590566U, 2696092212U, + 3894665932U, 145835667U, 249563655U, 1932210840U, 2431696407U, + 3312636759U, 214962629U, 2092026914U, 3020145527U, 4073039873U, + 2739105705U, 1308336752U, 855104522U, 2391715321U, 67448785U, + 547989482U, 854411802U, 3608633740U, 431731530U, 537375589U, + 3888005760U, 696099141U, 397343236U, 1864511780U, 44029739U, + 1729526891U, 1993398655U, 2010173426U, 2591546756U, 275223291U, + 1503900299U, 4217765081U, 2185635252U, 1122436015U, 3550155364U, + 681707194U, 3260479338U, 933579397U, 2983029282U, 2505504587U, + 2667410393U, 2962684490U, 4139721708U, 2658172284U, 2452602383U, + 2607631612U, 1344296217U, 3075398709U, 2949785295U, 1049956168U, + 3917185129U, 2155660174U, 3280524475U, 1503827867U, 674380765U, + 1918468193U, 3843983676U, 634358221U, 2538335643U, 1873351298U, + 3368723763U, 2129144130U, 3203528633U, 3087174986U, 2691698871U, + 2516284287U, 24437745U, 1118381474U, 2816314867U, 2448576035U, + 4281989654U, 217287825U, 165872888U, 2628995722U, 3533525116U, + 2721669106U, 872340568U, 3429930655U, 3309047304U, 3916704967U, + 3270160355U, 1348884255U, 1634797670U, 881214967U, 4259633554U, + 174613027U, 1103974314U, 1625224232U, 2678368291U, 1133866707U, + 3853082619U, 4073196549U, 1189620777U, 637238656U, 930241537U, + 4042750792U, 3842136042U, 2417007212U, 2524907510U, 1243036827U, + 1282059441U, 3764588774U, 1394459615U, 2323620015U, 1166152231U, + 3307479609U, 3849322257U, 3507445699U, 4247696636U, 758393720U, + 967665141U, 1095244571U, 1319812152U, 407678762U, 2640605208U, + 2170766134U, 3663594275U, 4039329364U, 2512175520U, 725523154U, + 2249807004U, 3312617979U, 2414634172U, 1278482215U, 349206484U, + 1573063308U, 1196429124U, 3873264116U, 2400067801U, 268795167U, + 226175489U, 2961367263U, 1968719665U, 42656370U, 1010790699U, + 561600615U, 2422453992U, 3082197735U, 1636700484U, 3977715296U, + 3125350482U, 3478021514U, 2227819446U, 1540868045U, 3061908980U, + 1087362407U, 3625200291U, 361937537U, 580441897U, 1520043666U, + 2270875402U, 1009161260U, 2502355842U, 4278769785U, 473902412U, + 1057239083U, 1905829039U, 1483781177U, 2080011417U, 1207494246U, + 1806991954U, 2194674403U, 3455972205U, 807207678U, 3655655687U, + 674112918U, 195425752U, 3917890095U, 1874364234U, 1837892715U, + 3663478166U, 1548892014U, 2570748714U, 2049929836U, 2167029704U, + 697543767U, 3499545023U, 3342496315U, 1725251190U, 3561387469U, + 2905606616U, 1580182447U, 3934525927U, 4103172792U, 1365672522U, + 1534795737U, 3308667416U, 2841911405U, 3943182730U, 4072020313U, + 3494770452U, 3332626671U, 55327267U, 478030603U, 411080625U, + 3419529010U, 1604767823U, 3513468014U, 570668510U, 913790824U, + 2283967995U, 695159462U, 3825542932U, 4150698144U, 1829758699U, + 202895590U, 1609122645U, 1267651008U, 2910315509U, 2511475445U, + 2477423819U, 3932081579U, 900879979U, 2145588390U, 2670007504U, + 580819444U, 1864996828U, 2526325979U, 1019124258U, 815508628U, + 2765933989U, 1277301341U, 3006021786U, 855540956U, 288025710U, + 1919594237U, 2331223864U, 177452412U, 2475870369U, 2689291749U, + 865194284U, 253432152U, 2628531804U, 2861208555U, 2361597573U, + 1653952120U, 1039661024U, 2159959078U, 3709040440U, 3564718533U, + 2596878672U, 2041442161U, 31164696U, 2662962485U, 3665637339U, + 1678115244U, 2699839832U, 3651968520U, 3521595541U, 458433303U, + 2423096824U, 21831741U, 380011703U, 2498168716U, 861806087U, + 1673574843U, 4188794405U, 2520563651U, 2632279153U, 2170465525U, + 4171949898U, 3886039621U, 1661344005U, 3424285243U, 992588372U, + 2500984144U, 2993248497U, 3590193895U, 1535327365U, 515645636U, + 131633450U, 3729760261U, 1613045101U, 3254194278U, 15889678U, + 1493590689U, 244148718U, 2991472662U, 1401629333U, 777349878U, + 2501401703U, 4285518317U, 3794656178U, 955526526U, 3442142820U, + 3970298374U, 736025417U, 2737370764U, 1271509744U, 440570731U, + 136141826U, 1596189518U, 923399175U, 257541519U, 3505774281U, + 2194358432U, 2518162991U, 1379893637U, 2667767062U, 3748146247U, + 1821712620U, 3923161384U, 1947811444U, 2392527197U, 4127419685U, + 1423694998U, 4156576871U, 1382885582U, 3420127279U, 3617499534U, + 2994377493U, 4038063986U, 1918458672U, 2983166794U, 4200449033U, + 353294540U, 1609232588U, 243926648U, 2332803291U, 507996832U, + 2392838793U, 4075145196U, 2060984340U, 4287475136U, 88232602U, + 2491531140U, 4159725633U, 2272075455U, 759298618U, 201384554U, + 838356250U, 1416268324U, 674476934U, 90795364U, 141672229U, + 3660399588U, 4196417251U, 3249270244U, 3774530247U, 59587265U, + 3683164208U, 19392575U, 1463123697U, 1882205379U, 293780489U, + 2553160622U, 2933904694U, 675638239U, 2851336944U, 1435238743U, + 2448730183U, 804436302U, 2119845972U, 322560608U, 4097732704U, + 2987802540U, 641492617U, 2575442710U, 4217822703U, 3271835300U, + 2836418300U, 3739921620U, 2138378768U, 2879771855U, 4294903423U, + 3121097946U, 2603440486U, 2560820391U, 1012930944U, 2313499967U, + 584489368U, 3431165766U, 897384869U, 2062537737U, 2847889234U, + 3742362450U, 2951174585U, 4204621084U, 1109373893U, 3668075775U, + 2750138839U, 3518055702U, 733072558U, 4169325400U, 788493625U +}; +static const uint64_t init_gen_rand_64_expected[] = { + KQU(16924766246869039260), KQU( 8201438687333352714), + KQU( 2265290287015001750), KQU(18397264611805473832), + KQU( 3375255223302384358), KQU( 6345559975416828796), + KQU(18229739242790328073), KQU( 7596792742098800905), + KQU( 255338647169685981), KQU( 2052747240048610300), + KQU(18328151576097299343), KQU(12472905421133796567), + KQU(11315245349717600863), KQU(16594110197775871209), + KQU(15708751964632456450), KQU(10452031272054632535), + KQU(11097646720811454386), KQU( 4556090668445745441), + KQU(17116187693090663106), KQU(14931526836144510645), + KQU( 9190752218020552591), KQU( 9625800285771901401), + KQU(13995141077659972832), KQU( 5194209094927829625), + KQU( 4156788379151063303), KQU( 8523452593770139494), + KQU(14082382103049296727), KQU( 2462601863986088483), + KQU( 3030583461592840678), KQU( 5221622077872827681), + KQU( 3084210671228981236), KQU(13956758381389953823), + KQU(13503889856213423831), KQU(15696904024189836170), + KQU( 4612584152877036206), KQU( 6231135538447867881), + KQU(10172457294158869468), KQU( 6452258628466708150), + KQU(14044432824917330221), KQU( 370168364480044279), + KQU(10102144686427193359), KQU( 667870489994776076), + KQU( 2732271956925885858), KQU(18027788905977284151), + KQU(15009842788582923859), KQU( 7136357960180199542), + KQU(15901736243475578127), KQU(16951293785352615701), + KQU(10551492125243691632), KQU(17668869969146434804), + KQU(13646002971174390445), KQU( 9804471050759613248), + KQU( 5511670439655935493), KQU(18103342091070400926), + KQU(17224512747665137533), KQU(15534627482992618168), + KQU( 1423813266186582647), KQU(15821176807932930024), + KQU( 30323369733607156), KQU(11599382494723479403), + KQU( 653856076586810062), KQU( 3176437395144899659), + KQU(14028076268147963917), KQU(16156398271809666195), + KQU( 3166955484848201676), KQU( 5746805620136919390), + KQU(17297845208891256593), KQU(11691653183226428483), + KQU(17900026146506981577), KQU(15387382115755971042), + KQU(16923567681040845943), KQU( 8039057517199388606), + KQU(11748409241468629263), KQU( 794358245539076095), + KQU(13438501964693401242), KQU(14036803236515618962), + KQU( 5252311215205424721), KQU(17806589612915509081), + KQU( 6802767092397596006), KQU(14212120431184557140), + KQU( 1072951366761385712), KQU(13098491780722836296), + KQU( 9466676828710797353), KQU(12673056849042830081), + KQU(12763726623645357580), KQU(16468961652999309493), + KQU(15305979875636438926), KQU(17444713151223449734), + KQU( 5692214267627883674), KQU(13049589139196151505), + KQU( 880115207831670745), KQU( 1776529075789695498), + KQU(16695225897801466485), KQU(10666901778795346845), + KQU( 6164389346722833869), KQU( 2863817793264300475), + KQU( 9464049921886304754), KQU( 3993566636740015468), + KQU( 9983749692528514136), KQU(16375286075057755211), + KQU(16042643417005440820), KQU(11445419662923489877), + KQU( 7999038846885158836), KQU( 6721913661721511535), + KQU( 5363052654139357320), KQU( 1817788761173584205), + KQU(13290974386445856444), KQU( 4650350818937984680), + KQU( 8219183528102484836), KQU( 1569862923500819899), + KQU( 4189359732136641860), KQU(14202822961683148583), + KQU( 4457498315309429058), KQU(13089067387019074834), + KQU(11075517153328927293), KQU(10277016248336668389), + KQU( 7070509725324401122), KQU(17808892017780289380), + KQU(13143367339909287349), KQU( 1377743745360085151), + KQU( 5749341807421286485), KQU(14832814616770931325), + KQU( 7688820635324359492), KQU(10960474011539770045), + KQU( 81970066653179790), KQU(12619476072607878022), + KQU( 4419566616271201744), KQU(15147917311750568503), + KQU( 5549739182852706345), KQU( 7308198397975204770), + KQU(13580425496671289278), KQU(17070764785210130301), + KQU( 8202832846285604405), KQU( 6873046287640887249), + KQU( 6927424434308206114), KQU( 6139014645937224874), + KQU(10290373645978487639), KQU(15904261291701523804), + KQU( 9628743442057826883), KQU(18383429096255546714), + KQU( 4977413265753686967), KQU( 7714317492425012869), + KQU( 9025232586309926193), KQU(14627338359776709107), + KQU(14759849896467790763), KQU(10931129435864423252), + KQU( 4588456988775014359), KQU(10699388531797056724), + KQU( 468652268869238792), KQU( 5755943035328078086), + KQU( 2102437379988580216), KQU( 9986312786506674028), + KQU( 2654207180040945604), KQU( 8726634790559960062), + KQU( 100497234871808137), KQU( 2800137176951425819), + KQU( 6076627612918553487), KQU( 5780186919186152796), + KQU( 8179183595769929098), KQU( 6009426283716221169), + KQU( 2796662551397449358), KQU( 1756961367041986764), + KQU( 6972897917355606205), KQU(14524774345368968243), + KQU( 2773529684745706940), KQU( 4853632376213075959), + KQU( 4198177923731358102), KQU( 8271224913084139776), + KQU( 2741753121611092226), KQU(16782366145996731181), + KQU(15426125238972640790), KQU(13595497100671260342), + KQU( 3173531022836259898), KQU( 6573264560319511662), + KQU(18041111951511157441), KQU( 2351433581833135952), + KQU( 3113255578908173487), KQU( 1739371330877858784), + KQU(16046126562789165480), KQU( 8072101652214192925), + KQU(15267091584090664910), KQU( 9309579200403648940), + KQU( 5218892439752408722), KQU(14492477246004337115), + KQU(17431037586679770619), KQU( 7385248135963250480), + KQU( 9580144956565560660), KQU( 4919546228040008720), + KQU(15261542469145035584), KQU(18233297270822253102), + KQU( 5453248417992302857), KQU( 9309519155931460285), + KQU(10342813012345291756), KQU(15676085186784762381), + KQU(15912092950691300645), KQU( 9371053121499003195), + KQU( 9897186478226866746), KQU(14061858287188196327), + KQU( 122575971620788119), KQU(12146750969116317754), + KQU( 4438317272813245201), KQU( 8332576791009527119), + KQU(13907785691786542057), KQU(10374194887283287467), + KQU( 2098798755649059566), KQU( 3416235197748288894), + KQU( 8688269957320773484), KQU( 7503964602397371571), + KQU(16724977015147478236), KQU( 9461512855439858184), + KQU(13259049744534534727), KQU( 3583094952542899294), + KQU( 8764245731305528292), KQU(13240823595462088985), + KQU(13716141617617910448), KQU(18114969519935960955), + KQU( 2297553615798302206), KQU( 4585521442944663362), + KQU(17776858680630198686), KQU( 4685873229192163363), + KQU( 152558080671135627), KQU(15424900540842670088), + KQU(13229630297130024108), KQU(17530268788245718717), + KQU(16675633913065714144), KQU( 3158912717897568068), + KQU(15399132185380087288), KQU( 7401418744515677872), + KQU(13135412922344398535), KQU( 6385314346100509511), + KQU(13962867001134161139), KQU(10272780155442671999), + KQU(12894856086597769142), KQU(13340877795287554994), + KQU(12913630602094607396), KQU(12543167911119793857), + KQU(17343570372251873096), KQU(10959487764494150545), + KQU( 6966737953093821128), KQU(13780699135496988601), + KQU( 4405070719380142046), KQU(14923788365607284982), + KQU( 2869487678905148380), KQU( 6416272754197188403), + KQU(15017380475943612591), KQU( 1995636220918429487), + KQU( 3402016804620122716), KQU(15800188663407057080), + KQU(11362369990390932882), KQU(15262183501637986147), + KQU(10239175385387371494), KQU( 9352042420365748334), + KQU( 1682457034285119875), KQU( 1724710651376289644), + KQU( 2038157098893817966), KQU( 9897825558324608773), + KQU( 1477666236519164736), KQU(16835397314511233640), + KQU(10370866327005346508), KQU(10157504370660621982), + KQU(12113904045335882069), KQU(13326444439742783008), + KQU(11302769043000765804), KQU(13594979923955228484), + KQU(11779351762613475968), KQU( 3786101619539298383), + KQU( 8021122969180846063), KQU(15745904401162500495), + KQU(10762168465993897267), KQU(13552058957896319026), + KQU(11200228655252462013), KQU( 5035370357337441226), + KQU( 7593918984545500013), KQU( 5418554918361528700), + KQU( 4858270799405446371), KQU( 9974659566876282544), + KQU(18227595922273957859), KQU( 2772778443635656220), + KQU(14285143053182085385), KQU( 9939700992429600469), + KQU(12756185904545598068), KQU( 2020783375367345262), + KQU( 57026775058331227), KQU( 950827867930065454), + KQU( 6602279670145371217), KQU( 2291171535443566929), + KQU( 5832380724425010313), KQU( 1220343904715982285), + KQU(17045542598598037633), KQU(15460481779702820971), + KQU(13948388779949365130), KQU(13975040175430829518), + KQU(17477538238425541763), KQU(11104663041851745725), + KQU(15860992957141157587), KQU(14529434633012950138), + KQU( 2504838019075394203), KQU( 7512113882611121886), + KQU( 4859973559980886617), KQU( 1258601555703250219), + KQU(15594548157514316394), KQU( 4516730171963773048), + KQU(11380103193905031983), KQU( 6809282239982353344), + KQU(18045256930420065002), KQU( 2453702683108791859), + KQU( 977214582986981460), KQU( 2006410402232713466), + KQU( 6192236267216378358), KQU( 3429468402195675253), + KQU(18146933153017348921), KQU(17369978576367231139), + KQU( 1246940717230386603), KQU(11335758870083327110), + KQU(14166488801730353682), KQU( 9008573127269635732), + KQU(10776025389820643815), KQU(15087605441903942962), + KQU( 1359542462712147922), KQU(13898874411226454206), + KQU(17911176066536804411), KQU( 9435590428600085274), + KQU( 294488509967864007), KQU( 8890111397567922046), + KQU( 7987823476034328778), KQU(13263827582440967651), + KQU( 7503774813106751573), KQU(14974747296185646837), + KQU( 8504765037032103375), KQU(17340303357444536213), + KQU( 7704610912964485743), KQU( 8107533670327205061), + KQU( 9062969835083315985), KQU(16968963142126734184), + KQU(12958041214190810180), KQU( 2720170147759570200), + KQU( 2986358963942189566), KQU(14884226322219356580), + KQU( 286224325144368520), KQU(11313800433154279797), + KQU(18366849528439673248), KQU(17899725929482368789), + KQU( 3730004284609106799), KQU( 1654474302052767205), + KQU( 5006698007047077032), KQU( 8196893913601182838), + KQU(15214541774425211640), KQU(17391346045606626073), + KQU( 8369003584076969089), KQU( 3939046733368550293), + KQU(10178639720308707785), KQU( 2180248669304388697), + KQU( 62894391300126322), KQU( 9205708961736223191), + KQU( 6837431058165360438), KQU( 3150743890848308214), + KQU(17849330658111464583), KQU(12214815643135450865), + KQU(13410713840519603402), KQU( 3200778126692046802), + KQU(13354780043041779313), KQU( 800850022756886036), + KQU(15660052933953067433), KQU( 6572823544154375676), + KQU(11030281857015819266), KQU(12682241941471433835), + KQU(11654136407300274693), KQU( 4517795492388641109), + KQU( 9757017371504524244), KQU(17833043400781889277), + KQU(12685085201747792227), KQU(10408057728835019573), + KQU( 98370418513455221), KQU( 6732663555696848598), + KQU(13248530959948529780), KQU( 3530441401230622826), + KQU(18188251992895660615), KQU( 1847918354186383756), + KQU( 1127392190402660921), KQU(11293734643143819463), + KQU( 3015506344578682982), KQU(13852645444071153329), + KQU( 2121359659091349142), KQU( 1294604376116677694), + KQU( 5616576231286352318), KQU( 7112502442954235625), + KQU(11676228199551561689), KQU(12925182803007305359), + KQU( 7852375518160493082), KQU( 1136513130539296154), + KQU( 5636923900916593195), KQU( 3221077517612607747), + KQU(17784790465798152513), KQU( 3554210049056995938), + KQU(17476839685878225874), KQU( 3206836372585575732), + KQU( 2765333945644823430), KQU(10080070903718799528), + KQU( 5412370818878286353), KQU( 9689685887726257728), + KQU( 8236117509123533998), KQU( 1951139137165040214), + KQU( 4492205209227980349), KQU(16541291230861602967), + KQU( 1424371548301437940), KQU( 9117562079669206794), + KQU(14374681563251691625), KQU(13873164030199921303), + KQU( 6680317946770936731), KQU(15586334026918276214), + KQU(10896213950976109802), KQU( 9506261949596413689), + KQU( 9903949574308040616), KQU( 6038397344557204470), + KQU( 174601465422373648), KQU(15946141191338238030), + KQU(17142225620992044937), KQU( 7552030283784477064), + KQU( 2947372384532947997), KQU( 510797021688197711), + KQU( 4962499439249363461), KQU( 23770320158385357), + KQU( 959774499105138124), KQU( 1468396011518788276), + KQU( 2015698006852312308), KQU( 4149400718489980136), + KQU( 5992916099522371188), KQU(10819182935265531076), + KQU(16189787999192351131), KQU( 342833961790261950), + KQU(12470830319550495336), KQU(18128495041912812501), + KQU( 1193600899723524337), KQU( 9056793666590079770), + KQU( 2154021227041669041), KQU( 4963570213951235735), + KQU( 4865075960209211409), KQU( 2097724599039942963), + KQU( 2024080278583179845), KQU(11527054549196576736), + KQU(10650256084182390252), KQU( 4808408648695766755), + KQU( 1642839215013788844), KQU(10607187948250398390), + KQU( 7076868166085913508), KQU( 730522571106887032), + KQU(12500579240208524895), KQU( 4484390097311355324), + KQU(15145801330700623870), KQU( 8055827661392944028), + KQU( 5865092976832712268), KQU(15159212508053625143), + KQU( 3560964582876483341), KQU( 4070052741344438280), + KQU( 6032585709886855634), KQU(15643262320904604873), + KQU( 2565119772293371111), KQU( 318314293065348260), + KQU(15047458749141511872), KQU( 7772788389811528730), + KQU( 7081187494343801976), KQU( 6465136009467253947), + KQU(10425940692543362069), KQU( 554608190318339115), + KQU(14796699860302125214), KQU( 1638153134431111443), + KQU(10336967447052276248), KQU( 8412308070396592958), + KQU( 4004557277152051226), KQU( 8143598997278774834), + KQU(16413323996508783221), KQU(13139418758033994949), + KQU( 9772709138335006667), KQU( 2818167159287157659), + KQU(17091740573832523669), KQU(14629199013130751608), + KQU(18268322711500338185), KQU( 8290963415675493063), + KQU( 8830864907452542588), KQU( 1614839084637494849), + KQU(14855358500870422231), KQU( 3472996748392519937), + KQU(15317151166268877716), KQU( 5825895018698400362), + KQU(16730208429367544129), KQU(10481156578141202800), + KQU( 4746166512382823750), KQU(12720876014472464998), + KQU( 8825177124486735972), KQU(13733447296837467838), + KQU( 6412293741681359625), KQU( 8313213138756135033), + KQU(11421481194803712517), KQU( 7997007691544174032), + KQU( 6812963847917605930), KQU( 9683091901227558641), + KQU(14703594165860324713), KQU( 1775476144519618309), + KQU( 2724283288516469519), KQU( 717642555185856868), + KQU( 8736402192215092346), KQU(11878800336431381021), + KQU( 4348816066017061293), KQU( 6115112756583631307), + KQU( 9176597239667142976), KQU(12615622714894259204), + KQU(10283406711301385987), KQU( 5111762509485379420), + KQU( 3118290051198688449), KQU( 7345123071632232145), + KQU( 9176423451688682359), KQU( 4843865456157868971), + KQU(12008036363752566088), KQU(12058837181919397720), + KQU( 2145073958457347366), KQU( 1526504881672818067), + KQU( 3488830105567134848), KQU(13208362960674805143), + KQU( 4077549672899572192), KQU( 7770995684693818365), + KQU( 1398532341546313593), KQU(12711859908703927840), + KQU( 1417561172594446813), KQU(17045191024194170604), + KQU( 4101933177604931713), KQU(14708428834203480320), + KQU(17447509264469407724), KQU(14314821973983434255), + KQU(17990472271061617265), KQU( 5087756685841673942), + KQU(12797820586893859939), KQU( 1778128952671092879), + KQU( 3535918530508665898), KQU( 9035729701042481301), + KQU(14808661568277079962), KQU(14587345077537747914), + KQU(11920080002323122708), KQU( 6426515805197278753), + KQU( 3295612216725984831), KQU(11040722532100876120), + KQU(12305952936387598754), KQU(16097391899742004253), + KQU( 4908537335606182208), KQU(12446674552196795504), + KQU(16010497855816895177), KQU( 9194378874788615551), + KQU( 3382957529567613384), KQU( 5154647600754974077), + KQU( 9801822865328396141), KQU( 9023662173919288143), + KQU(17623115353825147868), KQU( 8238115767443015816), + KQU(15811444159859002560), KQU( 9085612528904059661), + KQU( 6888601089398614254), KQU( 258252992894160189), + KQU( 6704363880792428622), KQU( 6114966032147235763), + KQU(11075393882690261875), KQU( 8797664238933620407), + KQU( 5901892006476726920), KQU( 5309780159285518958), + KQU(14940808387240817367), KQU(14642032021449656698), + KQU( 9808256672068504139), KQU( 3670135111380607658), + KQU(11211211097845960152), KQU( 1474304506716695808), + KQU(15843166204506876239), KQU( 7661051252471780561), + KQU(10170905502249418476), KQU( 7801416045582028589), + KQU( 2763981484737053050), KQU( 9491377905499253054), + KQU(16201395896336915095), KQU( 9256513756442782198), + KQU( 5411283157972456034), KQU( 5059433122288321676), + KQU( 4327408006721123357), KQU( 9278544078834433377), + KQU( 7601527110882281612), KQU(11848295896975505251), + KQU(12096998801094735560), KQU(14773480339823506413), + KQU(15586227433895802149), KQU(12786541257830242872), + KQU( 6904692985140503067), KQU( 5309011515263103959), + KQU(12105257191179371066), KQU(14654380212442225037), + KQU( 2556774974190695009), KQU( 4461297399927600261), + KQU(14888225660915118646), KQU(14915459341148291824), + KQU( 2738802166252327631), KQU( 6047155789239131512), + KQU(12920545353217010338), KQU(10697617257007840205), + KQU( 2751585253158203504), KQU(13252729159780047496), + KQU(14700326134672815469), KQU(14082527904374600529), + KQU(16852962273496542070), KQU(17446675504235853907), + KQU(15019600398527572311), KQU(12312781346344081551), + KQU(14524667935039810450), KQU( 5634005663377195738), + KQU(11375574739525000569), KQU( 2423665396433260040), + KQU( 5222836914796015410), KQU( 4397666386492647387), + KQU( 4619294441691707638), KQU( 665088602354770716), + KQU(13246495665281593610), KQU( 6564144270549729409), + KQU(10223216188145661688), KQU( 3961556907299230585), + KQU(11543262515492439914), KQU(16118031437285993790), + KQU( 7143417964520166465), KQU(13295053515909486772), + KQU( 40434666004899675), KQU(17127804194038347164), + KQU( 8599165966560586269), KQU( 8214016749011284903), + KQU(13725130352140465239), KQU( 5467254474431726291), + KQU( 7748584297438219877), KQU(16933551114829772472), + KQU( 2169618439506799400), KQU( 2169787627665113463), + KQU(17314493571267943764), KQU(18053575102911354912), + KQU(11928303275378476973), KQU(11593850925061715550), + KQU(17782269923473589362), KQU( 3280235307704747039), + KQU( 6145343578598685149), KQU(17080117031114086090), + KQU(18066839902983594755), KQU( 6517508430331020706), + KQU( 8092908893950411541), KQU(12558378233386153732), + KQU( 4476532167973132976), KQU(16081642430367025016), + KQU( 4233154094369139361), KQU( 8693630486693161027), + KQU(11244959343027742285), KQU(12273503967768513508), + KQU(14108978636385284876), KQU( 7242414665378826984), + KQU( 6561316938846562432), KQU( 8601038474994665795), + KQU(17532942353612365904), KQU(17940076637020912186), + KQU( 7340260368823171304), KQU( 7061807613916067905), + KQU(10561734935039519326), KQU(17990796503724650862), + KQU( 6208732943911827159), KQU( 359077562804090617), + KQU(14177751537784403113), KQU(10659599444915362902), + KQU(15081727220615085833), KQU(13417573895659757486), + KQU(15513842342017811524), KQU(11814141516204288231), + KQU( 1827312513875101814), KQU( 2804611699894603103), + KQU(17116500469975602763), KQU(12270191815211952087), + KQU(12256358467786024988), KQU(18435021722453971267), + KQU( 671330264390865618), KQU( 476504300460286050), + KQU(16465470901027093441), KQU( 4047724406247136402), + KQU( 1322305451411883346), KQU( 1388308688834322280), + KQU( 7303989085269758176), KQU( 9323792664765233642), + KQU( 4542762575316368936), KQU(17342696132794337618), + KQU( 4588025054768498379), KQU(13415475057390330804), + KQU(17880279491733405570), KQU(10610553400618620353), + KQU( 3180842072658960139), KQU(13002966655454270120), + KQU( 1665301181064982826), KQU( 7083673946791258979), + KQU( 190522247122496820), KQU(17388280237250677740), + KQU( 8430770379923642945), KQU(12987180971921668584), + KQU( 2311086108365390642), KQU( 2870984383579822345), + KQU(14014682609164653318), KQU(14467187293062251484), + KQU( 192186361147413298), KQU(15171951713531796524), + KQU( 9900305495015948728), KQU(17958004775615466344), + KQU(14346380954498606514), KQU(18040047357617407096), + KQU( 5035237584833424532), KQU(15089555460613972287), + KQU( 4131411873749729831), KQU( 1329013581168250330), + KQU(10095353333051193949), KQU(10749518561022462716), + KQU( 9050611429810755847), KQU(15022028840236655649), + KQU( 8775554279239748298), KQU(13105754025489230502), + KQU(15471300118574167585), KQU( 89864764002355628), + KQU( 8776416323420466637), KQU( 5280258630612040891), + KQU( 2719174488591862912), KQU( 7599309137399661994), + KQU(15012887256778039979), KQU(14062981725630928925), + KQU(12038536286991689603), KQU( 7089756544681775245), + KQU(10376661532744718039), KQU( 1265198725901533130), + KQU(13807996727081142408), KQU( 2935019626765036403), + KQU( 7651672460680700141), KQU( 3644093016200370795), + KQU( 2840982578090080674), KQU(17956262740157449201), + KQU(18267979450492880548), KQU(11799503659796848070), + KQU( 9942537025669672388), KQU(11886606816406990297), + KQU( 5488594946437447576), KQU( 7226714353282744302), + KQU( 3784851653123877043), KQU( 878018453244803041), + KQU(12110022586268616085), KQU( 734072179404675123), + KQU(11869573627998248542), KQU( 469150421297783998), + KQU( 260151124912803804), KQU(11639179410120968649), + KQU( 9318165193840846253), KQU(12795671722734758075), + KQU(15318410297267253933), KQU( 691524703570062620), + KQU( 5837129010576994601), KQU(15045963859726941052), + KQU( 5850056944932238169), KQU(12017434144750943807), + KQU( 7447139064928956574), KQU( 3101711812658245019), + KQU(16052940704474982954), KQU(18195745945986994042), + KQU( 8932252132785575659), KQU(13390817488106794834), + KQU(11582771836502517453), KQU( 4964411326683611686), + KQU( 2195093981702694011), KQU(14145229538389675669), + KQU(16459605532062271798), KQU( 866316924816482864), + KQU( 4593041209937286377), KQU( 8415491391910972138), + KQU( 4171236715600528969), KQU(16637569303336782889), + KQU( 2002011073439212680), KQU(17695124661097601411), + KQU( 4627687053598611702), KQU( 7895831936020190403), + KQU( 8455951300917267802), KQU( 2923861649108534854), + KQU( 8344557563927786255), KQU( 6408671940373352556), + KQU(12210227354536675772), KQU(14294804157294222295), + KQU(10103022425071085127), KQU(10092959489504123771), + KQU( 6554774405376736268), KQU(12629917718410641774), + KQU( 6260933257596067126), KQU( 2460827021439369673), + KQU( 2541962996717103668), KQU( 597377203127351475), + KQU( 5316984203117315309), KQU( 4811211393563241961), + KQU(13119698597255811641), KQU( 8048691512862388981), + KQU(10216818971194073842), KQU( 4612229970165291764), + KQU(10000980798419974770), KQU( 6877640812402540687), + KQU( 1488727563290436992), KQU( 2227774069895697318), + KQU(11237754507523316593), KQU(13478948605382290972), + KQU( 1963583846976858124), KQU( 5512309205269276457), + KQU( 3972770164717652347), KQU( 3841751276198975037), + KQU(10283343042181903117), KQU( 8564001259792872199), + KQU(16472187244722489221), KQU( 8953493499268945921), + KQU( 3518747340357279580), KQU( 4003157546223963073), + KQU( 3270305958289814590), KQU( 3966704458129482496), + KQU( 8122141865926661939), KQU(14627734748099506653), + KQU(13064426990862560568), KQU( 2414079187889870829), + KQU( 5378461209354225306), KQU(10841985740128255566), + KQU( 538582442885401738), KQU( 7535089183482905946), + KQU(16117559957598879095), KQU( 8477890721414539741), + KQU( 1459127491209533386), KQU(17035126360733620462), + KQU( 8517668552872379126), KQU(10292151468337355014), + KQU(17081267732745344157), KQU(13751455337946087178), + KQU(14026945459523832966), KQU( 6653278775061723516), + KQU(10619085543856390441), KQU( 2196343631481122885), + KQU(10045966074702826136), KQU(10082317330452718282), + KQU( 5920859259504831242), KQU( 9951879073426540617), + KQU( 7074696649151414158), KQU(15808193543879464318), + KQU( 7385247772746953374), KQU( 3192003544283864292), + KQU(18153684490917593847), KQU(12423498260668568905), + KQU(10957758099756378169), KQU(11488762179911016040), + KQU( 2099931186465333782), KQU(11180979581250294432), + KQU( 8098916250668367933), KQU( 3529200436790763465), + KQU(12988418908674681745), KQU( 6147567275954808580), + KQU( 3207503344604030989), KQU(10761592604898615360), + KQU( 229854861031893504), KQU( 8809853962667144291), + KQU(13957364469005693860), KQU( 7634287665224495886), + KQU(12353487366976556874), KQU( 1134423796317152034), + KQU( 2088992471334107068), KQU( 7393372127190799698), + KQU( 1845367839871058391), KQU( 207922563987322884), + KQU(11960870813159944976), KQU(12182120053317317363), + KQU(17307358132571709283), KQU(13871081155552824936), + KQU(18304446751741566262), KQU( 7178705220184302849), + KQU(10929605677758824425), KQU(16446976977835806844), + KQU(13723874412159769044), KQU( 6942854352100915216), + KQU( 1726308474365729390), KQU( 2150078766445323155), + KQU(15345558947919656626), KQU(12145453828874527201), + KQU( 2054448620739726849), KQU( 2740102003352628137), + KQU(11294462163577610655), KQU( 756164283387413743), + KQU(17841144758438810880), KQU(10802406021185415861), + KQU( 8716455530476737846), KQU( 6321788834517649606), + KQU(14681322910577468426), KQU(17330043563884336387), + KQU(12701802180050071614), KQU(14695105111079727151), + KQU( 5112098511654172830), KQU( 4957505496794139973), + KQU( 8270979451952045982), KQU(12307685939199120969), + KQU(12425799408953443032), KQU( 8376410143634796588), + KQU(16621778679680060464), KQU( 3580497854566660073), + KQU( 1122515747803382416), KQU( 857664980960597599), + KQU( 6343640119895925918), KQU(12878473260854462891), + KQU(10036813920765722626), KQU(14451335468363173812), + KQU( 5476809692401102807), KQU(16442255173514366342), + KQU(13060203194757167104), KQU(14354124071243177715), + KQU(15961249405696125227), KQU(13703893649690872584), + KQU( 363907326340340064), KQU( 6247455540491754842), + KQU(12242249332757832361), KQU( 156065475679796717), + KQU( 9351116235749732355), KQU( 4590350628677701405), + KQU( 1671195940982350389), KQU(13501398458898451905), + KQU( 6526341991225002255), KQU( 1689782913778157592), + KQU( 7439222350869010334), KQU(13975150263226478308), + KQU(11411961169932682710), KQU(17204271834833847277), + KQU( 541534742544435367), KQU( 6591191931218949684), + KQU( 2645454775478232486), KQU( 4322857481256485321), + KQU( 8477416487553065110), KQU(12902505428548435048), + KQU( 971445777981341415), KQU(14995104682744976712), + KQU( 4243341648807158063), KQU( 8695061252721927661), + KQU( 5028202003270177222), KQU( 2289257340915567840), + KQU(13870416345121866007), KQU(13994481698072092233), + KQU( 6912785400753196481), KQU( 2278309315841980139), + KQU( 4329765449648304839), KQU( 5963108095785485298), + KQU( 4880024847478722478), KQU(16015608779890240947), + KQU( 1866679034261393544), KQU( 914821179919731519), + KQU( 9643404035648760131), KQU( 2418114953615593915), + KQU( 944756836073702374), KQU(15186388048737296834), + KQU( 7723355336128442206), KQU( 7500747479679599691), + KQU(18013961306453293634), KQU( 2315274808095756456), + KQU(13655308255424029566), KQU(17203800273561677098), + KQU( 1382158694422087756), KQU( 5090390250309588976), + KQU( 517170818384213989), KQU( 1612709252627729621), + KQU( 1330118955572449606), KQU( 300922478056709885), + KQU(18115693291289091987), KQU(13491407109725238321), + KQU(15293714633593827320), KQU( 5151539373053314504), + KQU( 5951523243743139207), KQU(14459112015249527975), + KQU( 5456113959000700739), KQU( 3877918438464873016), + KQU(12534071654260163555), KQU(15871678376893555041), + KQU(11005484805712025549), KQU(16353066973143374252), + KQU( 4358331472063256685), KQU( 8268349332210859288), + KQU(12485161590939658075), KQU(13955993592854471343), + KQU( 5911446886848367039), KQU(14925834086813706974), + KQU( 6590362597857994805), KQU( 1280544923533661875), + KQU( 1637756018947988164), KQU( 4734090064512686329), + KQU(16693705263131485912), KQU( 6834882340494360958), + KQU( 8120732176159658505), KQU( 2244371958905329346), + KQU(10447499707729734021), KQU( 7318742361446942194), + KQU( 8032857516355555296), KQU(14023605983059313116), + KQU( 1032336061815461376), KQU( 9840995337876562612), + KQU( 9869256223029203587), KQU(12227975697177267636), + KQU(12728115115844186033), KQU( 7752058479783205470), + KQU( 729733219713393087), KQU(12954017801239007622) +}; +static const uint64_t init_by_array_64_expected[] = { + KQU( 2100341266307895239), KQU( 8344256300489757943), + KQU(15687933285484243894), KQU( 8268620370277076319), + KQU(12371852309826545459), KQU( 8800491541730110238), + KQU(18113268950100835773), KQU( 2886823658884438119), + KQU( 3293667307248180724), KQU( 9307928143300172731), + KQU( 7688082017574293629), KQU( 900986224735166665), + KQU( 9977972710722265039), KQU( 6008205004994830552), + KQU( 546909104521689292), KQU( 7428471521869107594), + KQU(14777563419314721179), KQU(16116143076567350053), + KQU( 5322685342003142329), KQU( 4200427048445863473), + KQU( 4693092150132559146), KQU(13671425863759338582), + KQU( 6747117460737639916), KQU( 4732666080236551150), + KQU( 5912839950611941263), KQU( 3903717554504704909), + KQU( 2615667650256786818), KQU(10844129913887006352), + KQU(13786467861810997820), KQU(14267853002994021570), + KQU(13767807302847237439), KQU(16407963253707224617), + KQU( 4802498363698583497), KQU( 2523802839317209764), + KQU( 3822579397797475589), KQU( 8950320572212130610), + KQU( 3745623504978342534), KQU(16092609066068482806), + KQU( 9817016950274642398), KQU(10591660660323829098), + KQU(11751606650792815920), KQU( 5122873818577122211), + KQU(17209553764913936624), KQU( 6249057709284380343), + KQU(15088791264695071830), KQU(15344673071709851930), + KQU( 4345751415293646084), KQU( 2542865750703067928), + KQU(13520525127852368784), KQU(18294188662880997241), + KQU( 3871781938044881523), KQU( 2873487268122812184), + KQU(15099676759482679005), KQU(15442599127239350490), + KQU( 6311893274367710888), KQU( 3286118760484672933), + KQU( 4146067961333542189), KQU(13303942567897208770), + KQU( 8196013722255630418), KQU( 4437815439340979989), + KQU(15433791533450605135), KQU( 4254828956815687049), + KQU( 1310903207708286015), KQU(10529182764462398549), + KQU(14900231311660638810), KQU( 9727017277104609793), + KQU( 1821308310948199033), KQU(11628861435066772084), + KQU( 9469019138491546924), KQU( 3145812670532604988), + KQU( 9938468915045491919), KQU( 1562447430672662142), + KQU(13963995266697989134), KQU( 3356884357625028695), + KQU( 4499850304584309747), KQU( 8456825817023658122), + KQU(10859039922814285279), KQU( 8099512337972526555), + KQU( 348006375109672149), KQU(11919893998241688603), + KQU( 1104199577402948826), KQU(16689191854356060289), + KQU(10992552041730168078), KQU( 7243733172705465836), + KQU( 5668075606180319560), KQU(18182847037333286970), + KQU( 4290215357664631322), KQU( 4061414220791828613), + KQU(13006291061652989604), KQU( 7140491178917128798), + KQU(12703446217663283481), KQU( 5500220597564558267), + KQU(10330551509971296358), KQU(15958554768648714492), + KQU( 5174555954515360045), KQU( 1731318837687577735), + KQU( 3557700801048354857), KQU(13764012341928616198), + KQU(13115166194379119043), KQU( 7989321021560255519), + KQU( 2103584280905877040), KQU( 9230788662155228488), + KQU(16396629323325547654), KQU( 657926409811318051), + KQU(15046700264391400727), KQU( 5120132858771880830), + KQU( 7934160097989028561), KQU( 6963121488531976245), + KQU(17412329602621742089), KQU(15144843053931774092), + KQU(17204176651763054532), KQU(13166595387554065870), + KQU( 8590377810513960213), KQU( 5834365135373991938), + KQU( 7640913007182226243), KQU( 3479394703859418425), + KQU(16402784452644521040), KQU( 4993979809687083980), + KQU(13254522168097688865), KQU(15643659095244365219), + KQU( 5881437660538424982), KQU(11174892200618987379), + KQU( 254409966159711077), KQU(17158413043140549909), + KQU( 3638048789290376272), KQU( 1376816930299489190), + KQU( 4622462095217761923), KQU(15086407973010263515), + KQU(13253971772784692238), KQU( 5270549043541649236), + KQU(11182714186805411604), KQU(12283846437495577140), + KQU( 5297647149908953219), KQU(10047451738316836654), + KQU( 4938228100367874746), KQU(12328523025304077923), + KQU( 3601049438595312361), KQU( 9313624118352733770), + KQU(13322966086117661798), KQU(16660005705644029394), + KQU(11337677526988872373), KQU(13869299102574417795), + KQU(15642043183045645437), KQU( 3021755569085880019), + KQU( 4979741767761188161), KQU(13679979092079279587), + KQU( 3344685842861071743), KQU(13947960059899588104), + KQU( 305806934293368007), KQU( 5749173929201650029), + KQU(11123724852118844098), KQU(15128987688788879802), + KQU(15251651211024665009), KQU( 7689925933816577776), + KQU(16732804392695859449), KQU(17087345401014078468), + KQU(14315108589159048871), KQU( 4820700266619778917), + KQU(16709637539357958441), KQU( 4936227875177351374), + KQU( 2137907697912987247), KQU(11628565601408395420), + KQU( 2333250549241556786), KQU( 5711200379577778637), + KQU( 5170680131529031729), KQU(12620392043061335164), + KQU( 95363390101096078), KQU( 5487981914081709462), + KQU( 1763109823981838620), KQU( 3395861271473224396), + KQU( 1300496844282213595), KQU( 6894316212820232902), + KQU(10673859651135576674), KQU( 5911839658857903252), + KQU(17407110743387299102), KQU( 8257427154623140385), + KQU(11389003026741800267), KQU( 4070043211095013717), + KQU(11663806997145259025), KQU(15265598950648798210), + KQU( 630585789434030934), KQU( 3524446529213587334), + KQU( 7186424168495184211), KQU(10806585451386379021), + KQU(11120017753500499273), KQU( 1586837651387701301), + KQU(17530454400954415544), KQU( 9991670045077880430), + KQU( 7550997268990730180), KQU( 8640249196597379304), + KQU( 3522203892786893823), KQU(10401116549878854788), + KQU(13690285544733124852), KQU( 8295785675455774586), + KQU(15535716172155117603), KQU( 3112108583723722511), + KQU(17633179955339271113), KQU(18154208056063759375), + KQU( 1866409236285815666), KQU(13326075895396412882), + KQU( 8756261842948020025), KQU( 6281852999868439131), + KQU(15087653361275292858), KQU(10333923911152949397), + KQU( 5265567645757408500), KQU(12728041843210352184), + KQU( 6347959327507828759), KQU( 154112802625564758), + KQU(18235228308679780218), KQU( 3253805274673352418), + KQU( 4849171610689031197), KQU(17948529398340432518), + KQU(13803510475637409167), KQU(13506570190409883095), + KQU(15870801273282960805), KQU( 8451286481299170773), + KQU( 9562190620034457541), KQU( 8518905387449138364), + KQU(12681306401363385655), KQU( 3788073690559762558), + KQU( 5256820289573487769), KQU( 2752021372314875467), + KQU( 6354035166862520716), KQU( 4328956378309739069), + KQU( 449087441228269600), KQU( 5533508742653090868), + KQU( 1260389420404746988), KQU(18175394473289055097), + KQU( 1535467109660399420), KQU( 8818894282874061442), + KQU(12140873243824811213), KQU(15031386653823014946), + KQU( 1286028221456149232), KQU( 6329608889367858784), + KQU( 9419654354945132725), KQU( 6094576547061672379), + KQU(17706217251847450255), KQU( 1733495073065878126), + KQU(16918923754607552663), KQU( 8881949849954945044), + KQU(12938977706896313891), KQU(14043628638299793407), + KQU(18393874581723718233), KQU( 6886318534846892044), + KQU(14577870878038334081), KQU(13541558383439414119), + KQU(13570472158807588273), KQU(18300760537910283361), + KQU( 818368572800609205), KQU( 1417000585112573219), + KQU(12337533143867683655), KQU(12433180994702314480), + KQU( 778190005829189083), KQU(13667356216206524711), + KQU( 9866149895295225230), KQU(11043240490417111999), + KQU( 1123933826541378598), KQU( 6469631933605123610), + KQU(14508554074431980040), KQU(13918931242962026714), + KQU( 2870785929342348285), KQU(14786362626740736974), + KQU(13176680060902695786), KQU( 9591778613541679456), + KQU( 9097662885117436706), KQU( 749262234240924947), + KQU( 1944844067793307093), KQU( 4339214904577487742), + KQU( 8009584152961946551), KQU(16073159501225501777), + KQU( 3335870590499306217), KQU(17088312653151202847), + KQU( 3108893142681931848), KQU(16636841767202792021), + KQU(10423316431118400637), KQU( 8008357368674443506), + KQU(11340015231914677875), KQU(17687896501594936090), + KQU(15173627921763199958), KQU( 542569482243721959), + KQU(15071714982769812975), KQU( 4466624872151386956), + KQU( 1901780715602332461), KQU( 9822227742154351098), + KQU( 1479332892928648780), KQU( 6981611948382474400), + KQU( 7620824924456077376), KQU(14095973329429406782), + KQU( 7902744005696185404), KQU(15830577219375036920), + KQU(10287076667317764416), KQU(12334872764071724025), + KQU( 4419302088133544331), KQU(14455842851266090520), + KQU(12488077416504654222), KQU( 7953892017701886766), + KQU( 6331484925529519007), KQU( 4902145853785030022), + KQU(17010159216096443073), KQU(11945354668653886087), + KQU(15112022728645230829), KQU(17363484484522986742), + KQU( 4423497825896692887), KQU( 8155489510809067471), + KQU( 258966605622576285), KQU( 5462958075742020534), + KQU( 6763710214913276228), KQU( 2368935183451109054), + KQU(14209506165246453811), KQU( 2646257040978514881), + KQU( 3776001911922207672), KQU( 1419304601390147631), + KQU(14987366598022458284), KQU( 3977770701065815721), + KQU( 730820417451838898), KQU( 3982991703612885327), + KQU( 2803544519671388477), KQU(17067667221114424649), + KQU( 2922555119737867166), KQU( 1989477584121460932), + KQU(15020387605892337354), KQU( 9293277796427533547), + KQU(10722181424063557247), KQU(16704542332047511651), + KQU( 5008286236142089514), KQU(16174732308747382540), + KQU(17597019485798338402), KQU(13081745199110622093), + KQU( 8850305883842258115), KQU(12723629125624589005), + KQU( 8140566453402805978), KQU(15356684607680935061), + KQU(14222190387342648650), KQU(11134610460665975178), + KQU( 1259799058620984266), KQU(13281656268025610041), + KQU( 298262561068153992), KQU(12277871700239212922), + KQU(13911297774719779438), KQU(16556727962761474934), + KQU(17903010316654728010), KQU( 9682617699648434744), + KQU(14757681836838592850), KQU( 1327242446558524473), + KQU(11126645098780572792), KQU( 1883602329313221774), + KQU( 2543897783922776873), KQU(15029168513767772842), + KQU(12710270651039129878), KQU(16118202956069604504), + KQU(15010759372168680524), KQU( 2296827082251923948), + KQU(10793729742623518101), KQU(13829764151845413046), + KQU(17769301223184451213), KQU( 3118268169210783372), + KQU(17626204544105123127), KQU( 7416718488974352644), + KQU(10450751996212925994), KQU( 9352529519128770586), + KQU( 259347569641110140), KQU( 8048588892269692697), + KQU( 1774414152306494058), KQU(10669548347214355622), + KQU(13061992253816795081), KQU(18432677803063861659), + KQU( 8879191055593984333), KQU(12433753195199268041), + KQU(14919392415439730602), KQU( 6612848378595332963), + KQU( 6320986812036143628), KQU(10465592420226092859), + KQU( 4196009278962570808), KQU( 3747816564473572224), + KQU(17941203486133732898), KQU( 2350310037040505198), + KQU( 5811779859134370113), KQU(10492109599506195126), + KQU( 7699650690179541274), KQU( 1954338494306022961), + KQU(14095816969027231152), KQU( 5841346919964852061), + KQU(14945969510148214735), KQU( 3680200305887550992), + KQU( 6218047466131695792), KQU( 8242165745175775096), + KQU(11021371934053307357), KQU( 1265099502753169797), + KQU( 4644347436111321718), KQU( 3609296916782832859), + KQU( 8109807992218521571), KQU(18387884215648662020), + KQU(14656324896296392902), KQU(17386819091238216751), + KQU(17788300878582317152), KQU( 7919446259742399591), + KQU( 4466613134576358004), KQU(12928181023667938509), + KQU(13147446154454932030), KQU(16552129038252734620), + KQU( 8395299403738822450), KQU(11313817655275361164), + KQU( 434258809499511718), KQU( 2074882104954788676), + KQU( 7929892178759395518), KQU( 9006461629105745388), + KQU( 5176475650000323086), KQU(11128357033468341069), + KQU(12026158851559118955), KQU(14699716249471156500), + KQU( 448982497120206757), KQU( 4156475356685519900), + KQU( 6063816103417215727), KQU(10073289387954971479), + KQU( 8174466846138590962), KQU( 2675777452363449006), + KQU( 9090685420572474281), KQU( 6659652652765562060), + KQU(12923120304018106621), KQU(11117480560334526775), + KQU( 937910473424587511), KQU( 1838692113502346645), + KQU(11133914074648726180), KQU( 7922600945143884053), + KQU(13435287702700959550), KQU( 5287964921251123332), + KQU(11354875374575318947), KQU(17955724760748238133), + KQU(13728617396297106512), KQU( 4107449660118101255), + KQU( 1210269794886589623), KQU(11408687205733456282), + KQU( 4538354710392677887), KQU(13566803319341319267), + KQU(17870798107734050771), KQU( 3354318982568089135), + KQU( 9034450839405133651), KQU(13087431795753424314), + KQU( 950333102820688239), KQU( 1968360654535604116), + KQU(16840551645563314995), KQU( 8867501803892924995), + KQU(11395388644490626845), KQU( 1529815836300732204), + KQU(13330848522996608842), KQU( 1813432878817504265), + KQU( 2336867432693429560), KQU(15192805445973385902), + KQU( 2528593071076407877), KQU( 128459777936689248), + KQU( 9976345382867214866), KQU( 6208885766767996043), + KQU(14982349522273141706), KQU( 3099654362410737822), + KQU(13776700761947297661), KQU( 8806185470684925550), + KQU( 8151717890410585321), KQU( 640860591588072925), + KQU(14592096303937307465), KQU( 9056472419613564846), + KQU(14861544647742266352), KQU(12703771500398470216), + KQU( 3142372800384138465), KQU( 6201105606917248196), + KQU(18337516409359270184), KQU(15042268695665115339), + KQU(15188246541383283846), KQU(12800028693090114519), + KQU( 5992859621101493472), KQU(18278043971816803521), + KQU( 9002773075219424560), KQU( 7325707116943598353), + KQU( 7930571931248040822), KQU( 5645275869617023448), + KQU( 7266107455295958487), KQU( 4363664528273524411), + KQU(14313875763787479809), KQU(17059695613553486802), + KQU( 9247761425889940932), KQU(13704726459237593128), + KQU( 2701312427328909832), KQU(17235532008287243115), + KQU(14093147761491729538), KQU( 6247352273768386516), + KQU( 8268710048153268415), KQU( 7985295214477182083), + KQU(15624495190888896807), KQU( 3772753430045262788), + KQU( 9133991620474991698), KQU( 5665791943316256028), + KQU( 7551996832462193473), KQU(13163729206798953877), + KQU( 9263532074153846374), KQU( 1015460703698618353), + KQU(17929874696989519390), KQU(18257884721466153847), + KQU(16271867543011222991), KQU( 3905971519021791941), + KQU(16814488397137052085), KQU( 1321197685504621613), + KQU( 2870359191894002181), KQU(14317282970323395450), + KQU(13663920845511074366), KQU( 2052463995796539594), + KQU(14126345686431444337), KQU( 1727572121947022534), + KQU(17793552254485594241), KQU( 6738857418849205750), + KQU( 1282987123157442952), KQU(16655480021581159251), + KQU( 6784587032080183866), KQU(14726758805359965162), + KQU( 7577995933961987349), KQU(12539609320311114036), + KQU(10789773033385439494), KQU( 8517001497411158227), + KQU(10075543932136339710), KQU(14838152340938811081), + KQU( 9560840631794044194), KQU(17445736541454117475), + KQU(10633026464336393186), KQU(15705729708242246293), + KQU( 1117517596891411098), KQU( 4305657943415886942), + KQU( 4948856840533979263), KQU(16071681989041789593), + KQU(13723031429272486527), KQU( 7639567622306509462), + KQU(12670424537483090390), KQU( 9715223453097197134), + KQU( 5457173389992686394), KQU( 289857129276135145), + KQU(17048610270521972512), KQU( 692768013309835485), + KQU(14823232360546632057), KQU(18218002361317895936), + KQU( 3281724260212650204), KQU(16453957266549513795), + KQU( 8592711109774511881), KQU( 929825123473369579), + KQU(15966784769764367791), KQU( 9627344291450607588), + KQU(10849555504977813287), KQU( 9234566913936339275), + KQU( 6413807690366911210), KQU(10862389016184219267), + KQU(13842504799335374048), KQU( 1531994113376881174), + KQU( 2081314867544364459), KQU(16430628791616959932), + KQU( 8314714038654394368), KQU( 9155473892098431813), + KQU(12577843786670475704), KQU( 4399161106452401017), + KQU( 1668083091682623186), KQU( 1741383777203714216), + KQU( 2162597285417794374), KQU(15841980159165218736), + KQU( 1971354603551467079), KQU( 1206714764913205968), + KQU( 4790860439591272330), KQU(14699375615594055799), + KQU( 8374423871657449988), KQU(10950685736472937738), + KQU( 697344331343267176), KQU(10084998763118059810), + KQU(12897369539795983124), KQU(12351260292144383605), + KQU( 1268810970176811234), KQU( 7406287800414582768), + KQU( 516169557043807831), KQU( 5077568278710520380), + KQU( 3828791738309039304), KQU( 7721974069946943610), + KQU( 3534670260981096460), KQU( 4865792189600584891), + KQU(16892578493734337298), KQU( 9161499464278042590), + KQU(11976149624067055931), KQU(13219479887277343990), + KQU(14161556738111500680), KQU(14670715255011223056), + KQU( 4671205678403576558), KQU(12633022931454259781), + KQU(14821376219869187646), KQU( 751181776484317028), + KQU( 2192211308839047070), KQU(11787306362361245189), + KQU(10672375120744095707), KQU( 4601972328345244467), + KQU(15457217788831125879), KQU( 8464345256775460809), + KQU(10191938789487159478), KQU( 6184348739615197613), + KQU(11425436778806882100), KQU( 2739227089124319793), + KQU( 461464518456000551), KQU( 4689850170029177442), + KQU( 6120307814374078625), KQU(11153579230681708671), + KQU( 7891721473905347926), KQU(10281646937824872400), + KQU( 3026099648191332248), KQU( 8666750296953273818), + KQU(14978499698844363232), KQU(13303395102890132065), + KQU( 8182358205292864080), KQU(10560547713972971291), + KQU(11981635489418959093), KQU( 3134621354935288409), + KQU(11580681977404383968), KQU(14205530317404088650), + KQU( 5997789011854923157), KQU(13659151593432238041), + KQU(11664332114338865086), KQU( 7490351383220929386), + KQU( 7189290499881530378), KQU(15039262734271020220), + KQU( 2057217285976980055), KQU( 555570804905355739), + KQU(11235311968348555110), KQU(13824557146269603217), + KQU(16906788840653099693), KQU( 7222878245455661677), + KQU( 5245139444332423756), KQU( 4723748462805674292), + KQU(12216509815698568612), KQU(17402362976648951187), + KQU(17389614836810366768), KQU( 4880936484146667711), + KQU( 9085007839292639880), KQU(13837353458498535449), + KQU(11914419854360366677), KQU(16595890135313864103), + KQU( 6313969847197627222), KQU(18296909792163910431), + KQU(10041780113382084042), KQU( 2499478551172884794), + KQU(11057894246241189489), KQU( 9742243032389068555), + KQU(12838934582673196228), KQU(13437023235248490367), + KQU(13372420669446163240), KQU( 6752564244716909224), + KQU( 7157333073400313737), KQU(12230281516370654308), + KQU( 1182884552219419117), KQU( 2955125381312499218), + KQU(10308827097079443249), KQU( 1337648572986534958), + KQU(16378788590020343939), KQU( 108619126514420935), + KQU( 3990981009621629188), KQU( 5460953070230946410), + KQU( 9703328329366531883), KQU(13166631489188077236), + KQU( 1104768831213675170), KQU( 3447930458553877908), + KQU( 8067172487769945676), KQU( 5445802098190775347), + KQU( 3244840981648973873), KQU(17314668322981950060), + KQU( 5006812527827763807), KQU(18158695070225526260), + KQU( 2824536478852417853), KQU(13974775809127519886), + KQU( 9814362769074067392), KQU(17276205156374862128), + KQU(11361680725379306967), KQU( 3422581970382012542), + KQU(11003189603753241266), KQU(11194292945277862261), + KQU( 6839623313908521348), KQU(11935326462707324634), + KQU( 1611456788685878444), KQU(13112620989475558907), + KQU( 517659108904450427), KQU(13558114318574407624), + KQU(15699089742731633077), KQU( 4988979278862685458), + KQU( 8111373583056521297), KQU( 3891258746615399627), + KQU( 8137298251469718086), KQU(12748663295624701649), + KQU( 4389835683495292062), KQU( 5775217872128831729), + KQU( 9462091896405534927), KQU( 8498124108820263989), + KQU( 8059131278842839525), KQU(10503167994254090892), + KQU(11613153541070396656), KQU(18069248738504647790), + KQU( 570657419109768508), KQU( 3950574167771159665), + KQU( 5514655599604313077), KQU( 2908460854428484165), + KQU(10777722615935663114), KQU(12007363304839279486), + KQU( 9800646187569484767), KQU( 8795423564889864287), + KQU(14257396680131028419), KQU( 6405465117315096498), + KQU( 7939411072208774878), KQU(17577572378528990006), + KQU(14785873806715994850), KQU(16770572680854747390), + KQU(18127549474419396481), KQU(11637013449455757750), + KQU(14371851933996761086), KQU( 3601181063650110280), + KQU( 4126442845019316144), KQU(10198287239244320669), + KQU(18000169628555379659), KQU(18392482400739978269), + KQU( 6219919037686919957), KQU( 3610085377719446052), + KQU( 2513925039981776336), KQU(16679413537926716955), + KQU(12903302131714909434), KQU( 5581145789762985009), + KQU(12325955044293303233), KQU(17216111180742141204), + KQU( 6321919595276545740), KQU( 3507521147216174501), + KQU( 9659194593319481840), KQU(11473976005975358326), + KQU(14742730101435987026), KQU( 492845897709954780), + KQU(16976371186162599676), KQU(17712703422837648655), + KQU( 9881254778587061697), KQU( 8413223156302299551), + KQU( 1563841828254089168), KQU( 9996032758786671975), + KQU( 138877700583772667), KQU(13003043368574995989), + KQU( 4390573668650456587), KQU( 8610287390568126755), + KQU(15126904974266642199), KQU( 6703637238986057662), + KQU( 2873075592956810157), KQU( 6035080933946049418), + KQU(13382846581202353014), KQU( 7303971031814642463), + KQU(18418024405307444267), KQU( 5847096731675404647), + KQU( 4035880699639842500), KQU(11525348625112218478), + KQU( 3041162365459574102), KQU( 2604734487727986558), + KQU(15526341771636983145), KQU(14556052310697370254), + KQU(12997787077930808155), KQU( 9601806501755554499), + KQU(11349677952521423389), KQU(14956777807644899350), + KQU(16559736957742852721), KQU(12360828274778140726), + KQU( 6685373272009662513), KQU(16932258748055324130), + KQU(15918051131954158508), KQU( 1692312913140790144), + KQU( 546653826801637367), KQU( 5341587076045986652), + KQU(14975057236342585662), KQU(12374976357340622412), + KQU(10328833995181940552), KQU(12831807101710443149), + KQU(10548514914382545716), KQU( 2217806727199715993), + KQU(12627067369242845138), KQU( 4598965364035438158), + KQU( 150923352751318171), KQU(14274109544442257283), + KQU( 4696661475093863031), KQU( 1505764114384654516), + KQU(10699185831891495147), KQU( 2392353847713620519), + KQU( 3652870166711788383), KQU( 8640653276221911108), + KQU( 3894077592275889704), KQU( 4918592872135964845), + KQU(16379121273281400789), KQU(12058465483591683656), + KQU(11250106829302924945), KQU( 1147537556296983005), + KQU( 6376342756004613268), KQU(14967128191709280506), + KQU(18007449949790627628), KQU( 9497178279316537841), + KQU( 7920174844809394893), KQU(10037752595255719907), + KQU(15875342784985217697), KQU(15311615921712850696), + KQU( 9552902652110992950), KQU(14054979450099721140), + KQU( 5998709773566417349), KQU(18027910339276320187), + KQU( 8223099053868585554), KQU( 7842270354824999767), + KQU( 4896315688770080292), KQU(12969320296569787895), + KQU( 2674321489185759961), KQU( 4053615936864718439), + KQU(11349775270588617578), KQU( 4743019256284553975), + KQU( 5602100217469723769), KQU(14398995691411527813), + KQU( 7412170493796825470), KQU( 836262406131744846), + KQU( 8231086633845153022), KQU( 5161377920438552287), + KQU( 8828731196169924949), KQU(16211142246465502680), + KQU( 3307990879253687818), KQU( 5193405406899782022), + KQU( 8510842117467566693), KQU( 6070955181022405365), + KQU(14482950231361409799), KQU(12585159371331138077), + KQU( 3511537678933588148), KQU( 2041849474531116417), + KQU(10944936685095345792), KQU(18303116923079107729), + KQU( 2720566371239725320), KQU( 4958672473562397622), + KQU( 3032326668253243412), KQU(13689418691726908338), + KQU( 1895205511728843996), KQU( 8146303515271990527), + KQU(16507343500056113480), KQU( 473996939105902919), + KQU( 9897686885246881481), KQU(14606433762712790575), + KQU( 6732796251605566368), KQU( 1399778120855368916), + KQU( 935023885182833777), KQU(16066282816186753477), + KQU( 7291270991820612055), KQU(17530230393129853844), + KQU(10223493623477451366), KQU(15841725630495676683), + KQU(17379567246435515824), KQU( 8588251429375561971), + KQU(18339511210887206423), KQU(17349587430725976100), + KQU(12244876521394838088), KQU( 6382187714147161259), + KQU(12335807181848950831), KQU(16948885622305460665), + KQU(13755097796371520506), KQU(14806740373324947801), + KQU( 4828699633859287703), KQU( 8209879281452301604), + KQU(12435716669553736437), KQU(13970976859588452131), + KQU( 6233960842566773148), KQU(12507096267900505759), + KQU( 1198713114381279421), KQU(14989862731124149015), + KQU(15932189508707978949), KQU( 2526406641432708722), + KQU( 29187427817271982), KQU( 1499802773054556353), + KQU(10816638187021897173), KQU( 5436139270839738132), + KQU( 6659882287036010082), KQU( 2154048955317173697), + KQU(10887317019333757642), KQU(16281091802634424955), + KQU(10754549879915384901), KQU(10760611745769249815), + KQU( 2161505946972504002), KQU( 5243132808986265107), + KQU(10129852179873415416), KQU( 710339480008649081), + KQU( 7802129453068808528), KQU(17967213567178907213), + KQU(15730859124668605599), KQU(13058356168962376502), + KQU( 3701224985413645909), KQU(14464065869149109264), + KQU( 9959272418844311646), KQU(10157426099515958752), + KQU(14013736814538268528), KQU(17797456992065653951), + KQU(17418878140257344806), KQU(15457429073540561521), + KQU( 2184426881360949378), KQU( 2062193041154712416), + KQU( 8553463347406931661), KQU( 4913057625202871854), + KQU( 2668943682126618425), KQU(17064444737891172288), + KQU( 4997115903913298637), KQU(12019402608892327416), + KQU(17603584559765897352), KQU(11367529582073647975), + KQU( 8211476043518436050), KQU( 8676849804070323674), + KQU(18431829230394475730), KQU(10490177861361247904), + KQU( 9508720602025651349), KQU( 7409627448555722700), + KQU( 5804047018862729008), KQU(11943858176893142594), + KQU(11908095418933847092), KQU( 5415449345715887652), + KQU( 1554022699166156407), KQU( 9073322106406017161), + KQU( 7080630967969047082), KQU(18049736940860732943), + KQU(12748714242594196794), KQU( 1226992415735156741), + KQU(17900981019609531193), KQU(11720739744008710999), + KQU( 3006400683394775434), KQU(11347974011751996028), + KQU( 3316999628257954608), KQU( 8384484563557639101), + KQU(18117794685961729767), KQU( 1900145025596618194), + KQU(17459527840632892676), KQU( 5634784101865710994), + KQU( 7918619300292897158), KQU( 3146577625026301350), + KQU( 9955212856499068767), KQU( 1873995843681746975), + KQU( 1561487759967972194), KQU( 8322718804375878474), + KQU(11300284215327028366), KQU( 4667391032508998982), + KQU( 9820104494306625580), KQU(17922397968599970610), + KQU( 1784690461886786712), KQU(14940365084341346821), + KQU( 5348719575594186181), KQU(10720419084507855261), + KQU(14210394354145143274), KQU( 2426468692164000131), + KQU(16271062114607059202), KQU(14851904092357070247), + KQU( 6524493015693121897), KQU( 9825473835127138531), + KQU(14222500616268569578), KQU(15521484052007487468), + KQU(14462579404124614699), KQU(11012375590820665520), + KQU(11625327350536084927), KQU(14452017765243785417), + KQU( 9989342263518766305), KQU( 3640105471101803790), + KQU( 4749866455897513242), KQU(13963064946736312044), + KQU(10007416591973223791), KQU(18314132234717431115), + KQU( 3286596588617483450), KQU( 7726163455370818765), + KQU( 7575454721115379328), KQU( 5308331576437663422), + KQU(18288821894903530934), KQU( 8028405805410554106), + KQU(15744019832103296628), KQU( 149765559630932100), + KQU( 6137705557200071977), KQU(14513416315434803615), + KQU(11665702820128984473), KQU( 218926670505601386), + KQU( 6868675028717769519), KQU(15282016569441512302), + KQU( 5707000497782960236), KQU( 6671120586555079567), + KQU( 2194098052618985448), KQU(16849577895477330978), + KQU(12957148471017466283), KQU( 1997805535404859393), + KQU( 1180721060263860490), KQU(13206391310193756958), + KQU(12980208674461861797), KQU( 3825967775058875366), + KQU(17543433670782042631), KQU( 1518339070120322730), + KQU(16344584340890991669), KQU( 2611327165318529819), + KQU(11265022723283422529), KQU( 4001552800373196817), + KQU(14509595890079346161), KQU( 3528717165416234562), + KQU(18153222571501914072), KQU( 9387182977209744425), + KQU(10064342315985580021), KQU(11373678413215253977), + KQU( 2308457853228798099), KQU( 9729042942839545302), + KQU( 7833785471140127746), KQU( 6351049900319844436), + KQU(14454610627133496067), KQU(12533175683634819111), + KQU(15570163926716513029), KQU(13356980519185762498) +}; + +TEST_BEGIN(test_gen_rand_32) +{ + uint32_t array32[BLOCK_SIZE] JEMALLOC_ATTR(aligned(16)); + uint32_t array32_2[BLOCK_SIZE] JEMALLOC_ATTR(aligned(16)); + int i; + uint32_t r32; + sfmt_t *ctx; + + assert_d_le(get_min_array_size32(), BLOCK_SIZE, + "Array size too small"); + ctx = init_gen_rand(1234); + fill_array32(ctx, array32, BLOCK_SIZE); + fill_array32(ctx, array32_2, BLOCK_SIZE); + fini_gen_rand(ctx); + + ctx = init_gen_rand(1234); + for (i = 0; i < BLOCK_SIZE; i++) { + if (i < COUNT_1) { + assert_u32_eq(array32[i], init_gen_rand_32_expected[i], + "Output mismatch for i=%d", i); + } + r32 = gen_rand32(ctx); + assert_u32_eq(r32, array32[i], + "Mismatch at array32[%d]=%x, gen=%x", i, array32[i], r32); + } + for (i = 0; i < COUNT_2; i++) { + r32 = gen_rand32(ctx); + assert_u32_eq(r32, array32_2[i], + "Mismatch at array32_2[%d]=%x, gen=%x", i, array32_2[i], + r32); + } + fini_gen_rand(ctx); +} +TEST_END + +TEST_BEGIN(test_by_array_32) +{ + uint32_t array32[BLOCK_SIZE] JEMALLOC_ATTR(aligned(16)); + uint32_t array32_2[BLOCK_SIZE] JEMALLOC_ATTR(aligned(16)); + int i; + uint32_t ini[4] = {0x1234, 0x5678, 0x9abc, 0xdef0}; + uint32_t r32; + sfmt_t *ctx; + + assert_d_le(get_min_array_size32(), BLOCK_SIZE, + "Array size too small"); + ctx = init_by_array(ini, 4); + fill_array32(ctx, array32, BLOCK_SIZE); + fill_array32(ctx, array32_2, BLOCK_SIZE); + fini_gen_rand(ctx); + + ctx = init_by_array(ini, 4); + for (i = 0; i < BLOCK_SIZE; i++) { + if (i < COUNT_1) { + assert_u32_eq(array32[i], init_by_array_32_expected[i], + "Output mismatch for i=%d", i); + } + r32 = gen_rand32(ctx); + assert_u32_eq(r32, array32[i], + "Mismatch at array32[%d]=%x, gen=%x", i, array32[i], r32); + } + for (i = 0; i < COUNT_2; i++) { + r32 = gen_rand32(ctx); + assert_u32_eq(r32, array32_2[i], + "Mismatch at array32_2[%d]=%x, gen=%x", i, array32_2[i], + r32); + } + fini_gen_rand(ctx); +} +TEST_END + +TEST_BEGIN(test_gen_rand_64) +{ + uint64_t array64[BLOCK_SIZE64] JEMALLOC_ATTR(aligned(16)); + uint64_t array64_2[BLOCK_SIZE64] JEMALLOC_ATTR(aligned(16)); + int i; + uint64_t r; + sfmt_t *ctx; + + assert_d_le(get_min_array_size64(), BLOCK_SIZE64, + "Array size too small"); + ctx = init_gen_rand(4321); + fill_array64(ctx, array64, BLOCK_SIZE64); + fill_array64(ctx, array64_2, BLOCK_SIZE64); + fini_gen_rand(ctx); + + ctx = init_gen_rand(4321); + for (i = 0; i < BLOCK_SIZE64; i++) { + if (i < COUNT_1) { + assert_u64_eq(array64[i], init_gen_rand_64_expected[i], + "Output mismatch for i=%d", i); + } + r = gen_rand64(ctx); + assert_u64_eq(r, array64[i], + "Mismatch at array64[%d]=%"FMTx64", gen=%"FMTx64, i, + array64[i], r); + } + for (i = 0; i < COUNT_2; i++) { + r = gen_rand64(ctx); + assert_u64_eq(r, array64_2[i], + "Mismatch at array64_2[%d]=%"FMTx64" gen=%"FMTx64"", i, + array64_2[i], r); + } + fini_gen_rand(ctx); +} +TEST_END + +TEST_BEGIN(test_by_array_64) +{ + uint64_t array64[BLOCK_SIZE64] JEMALLOC_ATTR(aligned(16)); + uint64_t array64_2[BLOCK_SIZE64] JEMALLOC_ATTR(aligned(16)); + int i; + uint64_t r; + uint32_t ini[] = {5, 4, 3, 2, 1}; + sfmt_t *ctx; + + assert_d_le(get_min_array_size64(), BLOCK_SIZE64, + "Array size too small"); + ctx = init_by_array(ini, 5); + fill_array64(ctx, array64, BLOCK_SIZE64); + fill_array64(ctx, array64_2, BLOCK_SIZE64); + fini_gen_rand(ctx); + + ctx = init_by_array(ini, 5); + for (i = 0; i < BLOCK_SIZE64; i++) { + if (i < COUNT_1) { + assert_u64_eq(array64[i], init_by_array_64_expected[i], + "Output mismatch for i=%d", i); + } + r = gen_rand64(ctx); + assert_u64_eq(r, array64[i], + "Mismatch at array64[%d]=%"FMTx64" gen=%"FMTx64, i, + array64[i], r); + } + for (i = 0; i < COUNT_2; i++) { + r = gen_rand64(ctx); + assert_u64_eq(r, array64_2[i], + "Mismatch at array64_2[%d]=%"FMTx64" gen=%"FMTx64, i, + array64_2[i], r); + } + fini_gen_rand(ctx); +} +TEST_END + +int +main(void) +{ + + return (test( + test_gen_rand_32, + test_by_array_32, + test_gen_rand_64, + test_by_array_64)); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/atomic.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/atomic.c new file mode 100644 index 0000000..bdd74f6 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/atomic.c @@ -0,0 +1,122 @@ +#include "test/jemalloc_test.h" + +#define TEST_STRUCT(p, t) \ +struct p##_test_s { \ + t accum0; \ + t x; \ + t s; \ +}; \ +typedef struct p##_test_s p##_test_t; + +#define TEST_BODY(p, t, tc, ta, FMT) do { \ + const p##_test_t tests[] = { \ + {(t)-1, (t)-1, (t)-2}, \ + {(t)-1, (t) 0, (t)-2}, \ + {(t)-1, (t) 1, (t)-2}, \ + \ + {(t) 0, (t)-1, (t)-2}, \ + {(t) 0, (t) 0, (t)-2}, \ + {(t) 0, (t) 1, (t)-2}, \ + \ + {(t) 1, (t)-1, (t)-2}, \ + {(t) 1, (t) 0, (t)-2}, \ + {(t) 1, (t) 1, (t)-2}, \ + \ + {(t)0, (t)-(1 << 22), (t)-2}, \ + {(t)0, (t)(1 << 22), (t)-2}, \ + {(t)(1 << 22), (t)-(1 << 22), (t)-2}, \ + {(t)(1 << 22), (t)(1 << 22), (t)-2} \ + }; \ + unsigned i; \ + \ + for (i = 0; i < sizeof(tests)/sizeof(p##_test_t); i++) { \ + bool err; \ + t accum = tests[i].accum0; \ + assert_##ta##_eq(atomic_read_##p(&accum), \ + tests[i].accum0, \ + "Erroneous read, i=%u", i); \ + \ + assert_##ta##_eq(atomic_add_##p(&accum, tests[i].x), \ + (t)((tc)tests[i].accum0 + (tc)tests[i].x), \ + "i=%u, accum=%"FMT", x=%"FMT, \ + i, tests[i].accum0, tests[i].x); \ + assert_##ta##_eq(atomic_read_##p(&accum), accum, \ + "Erroneous add, i=%u", i); \ + \ + accum = tests[i].accum0; \ + assert_##ta##_eq(atomic_sub_##p(&accum, tests[i].x), \ + (t)((tc)tests[i].accum0 - (tc)tests[i].x), \ + "i=%u, accum=%"FMT", x=%"FMT, \ + i, tests[i].accum0, tests[i].x); \ + assert_##ta##_eq(atomic_read_##p(&accum), accum, \ + "Erroneous sub, i=%u", i); \ + \ + accum = tests[i].accum0; \ + err = atomic_cas_##p(&accum, tests[i].x, tests[i].s); \ + assert_b_eq(err, tests[i].accum0 != tests[i].x, \ + "Erroneous cas success/failure result"); \ + assert_##ta##_eq(accum, err ? tests[i].accum0 : \ + tests[i].s, "Erroneous cas effect, i=%u", i); \ + \ + accum = tests[i].accum0; \ + atomic_write_##p(&accum, tests[i].s); \ + assert_##ta##_eq(accum, tests[i].s, \ + "Erroneous write, i=%u", i); \ + } \ +} while (0) + +TEST_STRUCT(uint64, uint64_t) +TEST_BEGIN(test_atomic_uint64) +{ + +#if !(LG_SIZEOF_PTR == 3 || LG_SIZEOF_INT == 3) + test_skip("64-bit atomic operations not supported"); +#else + TEST_BODY(uint64, uint64_t, uint64_t, u64, FMTx64); +#endif +} +TEST_END + +TEST_STRUCT(uint32, uint32_t) +TEST_BEGIN(test_atomic_uint32) +{ + + TEST_BODY(uint32, uint32_t, uint32_t, u32, "#"FMTx32); +} +TEST_END + +TEST_STRUCT(p, void *) +TEST_BEGIN(test_atomic_p) +{ + + TEST_BODY(p, void *, uintptr_t, ptr, "p"); +} +TEST_END + +TEST_STRUCT(z, size_t) +TEST_BEGIN(test_atomic_z) +{ + + TEST_BODY(z, size_t, size_t, zu, "#zx"); +} +TEST_END + +TEST_STRUCT(u, unsigned) +TEST_BEGIN(test_atomic_u) +{ + + TEST_BODY(u, unsigned, unsigned, u, "#x"); +} +TEST_END + +int +main(void) +{ + + return (test( + test_atomic_uint64, + test_atomic_uint32, + test_atomic_p, + test_atomic_z, + test_atomic_u)); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/bitmap.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/bitmap.c new file mode 100644 index 0000000..7da583d --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/bitmap.c @@ -0,0 +1,159 @@ +#include "test/jemalloc_test.h" + +TEST_BEGIN(test_bitmap_size) +{ + size_t i, prev_size; + + prev_size = 0; + for (i = 1; i <= BITMAP_MAXBITS; i++) { + size_t size = bitmap_size(i); + assert_true(size >= prev_size, + "Bitmap size is smaller than expected"); + prev_size = size; + } +} +TEST_END + +TEST_BEGIN(test_bitmap_init) +{ + size_t i; + + for (i = 1; i <= BITMAP_MAXBITS; i++) { + bitmap_info_t binfo; + bitmap_info_init(&binfo, i); + { + size_t j; + bitmap_t *bitmap = (bitmap_t *)malloc(sizeof(bitmap_t) * + bitmap_info_ngroups(&binfo)); + bitmap_init(bitmap, &binfo); + + for (j = 0; j < i; j++) { + assert_false(bitmap_get(bitmap, &binfo, j), + "Bit should be unset"); + } + free(bitmap); + } + } +} +TEST_END + +TEST_BEGIN(test_bitmap_set) +{ + size_t i; + + for (i = 1; i <= BITMAP_MAXBITS; i++) { + bitmap_info_t binfo; + bitmap_info_init(&binfo, i); + { + size_t j; + bitmap_t *bitmap = (bitmap_t *)malloc(sizeof(bitmap_t) * + bitmap_info_ngroups(&binfo)); + bitmap_init(bitmap, &binfo); + + for (j = 0; j < i; j++) + bitmap_set(bitmap, &binfo, j); + assert_true(bitmap_full(bitmap, &binfo), + "All bits should be set"); + free(bitmap); + } + } +} +TEST_END + +TEST_BEGIN(test_bitmap_unset) +{ + size_t i; + + for (i = 1; i <= BITMAP_MAXBITS; i++) { + bitmap_info_t binfo; + bitmap_info_init(&binfo, i); + { + size_t j; + bitmap_t *bitmap = (bitmap_t *)malloc(sizeof(bitmap_t) * + bitmap_info_ngroups(&binfo)); + bitmap_init(bitmap, &binfo); + + for (j = 0; j < i; j++) + bitmap_set(bitmap, &binfo, j); + assert_true(bitmap_full(bitmap, &binfo), + "All bits should be set"); + for (j = 0; j < i; j++) + bitmap_unset(bitmap, &binfo, j); + for (j = 0; j < i; j++) + bitmap_set(bitmap, &binfo, j); + assert_true(bitmap_full(bitmap, &binfo), + "All bits should be set"); + free(bitmap); + } + } +} +TEST_END + +TEST_BEGIN(test_bitmap_sfu) +{ + size_t i; + + for (i = 1; i <= BITMAP_MAXBITS; i++) { + bitmap_info_t binfo; + bitmap_info_init(&binfo, i); + { + ssize_t j; + bitmap_t *bitmap = (bitmap_t *)malloc(sizeof(bitmap_t) * + bitmap_info_ngroups(&binfo)); + bitmap_init(bitmap, &binfo); + + /* Iteratively set bits starting at the beginning. */ + for (j = 0; j < i; j++) { + assert_zd_eq(bitmap_sfu(bitmap, &binfo), j, + "First unset bit should be just after " + "previous first unset bit"); + } + assert_true(bitmap_full(bitmap, &binfo), + "All bits should be set"); + + /* + * Iteratively unset bits starting at the end, and + * verify that bitmap_sfu() reaches the unset bits. + */ + for (j = i - 1; j >= 0; j--) { + bitmap_unset(bitmap, &binfo, j); + assert_zd_eq(bitmap_sfu(bitmap, &binfo), j, + "First unset bit should the bit previously " + "unset"); + bitmap_unset(bitmap, &binfo, j); + } + assert_false(bitmap_get(bitmap, &binfo, 0), + "Bit should be unset"); + + /* + * Iteratively set bits starting at the beginning, and + * verify that bitmap_sfu() looks past them. + */ + for (j = 1; j < i; j++) { + bitmap_set(bitmap, &binfo, j - 1); + assert_zd_eq(bitmap_sfu(bitmap, &binfo), j, + "First unset bit should be just after the " + "bit previously set"); + bitmap_unset(bitmap, &binfo, j); + } + assert_zd_eq(bitmap_sfu(bitmap, &binfo), i - 1, + "First unset bit should be the last bit"); + assert_true(bitmap_full(bitmap, &binfo), + "All bits should be set"); + free(bitmap); + } + } +} +TEST_END + +int +main(void) +{ + + return (test( + test_bitmap_size, + test_bitmap_init, + test_bitmap_set, + test_bitmap_unset, + test_bitmap_sfu)); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/ckh.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/ckh.c new file mode 100644 index 0000000..b117595 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/ckh.c @@ -0,0 +1,214 @@ +#include "test/jemalloc_test.h" + +TEST_BEGIN(test_new_delete) +{ + tsd_t *tsd; + ckh_t ckh; + + tsd = tsd_fetch(); + + assert_false(ckh_new(tsd, &ckh, 2, ckh_string_hash, ckh_string_keycomp), + "Unexpected ckh_new() error"); + ckh_delete(tsd, &ckh); + + assert_false(ckh_new(tsd, &ckh, 3, ckh_pointer_hash, + ckh_pointer_keycomp), "Unexpected ckh_new() error"); + ckh_delete(tsd, &ckh); +} +TEST_END + +TEST_BEGIN(test_count_insert_search_remove) +{ + tsd_t *tsd; + ckh_t ckh; + const char *strs[] = { + "a string", + "A string", + "a string.", + "A string." + }; + const char *missing = "A string not in the hash table."; + size_t i; + + tsd = tsd_fetch(); + + assert_false(ckh_new(tsd, &ckh, 2, ckh_string_hash, ckh_string_keycomp), + "Unexpected ckh_new() error"); + assert_zu_eq(ckh_count(&ckh), 0, + "ckh_count() should return %zu, but it returned %zu", ZU(0), + ckh_count(&ckh)); + + /* Insert. */ + for (i = 0; i < sizeof(strs)/sizeof(const char *); i++) { + ckh_insert(tsd, &ckh, strs[i], strs[i]); + assert_zu_eq(ckh_count(&ckh), i+1, + "ckh_count() should return %zu, but it returned %zu", i+1, + ckh_count(&ckh)); + } + + /* Search. */ + for (i = 0; i < sizeof(strs)/sizeof(const char *); i++) { + union { + void *p; + const char *s; + } k, v; + void **kp, **vp; + const char *ks, *vs; + + kp = (i & 1) ? &k.p : NULL; + vp = (i & 2) ? &v.p : NULL; + k.p = NULL; + v.p = NULL; + assert_false(ckh_search(&ckh, strs[i], kp, vp), + "Unexpected ckh_search() error"); + + ks = (i & 1) ? strs[i] : (const char *)NULL; + vs = (i & 2) ? strs[i] : (const char *)NULL; + assert_ptr_eq((void *)ks, (void *)k.s, "Key mismatch, i=%zu", + i); + assert_ptr_eq((void *)vs, (void *)v.s, "Value mismatch, i=%zu", + i); + } + assert_true(ckh_search(&ckh, missing, NULL, NULL), + "Unexpected ckh_search() success"); + + /* Remove. */ + for (i = 0; i < sizeof(strs)/sizeof(const char *); i++) { + union { + void *p; + const char *s; + } k, v; + void **kp, **vp; + const char *ks, *vs; + + kp = (i & 1) ? &k.p : NULL; + vp = (i & 2) ? &v.p : NULL; + k.p = NULL; + v.p = NULL; + assert_false(ckh_remove(tsd, &ckh, strs[i], kp, vp), + "Unexpected ckh_remove() error"); + + ks = (i & 1) ? strs[i] : (const char *)NULL; + vs = (i & 2) ? strs[i] : (const char *)NULL; + assert_ptr_eq((void *)ks, (void *)k.s, "Key mismatch, i=%zu", + i); + assert_ptr_eq((void *)vs, (void *)v.s, "Value mismatch, i=%zu", + i); + assert_zu_eq(ckh_count(&ckh), + sizeof(strs)/sizeof(const char *) - i - 1, + "ckh_count() should return %zu, but it returned %zu", + sizeof(strs)/sizeof(const char *) - i - 1, + ckh_count(&ckh)); + } + + ckh_delete(tsd, &ckh); +} +TEST_END + +TEST_BEGIN(test_insert_iter_remove) +{ +#define NITEMS ZU(1000) + tsd_t *tsd; + ckh_t ckh; + void **p[NITEMS]; + void *q, *r; + size_t i; + + tsd = tsd_fetch(); + + assert_false(ckh_new(tsd, &ckh, 2, ckh_pointer_hash, + ckh_pointer_keycomp), "Unexpected ckh_new() error"); + + for (i = 0; i < NITEMS; i++) { + p[i] = mallocx(i+1, 0); + assert_ptr_not_null(p[i], "Unexpected mallocx() failure"); + } + + for (i = 0; i < NITEMS; i++) { + size_t j; + + for (j = i; j < NITEMS; j++) { + assert_false(ckh_insert(tsd, &ckh, p[j], p[j]), + "Unexpected ckh_insert() failure"); + assert_false(ckh_search(&ckh, p[j], &q, &r), + "Unexpected ckh_search() failure"); + assert_ptr_eq(p[j], q, "Key pointer mismatch"); + assert_ptr_eq(p[j], r, "Value pointer mismatch"); + } + + assert_zu_eq(ckh_count(&ckh), NITEMS, + "ckh_count() should return %zu, but it returned %zu", + NITEMS, ckh_count(&ckh)); + + for (j = i + 1; j < NITEMS; j++) { + assert_false(ckh_search(&ckh, p[j], NULL, NULL), + "Unexpected ckh_search() failure"); + assert_false(ckh_remove(tsd, &ckh, p[j], &q, &r), + "Unexpected ckh_remove() failure"); + assert_ptr_eq(p[j], q, "Key pointer mismatch"); + assert_ptr_eq(p[j], r, "Value pointer mismatch"); + assert_true(ckh_search(&ckh, p[j], NULL, NULL), + "Unexpected ckh_search() success"); + assert_true(ckh_remove(tsd, &ckh, p[j], &q, &r), + "Unexpected ckh_remove() success"); + } + + { + bool seen[NITEMS]; + size_t tabind; + + memset(seen, 0, sizeof(seen)); + + for (tabind = 0; !ckh_iter(&ckh, &tabind, &q, &r);) { + size_t k; + + assert_ptr_eq(q, r, "Key and val not equal"); + + for (k = 0; k < NITEMS; k++) { + if (p[k] == q) { + assert_false(seen[k], + "Item %zu already seen", k); + seen[k] = true; + break; + } + } + } + + for (j = 0; j < i + 1; j++) + assert_true(seen[j], "Item %zu not seen", j); + for (; j < NITEMS; j++) + assert_false(seen[j], "Item %zu seen", j); + } + } + + for (i = 0; i < NITEMS; i++) { + assert_false(ckh_search(&ckh, p[i], NULL, NULL), + "Unexpected ckh_search() failure"); + assert_false(ckh_remove(tsd, &ckh, p[i], &q, &r), + "Unexpected ckh_remove() failure"); + assert_ptr_eq(p[i], q, "Key pointer mismatch"); + assert_ptr_eq(p[i], r, "Value pointer mismatch"); + assert_true(ckh_search(&ckh, p[i], NULL, NULL), + "Unexpected ckh_search() success"); + assert_true(ckh_remove(tsd, &ckh, p[i], &q, &r), + "Unexpected ckh_remove() success"); + dallocx(p[i], 0); + } + + assert_zu_eq(ckh_count(&ckh), 0, + "ckh_count() should return %zu, but it returned %zu", + ZU(0), ckh_count(&ckh)); + ckh_delete(tsd, &ckh); +#undef NITEMS +} +TEST_END + +int +main(void) +{ + + return (test( + test_new_delete, + test_count_insert_search_remove, + test_insert_iter_remove)); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/hash.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/hash.c new file mode 100644 index 0000000..77a8ced --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/hash.c @@ -0,0 +1,171 @@ +/* + * This file is based on code that is part of SMHasher + * (https://code.google.com/p/smhasher/), and is subject to the MIT license + * (http://www.opensource.org/licenses/mit-license.php). Both email addresses + * associated with the source code's revision history belong to Austin Appleby, + * and the revision history ranges from 2010 to 2012. Therefore the copyright + * and license are here taken to be: + * + * Copyright (c) 2010-2012 Austin Appleby + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "test/jemalloc_test.h" + +typedef enum { + hash_variant_x86_32, + hash_variant_x86_128, + hash_variant_x64_128 +} hash_variant_t; + +static size_t +hash_variant_bits(hash_variant_t variant) +{ + + switch (variant) { + case hash_variant_x86_32: return (32); + case hash_variant_x86_128: return (128); + case hash_variant_x64_128: return (128); + default: not_reached(); + } +} + +static const char * +hash_variant_string(hash_variant_t variant) +{ + + switch (variant) { + case hash_variant_x86_32: return ("hash_x86_32"); + case hash_variant_x86_128: return ("hash_x86_128"); + case hash_variant_x64_128: return ("hash_x64_128"); + default: not_reached(); + } +} + +static void +hash_variant_verify(hash_variant_t variant) +{ + const size_t hashbytes = hash_variant_bits(variant) / 8; + uint8_t key[256]; + VARIABLE_ARRAY(uint8_t, hashes, hashbytes * 256); + VARIABLE_ARRAY(uint8_t, final, hashbytes); + unsigned i; + uint32_t computed, expected; + + memset(key, 0, sizeof(key)); + memset(hashes, 0, sizeof(hashes)); + memset(final, 0, sizeof(final)); + + /* + * Hash keys of the form {0}, {0,1}, {0,1,2}, ..., {0,1,...,255} as the + * seed. + */ + for (i = 0; i < 256; i++) { + key[i] = (uint8_t)i; + switch (variant) { + case hash_variant_x86_32: { + uint32_t out; + out = hash_x86_32(key, i, 256-i); + memcpy(&hashes[i*hashbytes], &out, hashbytes); + break; + } case hash_variant_x86_128: { + uint64_t out[2]; + hash_x86_128(key, i, 256-i, out); + memcpy(&hashes[i*hashbytes], out, hashbytes); + break; + } case hash_variant_x64_128: { + uint64_t out[2]; + hash_x64_128(key, i, 256-i, out); + memcpy(&hashes[i*hashbytes], out, hashbytes); + break; + } default: not_reached(); + } + } + + /* Hash the result array. */ + switch (variant) { + case hash_variant_x86_32: { + uint32_t out = hash_x86_32(hashes, hashbytes*256, 0); + memcpy(final, &out, sizeof(out)); + break; + } case hash_variant_x86_128: { + uint64_t out[2]; + hash_x86_128(hashes, hashbytes*256, 0, out); + memcpy(final, out, sizeof(out)); + break; + } case hash_variant_x64_128: { + uint64_t out[2]; + hash_x64_128(hashes, hashbytes*256, 0, out); + memcpy(final, out, sizeof(out)); + break; + } default: not_reached(); + } + + computed = (final[0] << 0) | (final[1] << 8) | (final[2] << 16) | + (final[3] << 24); + + switch (variant) { +#ifdef JEMALLOC_BIG_ENDIAN + case hash_variant_x86_32: expected = 0x6213303eU; break; + case hash_variant_x86_128: expected = 0x266820caU; break; + case hash_variant_x64_128: expected = 0xcc622b6fU; break; +#else + case hash_variant_x86_32: expected = 0xb0f57ee3U; break; + case hash_variant_x86_128: expected = 0xb3ece62aU; break; + case hash_variant_x64_128: expected = 0x6384ba69U; break; +#endif + default: not_reached(); + } + + assert_u32_eq(computed, expected, + "Hash mismatch for %s(): expected %#x but got %#x", + hash_variant_string(variant), expected, computed); +} + +TEST_BEGIN(test_hash_x86_32) +{ + + hash_variant_verify(hash_variant_x86_32); +} +TEST_END + +TEST_BEGIN(test_hash_x86_128) +{ + + hash_variant_verify(hash_variant_x86_128); +} +TEST_END + +TEST_BEGIN(test_hash_x64_128) +{ + + hash_variant_verify(hash_variant_x64_128); +} +TEST_END + +int +main(void) +{ + + return (test( + test_hash_x86_32, + test_hash_x86_128, + test_hash_x64_128)); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/junk.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/junk.c new file mode 100644 index 0000000..b23dd1e --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/junk.c @@ -0,0 +1,254 @@ +#include "test/jemalloc_test.h" + +#ifdef JEMALLOC_FILL +# ifndef JEMALLOC_TEST_JUNK_OPT +# define JEMALLOC_TEST_JUNK_OPT "junk:true" +# endif +const char *malloc_conf = + "abort:false,zero:false,redzone:true,quarantine:0," JEMALLOC_TEST_JUNK_OPT; +#endif + +static arena_dalloc_junk_small_t *arena_dalloc_junk_small_orig; +static arena_dalloc_junk_large_t *arena_dalloc_junk_large_orig; +static huge_dalloc_junk_t *huge_dalloc_junk_orig; +static void *watch_for_junking; +static bool saw_junking; + +static void +watch_junking(void *p) +{ + + watch_for_junking = p; + saw_junking = false; +} + +static void +arena_dalloc_junk_small_intercept(void *ptr, arena_bin_info_t *bin_info) +{ + size_t i; + + arena_dalloc_junk_small_orig(ptr, bin_info); + for (i = 0; i < bin_info->reg_size; i++) { + assert_c_eq(((char *)ptr)[i], 0x5a, + "Missing junk fill for byte %zu/%zu of deallocated region", + i, bin_info->reg_size); + } + if (ptr == watch_for_junking) + saw_junking = true; +} + +static void +arena_dalloc_junk_large_intercept(void *ptr, size_t usize) +{ + size_t i; + + arena_dalloc_junk_large_orig(ptr, usize); + for (i = 0; i < usize; i++) { + assert_c_eq(((char *)ptr)[i], 0x5a, + "Missing junk fill for byte %zu/%zu of deallocated region", + i, usize); + } + if (ptr == watch_for_junking) + saw_junking = true; +} + +static void +huge_dalloc_junk_intercept(void *ptr, size_t usize) +{ + + huge_dalloc_junk_orig(ptr, usize); + /* + * The conditions under which junk filling actually occurs are nuanced + * enough that it doesn't make sense to duplicate the decision logic in + * test code, so don't actually check that the region is junk-filled. + */ + if (ptr == watch_for_junking) + saw_junking = true; +} + +static void +test_junk(size_t sz_min, size_t sz_max) +{ + char *s; + size_t sz_prev, sz, i; + + if (opt_junk_free) { + arena_dalloc_junk_small_orig = arena_dalloc_junk_small; + arena_dalloc_junk_small = arena_dalloc_junk_small_intercept; + arena_dalloc_junk_large_orig = arena_dalloc_junk_large; + arena_dalloc_junk_large = arena_dalloc_junk_large_intercept; + huge_dalloc_junk_orig = huge_dalloc_junk; + huge_dalloc_junk = huge_dalloc_junk_intercept; + } + + sz_prev = 0; + s = (char *)mallocx(sz_min, 0); + assert_ptr_not_null((void *)s, "Unexpected mallocx() failure"); + + for (sz = sallocx(s, 0); sz <= sz_max; + sz_prev = sz, sz = sallocx(s, 0)) { + if (sz_prev > 0) { + assert_c_eq(s[0], 'a', + "Previously allocated byte %zu/%zu is corrupted", + ZU(0), sz_prev); + assert_c_eq(s[sz_prev-1], 'a', + "Previously allocated byte %zu/%zu is corrupted", + sz_prev-1, sz_prev); + } + + for (i = sz_prev; i < sz; i++) { + if (opt_junk_alloc) { + assert_c_eq(s[i], 0xa5, + "Newly allocated byte %zu/%zu isn't " + "junk-filled", i, sz); + } + s[i] = 'a'; + } + + if (xallocx(s, sz+1, 0, 0) == sz) { + watch_junking(s); + s = (char *)rallocx(s, sz+1, 0); + assert_ptr_not_null((void *)s, + "Unexpected rallocx() failure"); + assert_true(!opt_junk_free || saw_junking, + "Expected region of size %zu to be junk-filled", + sz); + } + } + + watch_junking(s); + dallocx(s, 0); + assert_true(!opt_junk_free || saw_junking, + "Expected region of size %zu to be junk-filled", sz); + + if (opt_junk_free) { + arena_dalloc_junk_small = arena_dalloc_junk_small_orig; + arena_dalloc_junk_large = arena_dalloc_junk_large_orig; + huge_dalloc_junk = huge_dalloc_junk_orig; + } +} + +TEST_BEGIN(test_junk_small) +{ + + test_skip_if(!config_fill); + test_junk(1, SMALL_MAXCLASS-1); +} +TEST_END + +TEST_BEGIN(test_junk_large) +{ + + test_skip_if(!config_fill); + test_junk(SMALL_MAXCLASS+1, large_maxclass); +} +TEST_END + +TEST_BEGIN(test_junk_huge) +{ + + test_skip_if(!config_fill); + test_junk(large_maxclass+1, chunksize*2); +} +TEST_END + +arena_ralloc_junk_large_t *arena_ralloc_junk_large_orig; +static void *most_recently_trimmed; + +static size_t +shrink_size(size_t size) +{ + size_t shrink_size; + + for (shrink_size = size - 1; nallocx(shrink_size, 0) == size; + shrink_size--) + ; /* Do nothing. */ + + return (shrink_size); +} + +static void +arena_ralloc_junk_large_intercept(void *ptr, size_t old_usize, size_t usize) +{ + + arena_ralloc_junk_large_orig(ptr, old_usize, usize); + assert_zu_eq(old_usize, large_maxclass, "Unexpected old_usize"); + assert_zu_eq(usize, shrink_size(large_maxclass), "Unexpected usize"); + most_recently_trimmed = ptr; +} + +TEST_BEGIN(test_junk_large_ralloc_shrink) +{ + void *p1, *p2; + + p1 = mallocx(large_maxclass, 0); + assert_ptr_not_null(p1, "Unexpected mallocx() failure"); + + arena_ralloc_junk_large_orig = arena_ralloc_junk_large; + arena_ralloc_junk_large = arena_ralloc_junk_large_intercept; + + p2 = rallocx(p1, shrink_size(large_maxclass), 0); + assert_ptr_eq(p1, p2, "Unexpected move during shrink"); + + arena_ralloc_junk_large = arena_ralloc_junk_large_orig; + + assert_ptr_eq(most_recently_trimmed, p1, + "Expected trimmed portion of region to be junk-filled"); +} +TEST_END + +static bool detected_redzone_corruption; + +static void +arena_redzone_corruption_replacement(void *ptr, size_t usize, bool after, + size_t offset, uint8_t byte) +{ + + detected_redzone_corruption = true; +} + +TEST_BEGIN(test_junk_redzone) +{ + char *s; + arena_redzone_corruption_t *arena_redzone_corruption_orig; + + test_skip_if(!config_fill); + test_skip_if(!opt_junk_alloc || !opt_junk_free); + + arena_redzone_corruption_orig = arena_redzone_corruption; + arena_redzone_corruption = arena_redzone_corruption_replacement; + + /* Test underflow. */ + detected_redzone_corruption = false; + s = (char *)mallocx(1, 0); + assert_ptr_not_null((void *)s, "Unexpected mallocx() failure"); + s[-1] = 0xbb; + dallocx(s, 0); + assert_true(detected_redzone_corruption, + "Did not detect redzone corruption"); + + /* Test overflow. */ + detected_redzone_corruption = false; + s = (char *)mallocx(1, 0); + assert_ptr_not_null((void *)s, "Unexpected mallocx() failure"); + s[sallocx(s, 0)] = 0xbb; + dallocx(s, 0); + assert_true(detected_redzone_corruption, + "Did not detect redzone corruption"); + + arena_redzone_corruption = arena_redzone_corruption_orig; +} +TEST_END + +int +main(void) +{ + + assert(!config_fill || opt_junk_alloc || opt_junk_free); + return (test( + test_junk_small, + test_junk_large, + test_junk_huge, + test_junk_large_ralloc_shrink, + test_junk_redzone)); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/junk_alloc.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/junk_alloc.c new file mode 100644 index 0000000..8db3331 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/junk_alloc.c @@ -0,0 +1,3 @@ +#define JEMALLOC_TEST_JUNK_OPT "junk:alloc" +#include "junk.c" +#undef JEMALLOC_TEST_JUNK_OPT diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/junk_free.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/junk_free.c new file mode 100644 index 0000000..482a61d --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/junk_free.c @@ -0,0 +1,3 @@ +#define JEMALLOC_TEST_JUNK_OPT "junk:free" +#include "junk.c" +#undef JEMALLOC_TEST_JUNK_OPT diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/lg_chunk.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/lg_chunk.c new file mode 100644 index 0000000..7e5df38 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/lg_chunk.c @@ -0,0 +1,26 @@ +#include "test/jemalloc_test.h" + +/* + * Make sure that opt.lg_chunk clamping is sufficient. In practice, this test + * program will fail a debug assertion during initialization and abort (rather + * than the test soft-failing) if clamping is insufficient. + */ +const char *malloc_conf = "lg_chunk:0"; + +TEST_BEGIN(test_lg_chunk_clamp) +{ + void *p; + + p = mallocx(1, 0); + assert_ptr_not_null(p, "Unexpected mallocx() failure"); + dallocx(p, 0); +} +TEST_END + +int +main(void) +{ + + return (test( + test_lg_chunk_clamp)); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/mallctl.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/mallctl.c new file mode 100644 index 0000000..31e354c --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/mallctl.c @@ -0,0 +1,633 @@ +#include "test/jemalloc_test.h" + +TEST_BEGIN(test_mallctl_errors) +{ + uint64_t epoch; + size_t sz; + + assert_d_eq(mallctl("no_such_name", NULL, NULL, NULL, 0), ENOENT, + "mallctl() should return ENOENT for non-existent names"); + + assert_d_eq(mallctl("version", NULL, NULL, "0.0.0", strlen("0.0.0")), + EPERM, "mallctl() should return EPERM on attempt to write " + "read-only value"); + + assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)-1), + EINVAL, "mallctl() should return EINVAL for input size mismatch"); + assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)+1), + EINVAL, "mallctl() should return EINVAL for input size mismatch"); + + sz = sizeof(epoch)-1; + assert_d_eq(mallctl("epoch", &epoch, &sz, NULL, 0), EINVAL, + "mallctl() should return EINVAL for output size mismatch"); + sz = sizeof(epoch)+1; + assert_d_eq(mallctl("epoch", &epoch, &sz, NULL, 0), EINVAL, + "mallctl() should return EINVAL for output size mismatch"); +} +TEST_END + +TEST_BEGIN(test_mallctlnametomib_errors) +{ + size_t mib[1]; + size_t miblen; + + miblen = sizeof(mib)/sizeof(size_t); + assert_d_eq(mallctlnametomib("no_such_name", mib, &miblen), ENOENT, + "mallctlnametomib() should return ENOENT for non-existent names"); +} +TEST_END + +TEST_BEGIN(test_mallctlbymib_errors) +{ + uint64_t epoch; + size_t sz; + size_t mib[1]; + size_t miblen; + + miblen = sizeof(mib)/sizeof(size_t); + assert_d_eq(mallctlnametomib("version", mib, &miblen), 0, + "Unexpected mallctlnametomib() failure"); + + assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, "0.0.0", + strlen("0.0.0")), EPERM, "mallctl() should return EPERM on " + "attempt to write read-only value"); + + miblen = sizeof(mib)/sizeof(size_t); + assert_d_eq(mallctlnametomib("epoch", mib, &miblen), 0, + "Unexpected mallctlnametomib() failure"); + + assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, &epoch, + sizeof(epoch)-1), EINVAL, + "mallctlbymib() should return EINVAL for input size mismatch"); + assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, &epoch, + sizeof(epoch)+1), EINVAL, + "mallctlbymib() should return EINVAL for input size mismatch"); + + sz = sizeof(epoch)-1; + assert_d_eq(mallctlbymib(mib, miblen, &epoch, &sz, NULL, 0), EINVAL, + "mallctlbymib() should return EINVAL for output size mismatch"); + sz = sizeof(epoch)+1; + assert_d_eq(mallctlbymib(mib, miblen, &epoch, &sz, NULL, 0), EINVAL, + "mallctlbymib() should return EINVAL for output size mismatch"); +} +TEST_END + +TEST_BEGIN(test_mallctl_read_write) +{ + uint64_t old_epoch, new_epoch; + size_t sz = sizeof(old_epoch); + + /* Blind. */ + assert_d_eq(mallctl("epoch", NULL, NULL, NULL, 0), 0, + "Unexpected mallctl() failure"); + assert_zu_eq(sz, sizeof(old_epoch), "Unexpected output size"); + + /* Read. */ + assert_d_eq(mallctl("epoch", &old_epoch, &sz, NULL, 0), 0, + "Unexpected mallctl() failure"); + assert_zu_eq(sz, sizeof(old_epoch), "Unexpected output size"); + + /* Write. */ + assert_d_eq(mallctl("epoch", NULL, NULL, &new_epoch, sizeof(new_epoch)), + 0, "Unexpected mallctl() failure"); + assert_zu_eq(sz, sizeof(old_epoch), "Unexpected output size"); + + /* Read+write. */ + assert_d_eq(mallctl("epoch", &old_epoch, &sz, &new_epoch, + sizeof(new_epoch)), 0, "Unexpected mallctl() failure"); + assert_zu_eq(sz, sizeof(old_epoch), "Unexpected output size"); +} +TEST_END + +TEST_BEGIN(test_mallctlnametomib_short_mib) +{ + size_t mib[4]; + size_t miblen; + + miblen = 3; + mib[3] = 42; + assert_d_eq(mallctlnametomib("arenas.bin.0.nregs", mib, &miblen), 0, + "Unexpected mallctlnametomib() failure"); + assert_zu_eq(miblen, 3, "Unexpected mib output length"); + assert_zu_eq(mib[3], 42, + "mallctlnametomib() wrote past the end of the input mib"); +} +TEST_END + +TEST_BEGIN(test_mallctl_config) +{ + +#define TEST_MALLCTL_CONFIG(config) do { \ + bool oldval; \ + size_t sz = sizeof(oldval); \ + assert_d_eq(mallctl("config."#config, &oldval, &sz, NULL, 0), \ + 0, "Unexpected mallctl() failure"); \ + assert_b_eq(oldval, config_##config, "Incorrect config value"); \ + assert_zu_eq(sz, sizeof(oldval), "Unexpected output size"); \ +} while (0) + + TEST_MALLCTL_CONFIG(cache_oblivious); + TEST_MALLCTL_CONFIG(debug); + TEST_MALLCTL_CONFIG(fill); + TEST_MALLCTL_CONFIG(lazy_lock); + TEST_MALLCTL_CONFIG(munmap); + TEST_MALLCTL_CONFIG(prof); + TEST_MALLCTL_CONFIG(prof_libgcc); + TEST_MALLCTL_CONFIG(prof_libunwind); + TEST_MALLCTL_CONFIG(stats); + TEST_MALLCTL_CONFIG(tcache); + TEST_MALLCTL_CONFIG(tls); + TEST_MALLCTL_CONFIG(utrace); + TEST_MALLCTL_CONFIG(valgrind); + TEST_MALLCTL_CONFIG(xmalloc); + +#undef TEST_MALLCTL_CONFIG +} +TEST_END + +TEST_BEGIN(test_mallctl_opt) +{ + bool config_always = true; + +#define TEST_MALLCTL_OPT(t, opt, config) do { \ + t oldval; \ + size_t sz = sizeof(oldval); \ + int expected = config_##config ? 0 : ENOENT; \ + int result = mallctl("opt."#opt, &oldval, &sz, NULL, 0); \ + assert_d_eq(result, expected, \ + "Unexpected mallctl() result for opt."#opt); \ + assert_zu_eq(sz, sizeof(oldval), "Unexpected output size"); \ +} while (0) + + TEST_MALLCTL_OPT(bool, abort, always); + TEST_MALLCTL_OPT(size_t, lg_chunk, always); + TEST_MALLCTL_OPT(const char *, dss, always); + TEST_MALLCTL_OPT(size_t, narenas, always); + TEST_MALLCTL_OPT(ssize_t, lg_dirty_mult, always); + TEST_MALLCTL_OPT(bool, stats_print, always); + TEST_MALLCTL_OPT(const char *, junk, fill); + TEST_MALLCTL_OPT(size_t, quarantine, fill); + TEST_MALLCTL_OPT(bool, redzone, fill); + TEST_MALLCTL_OPT(bool, zero, fill); + TEST_MALLCTL_OPT(bool, utrace, utrace); + TEST_MALLCTL_OPT(bool, xmalloc, xmalloc); + TEST_MALLCTL_OPT(bool, tcache, tcache); + TEST_MALLCTL_OPT(size_t, lg_tcache_max, tcache); + TEST_MALLCTL_OPT(bool, prof, prof); + TEST_MALLCTL_OPT(const char *, prof_prefix, prof); + TEST_MALLCTL_OPT(bool, prof_active, prof); + TEST_MALLCTL_OPT(ssize_t, lg_prof_sample, prof); + TEST_MALLCTL_OPT(bool, prof_accum, prof); + TEST_MALLCTL_OPT(ssize_t, lg_prof_interval, prof); + TEST_MALLCTL_OPT(bool, prof_gdump, prof); + TEST_MALLCTL_OPT(bool, prof_final, prof); + TEST_MALLCTL_OPT(bool, prof_leak, prof); + +#undef TEST_MALLCTL_OPT +} +TEST_END + +TEST_BEGIN(test_manpage_example) +{ + unsigned nbins, i; + size_t mib[4]; + size_t len, miblen; + + len = sizeof(nbins); + assert_d_eq(mallctl("arenas.nbins", &nbins, &len, NULL, 0), 0, + "Unexpected mallctl() failure"); + + miblen = 4; + assert_d_eq(mallctlnametomib("arenas.bin.0.size", mib, &miblen), 0, + "Unexpected mallctlnametomib() failure"); + for (i = 0; i < nbins; i++) { + size_t bin_size; + + mib[2] = i; + len = sizeof(bin_size); + assert_d_eq(mallctlbymib(mib, miblen, &bin_size, &len, NULL, 0), + 0, "Unexpected mallctlbymib() failure"); + /* Do something with bin_size... */ + } +} +TEST_END + +TEST_BEGIN(test_tcache_none) +{ + void *p0, *q, *p1; + + test_skip_if(!config_tcache); + + /* Allocate p and q. */ + p0 = mallocx(42, 0); + assert_ptr_not_null(p0, "Unexpected mallocx() failure"); + q = mallocx(42, 0); + assert_ptr_not_null(q, "Unexpected mallocx() failure"); + + /* Deallocate p and q, but bypass the tcache for q. */ + dallocx(p0, 0); + dallocx(q, MALLOCX_TCACHE_NONE); + + /* Make sure that tcache-based allocation returns p, not q. */ + p1 = mallocx(42, 0); + assert_ptr_not_null(p1, "Unexpected mallocx() failure"); + assert_ptr_eq(p0, p1, "Expected tcache to allocate cached region"); + + /* Clean up. */ + dallocx(p1, MALLOCX_TCACHE_NONE); +} +TEST_END + +TEST_BEGIN(test_tcache) +{ +#define NTCACHES 10 + unsigned tis[NTCACHES]; + void *ps[NTCACHES]; + void *qs[NTCACHES]; + unsigned i; + size_t sz, psz, qsz; + + test_skip_if(!config_tcache); + + psz = 42; + qsz = nallocx(psz, 0) + 1; + + /* Create tcaches. */ + for (i = 0; i < NTCACHES; i++) { + sz = sizeof(unsigned); + assert_d_eq(mallctl("tcache.create", &tis[i], &sz, NULL, 0), 0, + "Unexpected mallctl() failure, i=%u", i); + } + + /* Exercise tcache ID recycling. */ + for (i = 0; i < NTCACHES; i++) { + assert_d_eq(mallctl("tcache.destroy", NULL, NULL, &tis[i], + sizeof(unsigned)), 0, "Unexpected mallctl() failure, i=%u", + i); + } + for (i = 0; i < NTCACHES; i++) { + sz = sizeof(unsigned); + assert_d_eq(mallctl("tcache.create", &tis[i], &sz, NULL, 0), 0, + "Unexpected mallctl() failure, i=%u", i); + } + + /* Flush empty tcaches. */ + for (i = 0; i < NTCACHES; i++) { + assert_d_eq(mallctl("tcache.flush", NULL, NULL, &tis[i], + sizeof(unsigned)), 0, "Unexpected mallctl() failure, i=%u", + i); + } + + /* Cache some allocations. */ + for (i = 0; i < NTCACHES; i++) { + ps[i] = mallocx(psz, MALLOCX_TCACHE(tis[i])); + assert_ptr_not_null(ps[i], "Unexpected mallocx() failure, i=%u", + i); + dallocx(ps[i], MALLOCX_TCACHE(tis[i])); + + qs[i] = mallocx(qsz, MALLOCX_TCACHE(tis[i])); + assert_ptr_not_null(qs[i], "Unexpected mallocx() failure, i=%u", + i); + dallocx(qs[i], MALLOCX_TCACHE(tis[i])); + } + + /* Verify that tcaches allocate cached regions. */ + for (i = 0; i < NTCACHES; i++) { + void *p0 = ps[i]; + ps[i] = mallocx(psz, MALLOCX_TCACHE(tis[i])); + assert_ptr_not_null(ps[i], "Unexpected mallocx() failure, i=%u", + i); + assert_ptr_eq(ps[i], p0, + "Expected mallocx() to allocate cached region, i=%u", i); + } + + /* Verify that reallocation uses cached regions. */ + for (i = 0; i < NTCACHES; i++) { + void *q0 = qs[i]; + qs[i] = rallocx(ps[i], qsz, MALLOCX_TCACHE(tis[i])); + assert_ptr_not_null(qs[i], "Unexpected rallocx() failure, i=%u", + i); + assert_ptr_eq(qs[i], q0, + "Expected rallocx() to allocate cached region, i=%u", i); + /* Avoid undefined behavior in case of test failure. */ + if (qs[i] == NULL) + qs[i] = ps[i]; + } + for (i = 0; i < NTCACHES; i++) + dallocx(qs[i], MALLOCX_TCACHE(tis[i])); + + /* Flush some non-empty tcaches. */ + for (i = 0; i < NTCACHES/2; i++) { + assert_d_eq(mallctl("tcache.flush", NULL, NULL, &tis[i], + sizeof(unsigned)), 0, "Unexpected mallctl() failure, i=%u", + i); + } + + /* Destroy tcaches. */ + for (i = 0; i < NTCACHES; i++) { + assert_d_eq(mallctl("tcache.destroy", NULL, NULL, &tis[i], + sizeof(unsigned)), 0, "Unexpected mallctl() failure, i=%u", + i); + } +} +TEST_END + +TEST_BEGIN(test_thread_arena) +{ + unsigned arena_old, arena_new, narenas; + size_t sz = sizeof(unsigned); + + assert_d_eq(mallctl("arenas.narenas", &narenas, &sz, NULL, 0), 0, + "Unexpected mallctl() failure"); + assert_u_eq(narenas, opt_narenas, "Number of arenas incorrect"); + arena_new = narenas - 1; + assert_d_eq(mallctl("thread.arena", &arena_old, &sz, &arena_new, + sizeof(unsigned)), 0, "Unexpected mallctl() failure"); + arena_new = 0; + assert_d_eq(mallctl("thread.arena", &arena_old, &sz, &arena_new, + sizeof(unsigned)), 0, "Unexpected mallctl() failure"); +} +TEST_END + +TEST_BEGIN(test_arena_i_lg_dirty_mult) +{ + ssize_t lg_dirty_mult, orig_lg_dirty_mult, prev_lg_dirty_mult; + size_t sz = sizeof(ssize_t); + + assert_d_eq(mallctl("arena.0.lg_dirty_mult", &orig_lg_dirty_mult, &sz, + NULL, 0), 0, "Unexpected mallctl() failure"); + + lg_dirty_mult = -2; + assert_d_eq(mallctl("arena.0.lg_dirty_mult", NULL, NULL, + &lg_dirty_mult, sizeof(ssize_t)), EFAULT, + "Unexpected mallctl() success"); + + lg_dirty_mult = (sizeof(size_t) << 3); + assert_d_eq(mallctl("arena.0.lg_dirty_mult", NULL, NULL, + &lg_dirty_mult, sizeof(ssize_t)), EFAULT, + "Unexpected mallctl() success"); + + for (prev_lg_dirty_mult = orig_lg_dirty_mult, lg_dirty_mult = -1; + lg_dirty_mult < (ssize_t)(sizeof(size_t) << 3); prev_lg_dirty_mult + = lg_dirty_mult, lg_dirty_mult++) { + ssize_t old_lg_dirty_mult; + + assert_d_eq(mallctl("arena.0.lg_dirty_mult", &old_lg_dirty_mult, + &sz, &lg_dirty_mult, sizeof(ssize_t)), 0, + "Unexpected mallctl() failure"); + assert_zd_eq(old_lg_dirty_mult, prev_lg_dirty_mult, + "Unexpected old arena.0.lg_dirty_mult"); + } +} +TEST_END + +TEST_BEGIN(test_arena_i_purge) +{ + unsigned narenas; + size_t sz = sizeof(unsigned); + size_t mib[3]; + size_t miblen = 3; + + assert_d_eq(mallctl("arena.0.purge", NULL, NULL, NULL, 0), 0, + "Unexpected mallctl() failure"); + + assert_d_eq(mallctl("arenas.narenas", &narenas, &sz, NULL, 0), 0, + "Unexpected mallctl() failure"); + assert_d_eq(mallctlnametomib("arena.0.purge", mib, &miblen), 0, + "Unexpected mallctlnametomib() failure"); + mib[1] = narenas; + assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, NULL, 0), 0, + "Unexpected mallctlbymib() failure"); +} +TEST_END + +TEST_BEGIN(test_arena_i_dss) +{ + const char *dss_prec_old, *dss_prec_new; + size_t sz = sizeof(dss_prec_old); + size_t mib[3]; + size_t miblen; + + miblen = sizeof(mib)/sizeof(size_t); + assert_d_eq(mallctlnametomib("arena.0.dss", mib, &miblen), 0, + "Unexpected mallctlnametomib() error"); + + dss_prec_new = "disabled"; + assert_d_eq(mallctlbymib(mib, miblen, &dss_prec_old, &sz, &dss_prec_new, + sizeof(dss_prec_new)), 0, "Unexpected mallctl() failure"); + assert_str_ne(dss_prec_old, "primary", + "Unexpected default for dss precedence"); + + assert_d_eq(mallctlbymib(mib, miblen, &dss_prec_new, &sz, &dss_prec_old, + sizeof(dss_prec_old)), 0, "Unexpected mallctl() failure"); + + assert_d_eq(mallctlbymib(mib, miblen, &dss_prec_old, &sz, NULL, 0), 0, + "Unexpected mallctl() failure"); + assert_str_ne(dss_prec_old, "primary", + "Unexpected value for dss precedence"); + + mib[1] = narenas_total_get(); + dss_prec_new = "disabled"; + assert_d_eq(mallctlbymib(mib, miblen, &dss_prec_old, &sz, &dss_prec_new, + sizeof(dss_prec_new)), 0, "Unexpected mallctl() failure"); + assert_str_ne(dss_prec_old, "primary", + "Unexpected default for dss precedence"); + + assert_d_eq(mallctlbymib(mib, miblen, &dss_prec_new, &sz, &dss_prec_old, + sizeof(dss_prec_new)), 0, "Unexpected mallctl() failure"); + + assert_d_eq(mallctlbymib(mib, miblen, &dss_prec_old, &sz, NULL, 0), 0, + "Unexpected mallctl() failure"); + assert_str_ne(dss_prec_old, "primary", + "Unexpected value for dss precedence"); +} +TEST_END + +TEST_BEGIN(test_arenas_initialized) +{ + unsigned narenas; + size_t sz = sizeof(narenas); + + assert_d_eq(mallctl("arenas.narenas", &narenas, &sz, NULL, 0), 0, + "Unexpected mallctl() failure"); + { + VARIABLE_ARRAY(bool, initialized, narenas); + + sz = narenas * sizeof(bool); + assert_d_eq(mallctl("arenas.initialized", initialized, &sz, + NULL, 0), 0, "Unexpected mallctl() failure"); + } +} +TEST_END + +TEST_BEGIN(test_arenas_lg_dirty_mult) +{ + ssize_t lg_dirty_mult, orig_lg_dirty_mult, prev_lg_dirty_mult; + size_t sz = sizeof(ssize_t); + + assert_d_eq(mallctl("arenas.lg_dirty_mult", &orig_lg_dirty_mult, &sz, + NULL, 0), 0, "Unexpected mallctl() failure"); + + lg_dirty_mult = -2; + assert_d_eq(mallctl("arenas.lg_dirty_mult", NULL, NULL, + &lg_dirty_mult, sizeof(ssize_t)), EFAULT, + "Unexpected mallctl() success"); + + lg_dirty_mult = (sizeof(size_t) << 3); + assert_d_eq(mallctl("arenas.lg_dirty_mult", NULL, NULL, + &lg_dirty_mult, sizeof(ssize_t)), EFAULT, + "Unexpected mallctl() success"); + + for (prev_lg_dirty_mult = orig_lg_dirty_mult, lg_dirty_mult = -1; + lg_dirty_mult < (ssize_t)(sizeof(size_t) << 3); prev_lg_dirty_mult = + lg_dirty_mult, lg_dirty_mult++) { + ssize_t old_lg_dirty_mult; + + assert_d_eq(mallctl("arenas.lg_dirty_mult", &old_lg_dirty_mult, + &sz, &lg_dirty_mult, sizeof(ssize_t)), 0, + "Unexpected mallctl() failure"); + assert_zd_eq(old_lg_dirty_mult, prev_lg_dirty_mult, + "Unexpected old arenas.lg_dirty_mult"); + } +} +TEST_END + +TEST_BEGIN(test_arenas_constants) +{ + +#define TEST_ARENAS_CONSTANT(t, name, expected) do { \ + t name; \ + size_t sz = sizeof(t); \ + assert_d_eq(mallctl("arenas."#name, &name, &sz, NULL, 0), 0, \ + "Unexpected mallctl() failure"); \ + assert_zu_eq(name, expected, "Incorrect "#name" size"); \ +} while (0) + + TEST_ARENAS_CONSTANT(size_t, quantum, QUANTUM); + TEST_ARENAS_CONSTANT(size_t, page, PAGE); + TEST_ARENAS_CONSTANT(unsigned, nbins, NBINS); + TEST_ARENAS_CONSTANT(unsigned, nlruns, nlclasses); + TEST_ARENAS_CONSTANT(unsigned, nhchunks, nhclasses); + +#undef TEST_ARENAS_CONSTANT +} +TEST_END + +TEST_BEGIN(test_arenas_bin_constants) +{ + +#define TEST_ARENAS_BIN_CONSTANT(t, name, expected) do { \ + t name; \ + size_t sz = sizeof(t); \ + assert_d_eq(mallctl("arenas.bin.0."#name, &name, &sz, NULL, 0), \ + 0, "Unexpected mallctl() failure"); \ + assert_zu_eq(name, expected, "Incorrect "#name" size"); \ +} while (0) + + TEST_ARENAS_BIN_CONSTANT(size_t, size, arena_bin_info[0].reg_size); + TEST_ARENAS_BIN_CONSTANT(uint32_t, nregs, arena_bin_info[0].nregs); + TEST_ARENAS_BIN_CONSTANT(size_t, run_size, arena_bin_info[0].run_size); + +#undef TEST_ARENAS_BIN_CONSTANT +} +TEST_END + +TEST_BEGIN(test_arenas_lrun_constants) +{ + +#define TEST_ARENAS_LRUN_CONSTANT(t, name, expected) do { \ + t name; \ + size_t sz = sizeof(t); \ + assert_d_eq(mallctl("arenas.lrun.0."#name, &name, &sz, NULL, \ + 0), 0, "Unexpected mallctl() failure"); \ + assert_zu_eq(name, expected, "Incorrect "#name" size"); \ +} while (0) + + TEST_ARENAS_LRUN_CONSTANT(size_t, size, LARGE_MINCLASS); + +#undef TEST_ARENAS_LRUN_CONSTANT +} +TEST_END + +TEST_BEGIN(test_arenas_hchunk_constants) +{ + +#define TEST_ARENAS_HCHUNK_CONSTANT(t, name, expected) do { \ + t name; \ + size_t sz = sizeof(t); \ + assert_d_eq(mallctl("arenas.hchunk.0."#name, &name, &sz, NULL, \ + 0), 0, "Unexpected mallctl() failure"); \ + assert_zu_eq(name, expected, "Incorrect "#name" size"); \ +} while (0) + + TEST_ARENAS_HCHUNK_CONSTANT(size_t, size, chunksize); + +#undef TEST_ARENAS_HCHUNK_CONSTANT +} +TEST_END + +TEST_BEGIN(test_arenas_extend) +{ + unsigned narenas_before, arena, narenas_after; + size_t sz = sizeof(unsigned); + + assert_d_eq(mallctl("arenas.narenas", &narenas_before, &sz, NULL, 0), 0, + "Unexpected mallctl() failure"); + assert_d_eq(mallctl("arenas.extend", &arena, &sz, NULL, 0), 0, + "Unexpected mallctl() failure"); + assert_d_eq(mallctl("arenas.narenas", &narenas_after, &sz, NULL, 0), 0, + "Unexpected mallctl() failure"); + + assert_u_eq(narenas_before+1, narenas_after, + "Unexpected number of arenas before versus after extension"); + assert_u_eq(arena, narenas_after-1, "Unexpected arena index"); +} +TEST_END + +TEST_BEGIN(test_stats_arenas) +{ + +#define TEST_STATS_ARENAS(t, name) do { \ + t name; \ + size_t sz = sizeof(t); \ + assert_d_eq(mallctl("stats.arenas.0."#name, &name, &sz, NULL, \ + 0), 0, "Unexpected mallctl() failure"); \ +} while (0) + + TEST_STATS_ARENAS(const char *, dss); + TEST_STATS_ARENAS(unsigned, nthreads); + TEST_STATS_ARENAS(size_t, pactive); + TEST_STATS_ARENAS(size_t, pdirty); + +#undef TEST_STATS_ARENAS +} +TEST_END + +int +main(void) +{ + + return (test( + test_mallctl_errors, + test_mallctlnametomib_errors, + test_mallctlbymib_errors, + test_mallctl_read_write, + test_mallctlnametomib_short_mib, + test_mallctl_config, + test_mallctl_opt, + test_manpage_example, + test_tcache_none, + test_tcache, + test_thread_arena, + test_arena_i_lg_dirty_mult, + test_arena_i_purge, + test_arena_i_dss, + test_arenas_initialized, + test_arenas_lg_dirty_mult, + test_arenas_constants, + test_arenas_bin_constants, + test_arenas_lrun_constants, + test_arenas_hchunk_constants, + test_arenas_extend, + test_stats_arenas)); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/math.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/math.c new file mode 100644 index 0000000..ebec77a --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/math.c @@ -0,0 +1,394 @@ +#include "test/jemalloc_test.h" + +#define MAX_REL_ERR 1.0e-9 +#define MAX_ABS_ERR 1.0e-9 + +#include + +#ifndef INFINITY +#define INFINITY (DBL_MAX + DBL_MAX) +#endif + +static bool +double_eq_rel(double a, double b, double max_rel_err, double max_abs_err) +{ + double rel_err; + + if (fabs(a - b) < max_abs_err) + return (true); + rel_err = (fabs(b) > fabs(a)) ? fabs((a-b)/b) : fabs((a-b)/a); + return (rel_err < max_rel_err); +} + +static uint64_t +factorial(unsigned x) +{ + uint64_t ret = 1; + unsigned i; + + for (i = 2; i <= x; i++) + ret *= (uint64_t)i; + + return (ret); +} + +TEST_BEGIN(test_ln_gamma_factorial) +{ + unsigned x; + + /* exp(ln_gamma(x)) == (x-1)! for integer x. */ + for (x = 1; x <= 21; x++) { + assert_true(double_eq_rel(exp(ln_gamma(x)), + (double)factorial(x-1), MAX_REL_ERR, MAX_ABS_ERR), + "Incorrect factorial result for x=%u", x); + } +} +TEST_END + +/* Expected ln_gamma([0.0..100.0] increment=0.25). */ +static const double ln_gamma_misc_expected[] = { + INFINITY, + 1.28802252469807743, 0.57236494292470008, 0.20328095143129538, + 0.00000000000000000, -0.09827183642181320, -0.12078223763524518, + -0.08440112102048555, 0.00000000000000000, 0.12487171489239651, + 0.28468287047291918, 0.47521466691493719, 0.69314718055994529, + 0.93580193110872523, 1.20097360234707429, 1.48681557859341718, + 1.79175946922805496, 2.11445692745037128, 2.45373657084244234, + 2.80857141857573644, 3.17805383034794575, 3.56137591038669710, + 3.95781396761871651, 4.36671603662228680, 4.78749174278204581, + 5.21960398699022932, 5.66256205985714178, 6.11591589143154568, + 6.57925121201010121, 7.05218545073853953, 7.53436423675873268, + 8.02545839631598312, 8.52516136106541467, 9.03318691960512332, + 9.54926725730099690, 10.07315123968123949, 10.60460290274525086, + 11.14340011995171231, 11.68933342079726856, 12.24220494005076176, + 12.80182748008146909, 13.36802367147604720, 13.94062521940376342, + 14.51947222506051816, 15.10441257307551943, 15.69530137706046524, + 16.29200047656724237, 16.89437797963419285, 17.50230784587389010, + 18.11566950571089407, 18.73434751193644843, 19.35823122022435427, + 19.98721449566188468, 20.62119544270163018, 21.26007615624470048, + 21.90376249182879320, 22.55216385312342098, 23.20519299513386002, + 23.86276584168908954, 24.52480131594137802, 25.19122118273868338, + 25.86194990184851861, 26.53691449111561340, 27.21604439872720604, + 27.89927138384089389, 28.58652940490193828, 29.27775451504081516, + 29.97288476399884871, 30.67186010608067548, 31.37462231367769050, + 32.08111489594735843, 32.79128302226991565, 33.50507345013689076, + 34.22243445715505317, 34.94331577687681545, 35.66766853819134298, + 36.39544520803305261, 37.12659953718355865, 37.86108650896109395, + 38.59886229060776230, 39.33988418719949465, 40.08411059791735198, + 40.83150097453079752, 41.58201578195490100, 42.33561646075348506, + 43.09226539146988699, 43.85192586067515208, 44.61456202863158893, + 45.38013889847690052, 46.14862228684032885, 46.91997879580877395, + 47.69417578616628361, 48.47118135183522014, 49.25096429545256882, + 50.03349410501914463, 50.81874093156324790, 51.60667556776436982, + 52.39726942748592364, 53.19049452616926743, 53.98632346204390586, + 54.78472939811231157, 55.58568604486942633, 56.38916764371992940, + 57.19514895105859864, 58.00360522298051080, 58.81451220059079787, + 59.62784609588432261, 60.44358357816834371, 61.26170176100199427, + 62.08217818962842927, 62.90499082887649962, 63.73011805151035958, + 64.55753862700632340, 65.38723171073768015, 66.21917683354901385, + 67.05335389170279825, 67.88974313718154008, 68.72832516833013017, + 69.56908092082363737, 70.41199165894616385, 71.25703896716800045, + 72.10420474200799390, 72.95347118416940191, 73.80482079093779646, + 74.65823634883015814, 75.51370092648485866, 76.37119786778275454, + 77.23071078519033961, 78.09222355331530707, 78.95572030266725960, + 79.82118541361435859, 80.68860351052903468, 81.55795945611502873, + 82.42923834590904164, 83.30242550295004378, 84.17750647261028973, + 85.05446701758152983, 85.93329311301090456, 86.81397094178107920, + 87.69648688992882057, 88.58082754219766741, 89.46697967771913795, + 90.35493026581838194, 91.24466646193963015, 92.13617560368709292, + 93.02944520697742803, 93.92446296229978486, 94.82121673107967297, + 95.71969454214321615, 96.61988458827809723, 97.52177522288820910, + 98.42535495673848800, 99.33061245478741341, 100.23753653310367895, + 101.14611615586458981, 102.05634043243354370, 102.96819861451382394, + 103.88168009337621811, 104.79677439715833032, 105.71347118823287303, + 106.63176026064346047, 107.55163153760463501, 108.47307506906540198, + 109.39608102933323153, 110.32063971475740516, 111.24674154146920557, + 112.17437704317786995, 113.10353686902013237, 114.03421178146170689, + 114.96639265424990128, 115.90007047041454769, 116.83523632031698014, + 117.77188139974506953, 118.70999700805310795, 119.64957454634490830, + 120.59060551569974962, 121.53308151543865279, 122.47699424143097247, + 123.42233548443955726, 124.36909712850338394, 125.31727114935689826, + 126.26684961288492559, 127.21782467361175861, 128.17018857322420899, + 129.12393363912724453, 130.07905228303084755, 131.03553699956862033, + 131.99338036494577864, 132.95257503561629164, 133.91311374698926784, + 134.87498931216194364, 135.83819462068046846, 136.80272263732638294, + 137.76856640092901785, 138.73571902320256299, 139.70417368760718091, + 140.67392364823425055, 141.64496222871400732, 142.61728282114600574, + 143.59087888505104047, 144.56574394634486680, 145.54187159633210058, + 146.51925549072063859, 147.49788934865566148, 148.47776695177302031, + 149.45888214327129617, 150.44122882700193600, 151.42480096657754984, + 152.40959258449737490, 153.39559776128982094, 154.38281063467164245, + 155.37122539872302696, 156.36083630307879844, 157.35163765213474107, + 158.34362380426921391, 159.33678917107920370, 160.33112821663092973, + 161.32663545672428995, 162.32330545817117695, 163.32113283808695314, + 164.32011226319519892, 165.32023844914485267, 166.32150615984036790, + 167.32391020678358018, 168.32744544842768164, 169.33210678954270634, + 170.33788918059275375, 171.34478761712384198, 172.35279713916281707, + 173.36191283062726143, 174.37212981874515094, 175.38344327348534080, + 176.39584840699734514, 177.40934047306160437, 178.42391476654847793, + 179.43956662288721304, 180.45629141754378111, 181.47408456550741107, + 182.49294152078630304, 183.51285777591152737, 184.53382886144947861, + 185.55585034552262869, 186.57891783333786861, 187.60302696672312095, + 188.62817342367162610, 189.65435291789341932, 190.68156119837468054, + 191.70979404894376330, 192.73904728784492590, 193.76931676731820176, + 194.80059837318714244, 195.83288802445184729, 196.86618167288995096, + 197.90047530266301123, 198.93576492992946214, 199.97204660246373464, + 201.00931639928148797, 202.04757043027063901, 203.08680483582807597, + 204.12701578650228385, 205.16819948264117102, 206.21035215404597807, + 207.25347005962987623, 208.29754948708190909, 209.34258675253678916, + 210.38857820024875878, 211.43552020227099320, 212.48340915813977858, + 213.53224149456323744, 214.58201366511514152, 215.63272214993284592, + 216.68436345542014010, 217.73693411395422004, 218.79043068359703739, + 219.84484974781133815, 220.90018791517996988, 221.95644181913033322, + 223.01360811766215875, 224.07168349307951871, 225.13066465172661879, + 226.19054832372759734, 227.25133126272962159, 228.31301024565024704, + 229.37558207242807384, 230.43904356577689896, 231.50339157094342113, + 232.56862295546847008, 233.63473460895144740, 234.70172344281823484, + 235.76958639009222907, 236.83832040516844586, 237.90792246359117712, + 238.97838956183431947, 240.04971871708477238, 241.12190696702904802, + 242.19495136964280846, 243.26884900298270509, 244.34359696498191283, + 245.41919237324782443, 246.49563236486270057, 247.57291409618682110, + 248.65103474266476269, 249.72999149863338175, 250.80978157713354904, + 251.89040220972316320, 252.97185064629374551, 254.05412415488834199, + 255.13722002152300661, 256.22113555000953511, 257.30586806178126835, + 258.39141489572085675, 259.47777340799029844, 260.56494097186322279, + 261.65291497755913497, 262.74169283208021852, 263.83127195904967266, + 264.92164979855277807, 266.01282380697938379, 267.10479145686849733, + 268.19755023675537586, 269.29109765101975427, 270.38543121973674488, + 271.48054847852881721, 272.57644697842033565, 273.67312428569374561, + 274.77057798174683967, 275.86880566295326389, 276.96780494052313770, + 278.06757344036617496, 279.16810880295668085, 280.26940868320008349, + 281.37147075030043197, 282.47429268763045229, 283.57787219260217171, + 284.68220697654078322, 285.78729476455760050, 286.89313329542699194, + 287.99972032146268930, 289.10705360839756395, 290.21513093526289140, + 291.32395009427028754, 292.43350889069523646, 293.54380514276073200, + 294.65483668152336350, 295.76660135076059532, 296.87909700685889902, + 297.99232151870342022, 299.10627276756946458, 300.22094864701409733, + 301.33634706277030091, 302.45246593264130297, 303.56930318639643929, + 304.68685676566872189, 305.80512462385280514, 306.92410472600477078, + 308.04379504874236773, 309.16419358014690033, 310.28529831966631036, + 311.40710727801865687, 312.52961847709792664, 313.65282994987899201, + 314.77673974032603610, 315.90134590329950015, 317.02664650446632777, + 318.15263962020929966, 319.27932333753892635, 320.40669575400545455, + 321.53475497761127144, 322.66349912672620803, 323.79292633000159185, + 324.92303472628691452, 326.05382246454587403, 327.18528770377525916, + 328.31742861292224234, 329.45024337080525356, 330.58373016603343331, + 331.71788719692847280, 332.85271267144611329, 333.98820480709991898, + 335.12436183088397001, 336.26118197919845443, 337.39866349777429377, + 338.53680464159958774, 339.67560367484657036, 340.81505887079896411, + 341.95516851178109619, 343.09593088908627578, 344.23734430290727460, + 345.37940706226686416, 346.52211748494903532, 347.66547389743118401, + 348.80947463481720661, 349.95411804077025408, 351.09940246744753267, + 352.24532627543504759, 353.39188783368263103, 354.53908551944078908, + 355.68691771819692349, 356.83538282361303118, 357.98447923746385868, + 359.13420536957539753 +}; + +TEST_BEGIN(test_ln_gamma_misc) +{ + unsigned i; + + for (i = 1; i < sizeof(ln_gamma_misc_expected)/sizeof(double); i++) { + double x = (double)i * 0.25; + assert_true(double_eq_rel(ln_gamma(x), + ln_gamma_misc_expected[i], MAX_REL_ERR, MAX_ABS_ERR), + "Incorrect ln_gamma result for i=%u", i); + } +} +TEST_END + +/* Expected pt_norm([0.01..0.99] increment=0.01). */ +static const double pt_norm_expected[] = { + -INFINITY, + -2.32634787404084076, -2.05374891063182252, -1.88079360815125085, + -1.75068607125216946, -1.64485362695147264, -1.55477359459685305, + -1.47579102817917063, -1.40507156030963221, -1.34075503369021654, + -1.28155156554460081, -1.22652812003661049, -1.17498679206608991, + -1.12639112903880045, -1.08031934081495606, -1.03643338949378938, + -0.99445788320975281, -0.95416525314619416, -0.91536508784281390, + -0.87789629505122846, -0.84162123357291418, -0.80642124701824025, + -0.77219321418868492, -0.73884684918521371, -0.70630256284008752, + -0.67448975019608171, -0.64334540539291685, -0.61281299101662701, + -0.58284150727121620, -0.55338471955567281, -0.52440051270804067, + -0.49585034734745320, -0.46769879911450812, -0.43991316567323380, + -0.41246312944140462, -0.38532046640756751, -0.35845879325119373, + -0.33185334643681652, -0.30548078809939738, -0.27931903444745404, + -0.25334710313579978, -0.22754497664114931, -0.20189347914185077, + -0.17637416478086135, -0.15096921549677725, -0.12566134685507399, + -0.10043372051146975, -0.07526986209982976, -0.05015358346473352, + -0.02506890825871106, 0.00000000000000000, 0.02506890825871106, + 0.05015358346473366, 0.07526986209982990, 0.10043372051146990, + 0.12566134685507413, 0.15096921549677739, 0.17637416478086146, + 0.20189347914185105, 0.22754497664114931, 0.25334710313579978, + 0.27931903444745404, 0.30548078809939738, 0.33185334643681652, + 0.35845879325119373, 0.38532046640756762, 0.41246312944140484, + 0.43991316567323391, 0.46769879911450835, 0.49585034734745348, + 0.52440051270804111, 0.55338471955567303, 0.58284150727121620, + 0.61281299101662701, 0.64334540539291685, 0.67448975019608171, + 0.70630256284008752, 0.73884684918521371, 0.77219321418868492, + 0.80642124701824036, 0.84162123357291441, 0.87789629505122879, + 0.91536508784281423, 0.95416525314619460, 0.99445788320975348, + 1.03643338949378938, 1.08031934081495606, 1.12639112903880045, + 1.17498679206608991, 1.22652812003661049, 1.28155156554460081, + 1.34075503369021654, 1.40507156030963265, 1.47579102817917085, + 1.55477359459685394, 1.64485362695147308, 1.75068607125217102, + 1.88079360815125041, 2.05374891063182208, 2.32634787404084076 +}; + +TEST_BEGIN(test_pt_norm) +{ + unsigned i; + + for (i = 1; i < sizeof(pt_norm_expected)/sizeof(double); i++) { + double p = (double)i * 0.01; + assert_true(double_eq_rel(pt_norm(p), pt_norm_expected[i], + MAX_REL_ERR, MAX_ABS_ERR), + "Incorrect pt_norm result for i=%u", i); + } +} +TEST_END + +/* + * Expected pt_chi2(p=[0.01..0.99] increment=0.07, + * df={0.1, 1.1, 10.1, 100.1, 1000.1}). + */ +static const double pt_chi2_df[] = {0.1, 1.1, 10.1, 100.1, 1000.1}; +static const double pt_chi2_expected[] = { + 1.168926411457320e-40, 1.347680397072034e-22, 3.886980416666260e-17, + 8.245951724356564e-14, 2.068936347497604e-11, 1.562561743309233e-09, + 5.459543043426564e-08, 1.114775688149252e-06, 1.532101202364371e-05, + 1.553884683726585e-04, 1.239396954915939e-03, 8.153872320255721e-03, + 4.631183739647523e-02, 2.473187311701327e-01, 2.175254800183617e+00, + + 0.0003729887888876379, 0.0164409238228929513, 0.0521523015190650113, + 0.1064701372271216612, 0.1800913735793082115, 0.2748704281195626931, + 0.3939246282787986497, 0.5420727552260817816, 0.7267265822221973259, + 0.9596554296000253670, 1.2607440376386165326, 1.6671185084541604304, + 2.2604828984738705167, 3.2868613342148607082, 6.9298574921692139839, + + 2.606673548632508, 4.602913725294877, 5.646152813924212, + 6.488971315540869, 7.249823275816285, 7.977314231410841, + 8.700354939944047, 9.441728024225892, 10.224338321374127, + 11.076435368801061, 12.039320937038386, 13.183878752697167, + 14.657791935084575, 16.885728216339373, 23.361991680031817, + + 70.14844087392152, 80.92379498849355, 85.53325420085891, + 88.94433120715347, 91.83732712857017, 94.46719943606301, + 96.96896479994635, 99.43412843510363, 101.94074719829733, + 104.57228644307247, 107.43900093448734, 110.71844673417287, + 114.76616819871325, 120.57422505959563, 135.92318818757556, + + 899.0072447849649, 937.9271278858220, 953.8117189560207, + 965.3079371501154, 974.8974061207954, 983.4936235182347, + 991.5691170518946, 999.4334123954690, 1007.3391826856553, + 1015.5445154999951, 1024.3777075619569, 1034.3538789836223, + 1046.4872561869577, 1063.5717461999654, 1107.0741966053859 +}; + +TEST_BEGIN(test_pt_chi2) +{ + unsigned i, j; + unsigned e = 0; + + for (i = 0; i < sizeof(pt_chi2_df)/sizeof(double); i++) { + double df = pt_chi2_df[i]; + double ln_gamma_df = ln_gamma(df * 0.5); + for (j = 1; j < 100; j += 7) { + double p = (double)j * 0.01; + assert_true(double_eq_rel(pt_chi2(p, df, ln_gamma_df), + pt_chi2_expected[e], MAX_REL_ERR, MAX_ABS_ERR), + "Incorrect pt_chi2 result for i=%u, j=%u", i, j); + e++; + } + } +} +TEST_END + +/* + * Expected pt_gamma(p=[0.1..0.99] increment=0.07, + * shape=[0.5..3.0] increment=0.5). + */ +static const double pt_gamma_shape[] = {0.5, 1.0, 1.5, 2.0, 2.5, 3.0}; +static const double pt_gamma_expected[] = { + 7.854392895485103e-05, 5.043466107888016e-03, 1.788288957794883e-02, + 3.900956150232906e-02, 6.913847560638034e-02, 1.093710833465766e-01, + 1.613412523825817e-01, 2.274682115597864e-01, 3.114117323127083e-01, + 4.189466220207417e-01, 5.598106789059246e-01, 7.521856146202706e-01, + 1.036125427911119e+00, 1.532450860038180e+00, 3.317448300510606e+00, + + 0.01005033585350144, 0.08338160893905107, 0.16251892949777497, + 0.24846135929849966, 0.34249030894677596, 0.44628710262841947, + 0.56211891815354142, 0.69314718055994529, 0.84397007029452920, + 1.02165124753198167, 1.23787435600161766, 1.51412773262977574, + 1.89711998488588196, 2.52572864430825783, 4.60517018598809091, + + 0.05741590094955853, 0.24747378084860744, 0.39888572212236084, + 0.54394139997444901, 0.69048812513915159, 0.84311389861296104, + 1.00580622221479898, 1.18298694218766931, 1.38038096305861213, + 1.60627736383027453, 1.87396970522337947, 2.20749220408081070, + 2.65852391865854942, 3.37934630984842244, 5.67243336507218476, + + 0.1485547402532659, 0.4657458011640391, 0.6832386130709406, + 0.8794297834672100, 1.0700752852474524, 1.2629614217350744, + 1.4638400448580779, 1.6783469900166610, 1.9132338090606940, + 2.1778589228618777, 2.4868823970010991, 2.8664695666264195, + 3.3724415436062114, 4.1682658512758071, 6.6383520679938108, + + 0.2771490383641385, 0.7195001279643727, 0.9969081732265243, + 1.2383497880608061, 1.4675206597269927, 1.6953064251816552, + 1.9291243435606809, 2.1757300955477641, 2.4428032131216391, + 2.7406534569230616, 3.0851445039665513, 3.5043101122033367, + 4.0575997065264637, 4.9182956424675286, 7.5431362346944937, + + 0.4360451650782932, 0.9983600902486267, 1.3306365880734528, + 1.6129750834753802, 1.8767241606994294, 2.1357032436097660, + 2.3988853336865565, 2.6740603137235603, 2.9697561737517959, + 3.2971457713883265, 3.6731795898504660, 4.1275751617770631, + 4.7230515633946677, 5.6417477865306020, 8.4059469148854635 +}; + +TEST_BEGIN(test_pt_gamma_shape) +{ + unsigned i, j; + unsigned e = 0; + + for (i = 0; i < sizeof(pt_gamma_shape)/sizeof(double); i++) { + double shape = pt_gamma_shape[i]; + double ln_gamma_shape = ln_gamma(shape); + for (j = 1; j < 100; j += 7) { + double p = (double)j * 0.01; + assert_true(double_eq_rel(pt_gamma(p, shape, 1.0, + ln_gamma_shape), pt_gamma_expected[e], MAX_REL_ERR, + MAX_ABS_ERR), + "Incorrect pt_gamma result for i=%u, j=%u", i, j); + e++; + } + } +} +TEST_END + +TEST_BEGIN(test_pt_gamma_scale) +{ + double shape = 1.0; + double ln_gamma_shape = ln_gamma(shape); + + assert_true(double_eq_rel( + pt_gamma(0.5, shape, 1.0, ln_gamma_shape) * 10.0, + pt_gamma(0.5, shape, 10.0, ln_gamma_shape), MAX_REL_ERR, + MAX_ABS_ERR), + "Scale should be trivially equivalent to external multiplication"); +} +TEST_END + +int +main(void) +{ + + return (test( + test_ln_gamma_factorial, + test_ln_gamma_misc, + test_pt_norm, + test_pt_chi2, + test_pt_gamma_shape, + test_pt_gamma_scale)); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/mq.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/mq.c new file mode 100644 index 0000000..bde2a48 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/mq.c @@ -0,0 +1,93 @@ +#include "test/jemalloc_test.h" + +#define NSENDERS 3 +#define NMSGS 100000 + +typedef struct mq_msg_s mq_msg_t; +struct mq_msg_s { + mq_msg(mq_msg_t) link; +}; +mq_gen(static, mq_, mq_t, mq_msg_t, link) + +TEST_BEGIN(test_mq_basic) +{ + mq_t mq; + mq_msg_t msg; + + assert_false(mq_init(&mq), "Unexpected mq_init() failure"); + assert_u_eq(mq_count(&mq), 0, "mq should be empty"); + assert_ptr_null(mq_tryget(&mq), + "mq_tryget() should fail when the queue is empty"); + + mq_put(&mq, &msg); + assert_u_eq(mq_count(&mq), 1, "mq should contain one message"); + assert_ptr_eq(mq_tryget(&mq), &msg, "mq_tryget() should return msg"); + + mq_put(&mq, &msg); + assert_ptr_eq(mq_get(&mq), &msg, "mq_get() should return msg"); + + mq_fini(&mq); +} +TEST_END + +static void * +thd_receiver_start(void *arg) +{ + mq_t *mq = (mq_t *)arg; + unsigned i; + + for (i = 0; i < (NSENDERS * NMSGS); i++) { + mq_msg_t *msg = mq_get(mq); + assert_ptr_not_null(msg, "mq_get() should never return NULL"); + dallocx(msg, 0); + } + return (NULL); +} + +static void * +thd_sender_start(void *arg) +{ + mq_t *mq = (mq_t *)arg; + unsigned i; + + for (i = 0; i < NMSGS; i++) { + mq_msg_t *msg; + void *p; + p = mallocx(sizeof(mq_msg_t), 0); + assert_ptr_not_null(p, "Unexpected mallocx() failure"); + msg = (mq_msg_t *)p; + mq_put(mq, msg); + } + return (NULL); +} + +TEST_BEGIN(test_mq_threaded) +{ + mq_t mq; + thd_t receiver; + thd_t senders[NSENDERS]; + unsigned i; + + assert_false(mq_init(&mq), "Unexpected mq_init() failure"); + + thd_create(&receiver, thd_receiver_start, (void *)&mq); + for (i = 0; i < NSENDERS; i++) + thd_create(&senders[i], thd_sender_start, (void *)&mq); + + thd_join(receiver, NULL); + for (i = 0; i < NSENDERS; i++) + thd_join(senders[i], NULL); + + mq_fini(&mq); +} +TEST_END + +int +main(void) +{ + + return (test( + test_mq_basic, + test_mq_threaded)); +} + diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/mtx.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/mtx.c new file mode 100644 index 0000000..96ff694 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/mtx.c @@ -0,0 +1,60 @@ +#include "test/jemalloc_test.h" + +#define NTHREADS 2 +#define NINCRS 2000000 + +TEST_BEGIN(test_mtx_basic) +{ + mtx_t mtx; + + assert_false(mtx_init(&mtx), "Unexpected mtx_init() failure"); + mtx_lock(&mtx); + mtx_unlock(&mtx); + mtx_fini(&mtx); +} +TEST_END + +typedef struct { + mtx_t mtx; + unsigned x; +} thd_start_arg_t; + +static void * +thd_start(void *varg) +{ + thd_start_arg_t *arg = (thd_start_arg_t *)varg; + unsigned i; + + for (i = 0; i < NINCRS; i++) { + mtx_lock(&arg->mtx); + arg->x++; + mtx_unlock(&arg->mtx); + } + return (NULL); +} + +TEST_BEGIN(test_mtx_race) +{ + thd_start_arg_t arg; + thd_t thds[NTHREADS]; + unsigned i; + + assert_false(mtx_init(&arg.mtx), "Unexpected mtx_init() failure"); + arg.x = 0; + for (i = 0; i < NTHREADS; i++) + thd_create(&thds[i], thd_start, (void *)&arg); + for (i = 0; i < NTHREADS; i++) + thd_join(thds[i], NULL); + assert_u_eq(arg.x, NTHREADS * NINCRS, + "Race-related counter corruption"); +} +TEST_END + +int +main(void) +{ + + return (test( + test_mtx_basic, + test_mtx_race)); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/prof_accum.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/prof_accum.c new file mode 100644 index 0000000..fd229e0 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/prof_accum.c @@ -0,0 +1,91 @@ +#include "test/jemalloc_test.h" + +#define NTHREADS 4 +#define NALLOCS_PER_THREAD 50 +#define DUMP_INTERVAL 1 +#define BT_COUNT_CHECK_INTERVAL 5 + +#ifdef JEMALLOC_PROF +const char *malloc_conf = + "prof:true,prof_accum:true,prof_active:false,lg_prof_sample:0"; +#endif + +static int +prof_dump_open_intercept(bool propagate_err, const char *filename) +{ + int fd; + + fd = open("/dev/null", O_WRONLY); + assert_d_ne(fd, -1, "Unexpected open() failure"); + + return (fd); +} + +static void * +alloc_from_permuted_backtrace(unsigned thd_ind, unsigned iteration) +{ + + return (btalloc(1, thd_ind*NALLOCS_PER_THREAD + iteration)); +} + +static void * +thd_start(void *varg) +{ + unsigned thd_ind = *(unsigned *)varg; + size_t bt_count_prev, bt_count; + unsigned i_prev, i; + + i_prev = 0; + bt_count_prev = 0; + for (i = 0; i < NALLOCS_PER_THREAD; i++) { + void *p = alloc_from_permuted_backtrace(thd_ind, i); + dallocx(p, 0); + if (i % DUMP_INTERVAL == 0) { + assert_d_eq(mallctl("prof.dump", NULL, NULL, NULL, 0), + 0, "Unexpected error while dumping heap profile"); + } + + if (i % BT_COUNT_CHECK_INTERVAL == 0 || + i+1 == NALLOCS_PER_THREAD) { + bt_count = prof_bt_count(); + assert_zu_le(bt_count_prev+(i-i_prev), bt_count, + "Expected larger backtrace count increase"); + i_prev = i; + bt_count_prev = bt_count; + } + } + + return (NULL); +} + +TEST_BEGIN(test_idump) +{ + bool active; + thd_t thds[NTHREADS]; + unsigned thd_args[NTHREADS]; + unsigned i; + + test_skip_if(!config_prof); + + active = true; + assert_d_eq(mallctl("prof.active", NULL, NULL, &active, sizeof(active)), + 0, "Unexpected mallctl failure while activating profiling"); + + prof_dump_open = prof_dump_open_intercept; + + for (i = 0; i < NTHREADS; i++) { + thd_args[i] = i; + thd_create(&thds[i], thd_start, (void *)&thd_args[i]); + } + for (i = 0; i < NTHREADS; i++) + thd_join(thds[i], NULL); +} +TEST_END + +int +main(void) +{ + + return (test( + test_idump)); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/prof_active.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/prof_active.c new file mode 100644 index 0000000..8149095 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/prof_active.c @@ -0,0 +1,136 @@ +#include "test/jemalloc_test.h" + +#ifdef JEMALLOC_PROF +const char *malloc_conf = + "prof:true,prof_thread_active_init:false,lg_prof_sample:0"; +#endif + +static void +mallctl_bool_get(const char *name, bool expected, const char *func, int line) +{ + bool old; + size_t sz; + + sz = sizeof(old); + assert_d_eq(mallctl(name, &old, &sz, NULL, 0), 0, + "%s():%d: Unexpected mallctl failure reading %s", func, line, name); + assert_b_eq(old, expected, "%s():%d: Unexpected %s value", func, line, + name); +} + +static void +mallctl_bool_set(const char *name, bool old_expected, bool val_new, + const char *func, int line) +{ + bool old; + size_t sz; + + sz = sizeof(old); + assert_d_eq(mallctl(name, &old, &sz, &val_new, sizeof(val_new)), 0, + "%s():%d: Unexpected mallctl failure reading/writing %s", func, + line, name); + assert_b_eq(old, old_expected, "%s():%d: Unexpected %s value", func, + line, name); +} + +static void +mallctl_prof_active_get_impl(bool prof_active_old_expected, const char *func, + int line) +{ + + mallctl_bool_get("prof.active", prof_active_old_expected, func, line); +} +#define mallctl_prof_active_get(a) \ + mallctl_prof_active_get_impl(a, __func__, __LINE__) + +static void +mallctl_prof_active_set_impl(bool prof_active_old_expected, + bool prof_active_new, const char *func, int line) +{ + + mallctl_bool_set("prof.active", prof_active_old_expected, + prof_active_new, func, line); +} +#define mallctl_prof_active_set(a, b) \ + mallctl_prof_active_set_impl(a, b, __func__, __LINE__) + +static void +mallctl_thread_prof_active_get_impl(bool thread_prof_active_old_expected, + const char *func, int line) +{ + + mallctl_bool_get("thread.prof.active", thread_prof_active_old_expected, + func, line); +} +#define mallctl_thread_prof_active_get(a) \ + mallctl_thread_prof_active_get_impl(a, __func__, __LINE__) + +static void +mallctl_thread_prof_active_set_impl(bool thread_prof_active_old_expected, + bool thread_prof_active_new, const char *func, int line) +{ + + mallctl_bool_set("thread.prof.active", thread_prof_active_old_expected, + thread_prof_active_new, func, line); +} +#define mallctl_thread_prof_active_set(a, b) \ + mallctl_thread_prof_active_set_impl(a, b, __func__, __LINE__) + +static void +prof_sampling_probe_impl(bool expect_sample, const char *func, int line) +{ + void *p; + size_t expected_backtraces = expect_sample ? 1 : 0; + + assert_zu_eq(prof_bt_count(), 0, "%s():%d: Expected 0 backtraces", func, + line); + p = mallocx(1, 0); + assert_ptr_not_null(p, "Unexpected mallocx() failure"); + assert_zu_eq(prof_bt_count(), expected_backtraces, + "%s():%d: Unexpected backtrace count", func, line); + dallocx(p, 0); +} +#define prof_sampling_probe(a) \ + prof_sampling_probe_impl(a, __func__, __LINE__) + +TEST_BEGIN(test_prof_active) +{ + + test_skip_if(!config_prof); + + mallctl_prof_active_get(true); + mallctl_thread_prof_active_get(false); + + mallctl_prof_active_set(true, true); + mallctl_thread_prof_active_set(false, false); + /* prof.active, !thread.prof.active. */ + prof_sampling_probe(false); + + mallctl_prof_active_set(true, false); + mallctl_thread_prof_active_set(false, false); + /* !prof.active, !thread.prof.active. */ + prof_sampling_probe(false); + + mallctl_prof_active_set(false, false); + mallctl_thread_prof_active_set(false, true); + /* !prof.active, thread.prof.active. */ + prof_sampling_probe(false); + + mallctl_prof_active_set(false, true); + mallctl_thread_prof_active_set(true, true); + /* prof.active, thread.prof.active. */ + prof_sampling_probe(true); + + /* Restore settings. */ + mallctl_prof_active_set(true, true); + mallctl_thread_prof_active_set(true, false); +} +TEST_END + +int +main(void) +{ + + return (test( + test_prof_active)); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/prof_gdump.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/prof_gdump.c new file mode 100644 index 0000000..a0e6ee9 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/prof_gdump.c @@ -0,0 +1,81 @@ +#include "test/jemalloc_test.h" + +#ifdef JEMALLOC_PROF +const char *malloc_conf = "prof:true,prof_active:false,prof_gdump:true"; +#endif + +static bool did_prof_dump_open; + +static int +prof_dump_open_intercept(bool propagate_err, const char *filename) +{ + int fd; + + did_prof_dump_open = true; + + fd = open("/dev/null", O_WRONLY); + assert_d_ne(fd, -1, "Unexpected open() failure"); + + return (fd); +} + +TEST_BEGIN(test_gdump) +{ + bool active, gdump, gdump_old; + void *p, *q, *r, *s; + size_t sz; + + test_skip_if(!config_prof); + + active = true; + assert_d_eq(mallctl("prof.active", NULL, NULL, &active, sizeof(active)), + 0, "Unexpected mallctl failure while activating profiling"); + + prof_dump_open = prof_dump_open_intercept; + + did_prof_dump_open = false; + p = mallocx(chunksize, 0); + assert_ptr_not_null(p, "Unexpected mallocx() failure"); + assert_true(did_prof_dump_open, "Expected a profile dump"); + + did_prof_dump_open = false; + q = mallocx(chunksize, 0); + assert_ptr_not_null(q, "Unexpected mallocx() failure"); + assert_true(did_prof_dump_open, "Expected a profile dump"); + + gdump = false; + sz = sizeof(gdump_old); + assert_d_eq(mallctl("prof.gdump", &gdump_old, &sz, &gdump, + sizeof(gdump)), 0, + "Unexpected mallctl failure while disabling prof.gdump"); + assert(gdump_old); + did_prof_dump_open = false; + r = mallocx(chunksize, 0); + assert_ptr_not_null(q, "Unexpected mallocx() failure"); + assert_false(did_prof_dump_open, "Unexpected profile dump"); + + gdump = true; + sz = sizeof(gdump_old); + assert_d_eq(mallctl("prof.gdump", &gdump_old, &sz, &gdump, + sizeof(gdump)), 0, + "Unexpected mallctl failure while enabling prof.gdump"); + assert(!gdump_old); + did_prof_dump_open = false; + s = mallocx(chunksize, 0); + assert_ptr_not_null(q, "Unexpected mallocx() failure"); + assert_true(did_prof_dump_open, "Expected a profile dump"); + + dallocx(p, 0); + dallocx(q, 0); + dallocx(r, 0); + dallocx(s, 0); +} +TEST_END + +int +main(void) +{ + + return (test( + test_gdump)); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/prof_idump.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/prof_idump.c new file mode 100644 index 0000000..bdea53e --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/prof_idump.c @@ -0,0 +1,51 @@ +#include "test/jemalloc_test.h" + +#ifdef JEMALLOC_PROF +const char *malloc_conf = + "prof:true,prof_accum:true,prof_active:false,lg_prof_sample:0," + "lg_prof_interval:0"; +#endif + +static bool did_prof_dump_open; + +static int +prof_dump_open_intercept(bool propagate_err, const char *filename) +{ + int fd; + + did_prof_dump_open = true; + + fd = open("/dev/null", O_WRONLY); + assert_d_ne(fd, -1, "Unexpected open() failure"); + + return (fd); +} + +TEST_BEGIN(test_idump) +{ + bool active; + void *p; + + test_skip_if(!config_prof); + + active = true; + assert_d_eq(mallctl("prof.active", NULL, NULL, &active, sizeof(active)), + 0, "Unexpected mallctl failure while activating profiling"); + + prof_dump_open = prof_dump_open_intercept; + + did_prof_dump_open = false; + p = mallocx(1, 0); + assert_ptr_not_null(p, "Unexpected mallocx() failure"); + dallocx(p, 0); + assert_true(did_prof_dump_open, "Expected a profile dump"); +} +TEST_END + +int +main(void) +{ + + return (test( + test_idump)); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/prof_reset.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/prof_reset.c new file mode 100644 index 0000000..69983e5 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/prof_reset.c @@ -0,0 +1,302 @@ +#include "test/jemalloc_test.h" + +#ifdef JEMALLOC_PROF +const char *malloc_conf = + "prof:true,prof_active:false,lg_prof_sample:0"; +#endif + +static int +prof_dump_open_intercept(bool propagate_err, const char *filename) +{ + int fd; + + fd = open("/dev/null", O_WRONLY); + assert_d_ne(fd, -1, "Unexpected open() failure"); + + return (fd); +} + +static void +set_prof_active(bool active) +{ + + assert_d_eq(mallctl("prof.active", NULL, NULL, &active, sizeof(active)), + 0, "Unexpected mallctl failure"); +} + +static size_t +get_lg_prof_sample(void) +{ + size_t lg_prof_sample; + size_t sz = sizeof(size_t); + + assert_d_eq(mallctl("prof.lg_sample", &lg_prof_sample, &sz, NULL, 0), 0, + "Unexpected mallctl failure while reading profiling sample rate"); + return (lg_prof_sample); +} + +static void +do_prof_reset(size_t lg_prof_sample) +{ + assert_d_eq(mallctl("prof.reset", NULL, NULL, + &lg_prof_sample, sizeof(size_t)), 0, + "Unexpected mallctl failure while resetting profile data"); + assert_zu_eq(lg_prof_sample, get_lg_prof_sample(), + "Expected profile sample rate change"); +} + +TEST_BEGIN(test_prof_reset_basic) +{ + size_t lg_prof_sample_orig, lg_prof_sample, lg_prof_sample_next; + size_t sz; + unsigned i; + + test_skip_if(!config_prof); + + sz = sizeof(size_t); + assert_d_eq(mallctl("opt.lg_prof_sample", &lg_prof_sample_orig, &sz, + NULL, 0), 0, + "Unexpected mallctl failure while reading profiling sample rate"); + assert_zu_eq(lg_prof_sample_orig, 0, + "Unexpected profiling sample rate"); + lg_prof_sample = get_lg_prof_sample(); + assert_zu_eq(lg_prof_sample_orig, lg_prof_sample, + "Unexpected disagreement between \"opt.lg_prof_sample\" and " + "\"prof.lg_sample\""); + + /* Test simple resets. */ + for (i = 0; i < 2; i++) { + assert_d_eq(mallctl("prof.reset", NULL, NULL, NULL, 0), 0, + "Unexpected mallctl failure while resetting profile data"); + lg_prof_sample = get_lg_prof_sample(); + assert_zu_eq(lg_prof_sample_orig, lg_prof_sample, + "Unexpected profile sample rate change"); + } + + /* Test resets with prof.lg_sample changes. */ + lg_prof_sample_next = 1; + for (i = 0; i < 2; i++) { + do_prof_reset(lg_prof_sample_next); + lg_prof_sample = get_lg_prof_sample(); + assert_zu_eq(lg_prof_sample, lg_prof_sample_next, + "Expected profile sample rate change"); + lg_prof_sample_next = lg_prof_sample_orig; + } + + /* Make sure the test code restored prof.lg_sample. */ + lg_prof_sample = get_lg_prof_sample(); + assert_zu_eq(lg_prof_sample_orig, lg_prof_sample, + "Unexpected disagreement between \"opt.lg_prof_sample\" and " + "\"prof.lg_sample\""); +} +TEST_END + +bool prof_dump_header_intercepted = false; +prof_cnt_t cnt_all_copy = {0, 0, 0, 0}; +static bool +prof_dump_header_intercept(bool propagate_err, const prof_cnt_t *cnt_all) +{ + + prof_dump_header_intercepted = true; + memcpy(&cnt_all_copy, cnt_all, sizeof(prof_cnt_t)); + + return (false); +} + +TEST_BEGIN(test_prof_reset_cleanup) +{ + void *p; + prof_dump_header_t *prof_dump_header_orig; + + test_skip_if(!config_prof); + + set_prof_active(true); + + assert_zu_eq(prof_bt_count(), 0, "Expected 0 backtraces"); + p = mallocx(1, 0); + assert_ptr_not_null(p, "Unexpected mallocx() failure"); + assert_zu_eq(prof_bt_count(), 1, "Expected 1 backtrace"); + + prof_dump_header_orig = prof_dump_header; + prof_dump_header = prof_dump_header_intercept; + assert_false(prof_dump_header_intercepted, "Unexpected intercept"); + + assert_d_eq(mallctl("prof.dump", NULL, NULL, NULL, 0), + 0, "Unexpected error while dumping heap profile"); + assert_true(prof_dump_header_intercepted, "Expected intercept"); + assert_u64_eq(cnt_all_copy.curobjs, 1, "Expected 1 allocation"); + + assert_d_eq(mallctl("prof.reset", NULL, NULL, NULL, 0), 0, + "Unexpected error while resetting heap profile data"); + assert_d_eq(mallctl("prof.dump", NULL, NULL, NULL, 0), + 0, "Unexpected error while dumping heap profile"); + assert_u64_eq(cnt_all_copy.curobjs, 0, "Expected 0 allocations"); + assert_zu_eq(prof_bt_count(), 1, "Expected 1 backtrace"); + + prof_dump_header = prof_dump_header_orig; + + dallocx(p, 0); + assert_zu_eq(prof_bt_count(), 0, "Expected 0 backtraces"); + + set_prof_active(false); +} +TEST_END + +#define NTHREADS 4 +#define NALLOCS_PER_THREAD (1U << 13) +#define OBJ_RING_BUF_COUNT 1531 +#define RESET_INTERVAL (1U << 10) +#define DUMP_INTERVAL 3677 +static void * +thd_start(void *varg) +{ + unsigned thd_ind = *(unsigned *)varg; + unsigned i; + void *objs[OBJ_RING_BUF_COUNT]; + + memset(objs, 0, sizeof(objs)); + + for (i = 0; i < NALLOCS_PER_THREAD; i++) { + if (i % RESET_INTERVAL == 0) { + assert_d_eq(mallctl("prof.reset", NULL, NULL, NULL, 0), + 0, "Unexpected error while resetting heap profile " + "data"); + } + + if (i % DUMP_INTERVAL == 0) { + assert_d_eq(mallctl("prof.dump", NULL, NULL, NULL, 0), + 0, "Unexpected error while dumping heap profile"); + } + + { + void **pp = &objs[i % OBJ_RING_BUF_COUNT]; + if (*pp != NULL) { + dallocx(*pp, 0); + *pp = NULL; + } + *pp = btalloc(1, thd_ind*NALLOCS_PER_THREAD + i); + assert_ptr_not_null(*pp, + "Unexpected btalloc() failure"); + } + } + + /* Clean up any remaining objects. */ + for (i = 0; i < OBJ_RING_BUF_COUNT; i++) { + void **pp = &objs[i % OBJ_RING_BUF_COUNT]; + if (*pp != NULL) { + dallocx(*pp, 0); + *pp = NULL; + } + } + + return (NULL); +} + +TEST_BEGIN(test_prof_reset) +{ + size_t lg_prof_sample_orig; + thd_t thds[NTHREADS]; + unsigned thd_args[NTHREADS]; + unsigned i; + size_t bt_count, tdata_count; + + test_skip_if(!config_prof); + + bt_count = prof_bt_count(); + assert_zu_eq(bt_count, 0, + "Unexpected pre-existing tdata structures"); + tdata_count = prof_tdata_count(); + + lg_prof_sample_orig = get_lg_prof_sample(); + do_prof_reset(5); + + set_prof_active(true); + + for (i = 0; i < NTHREADS; i++) { + thd_args[i] = i; + thd_create(&thds[i], thd_start, (void *)&thd_args[i]); + } + for (i = 0; i < NTHREADS; i++) + thd_join(thds[i], NULL); + + assert_zu_eq(prof_bt_count(), bt_count, + "Unexpected bactrace count change"); + assert_zu_eq(prof_tdata_count(), tdata_count, + "Unexpected remaining tdata structures"); + + set_prof_active(false); + + do_prof_reset(lg_prof_sample_orig); +} +TEST_END +#undef NTHREADS +#undef NALLOCS_PER_THREAD +#undef OBJ_RING_BUF_COUNT +#undef RESET_INTERVAL +#undef DUMP_INTERVAL + +/* Test sampling at the same allocation site across resets. */ +#define NITER 10 +TEST_BEGIN(test_xallocx) +{ + size_t lg_prof_sample_orig; + unsigned i; + void *ptrs[NITER]; + + test_skip_if(!config_prof); + + lg_prof_sample_orig = get_lg_prof_sample(); + set_prof_active(true); + + /* Reset profiling. */ + do_prof_reset(0); + + for (i = 0; i < NITER; i++) { + void *p; + size_t sz, nsz; + + /* Reset profiling. */ + do_prof_reset(0); + + /* Allocate small object (which will be promoted). */ + p = ptrs[i] = mallocx(1, 0); + assert_ptr_not_null(p, "Unexpected mallocx() failure"); + + /* Reset profiling. */ + do_prof_reset(0); + + /* Perform successful xallocx(). */ + sz = sallocx(p, 0); + assert_zu_eq(xallocx(p, sz, 0, 0), sz, + "Unexpected xallocx() failure"); + + /* Perform unsuccessful xallocx(). */ + nsz = nallocx(sz+1, 0); + assert_zu_eq(xallocx(p, nsz, 0, 0), sz, + "Unexpected xallocx() success"); + } + + for (i = 0; i < NITER; i++) { + /* dallocx. */ + dallocx(ptrs[i], 0); + } + + set_prof_active(false); + do_prof_reset(lg_prof_sample_orig); +} +TEST_END +#undef NITER + +int +main(void) +{ + + /* Intercept dumping prior to running any tests. */ + prof_dump_open = prof_dump_open_intercept; + + return (test( + test_prof_reset_basic, + test_prof_reset_cleanup, + test_prof_reset, + test_xallocx)); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/prof_thread_name.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/prof_thread_name.c new file mode 100644 index 0000000..f501158 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/prof_thread_name.c @@ -0,0 +1,129 @@ +#include "test/jemalloc_test.h" + +#ifdef JEMALLOC_PROF +const char *malloc_conf = "prof:true,prof_active:false"; +#endif + +static void +mallctl_thread_name_get_impl(const char *thread_name_expected, const char *func, + int line) +{ + const char *thread_name_old; + size_t sz; + + sz = sizeof(thread_name_old); + assert_d_eq(mallctl("thread.prof.name", &thread_name_old, &sz, NULL, 0), + 0, "%s():%d: Unexpected mallctl failure reading thread.prof.name", + func, line); + assert_str_eq(thread_name_old, thread_name_expected, + "%s():%d: Unexpected thread.prof.name value", func, line); +} +#define mallctl_thread_name_get(a) \ + mallctl_thread_name_get_impl(a, __func__, __LINE__) + +static void +mallctl_thread_name_set_impl(const char *thread_name, const char *func, + int line) +{ + + assert_d_eq(mallctl("thread.prof.name", NULL, NULL, &thread_name, + sizeof(thread_name)), 0, + "%s():%d: Unexpected mallctl failure reading thread.prof.name", + func, line); + mallctl_thread_name_get_impl(thread_name, func, line); +} +#define mallctl_thread_name_set(a) \ + mallctl_thread_name_set_impl(a, __func__, __LINE__) + +TEST_BEGIN(test_prof_thread_name_validation) +{ + const char *thread_name; + + test_skip_if(!config_prof); + + mallctl_thread_name_get(""); + mallctl_thread_name_set("hi there"); + + /* NULL input shouldn't be allowed. */ + thread_name = NULL; + assert_d_eq(mallctl("thread.prof.name", NULL, NULL, &thread_name, + sizeof(thread_name)), EFAULT, + "Unexpected mallctl result writing \"%s\" to thread.prof.name", + thread_name); + + /* '\n' shouldn't be allowed. */ + thread_name = "hi\nthere"; + assert_d_eq(mallctl("thread.prof.name", NULL, NULL, &thread_name, + sizeof(thread_name)), EFAULT, + "Unexpected mallctl result writing \"%s\" to thread.prof.name", + thread_name); + + /* Simultaneous read/write shouldn't be allowed. */ + { + const char *thread_name_old; + size_t sz; + + sz = sizeof(thread_name_old); + assert_d_eq(mallctl("thread.prof.name", &thread_name_old, &sz, + &thread_name, sizeof(thread_name)), EPERM, + "Unexpected mallctl result writing \"%s\" to " + "thread.prof.name", thread_name); + } + + mallctl_thread_name_set(""); +} +TEST_END + +#define NTHREADS 4 +#define NRESET 25 +static void * +thd_start(void *varg) +{ + unsigned thd_ind = *(unsigned *)varg; + char thread_name[16] = ""; + unsigned i; + + malloc_snprintf(thread_name, sizeof(thread_name), "thread %u", thd_ind); + + mallctl_thread_name_get(""); + mallctl_thread_name_set(thread_name); + + for (i = 0; i < NRESET; i++) { + assert_d_eq(mallctl("prof.reset", NULL, NULL, NULL, 0), 0, + "Unexpected error while resetting heap profile data"); + mallctl_thread_name_get(thread_name); + } + + mallctl_thread_name_set(thread_name); + mallctl_thread_name_set(""); + + return (NULL); +} + +TEST_BEGIN(test_prof_thread_name_threaded) +{ + thd_t thds[NTHREADS]; + unsigned thd_args[NTHREADS]; + unsigned i; + + test_skip_if(!config_prof); + + for (i = 0; i < NTHREADS; i++) { + thd_args[i] = i; + thd_create(&thds[i], thd_start, (void *)&thd_args[i]); + } + for (i = 0; i < NTHREADS; i++) + thd_join(thds[i], NULL); +} +TEST_END +#undef NTHREADS +#undef NRESET + +int +main(void) +{ + + return (test( + test_prof_thread_name_validation, + test_prof_thread_name_threaded)); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/ql.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/ql.c new file mode 100644 index 0000000..05fad45 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/ql.c @@ -0,0 +1,209 @@ +#include "test/jemalloc_test.h" + +/* Number of ring entries, in [2..26]. */ +#define NENTRIES 9 + +typedef struct list_s list_t; +typedef ql_head(list_t) list_head_t; + +struct list_s { + ql_elm(list_t) link; + char id; +}; + +static void +test_empty_list(list_head_t *head) +{ + list_t *t; + unsigned i; + + assert_ptr_null(ql_first(head), "Unexpected element for empty list"); + assert_ptr_null(ql_last(head, link), + "Unexpected element for empty list"); + + i = 0; + ql_foreach(t, head, link) { + i++; + } + assert_u_eq(i, 0, "Unexpected element for empty list"); + + i = 0; + ql_reverse_foreach(t, head, link) { + i++; + } + assert_u_eq(i, 0, "Unexpected element for empty list"); +} + +TEST_BEGIN(test_ql_empty) +{ + list_head_t head; + + ql_new(&head); + test_empty_list(&head); +} +TEST_END + +static void +init_entries(list_t *entries, unsigned nentries) +{ + unsigned i; + + for (i = 0; i < nentries; i++) { + entries[i].id = 'a' + i; + ql_elm_new(&entries[i], link); + } +} + +static void +test_entries_list(list_head_t *head, list_t *entries, unsigned nentries) +{ + list_t *t; + unsigned i; + + assert_c_eq(ql_first(head)->id, entries[0].id, "Element id mismatch"); + assert_c_eq(ql_last(head, link)->id, entries[nentries-1].id, + "Element id mismatch"); + + i = 0; + ql_foreach(t, head, link) { + assert_c_eq(t->id, entries[i].id, "Element id mismatch"); + i++; + } + + i = 0; + ql_reverse_foreach(t, head, link) { + assert_c_eq(t->id, entries[nentries-i-1].id, + "Element id mismatch"); + i++; + } + + for (i = 0; i < nentries-1; i++) { + t = ql_next(head, &entries[i], link); + assert_c_eq(t->id, entries[i+1].id, "Element id mismatch"); + } + assert_ptr_null(ql_next(head, &entries[nentries-1], link), + "Unexpected element"); + + assert_ptr_null(ql_prev(head, &entries[0], link), "Unexpected element"); + for (i = 1; i < nentries; i++) { + t = ql_prev(head, &entries[i], link); + assert_c_eq(t->id, entries[i-1].id, "Element id mismatch"); + } +} + +TEST_BEGIN(test_ql_tail_insert) +{ + list_head_t head; + list_t entries[NENTRIES]; + unsigned i; + + ql_new(&head); + init_entries(entries, sizeof(entries)/sizeof(list_t)); + for (i = 0; i < NENTRIES; i++) + ql_tail_insert(&head, &entries[i], link); + + test_entries_list(&head, entries, NENTRIES); +} +TEST_END + +TEST_BEGIN(test_ql_tail_remove) +{ + list_head_t head; + list_t entries[NENTRIES]; + unsigned i; + + ql_new(&head); + init_entries(entries, sizeof(entries)/sizeof(list_t)); + for (i = 0; i < NENTRIES; i++) + ql_tail_insert(&head, &entries[i], link); + + for (i = 0; i < NENTRIES; i++) { + test_entries_list(&head, entries, NENTRIES-i); + ql_tail_remove(&head, list_t, link); + } + test_empty_list(&head); +} +TEST_END + +TEST_BEGIN(test_ql_head_insert) +{ + list_head_t head; + list_t entries[NENTRIES]; + unsigned i; + + ql_new(&head); + init_entries(entries, sizeof(entries)/sizeof(list_t)); + for (i = 0; i < NENTRIES; i++) + ql_head_insert(&head, &entries[NENTRIES-i-1], link); + + test_entries_list(&head, entries, NENTRIES); +} +TEST_END + +TEST_BEGIN(test_ql_head_remove) +{ + list_head_t head; + list_t entries[NENTRIES]; + unsigned i; + + ql_new(&head); + init_entries(entries, sizeof(entries)/sizeof(list_t)); + for (i = 0; i < NENTRIES; i++) + ql_head_insert(&head, &entries[NENTRIES-i-1], link); + + for (i = 0; i < NENTRIES; i++) { + test_entries_list(&head, &entries[i], NENTRIES-i); + ql_head_remove(&head, list_t, link); + } + test_empty_list(&head); +} +TEST_END + +TEST_BEGIN(test_ql_insert) +{ + list_head_t head; + list_t entries[8]; + list_t *a, *b, *c, *d, *e, *f, *g, *h; + + ql_new(&head); + init_entries(entries, sizeof(entries)/sizeof(list_t)); + a = &entries[0]; + b = &entries[1]; + c = &entries[2]; + d = &entries[3]; + e = &entries[4]; + f = &entries[5]; + g = &entries[6]; + h = &entries[7]; + + /* + * ql_remove(), ql_before_insert(), and ql_after_insert() are used + * internally by other macros that are already tested, so there's no + * need to test them completely. However, insertion/deletion from the + * middle of lists is not otherwise tested; do so here. + */ + ql_tail_insert(&head, f, link); + ql_before_insert(&head, f, b, link); + ql_before_insert(&head, f, c, link); + ql_after_insert(f, h, link); + ql_after_insert(f, g, link); + ql_before_insert(&head, b, a, link); + ql_after_insert(c, d, link); + ql_before_insert(&head, f, e, link); + + test_entries_list(&head, entries, sizeof(entries)/sizeof(list_t)); +} +TEST_END + +int +main(void) +{ + + return (test( + test_ql_empty, + test_ql_tail_insert, + test_ql_tail_remove, + test_ql_head_insert, + test_ql_head_remove, + test_ql_insert)); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/qr.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/qr.c new file mode 100644 index 0000000..a2a2d90 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/qr.c @@ -0,0 +1,248 @@ +#include "test/jemalloc_test.h" + +/* Number of ring entries, in [2..26]. */ +#define NENTRIES 9 +/* Split index, in [1..NENTRIES). */ +#define SPLIT_INDEX 5 + +typedef struct ring_s ring_t; + +struct ring_s { + qr(ring_t) link; + char id; +}; + +static void +init_entries(ring_t *entries) +{ + unsigned i; + + for (i = 0; i < NENTRIES; i++) { + qr_new(&entries[i], link); + entries[i].id = 'a' + i; + } +} + +static void +test_independent_entries(ring_t *entries) +{ + ring_t *t; + unsigned i, j; + + for (i = 0; i < NENTRIES; i++) { + j = 0; + qr_foreach(t, &entries[i], link) { + j++; + } + assert_u_eq(j, 1, + "Iteration over single-element ring should visit precisely " + "one element"); + } + for (i = 0; i < NENTRIES; i++) { + j = 0; + qr_reverse_foreach(t, &entries[i], link) { + j++; + } + assert_u_eq(j, 1, + "Iteration over single-element ring should visit precisely " + "one element"); + } + for (i = 0; i < NENTRIES; i++) { + t = qr_next(&entries[i], link); + assert_ptr_eq(t, &entries[i], + "Next element in single-element ring should be same as " + "current element"); + } + for (i = 0; i < NENTRIES; i++) { + t = qr_prev(&entries[i], link); + assert_ptr_eq(t, &entries[i], + "Previous element in single-element ring should be same as " + "current element"); + } +} + +TEST_BEGIN(test_qr_one) +{ + ring_t entries[NENTRIES]; + + init_entries(entries); + test_independent_entries(entries); +} +TEST_END + +static void +test_entries_ring(ring_t *entries) +{ + ring_t *t; + unsigned i, j; + + for (i = 0; i < NENTRIES; i++) { + j = 0; + qr_foreach(t, &entries[i], link) { + assert_c_eq(t->id, entries[(i+j) % NENTRIES].id, + "Element id mismatch"); + j++; + } + } + for (i = 0; i < NENTRIES; i++) { + j = 0; + qr_reverse_foreach(t, &entries[i], link) { + assert_c_eq(t->id, entries[(NENTRIES+i-j-1) % + NENTRIES].id, "Element id mismatch"); + j++; + } + } + for (i = 0; i < NENTRIES; i++) { + t = qr_next(&entries[i], link); + assert_c_eq(t->id, entries[(i+1) % NENTRIES].id, + "Element id mismatch"); + } + for (i = 0; i < NENTRIES; i++) { + t = qr_prev(&entries[i], link); + assert_c_eq(t->id, entries[(NENTRIES+i-1) % NENTRIES].id, + "Element id mismatch"); + } +} + +TEST_BEGIN(test_qr_after_insert) +{ + ring_t entries[NENTRIES]; + unsigned i; + + init_entries(entries); + for (i = 1; i < NENTRIES; i++) + qr_after_insert(&entries[i - 1], &entries[i], link); + test_entries_ring(entries); +} +TEST_END + +TEST_BEGIN(test_qr_remove) +{ + ring_t entries[NENTRIES]; + ring_t *t; + unsigned i, j; + + init_entries(entries); + for (i = 1; i < NENTRIES; i++) + qr_after_insert(&entries[i - 1], &entries[i], link); + + for (i = 0; i < NENTRIES; i++) { + j = 0; + qr_foreach(t, &entries[i], link) { + assert_c_eq(t->id, entries[i+j].id, + "Element id mismatch"); + j++; + } + j = 0; + qr_reverse_foreach(t, &entries[i], link) { + assert_c_eq(t->id, entries[NENTRIES - 1 - j].id, + "Element id mismatch"); + j++; + } + qr_remove(&entries[i], link); + } + test_independent_entries(entries); +} +TEST_END + +TEST_BEGIN(test_qr_before_insert) +{ + ring_t entries[NENTRIES]; + ring_t *t; + unsigned i, j; + + init_entries(entries); + for (i = 1; i < NENTRIES; i++) + qr_before_insert(&entries[i - 1], &entries[i], link); + for (i = 0; i < NENTRIES; i++) { + j = 0; + qr_foreach(t, &entries[i], link) { + assert_c_eq(t->id, entries[(NENTRIES+i-j) % + NENTRIES].id, "Element id mismatch"); + j++; + } + } + for (i = 0; i < NENTRIES; i++) { + j = 0; + qr_reverse_foreach(t, &entries[i], link) { + assert_c_eq(t->id, entries[(i+j+1) % NENTRIES].id, + "Element id mismatch"); + j++; + } + } + for (i = 0; i < NENTRIES; i++) { + t = qr_next(&entries[i], link); + assert_c_eq(t->id, entries[(NENTRIES+i-1) % NENTRIES].id, + "Element id mismatch"); + } + for (i = 0; i < NENTRIES; i++) { + t = qr_prev(&entries[i], link); + assert_c_eq(t->id, entries[(i+1) % NENTRIES].id, + "Element id mismatch"); + } +} +TEST_END + +static void +test_split_entries(ring_t *entries) +{ + ring_t *t; + unsigned i, j; + + for (i = 0; i < NENTRIES; i++) { + j = 0; + qr_foreach(t, &entries[i], link) { + if (i < SPLIT_INDEX) { + assert_c_eq(t->id, + entries[(i+j) % SPLIT_INDEX].id, + "Element id mismatch"); + } else { + assert_c_eq(t->id, entries[(i+j-SPLIT_INDEX) % + (NENTRIES-SPLIT_INDEX) + SPLIT_INDEX].id, + "Element id mismatch"); + } + j++; + } + } +} + +TEST_BEGIN(test_qr_meld_split) +{ + ring_t entries[NENTRIES]; + unsigned i; + + init_entries(entries); + for (i = 1; i < NENTRIES; i++) + qr_after_insert(&entries[i - 1], &entries[i], link); + + qr_split(&entries[0], &entries[SPLIT_INDEX], link); + test_split_entries(entries); + + qr_meld(&entries[0], &entries[SPLIT_INDEX], link); + test_entries_ring(entries); + + qr_meld(&entries[0], &entries[SPLIT_INDEX], link); + test_split_entries(entries); + + qr_split(&entries[0], &entries[SPLIT_INDEX], link); + test_entries_ring(entries); + + qr_split(&entries[0], &entries[0], link); + test_entries_ring(entries); + + qr_meld(&entries[0], &entries[0], link); + test_entries_ring(entries); +} +TEST_END + +int +main(void) +{ + + return (test( + test_qr_one, + test_qr_after_insert, + test_qr_remove, + test_qr_before_insert, + test_qr_meld_split)); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/quarantine.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/quarantine.c new file mode 100644 index 0000000..bbd48a5 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/quarantine.c @@ -0,0 +1,108 @@ +#include "test/jemalloc_test.h" + +#define QUARANTINE_SIZE 8192 +#define STRINGIFY_HELPER(x) #x +#define STRINGIFY(x) STRINGIFY_HELPER(x) + +#ifdef JEMALLOC_FILL +const char *malloc_conf = "abort:false,junk:true,redzone:true,quarantine:" + STRINGIFY(QUARANTINE_SIZE); +#endif + +void +quarantine_clear(void) +{ + void *p; + + p = mallocx(QUARANTINE_SIZE*2, 0); + assert_ptr_not_null(p, "Unexpected mallocx() failure"); + dallocx(p, 0); +} + +TEST_BEGIN(test_quarantine) +{ +#define SZ ZU(256) +#define NQUARANTINED (QUARANTINE_SIZE/SZ) + void *quarantined[NQUARANTINED+1]; + size_t i, j; + + test_skip_if(!config_fill); + + assert_zu_eq(nallocx(SZ, 0), SZ, + "SZ=%zu does not precisely equal a size class", SZ); + + quarantine_clear(); + + /* + * Allocate enough regions to completely fill the quarantine, plus one + * more. The last iteration occurs with a completely full quarantine, + * but no regions should be drained from the quarantine until the last + * deallocation occurs. Therefore no region recycling should occur + * until after this loop completes. + */ + for (i = 0; i < NQUARANTINED+1; i++) { + void *p = mallocx(SZ, 0); + assert_ptr_not_null(p, "Unexpected mallocx() failure"); + quarantined[i] = p; + dallocx(p, 0); + for (j = 0; j < i; j++) { + assert_ptr_ne(p, quarantined[j], + "Quarantined region recycled too early; " + "i=%zu, j=%zu", i, j); + } + } +#undef NQUARANTINED +#undef SZ +} +TEST_END + +static bool detected_redzone_corruption; + +static void +arena_redzone_corruption_replacement(void *ptr, size_t usize, bool after, + size_t offset, uint8_t byte) +{ + + detected_redzone_corruption = true; +} + +TEST_BEGIN(test_quarantine_redzone) +{ + char *s; + arena_redzone_corruption_t *arena_redzone_corruption_orig; + + test_skip_if(!config_fill); + + arena_redzone_corruption_orig = arena_redzone_corruption; + arena_redzone_corruption = arena_redzone_corruption_replacement; + + /* Test underflow. */ + detected_redzone_corruption = false; + s = (char *)mallocx(1, 0); + assert_ptr_not_null((void *)s, "Unexpected mallocx() failure"); + s[-1] = 0xbb; + dallocx(s, 0); + assert_true(detected_redzone_corruption, + "Did not detect redzone corruption"); + + /* Test overflow. */ + detected_redzone_corruption = false; + s = (char *)mallocx(1, 0); + assert_ptr_not_null((void *)s, "Unexpected mallocx() failure"); + s[sallocx(s, 0)] = 0xbb; + dallocx(s, 0); + assert_true(detected_redzone_corruption, + "Did not detect redzone corruption"); + + arena_redzone_corruption = arena_redzone_corruption_orig; +} +TEST_END + +int +main(void) +{ + + return (test( + test_quarantine, + test_quarantine_redzone)); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/rb.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/rb.c new file mode 100644 index 0000000..b38eb0e --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/rb.c @@ -0,0 +1,336 @@ +#include "test/jemalloc_test.h" + +#define rbtn_black_height(a_type, a_field, a_rbt, r_height) do { \ + a_type *rbp_bh_t; \ + for (rbp_bh_t = (a_rbt)->rbt_root, (r_height) = 0; \ + rbp_bh_t != &(a_rbt)->rbt_nil; \ + rbp_bh_t = rbtn_left_get(a_type, a_field, rbp_bh_t)) { \ + if (!rbtn_red_get(a_type, a_field, rbp_bh_t)) { \ + (r_height)++; \ + } \ + } \ +} while (0) + +typedef struct node_s node_t; + +struct node_s { +#define NODE_MAGIC 0x9823af7e + uint32_t magic; + rb_node(node_t) link; + uint64_t key; +}; + +static int +node_cmp(node_t *a, node_t *b) { + int ret; + + assert_u32_eq(a->magic, NODE_MAGIC, "Bad magic"); + assert_u32_eq(b->magic, NODE_MAGIC, "Bad magic"); + + ret = (a->key > b->key) - (a->key < b->key); + if (ret == 0) { + /* + * Duplicates are not allowed in the tree, so force an + * arbitrary ordering for non-identical items with equal keys. + */ + ret = (((uintptr_t)a) > ((uintptr_t)b)) + - (((uintptr_t)a) < ((uintptr_t)b)); + } + return (ret); +} + +typedef rb_tree(node_t) tree_t; +rb_gen(static, tree_, tree_t, node_t, link, node_cmp); + +TEST_BEGIN(test_rb_empty) +{ + tree_t tree; + node_t key; + + tree_new(&tree); + + assert_true(tree_empty(&tree), "Tree should be empty"); + assert_ptr_null(tree_first(&tree), "Unexpected node"); + assert_ptr_null(tree_last(&tree), "Unexpected node"); + + key.key = 0; + key.magic = NODE_MAGIC; + assert_ptr_null(tree_search(&tree, &key), "Unexpected node"); + + key.key = 0; + key.magic = NODE_MAGIC; + assert_ptr_null(tree_nsearch(&tree, &key), "Unexpected node"); + + key.key = 0; + key.magic = NODE_MAGIC; + assert_ptr_null(tree_psearch(&tree, &key), "Unexpected node"); +} +TEST_END + +static unsigned +tree_recurse(node_t *node, unsigned black_height, unsigned black_depth, + node_t *nil) +{ + unsigned ret = 0; + node_t *left_node = rbtn_left_get(node_t, link, node); + node_t *right_node = rbtn_right_get(node_t, link, node); + + if (!rbtn_red_get(node_t, link, node)) + black_depth++; + + /* Red nodes must be interleaved with black nodes. */ + if (rbtn_red_get(node_t, link, node)) { + assert_false(rbtn_red_get(node_t, link, left_node), + "Node should be black"); + assert_false(rbtn_red_get(node_t, link, right_node), + "Node should be black"); + } + + if (node == nil) + return (ret); + /* Self. */ + assert_u32_eq(node->magic, NODE_MAGIC, "Bad magic"); + + /* Left subtree. */ + if (left_node != nil) + ret += tree_recurse(left_node, black_height, black_depth, nil); + else + ret += (black_depth != black_height); + + /* Right subtree. */ + if (right_node != nil) + ret += tree_recurse(right_node, black_height, black_depth, nil); + else + ret += (black_depth != black_height); + + return (ret); +} + +static node_t * +tree_iterate_cb(tree_t *tree, node_t *node, void *data) +{ + unsigned *i = (unsigned *)data; + node_t *search_node; + + assert_u32_eq(node->magic, NODE_MAGIC, "Bad magic"); + + /* Test rb_search(). */ + search_node = tree_search(tree, node); + assert_ptr_eq(search_node, node, + "tree_search() returned unexpected node"); + + /* Test rb_nsearch(). */ + search_node = tree_nsearch(tree, node); + assert_ptr_eq(search_node, node, + "tree_nsearch() returned unexpected node"); + + /* Test rb_psearch(). */ + search_node = tree_psearch(tree, node); + assert_ptr_eq(search_node, node, + "tree_psearch() returned unexpected node"); + + (*i)++; + + return (NULL); +} + +static unsigned +tree_iterate(tree_t *tree) +{ + unsigned i; + + i = 0; + tree_iter(tree, NULL, tree_iterate_cb, (void *)&i); + + return (i); +} + +static unsigned +tree_iterate_reverse(tree_t *tree) +{ + unsigned i; + + i = 0; + tree_reverse_iter(tree, NULL, tree_iterate_cb, (void *)&i); + + return (i); +} + +static void +node_remove(tree_t *tree, node_t *node, unsigned nnodes) +{ + node_t *search_node; + unsigned black_height, imbalances; + + tree_remove(tree, node); + + /* Test rb_nsearch(). */ + search_node = tree_nsearch(tree, node); + if (search_node != NULL) { + assert_u64_ge(search_node->key, node->key, + "Key ordering error"); + } + + /* Test rb_psearch(). */ + search_node = tree_psearch(tree, node); + if (search_node != NULL) { + assert_u64_le(search_node->key, node->key, + "Key ordering error"); + } + + node->magic = 0; + + rbtn_black_height(node_t, link, tree, black_height); + imbalances = tree_recurse(tree->rbt_root, black_height, 0, + &(tree->rbt_nil)); + assert_u_eq(imbalances, 0, "Tree is unbalanced"); + assert_u_eq(tree_iterate(tree), nnodes-1, + "Unexpected node iteration count"); + assert_u_eq(tree_iterate_reverse(tree), nnodes-1, + "Unexpected node iteration count"); +} + +static node_t * +remove_iterate_cb(tree_t *tree, node_t *node, void *data) +{ + unsigned *nnodes = (unsigned *)data; + node_t *ret = tree_next(tree, node); + + node_remove(tree, node, *nnodes); + + return (ret); +} + +static node_t * +remove_reverse_iterate_cb(tree_t *tree, node_t *node, void *data) +{ + unsigned *nnodes = (unsigned *)data; + node_t *ret = tree_prev(tree, node); + + node_remove(tree, node, *nnodes); + + return (ret); +} + +TEST_BEGIN(test_rb_random) +{ +#define NNODES 25 +#define NBAGS 250 +#define SEED 42 + sfmt_t *sfmt; + uint64_t bag[NNODES]; + tree_t tree; + node_t nodes[NNODES]; + unsigned i, j, k, black_height, imbalances; + + sfmt = init_gen_rand(SEED); + for (i = 0; i < NBAGS; i++) { + switch (i) { + case 0: + /* Insert in order. */ + for (j = 0; j < NNODES; j++) + bag[j] = j; + break; + case 1: + /* Insert in reverse order. */ + for (j = 0; j < NNODES; j++) + bag[j] = NNODES - j - 1; + break; + default: + for (j = 0; j < NNODES; j++) + bag[j] = gen_rand64_range(sfmt, NNODES); + } + + for (j = 1; j <= NNODES; j++) { + /* Initialize tree and nodes. */ + tree_new(&tree); + tree.rbt_nil.magic = 0; + for (k = 0; k < j; k++) { + nodes[k].magic = NODE_MAGIC; + nodes[k].key = bag[k]; + } + + /* Insert nodes. */ + for (k = 0; k < j; k++) { + tree_insert(&tree, &nodes[k]); + + rbtn_black_height(node_t, link, &tree, + black_height); + imbalances = tree_recurse(tree.rbt_root, + black_height, 0, &(tree.rbt_nil)); + assert_u_eq(imbalances, 0, + "Tree is unbalanced"); + + assert_u_eq(tree_iterate(&tree), k+1, + "Unexpected node iteration count"); + assert_u_eq(tree_iterate_reverse(&tree), k+1, + "Unexpected node iteration count"); + + assert_false(tree_empty(&tree), + "Tree should not be empty"); + assert_ptr_not_null(tree_first(&tree), + "Tree should not be empty"); + assert_ptr_not_null(tree_last(&tree), + "Tree should not be empty"); + + tree_next(&tree, &nodes[k]); + tree_prev(&tree, &nodes[k]); + } + + /* Remove nodes. */ + switch (i % 4) { + case 0: + for (k = 0; k < j; k++) + node_remove(&tree, &nodes[k], j - k); + break; + case 1: + for (k = j; k > 0; k--) + node_remove(&tree, &nodes[k-1], k); + break; + case 2: { + node_t *start; + unsigned nnodes = j; + + start = NULL; + do { + start = tree_iter(&tree, start, + remove_iterate_cb, (void *)&nnodes); + nnodes--; + } while (start != NULL); + assert_u_eq(nnodes, 0, + "Removal terminated early"); + break; + } case 3: { + node_t *start; + unsigned nnodes = j; + + start = NULL; + do { + start = tree_reverse_iter(&tree, start, + remove_reverse_iterate_cb, + (void *)&nnodes); + nnodes--; + } while (start != NULL); + assert_u_eq(nnodes, 0, + "Removal terminated early"); + break; + } default: + not_reached(); + } + } + } + fini_gen_rand(sfmt); +#undef NNODES +#undef NBAGS +#undef SEED +} +TEST_END + +int +main(void) +{ + + return (test( + test_rb_empty, + test_rb_random)); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/rtree.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/rtree.c new file mode 100644 index 0000000..b54b3e8 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/rtree.c @@ -0,0 +1,151 @@ +#include "test/jemalloc_test.h" + +static rtree_node_elm_t * +node_alloc(size_t nelms) +{ + + return ((rtree_node_elm_t *)calloc(nelms, sizeof(rtree_node_elm_t))); +} + +static void +node_dalloc(rtree_node_elm_t *node) +{ + + free(node); +} + +TEST_BEGIN(test_rtree_get_empty) +{ + unsigned i; + + for (i = 1; i <= (sizeof(uintptr_t) << 3); i++) { + rtree_t rtree; + assert_false(rtree_new(&rtree, i, node_alloc, node_dalloc), + "Unexpected rtree_new() failure"); + assert_ptr_null(rtree_get(&rtree, 0, false), + "rtree_get() should return NULL for empty tree"); + rtree_delete(&rtree); + } +} +TEST_END + +TEST_BEGIN(test_rtree_extrema) +{ + unsigned i; + extent_node_t node_a, node_b; + + for (i = 1; i <= (sizeof(uintptr_t) << 3); i++) { + rtree_t rtree; + assert_false(rtree_new(&rtree, i, node_alloc, node_dalloc), + "Unexpected rtree_new() failure"); + + assert_false(rtree_set(&rtree, 0, &node_a), + "Unexpected rtree_set() failure"); + assert_ptr_eq(rtree_get(&rtree, 0, true), &node_a, + "rtree_get() should return previously set value"); + + assert_false(rtree_set(&rtree, ~((uintptr_t)0), &node_b), + "Unexpected rtree_set() failure"); + assert_ptr_eq(rtree_get(&rtree, ~((uintptr_t)0), true), &node_b, + "rtree_get() should return previously set value"); + + rtree_delete(&rtree); + } +} +TEST_END + +TEST_BEGIN(test_rtree_bits) +{ + unsigned i, j, k; + + for (i = 1; i < (sizeof(uintptr_t) << 3); i++) { + uintptr_t keys[] = {0, 1, + (((uintptr_t)1) << (sizeof(uintptr_t)*8-i)) - 1}; + extent_node_t node; + rtree_t rtree; + + assert_false(rtree_new(&rtree, i, node_alloc, node_dalloc), + "Unexpected rtree_new() failure"); + + for (j = 0; j < sizeof(keys)/sizeof(uintptr_t); j++) { + assert_false(rtree_set(&rtree, keys[j], &node), + "Unexpected rtree_set() failure"); + for (k = 0; k < sizeof(keys)/sizeof(uintptr_t); k++) { + assert_ptr_eq(rtree_get(&rtree, keys[k], true), + &node, "rtree_get() should return " + "previously set value and ignore " + "insignificant key bits; i=%u, j=%u, k=%u, " + "set key=%#"FMTxPTR", get key=%#"FMTxPTR, i, + j, k, keys[j], keys[k]); + } + assert_ptr_null(rtree_get(&rtree, + (((uintptr_t)1) << (sizeof(uintptr_t)*8-i)), false), + "Only leftmost rtree leaf should be set; " + "i=%u, j=%u", i, j); + assert_false(rtree_set(&rtree, keys[j], NULL), + "Unexpected rtree_set() failure"); + } + + rtree_delete(&rtree); + } +} +TEST_END + +TEST_BEGIN(test_rtree_random) +{ + unsigned i; + sfmt_t *sfmt; +#define NSET 16 +#define SEED 42 + + sfmt = init_gen_rand(SEED); + for (i = 1; i <= (sizeof(uintptr_t) << 3); i++) { + uintptr_t keys[NSET]; + extent_node_t node; + unsigned j; + rtree_t rtree; + + assert_false(rtree_new(&rtree, i, node_alloc, node_dalloc), + "Unexpected rtree_new() failure"); + + for (j = 0; j < NSET; j++) { + keys[j] = (uintptr_t)gen_rand64(sfmt); + assert_false(rtree_set(&rtree, keys[j], &node), + "Unexpected rtree_set() failure"); + assert_ptr_eq(rtree_get(&rtree, keys[j], true), &node, + "rtree_get() should return previously set value"); + } + for (j = 0; j < NSET; j++) { + assert_ptr_eq(rtree_get(&rtree, keys[j], true), &node, + "rtree_get() should return previously set value"); + } + + for (j = 0; j < NSET; j++) { + assert_false(rtree_set(&rtree, keys[j], NULL), + "Unexpected rtree_set() failure"); + assert_ptr_null(rtree_get(&rtree, keys[j], true), + "rtree_get() should return previously set value"); + } + for (j = 0; j < NSET; j++) { + assert_ptr_null(rtree_get(&rtree, keys[j], true), + "rtree_get() should return previously set value"); + } + + rtree_delete(&rtree); + } + fini_gen_rand(sfmt); +#undef NSET +#undef SEED +} +TEST_END + +int +main(void) +{ + + return (test( + test_rtree_get_empty, + test_rtree_extrema, + test_rtree_bits, + test_rtree_random)); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/size_classes.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/size_classes.c new file mode 100644 index 0000000..d3aaebd --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/size_classes.c @@ -0,0 +1,89 @@ +#include "test/jemalloc_test.h" + +static size_t +get_max_size_class(void) +{ + unsigned nhchunks; + size_t mib[4]; + size_t sz, miblen, max_size_class; + + sz = sizeof(unsigned); + assert_d_eq(mallctl("arenas.nhchunks", &nhchunks, &sz, NULL, 0), 0, + "Unexpected mallctl() error"); + + miblen = sizeof(mib) / sizeof(size_t); + assert_d_eq(mallctlnametomib("arenas.hchunk.0.size", mib, &miblen), 0, + "Unexpected mallctlnametomib() error"); + mib[2] = nhchunks - 1; + + sz = sizeof(size_t); + assert_d_eq(mallctlbymib(mib, miblen, &max_size_class, &sz, NULL, 0), 0, + "Unexpected mallctlbymib() error"); + + return (max_size_class); +} + +TEST_BEGIN(test_size_classes) +{ + size_t size_class, max_size_class; + szind_t index, max_index; + + max_size_class = get_max_size_class(); + max_index = size2index(max_size_class); + + for (index = 0, size_class = index2size(index); index < max_index || + size_class < max_size_class; index++, size_class = + index2size(index)) { + assert_true(index < max_index, + "Loop conditionals should be equivalent; index=%u, " + "size_class=%zu (%#zx)", index, size_class, size_class); + assert_true(size_class < max_size_class, + "Loop conditionals should be equivalent; index=%u, " + "size_class=%zu (%#zx)", index, size_class, size_class); + + assert_u_eq(index, size2index(size_class), + "size2index() does not reverse index2size(): index=%u -->" + " size_class=%zu --> index=%u --> size_class=%zu", index, + size_class, size2index(size_class), + index2size(size2index(size_class))); + assert_zu_eq(size_class, index2size(size2index(size_class)), + "index2size() does not reverse size2index(): index=%u -->" + " size_class=%zu --> index=%u --> size_class=%zu", index, + size_class, size2index(size_class), + index2size(size2index(size_class))); + + assert_u_eq(index+1, size2index(size_class+1), + "Next size_class does not round up properly"); + + assert_zu_eq(size_class, (index > 0) ? + s2u(index2size(index-1)+1) : s2u(1), + "s2u() does not round up to size class"); + assert_zu_eq(size_class, s2u(size_class-1), + "s2u() does not round up to size class"); + assert_zu_eq(size_class, s2u(size_class), + "s2u() does not compute same size class"); + assert_zu_eq(s2u(size_class+1), index2size(index+1), + "s2u() does not round up to next size class"); + } + + assert_u_eq(index, size2index(index2size(index)), + "size2index() does not reverse index2size()"); + assert_zu_eq(max_size_class, index2size(size2index(max_size_class)), + "index2size() does not reverse size2index()"); + + assert_zu_eq(size_class, s2u(index2size(index-1)+1), + "s2u() does not round up to size class"); + assert_zu_eq(size_class, s2u(size_class-1), + "s2u() does not round up to size class"); + assert_zu_eq(size_class, s2u(size_class), + "s2u() does not compute same size class"); +} +TEST_END + +int +main(void) +{ + + return (test( + test_size_classes)); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/stats.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/stats.c new file mode 100644 index 0000000..8e4bc63 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/stats.c @@ -0,0 +1,447 @@ +#include "test/jemalloc_test.h" + +TEST_BEGIN(test_stats_summary) +{ + size_t *cactive; + size_t sz, allocated, active, resident, mapped; + int expected = config_stats ? 0 : ENOENT; + + sz = sizeof(cactive); + assert_d_eq(mallctl("stats.cactive", &cactive, &sz, NULL, 0), expected, + "Unexpected mallctl() result"); + + sz = sizeof(size_t); + assert_d_eq(mallctl("stats.allocated", &allocated, &sz, NULL, 0), + expected, "Unexpected mallctl() result"); + assert_d_eq(mallctl("stats.active", &active, &sz, NULL, 0), expected, + "Unexpected mallctl() result"); + assert_d_eq(mallctl("stats.resident", &resident, &sz, NULL, 0), + expected, "Unexpected mallctl() result"); + assert_d_eq(mallctl("stats.mapped", &mapped, &sz, NULL, 0), expected, + "Unexpected mallctl() result"); + + if (config_stats) { + assert_zu_le(active, *cactive, + "active should be no larger than cactive"); + assert_zu_le(allocated, active, + "allocated should be no larger than active"); + assert_zu_lt(active, resident, + "active should be less than resident"); + assert_zu_lt(active, mapped, + "active should be less than mapped"); + } +} +TEST_END + +TEST_BEGIN(test_stats_huge) +{ + void *p; + uint64_t epoch; + size_t allocated; + uint64_t nmalloc, ndalloc, nrequests; + size_t sz; + int expected = config_stats ? 0 : ENOENT; + + p = mallocx(large_maxclass+1, 0); + assert_ptr_not_null(p, "Unexpected mallocx() failure"); + + assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)), 0, + "Unexpected mallctl() failure"); + + sz = sizeof(size_t); + assert_d_eq(mallctl("stats.arenas.0.huge.allocated", &allocated, &sz, + NULL, 0), expected, "Unexpected mallctl() result"); + sz = sizeof(uint64_t); + assert_d_eq(mallctl("stats.arenas.0.huge.nmalloc", &nmalloc, &sz, NULL, + 0), expected, "Unexpected mallctl() result"); + assert_d_eq(mallctl("stats.arenas.0.huge.ndalloc", &ndalloc, &sz, NULL, + 0), expected, "Unexpected mallctl() result"); + assert_d_eq(mallctl("stats.arenas.0.huge.nrequests", &nrequests, &sz, + NULL, 0), expected, "Unexpected mallctl() result"); + + if (config_stats) { + assert_zu_gt(allocated, 0, + "allocated should be greater than zero"); + assert_u64_ge(nmalloc, ndalloc, + "nmalloc should be at least as large as ndalloc"); + assert_u64_le(nmalloc, nrequests, + "nmalloc should no larger than nrequests"); + } + + dallocx(p, 0); +} +TEST_END + +TEST_BEGIN(test_stats_arenas_summary) +{ + unsigned arena; + void *little, *large, *huge; + uint64_t epoch; + size_t sz; + int expected = config_stats ? 0 : ENOENT; + size_t mapped; + uint64_t npurge, nmadvise, purged; + + arena = 0; + assert_d_eq(mallctl("thread.arena", NULL, NULL, &arena, sizeof(arena)), + 0, "Unexpected mallctl() failure"); + + little = mallocx(SMALL_MAXCLASS, 0); + assert_ptr_not_null(little, "Unexpected mallocx() failure"); + large = mallocx(large_maxclass, 0); + assert_ptr_not_null(large, "Unexpected mallocx() failure"); + huge = mallocx(chunksize, 0); + assert_ptr_not_null(huge, "Unexpected mallocx() failure"); + + assert_d_eq(mallctl("arena.0.purge", NULL, NULL, NULL, 0), 0, + "Unexpected mallctl() failure"); + + assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)), 0, + "Unexpected mallctl() failure"); + + sz = sizeof(size_t); + assert_d_eq(mallctl("stats.arenas.0.mapped", &mapped, &sz, NULL, 0), + expected, "Unexepected mallctl() result"); + sz = sizeof(uint64_t); + assert_d_eq(mallctl("stats.arenas.0.npurge", &npurge, &sz, NULL, 0), + expected, "Unexepected mallctl() result"); + assert_d_eq(mallctl("stats.arenas.0.nmadvise", &nmadvise, &sz, NULL, 0), + expected, "Unexepected mallctl() result"); + assert_d_eq(mallctl("stats.arenas.0.purged", &purged, &sz, NULL, 0), + expected, "Unexepected mallctl() result"); + + if (config_stats) { + assert_u64_gt(npurge, 0, + "At least one purge should have occurred"); + assert_u64_le(nmadvise, purged, + "nmadvise should be no greater than purged"); + } + + dallocx(little, 0); + dallocx(large, 0); + dallocx(huge, 0); +} +TEST_END + +void * +thd_start(void *arg) +{ + + return (NULL); +} + +static void +no_lazy_lock(void) +{ + thd_t thd; + + thd_create(&thd, thd_start, NULL); + thd_join(thd, NULL); +} + +TEST_BEGIN(test_stats_arenas_small) +{ + unsigned arena; + void *p; + size_t sz, allocated; + uint64_t epoch, nmalloc, ndalloc, nrequests; + int expected = config_stats ? 0 : ENOENT; + + no_lazy_lock(); /* Lazy locking would dodge tcache testing. */ + + arena = 0; + assert_d_eq(mallctl("thread.arena", NULL, NULL, &arena, sizeof(arena)), + 0, "Unexpected mallctl() failure"); + + p = mallocx(SMALL_MAXCLASS, 0); + assert_ptr_not_null(p, "Unexpected mallocx() failure"); + + assert_d_eq(mallctl("thread.tcache.flush", NULL, NULL, NULL, 0), + config_tcache ? 0 : ENOENT, "Unexpected mallctl() result"); + + assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)), 0, + "Unexpected mallctl() failure"); + + sz = sizeof(size_t); + assert_d_eq(mallctl("stats.arenas.0.small.allocated", &allocated, &sz, + NULL, 0), expected, "Unexpected mallctl() result"); + sz = sizeof(uint64_t); + assert_d_eq(mallctl("stats.arenas.0.small.nmalloc", &nmalloc, &sz, + NULL, 0), expected, "Unexpected mallctl() result"); + assert_d_eq(mallctl("stats.arenas.0.small.ndalloc", &ndalloc, &sz, + NULL, 0), expected, "Unexpected mallctl() result"); + assert_d_eq(mallctl("stats.arenas.0.small.nrequests", &nrequests, &sz, + NULL, 0), expected, "Unexpected mallctl() result"); + + if (config_stats) { + assert_zu_gt(allocated, 0, + "allocated should be greater than zero"); + assert_u64_gt(nmalloc, 0, + "nmalloc should be no greater than zero"); + assert_u64_ge(nmalloc, ndalloc, + "nmalloc should be at least as large as ndalloc"); + assert_u64_gt(nrequests, 0, + "nrequests should be greater than zero"); + } + + dallocx(p, 0); +} +TEST_END + +TEST_BEGIN(test_stats_arenas_large) +{ + unsigned arena; + void *p; + size_t sz, allocated; + uint64_t epoch, nmalloc, ndalloc, nrequests; + int expected = config_stats ? 0 : ENOENT; + + arena = 0; + assert_d_eq(mallctl("thread.arena", NULL, NULL, &arena, sizeof(arena)), + 0, "Unexpected mallctl() failure"); + + p = mallocx(large_maxclass, 0); + assert_ptr_not_null(p, "Unexpected mallocx() failure"); + + assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)), 0, + "Unexpected mallctl() failure"); + + sz = sizeof(size_t); + assert_d_eq(mallctl("stats.arenas.0.large.allocated", &allocated, &sz, + NULL, 0), expected, "Unexpected mallctl() result"); + sz = sizeof(uint64_t); + assert_d_eq(mallctl("stats.arenas.0.large.nmalloc", &nmalloc, &sz, + NULL, 0), expected, "Unexpected mallctl() result"); + assert_d_eq(mallctl("stats.arenas.0.large.ndalloc", &ndalloc, &sz, + NULL, 0), expected, "Unexpected mallctl() result"); + assert_d_eq(mallctl("stats.arenas.0.large.nrequests", &nrequests, &sz, + NULL, 0), expected, "Unexpected mallctl() result"); + + if (config_stats) { + assert_zu_gt(allocated, 0, + "allocated should be greater than zero"); + assert_zu_gt(nmalloc, 0, + "nmalloc should be greater than zero"); + assert_zu_ge(nmalloc, ndalloc, + "nmalloc should be at least as large as ndalloc"); + assert_zu_gt(nrequests, 0, + "nrequests should be greater than zero"); + } + + dallocx(p, 0); +} +TEST_END + +TEST_BEGIN(test_stats_arenas_huge) +{ + unsigned arena; + void *p; + size_t sz, allocated; + uint64_t epoch, nmalloc, ndalloc; + int expected = config_stats ? 0 : ENOENT; + + arena = 0; + assert_d_eq(mallctl("thread.arena", NULL, NULL, &arena, sizeof(arena)), + 0, "Unexpected mallctl() failure"); + + p = mallocx(chunksize, 0); + assert_ptr_not_null(p, "Unexpected mallocx() failure"); + + assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)), 0, + "Unexpected mallctl() failure"); + + sz = sizeof(size_t); + assert_d_eq(mallctl("stats.arenas.0.huge.allocated", &allocated, &sz, + NULL, 0), expected, "Unexpected mallctl() result"); + sz = sizeof(uint64_t); + assert_d_eq(mallctl("stats.arenas.0.huge.nmalloc", &nmalloc, &sz, + NULL, 0), expected, "Unexpected mallctl() result"); + assert_d_eq(mallctl("stats.arenas.0.huge.ndalloc", &ndalloc, &sz, + NULL, 0), expected, "Unexpected mallctl() result"); + + if (config_stats) { + assert_zu_gt(allocated, 0, + "allocated should be greater than zero"); + assert_zu_gt(nmalloc, 0, + "nmalloc should be greater than zero"); + assert_zu_ge(nmalloc, ndalloc, + "nmalloc should be at least as large as ndalloc"); + } + + dallocx(p, 0); +} +TEST_END + +TEST_BEGIN(test_stats_arenas_bins) +{ + unsigned arena; + void *p; + size_t sz, curruns, curregs; + uint64_t epoch, nmalloc, ndalloc, nrequests, nfills, nflushes; + uint64_t nruns, nreruns; + int expected = config_stats ? 0 : ENOENT; + + arena = 0; + assert_d_eq(mallctl("thread.arena", NULL, NULL, &arena, sizeof(arena)), + 0, "Unexpected mallctl() failure"); + + p = mallocx(arena_bin_info[0].reg_size, 0); + assert_ptr_not_null(p, "Unexpected mallocx() failure"); + + assert_d_eq(mallctl("thread.tcache.flush", NULL, NULL, NULL, 0), + config_tcache ? 0 : ENOENT, "Unexpected mallctl() result"); + + assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)), 0, + "Unexpected mallctl() failure"); + + sz = sizeof(uint64_t); + assert_d_eq(mallctl("stats.arenas.0.bins.0.nmalloc", &nmalloc, &sz, + NULL, 0), expected, "Unexpected mallctl() result"); + assert_d_eq(mallctl("stats.arenas.0.bins.0.ndalloc", &ndalloc, &sz, + NULL, 0), expected, "Unexpected mallctl() result"); + assert_d_eq(mallctl("stats.arenas.0.bins.0.nrequests", &nrequests, &sz, + NULL, 0), expected, "Unexpected mallctl() result"); + sz = sizeof(size_t); + assert_d_eq(mallctl("stats.arenas.0.bins.0.curregs", &curregs, &sz, + NULL, 0), expected, "Unexpected mallctl() result"); + + sz = sizeof(uint64_t); + assert_d_eq(mallctl("stats.arenas.0.bins.0.nfills", &nfills, &sz, + NULL, 0), config_tcache ? expected : ENOENT, + "Unexpected mallctl() result"); + assert_d_eq(mallctl("stats.arenas.0.bins.0.nflushes", &nflushes, &sz, + NULL, 0), config_tcache ? expected : ENOENT, + "Unexpected mallctl() result"); + + assert_d_eq(mallctl("stats.arenas.0.bins.0.nruns", &nruns, &sz, + NULL, 0), expected, "Unexpected mallctl() result"); + assert_d_eq(mallctl("stats.arenas.0.bins.0.nreruns", &nreruns, &sz, + NULL, 0), expected, "Unexpected mallctl() result"); + sz = sizeof(size_t); + assert_d_eq(mallctl("stats.arenas.0.bins.0.curruns", &curruns, &sz, + NULL, 0), expected, "Unexpected mallctl() result"); + + if (config_stats) { + assert_u64_gt(nmalloc, 0, + "nmalloc should be greater than zero"); + assert_u64_ge(nmalloc, ndalloc, + "nmalloc should be at least as large as ndalloc"); + assert_u64_gt(nrequests, 0, + "nrequests should be greater than zero"); + assert_zu_gt(curregs, 0, + "allocated should be greater than zero"); + if (config_tcache) { + assert_u64_gt(nfills, 0, + "At least one fill should have occurred"); + assert_u64_gt(nflushes, 0, + "At least one flush should have occurred"); + } + assert_u64_gt(nruns, 0, + "At least one run should have been allocated"); + assert_zu_gt(curruns, 0, + "At least one run should be currently allocated"); + } + + dallocx(p, 0); +} +TEST_END + +TEST_BEGIN(test_stats_arenas_lruns) +{ + unsigned arena; + void *p; + uint64_t epoch, nmalloc, ndalloc, nrequests; + size_t curruns, sz; + int expected = config_stats ? 0 : ENOENT; + + arena = 0; + assert_d_eq(mallctl("thread.arena", NULL, NULL, &arena, sizeof(arena)), + 0, "Unexpected mallctl() failure"); + + p = mallocx(LARGE_MINCLASS, 0); + assert_ptr_not_null(p, "Unexpected mallocx() failure"); + + assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)), 0, + "Unexpected mallctl() failure"); + + sz = sizeof(uint64_t); + assert_d_eq(mallctl("stats.arenas.0.lruns.0.nmalloc", &nmalloc, &sz, + NULL, 0), expected, "Unexpected mallctl() result"); + assert_d_eq(mallctl("stats.arenas.0.lruns.0.ndalloc", &ndalloc, &sz, + NULL, 0), expected, "Unexpected mallctl() result"); + assert_d_eq(mallctl("stats.arenas.0.lruns.0.nrequests", &nrequests, &sz, + NULL, 0), expected, "Unexpected mallctl() result"); + sz = sizeof(size_t); + assert_d_eq(mallctl("stats.arenas.0.lruns.0.curruns", &curruns, &sz, + NULL, 0), expected, "Unexpected mallctl() result"); + + if (config_stats) { + assert_u64_gt(nmalloc, 0, + "nmalloc should be greater than zero"); + assert_u64_ge(nmalloc, ndalloc, + "nmalloc should be at least as large as ndalloc"); + assert_u64_gt(nrequests, 0, + "nrequests should be greater than zero"); + assert_u64_gt(curruns, 0, + "At least one run should be currently allocated"); + } + + dallocx(p, 0); +} +TEST_END + +TEST_BEGIN(test_stats_arenas_hchunks) +{ + unsigned arena; + void *p; + uint64_t epoch, nmalloc, ndalloc; + size_t curhchunks, sz; + int expected = config_stats ? 0 : ENOENT; + + arena = 0; + assert_d_eq(mallctl("thread.arena", NULL, NULL, &arena, sizeof(arena)), + 0, "Unexpected mallctl() failure"); + + p = mallocx(chunksize, 0); + assert_ptr_not_null(p, "Unexpected mallocx() failure"); + + assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(epoch)), 0, + "Unexpected mallctl() failure"); + + sz = sizeof(uint64_t); + assert_d_eq(mallctl("stats.arenas.0.hchunks.0.nmalloc", &nmalloc, &sz, + NULL, 0), expected, "Unexpected mallctl() result"); + assert_d_eq(mallctl("stats.arenas.0.hchunks.0.ndalloc", &ndalloc, &sz, + NULL, 0), expected, "Unexpected mallctl() result"); + sz = sizeof(size_t); + assert_d_eq(mallctl("stats.arenas.0.hchunks.0.curhchunks", &curhchunks, + &sz, NULL, 0), expected, "Unexpected mallctl() result"); + + if (config_stats) { + assert_u64_gt(nmalloc, 0, + "nmalloc should be greater than zero"); + assert_u64_ge(nmalloc, ndalloc, + "nmalloc should be at least as large as ndalloc"); + assert_u64_gt(curhchunks, 0, + "At least one chunk should be currently allocated"); + } + + dallocx(p, 0); +} +TEST_END + +int +main(void) +{ + + return (test( + test_stats_summary, + test_stats_huge, + test_stats_arenas_summary, + test_stats_arenas_small, + test_stats_arenas_large, + test_stats_arenas_huge, + test_stats_arenas_bins, + test_stats_arenas_lruns, + test_stats_arenas_hchunks)); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/tsd.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/tsd.c new file mode 100644 index 0000000..8be787f --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/tsd.c @@ -0,0 +1,107 @@ +#include "test/jemalloc_test.h" + +#define THREAD_DATA 0x72b65c10 + +typedef unsigned int data_t; + +static bool data_cleanup_executed; + +malloc_tsd_types(data_, data_t) +malloc_tsd_protos(, data_, data_t) + +void +data_cleanup(void *arg) +{ + data_t *data = (data_t *)arg; + + if (!data_cleanup_executed) { + assert_x_eq(*data, THREAD_DATA, + "Argument passed into cleanup function should match tsd " + "value"); + } + data_cleanup_executed = true; + + /* + * Allocate during cleanup for two rounds, in order to assure that + * jemalloc's internal tsd reinitialization happens. + */ + switch (*data) { + case THREAD_DATA: + *data = 1; + data_tsd_set(data); + break; + case 1: + *data = 2; + data_tsd_set(data); + break; + case 2: + return; + default: + not_reached(); + } + + { + void *p = mallocx(1, 0); + assert_ptr_not_null(p, "Unexpeced mallocx() failure"); + dallocx(p, 0); + } +} + +malloc_tsd_externs(data_, data_t) +#define DATA_INIT 0x12345678 +malloc_tsd_data(, data_, data_t, DATA_INIT) +malloc_tsd_funcs(, data_, data_t, DATA_INIT, data_cleanup) + +static void * +thd_start(void *arg) +{ + data_t d = (data_t)(uintptr_t)arg; + void *p; + + assert_x_eq(*data_tsd_get(), DATA_INIT, + "Initial tsd get should return initialization value"); + + p = malloc(1); + assert_ptr_not_null(p, "Unexpected malloc() failure"); + + data_tsd_set(&d); + assert_x_eq(*data_tsd_get(), d, + "After tsd set, tsd get should return value that was set"); + + d = 0; + assert_x_eq(*data_tsd_get(), (data_t)(uintptr_t)arg, + "Resetting local data should have no effect on tsd"); + + free(p); + return (NULL); +} + +TEST_BEGIN(test_tsd_main_thread) +{ + + thd_start((void *) 0xa5f3e329); +} +TEST_END + +TEST_BEGIN(test_tsd_sub_thread) +{ + thd_t thd; + + data_cleanup_executed = false; + thd_create(&thd, thd_start, (void *)THREAD_DATA); + thd_join(thd, NULL); + assert_true(data_cleanup_executed, + "Cleanup function should have executed"); +} +TEST_END + +int +main(void) +{ + + data_tsd_boot(); + + return (test( + test_tsd_main_thread, + test_tsd_sub_thread)); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/util.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/util.c new file mode 100644 index 0000000..8ab39a4 --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/util.c @@ -0,0 +1,294 @@ +#include "test/jemalloc_test.h" + +TEST_BEGIN(test_pow2_ceil) +{ + unsigned i, pow2; + size_t x; + + assert_zu_eq(pow2_ceil(0), 0, "Unexpected result"); + + for (i = 0; i < sizeof(size_t) * 8; i++) { + assert_zu_eq(pow2_ceil(ZU(1) << i), ZU(1) << i, + "Unexpected result"); + } + + for (i = 2; i < sizeof(size_t) * 8; i++) { + assert_zu_eq(pow2_ceil((ZU(1) << i) - 1), ZU(1) << i, + "Unexpected result"); + } + + for (i = 0; i < sizeof(size_t) * 8 - 1; i++) { + assert_zu_eq(pow2_ceil((ZU(1) << i) + 1), ZU(1) << (i+1), + "Unexpected result"); + } + + for (pow2 = 1; pow2 < 25; pow2++) { + for (x = (ZU(1) << (pow2-1)) + 1; x <= ZU(1) << pow2; x++) { + assert_zu_eq(pow2_ceil(x), ZU(1) << pow2, + "Unexpected result, x=%zu", x); + } + } +} +TEST_END + +TEST_BEGIN(test_malloc_strtoumax_no_endptr) +{ + int err; + + set_errno(0); + assert_ju_eq(malloc_strtoumax("0", NULL, 0), 0, "Unexpected result"); + err = get_errno(); + assert_d_eq(err, 0, "Unexpected failure"); +} +TEST_END + +TEST_BEGIN(test_malloc_strtoumax) +{ + struct test_s { + const char *input; + const char *expected_remainder; + int base; + int expected_errno; + const char *expected_errno_name; + uintmax_t expected_x; + }; +#define ERR(e) e, #e +#define KUMAX(x) ((uintmax_t)x##ULL) + struct test_s tests[] = { + {"0", "0", -1, ERR(EINVAL), UINTMAX_MAX}, + {"0", "0", 1, ERR(EINVAL), UINTMAX_MAX}, + {"0", "0", 37, ERR(EINVAL), UINTMAX_MAX}, + + {"", "", 0, ERR(EINVAL), UINTMAX_MAX}, + {"+", "+", 0, ERR(EINVAL), UINTMAX_MAX}, + {"++3", "++3", 0, ERR(EINVAL), UINTMAX_MAX}, + {"-", "-", 0, ERR(EINVAL), UINTMAX_MAX}, + + {"42", "", 0, ERR(0), KUMAX(42)}, + {"+42", "", 0, ERR(0), KUMAX(42)}, + {"-42", "", 0, ERR(0), KUMAX(-42)}, + {"042", "", 0, ERR(0), KUMAX(042)}, + {"+042", "", 0, ERR(0), KUMAX(042)}, + {"-042", "", 0, ERR(0), KUMAX(-042)}, + {"0x42", "", 0, ERR(0), KUMAX(0x42)}, + {"+0x42", "", 0, ERR(0), KUMAX(0x42)}, + {"-0x42", "", 0, ERR(0), KUMAX(-0x42)}, + + {"0", "", 0, ERR(0), KUMAX(0)}, + {"1", "", 0, ERR(0), KUMAX(1)}, + + {"42", "", 0, ERR(0), KUMAX(42)}, + {" 42", "", 0, ERR(0), KUMAX(42)}, + {"42 ", " ", 0, ERR(0), KUMAX(42)}, + {"0x", "x", 0, ERR(0), KUMAX(0)}, + {"42x", "x", 0, ERR(0), KUMAX(42)}, + + {"07", "", 0, ERR(0), KUMAX(7)}, + {"010", "", 0, ERR(0), KUMAX(8)}, + {"08", "8", 0, ERR(0), KUMAX(0)}, + {"0_", "_", 0, ERR(0), KUMAX(0)}, + + {"0x", "x", 0, ERR(0), KUMAX(0)}, + {"0X", "X", 0, ERR(0), KUMAX(0)}, + {"0xg", "xg", 0, ERR(0), KUMAX(0)}, + {"0XA", "", 0, ERR(0), KUMAX(10)}, + + {"010", "", 10, ERR(0), KUMAX(10)}, + {"0x3", "x3", 10, ERR(0), KUMAX(0)}, + + {"12", "2", 2, ERR(0), KUMAX(1)}, + {"78", "8", 8, ERR(0), KUMAX(7)}, + {"9a", "a", 10, ERR(0), KUMAX(9)}, + {"9A", "A", 10, ERR(0), KUMAX(9)}, + {"fg", "g", 16, ERR(0), KUMAX(15)}, + {"FG", "G", 16, ERR(0), KUMAX(15)}, + {"0xfg", "g", 16, ERR(0), KUMAX(15)}, + {"0XFG", "G", 16, ERR(0), KUMAX(15)}, + {"z_", "_", 36, ERR(0), KUMAX(35)}, + {"Z_", "_", 36, ERR(0), KUMAX(35)} + }; +#undef ERR +#undef KUMAX + unsigned i; + + for (i = 0; i < sizeof(tests)/sizeof(struct test_s); i++) { + struct test_s *test = &tests[i]; + int err; + uintmax_t result; + char *remainder; + + set_errno(0); + result = malloc_strtoumax(test->input, &remainder, test->base); + err = get_errno(); + assert_d_eq(err, test->expected_errno, + "Expected errno %s for \"%s\", base %d", + test->expected_errno_name, test->input, test->base); + assert_str_eq(remainder, test->expected_remainder, + "Unexpected remainder for \"%s\", base %d", + test->input, test->base); + if (err == 0) { + assert_ju_eq(result, test->expected_x, + "Unexpected result for \"%s\", base %d", + test->input, test->base); + } + } +} +TEST_END + +TEST_BEGIN(test_malloc_snprintf_truncated) +{ +#define BUFLEN 15 + char buf[BUFLEN]; + int result; + size_t len; +#define TEST(expected_str_untruncated, ...) do { \ + result = malloc_snprintf(buf, len, __VA_ARGS__); \ + assert_d_eq(strncmp(buf, expected_str_untruncated, len-1), 0, \ + "Unexpected string inequality (\"%s\" vs \"%s\")", \ + buf, expected_str_untruncated); \ + assert_d_eq(result, strlen(expected_str_untruncated), \ + "Unexpected result"); \ +} while (0) + + for (len = 1; len < BUFLEN; len++) { + TEST("012346789", "012346789"); + TEST("a0123b", "a%sb", "0123"); + TEST("a01234567", "a%s%s", "0123", "4567"); + TEST("a0123 ", "a%-6s", "0123"); + TEST("a 0123", "a%6s", "0123"); + TEST("a 012", "a%6.3s", "0123"); + TEST("a 012", "a%*.*s", 6, 3, "0123"); + TEST("a 123b", "a% db", 123); + TEST("a123b", "a%-db", 123); + TEST("a-123b", "a%-db", -123); + TEST("a+123b", "a%+db", 123); + } +#undef BUFLEN +#undef TEST +} +TEST_END + +TEST_BEGIN(test_malloc_snprintf) +{ +#define BUFLEN 128 + char buf[BUFLEN]; + int result; +#define TEST(expected_str, ...) do { \ + result = malloc_snprintf(buf, sizeof(buf), __VA_ARGS__); \ + assert_str_eq(buf, expected_str, "Unexpected output"); \ + assert_d_eq(result, strlen(expected_str), "Unexpected result"); \ +} while (0) + + TEST("hello", "hello"); + + TEST("50%, 100%", "50%%, %d%%", 100); + + TEST("a0123b", "a%sb", "0123"); + + TEST("a 0123b", "a%5sb", "0123"); + TEST("a 0123b", "a%*sb", 5, "0123"); + + TEST("a0123 b", "a%-5sb", "0123"); + TEST("a0123b", "a%*sb", -1, "0123"); + TEST("a0123 b", "a%*sb", -5, "0123"); + TEST("a0123 b", "a%-*sb", -5, "0123"); + + TEST("a012b", "a%.3sb", "0123"); + TEST("a012b", "a%.*sb", 3, "0123"); + TEST("a0123b", "a%.*sb", -3, "0123"); + + TEST("a 012b", "a%5.3sb", "0123"); + TEST("a 012b", "a%5.*sb", 3, "0123"); + TEST("a 012b", "a%*.3sb", 5, "0123"); + TEST("a 012b", "a%*.*sb", 5, 3, "0123"); + TEST("a 0123b", "a%*.*sb", 5, -3, "0123"); + + TEST("_abcd_", "_%x_", 0xabcd); + TEST("_0xabcd_", "_%#x_", 0xabcd); + TEST("_1234_", "_%o_", 01234); + TEST("_01234_", "_%#o_", 01234); + TEST("_1234_", "_%u_", 1234); + + TEST("_1234_", "_%d_", 1234); + TEST("_ 1234_", "_% d_", 1234); + TEST("_+1234_", "_%+d_", 1234); + TEST("_-1234_", "_%d_", -1234); + TEST("_-1234_", "_% d_", -1234); + TEST("_-1234_", "_%+d_", -1234); + + TEST("_-1234_", "_%d_", -1234); + TEST("_1234_", "_%d_", 1234); + TEST("_-1234_", "_%i_", -1234); + TEST("_1234_", "_%i_", 1234); + TEST("_01234_", "_%#o_", 01234); + TEST("_1234_", "_%u_", 1234); + TEST("_0x1234abc_", "_%#x_", 0x1234abc); + TEST("_0X1234ABC_", "_%#X_", 0x1234abc); + TEST("_c_", "_%c_", 'c'); + TEST("_string_", "_%s_", "string"); + TEST("_0x42_", "_%p_", ((void *)0x42)); + + TEST("_-1234_", "_%ld_", ((long)-1234)); + TEST("_1234_", "_%ld_", ((long)1234)); + TEST("_-1234_", "_%li_", ((long)-1234)); + TEST("_1234_", "_%li_", ((long)1234)); + TEST("_01234_", "_%#lo_", ((long)01234)); + TEST("_1234_", "_%lu_", ((long)1234)); + TEST("_0x1234abc_", "_%#lx_", ((long)0x1234abc)); + TEST("_0X1234ABC_", "_%#lX_", ((long)0x1234ABC)); + + TEST("_-1234_", "_%lld_", ((long long)-1234)); + TEST("_1234_", "_%lld_", ((long long)1234)); + TEST("_-1234_", "_%lli_", ((long long)-1234)); + TEST("_1234_", "_%lli_", ((long long)1234)); + TEST("_01234_", "_%#llo_", ((long long)01234)); + TEST("_1234_", "_%llu_", ((long long)1234)); + TEST("_0x1234abc_", "_%#llx_", ((long long)0x1234abc)); + TEST("_0X1234ABC_", "_%#llX_", ((long long)0x1234ABC)); + + TEST("_-1234_", "_%qd_", ((long long)-1234)); + TEST("_1234_", "_%qd_", ((long long)1234)); + TEST("_-1234_", "_%qi_", ((long long)-1234)); + TEST("_1234_", "_%qi_", ((long long)1234)); + TEST("_01234_", "_%#qo_", ((long long)01234)); + TEST("_1234_", "_%qu_", ((long long)1234)); + TEST("_0x1234abc_", "_%#qx_", ((long long)0x1234abc)); + TEST("_0X1234ABC_", "_%#qX_", ((long long)0x1234ABC)); + + TEST("_-1234_", "_%jd_", ((intmax_t)-1234)); + TEST("_1234_", "_%jd_", ((intmax_t)1234)); + TEST("_-1234_", "_%ji_", ((intmax_t)-1234)); + TEST("_1234_", "_%ji_", ((intmax_t)1234)); + TEST("_01234_", "_%#jo_", ((intmax_t)01234)); + TEST("_1234_", "_%ju_", ((intmax_t)1234)); + TEST("_0x1234abc_", "_%#jx_", ((intmax_t)0x1234abc)); + TEST("_0X1234ABC_", "_%#jX_", ((intmax_t)0x1234ABC)); + + TEST("_1234_", "_%td_", ((ptrdiff_t)1234)); + TEST("_-1234_", "_%td_", ((ptrdiff_t)-1234)); + TEST("_1234_", "_%ti_", ((ptrdiff_t)1234)); + TEST("_-1234_", "_%ti_", ((ptrdiff_t)-1234)); + + TEST("_-1234_", "_%zd_", ((ssize_t)-1234)); + TEST("_1234_", "_%zd_", ((ssize_t)1234)); + TEST("_-1234_", "_%zi_", ((ssize_t)-1234)); + TEST("_1234_", "_%zi_", ((ssize_t)1234)); + TEST("_01234_", "_%#zo_", ((ssize_t)01234)); + TEST("_1234_", "_%zu_", ((ssize_t)1234)); + TEST("_0x1234abc_", "_%#zx_", ((ssize_t)0x1234abc)); + TEST("_0X1234ABC_", "_%#zX_", ((ssize_t)0x1234ABC)); +#undef BUFLEN +} +TEST_END + +int +main(void) +{ + + return (test( + test_pow2_ceil, + test_malloc_strtoumax_no_endptr, + test_malloc_strtoumax, + test_malloc_snprintf_truncated, + test_malloc_snprintf)); +} diff --git a/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/zero.c b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/zero.c new file mode 100644 index 0000000..93afc2b --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/deps/jemalloc/test/unit/zero.c @@ -0,0 +1,78 @@ +#include "test/jemalloc_test.h" + +#ifdef JEMALLOC_FILL +const char *malloc_conf = + "abort:false,junk:false,zero:true,redzone:false,quarantine:0"; +#endif + +static void +test_zero(size_t sz_min, size_t sz_max) +{ + char *s; + size_t sz_prev, sz, i; + + sz_prev = 0; + s = (char *)mallocx(sz_min, 0); + assert_ptr_not_null((void *)s, "Unexpected mallocx() failure"); + + for (sz = sallocx(s, 0); sz <= sz_max; + sz_prev = sz, sz = sallocx(s, 0)) { + if (sz_prev > 0) { + assert_c_eq(s[0], 'a', + "Previously allocated byte %zu/%zu is corrupted", + ZU(0), sz_prev); + assert_c_eq(s[sz_prev-1], 'a', + "Previously allocated byte %zu/%zu is corrupted", + sz_prev-1, sz_prev); + } + + for (i = sz_prev; i < sz; i++) { + assert_c_eq(s[i], 0x0, + "Newly allocated byte %zu/%zu isn't zero-filled", + i, sz); + s[i] = 'a'; + } + + if (xallocx(s, sz+1, 0, 0) == sz) { + s = (char *)rallocx(s, sz+1, 0); + assert_ptr_not_null((void *)s, + "Unexpected rallocx() failure"); + } + } + + dallocx(s, 0); +} + +TEST_BEGIN(test_zero_small) +{ + + test_skip_if(!config_fill); + test_zero(1, SMALL_MAXCLASS-1); +} +TEST_END + +TEST_BEGIN(test_zero_large) +{ + + test_skip_if(!config_fill); + test_zero(SMALL_MAXCLASS+1, large_maxclass); +} +TEST_END + +TEST_BEGIN(test_zero_huge) +{ + + test_skip_if(!config_fill); + test_zero(large_maxclass+1, chunksize*2); +} +TEST_END + +int +main(void) +{ + + return (test( + test_zero_small, + test_zero_large, + test_zero_huge)); +} diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/Android.mk b/redis-android/src/main/jni/redis-4.0.8/deps/lua/Android.mk similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/Android.mk rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/Android.mk diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/COPYRIGHT b/redis-android/src/main/jni/redis-4.0.8/deps/lua/COPYRIGHT similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/COPYRIGHT rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/COPYRIGHT diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/HISTORY b/redis-android/src/main/jni/redis-4.0.8/deps/lua/HISTORY similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/HISTORY rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/HISTORY diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/INSTALL b/redis-android/src/main/jni/redis-4.0.8/deps/lua/INSTALL similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/INSTALL rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/INSTALL diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/Makefile b/redis-android/src/main/jni/redis-4.0.8/deps/lua/Makefile similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/Makefile rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/Makefile diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/README b/redis-android/src/main/jni/redis-4.0.8/deps/lua/README similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/README rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/README diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/doc/contents.html b/redis-android/src/main/jni/redis-4.0.8/deps/lua/doc/contents.html similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/doc/contents.html rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/doc/contents.html diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/doc/cover.png b/redis-android/src/main/jni/redis-4.0.8/deps/lua/doc/cover.png similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/doc/cover.png rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/doc/cover.png diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/doc/logo.gif b/redis-android/src/main/jni/redis-4.0.8/deps/lua/doc/logo.gif similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/doc/logo.gif rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/doc/logo.gif diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/doc/lua.1 b/redis-android/src/main/jni/redis-4.0.8/deps/lua/doc/lua.1 similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/doc/lua.1 rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/doc/lua.1 diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/doc/lua.css b/redis-android/src/main/jni/redis-4.0.8/deps/lua/doc/lua.css similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/doc/lua.css rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/doc/lua.css diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/doc/lua.html b/redis-android/src/main/jni/redis-4.0.8/deps/lua/doc/lua.html similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/doc/lua.html rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/doc/lua.html diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/doc/luac.1 b/redis-android/src/main/jni/redis-4.0.8/deps/lua/doc/luac.1 similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/doc/luac.1 rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/doc/luac.1 diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/doc/luac.html b/redis-android/src/main/jni/redis-4.0.8/deps/lua/doc/luac.html similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/doc/luac.html rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/doc/luac.html diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/doc/manual.css b/redis-android/src/main/jni/redis-4.0.8/deps/lua/doc/manual.css similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/doc/manual.css rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/doc/manual.css diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/doc/manual.html b/redis-android/src/main/jni/redis-4.0.8/deps/lua/doc/manual.html similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/doc/manual.html rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/doc/manual.html diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/doc/readme.html b/redis-android/src/main/jni/redis-4.0.8/deps/lua/doc/readme.html similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/doc/readme.html rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/doc/readme.html diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/etc/Makefile b/redis-android/src/main/jni/redis-4.0.8/deps/lua/etc/Makefile similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/etc/Makefile rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/etc/Makefile diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/etc/README b/redis-android/src/main/jni/redis-4.0.8/deps/lua/etc/README similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/etc/README rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/etc/README diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/etc/all.c b/redis-android/src/main/jni/redis-4.0.8/deps/lua/etc/all.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/etc/all.c rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/etc/all.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/etc/lua.hpp b/redis-android/src/main/jni/redis-4.0.8/deps/lua/etc/lua.hpp similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/etc/lua.hpp rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/etc/lua.hpp diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/etc/lua.ico b/redis-android/src/main/jni/redis-4.0.8/deps/lua/etc/lua.ico similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/etc/lua.ico rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/etc/lua.ico diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/etc/lua.pc b/redis-android/src/main/jni/redis-4.0.8/deps/lua/etc/lua.pc similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/etc/lua.pc rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/etc/lua.pc diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/etc/luavs.bat b/redis-android/src/main/jni/redis-4.0.8/deps/lua/etc/luavs.bat similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/etc/luavs.bat rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/etc/luavs.bat diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/etc/min.c b/redis-android/src/main/jni/redis-4.0.8/deps/lua/etc/min.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/etc/min.c rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/etc/min.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/etc/noparser.c b/redis-android/src/main/jni/redis-4.0.8/deps/lua/etc/noparser.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/etc/noparser.c rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/etc/noparser.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/etc/strict.lua b/redis-android/src/main/jni/redis-4.0.8/deps/lua/etc/strict.lua similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/etc/strict.lua rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/etc/strict.lua diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/Makefile b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/Makefile similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/Makefile rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/Makefile diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/fpconv.c b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/fpconv.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/fpconv.c rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/fpconv.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/fpconv.h b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/fpconv.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/fpconv.h rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/fpconv.h diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lapi.c b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lapi.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lapi.c rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lapi.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lapi.h b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lapi.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lapi.h rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lapi.h diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lauxlib.c b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lauxlib.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lauxlib.c rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lauxlib.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lauxlib.h b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lauxlib.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lauxlib.h rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lauxlib.h diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lbaselib.c b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lbaselib.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lbaselib.c rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lbaselib.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lcode.c b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lcode.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lcode.c rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lcode.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lcode.h b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lcode.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lcode.h rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lcode.h diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/ldblib.c b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/ldblib.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/ldblib.c rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/ldblib.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/ldebug.c b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/ldebug.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/ldebug.c rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/ldebug.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/ldebug.h b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/ldebug.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/ldebug.h rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/ldebug.h diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/ldo.c b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/ldo.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/ldo.c rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/ldo.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/ldo.h b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/ldo.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/ldo.h rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/ldo.h diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/ldump.c b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/ldump.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/ldump.c rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/ldump.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lfunc.c b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lfunc.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lfunc.c rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lfunc.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lfunc.h b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lfunc.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lfunc.h rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lfunc.h diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lgc.c b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lgc.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lgc.c rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lgc.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lgc.h b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lgc.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lgc.h rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lgc.h diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/linit.c b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/linit.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/linit.c rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/linit.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/liolib.c b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/liolib.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/liolib.c rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/liolib.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/llex.c b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/llex.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/llex.c rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/llex.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/llex.h b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/llex.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/llex.h rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/llex.h diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/llimits.h b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/llimits.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/llimits.h rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/llimits.h diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lmathlib.c b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lmathlib.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lmathlib.c rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lmathlib.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lmem.c b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lmem.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lmem.c rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lmem.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lmem.h b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lmem.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lmem.h rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lmem.h diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/loadlib.c b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/loadlib.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/loadlib.c rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/loadlib.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lobject.c b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lobject.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lobject.c rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lobject.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lobject.h b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lobject.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lobject.h rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lobject.h diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lopcodes.c b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lopcodes.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lopcodes.c rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lopcodes.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lopcodes.h b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lopcodes.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lopcodes.h rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lopcodes.h diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/loslib.c b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/loslib.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/loslib.c rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/loslib.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lparser.c b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lparser.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lparser.c rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lparser.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lparser.h b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lparser.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lparser.h rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lparser.h diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lstate.c b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lstate.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lstate.c rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lstate.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lstate.h b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lstate.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lstate.h rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lstate.h diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lstring.c b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lstring.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lstring.c rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lstring.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lstring.h b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lstring.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lstring.h rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lstring.h diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lstrlib.c b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lstrlib.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lstrlib.c rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lstrlib.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/ltable.c b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/ltable.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/ltable.c rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/ltable.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/ltable.h b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/ltable.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/ltable.h rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/ltable.h diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/ltablib.c b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/ltablib.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/ltablib.c rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/ltablib.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/ltm.c b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/ltm.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/ltm.c rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/ltm.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/ltm.h b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/ltm.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/ltm.h rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/ltm.h diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lua.c b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lua.c similarity index 99% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lua.c rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lua.c index d8c8f98..44b089b 100644 --- a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lua.c +++ b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lua.c @@ -373,10 +373,11 @@ static int pmain (lua_State *L) { return 0; } + #ifdef __ANDROID__ -int dummy_main (int argc, char **argv) { + int dummy_main (int argc, char **argv) { #else -int main (int argc, char **argv) { + int main (int argc, char **argv) { #endif int status; struct Smain s; diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lua.h b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lua.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lua.h rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lua.h diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lua_bit.c b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lua_bit.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lua_bit.c rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lua_bit.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lua_cjson.c b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lua_cjson.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lua_cjson.c rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lua_cjson.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lua_cmsgpack.c b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lua_cmsgpack.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lua_cmsgpack.c rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lua_cmsgpack.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lua_struct.c b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lua_struct.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lua_struct.c rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lua_struct.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/luac.c b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/luac.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/luac.c rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/luac.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/luaconf.h b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/luaconf.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/luaconf.h rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/luaconf.h diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lualib.h b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lualib.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lualib.h rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lualib.h diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lundump.c b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lundump.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lundump.c rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lundump.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lundump.h b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lundump.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lundump.h rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lundump.h diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lvm.c b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lvm.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lvm.c rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lvm.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lvm.h b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lvm.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lvm.h rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lvm.h diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lzio.c b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lzio.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lzio.c rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lzio.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lzio.h b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lzio.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/lzio.h rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/lzio.h diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/print.c b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/print.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/print.c rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/print.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/strbuf.c b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/strbuf.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/strbuf.c rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/strbuf.c diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/src/strbuf.h b/redis-android/src/main/jni/redis-4.0.8/deps/lua/src/strbuf.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/src/strbuf.h rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/src/strbuf.h diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/test/README b/redis-android/src/main/jni/redis-4.0.8/deps/lua/test/README similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/test/README rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/test/README diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/test/bisect.lua b/redis-android/src/main/jni/redis-4.0.8/deps/lua/test/bisect.lua similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/test/bisect.lua rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/test/bisect.lua diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/test/cf.lua b/redis-android/src/main/jni/redis-4.0.8/deps/lua/test/cf.lua similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/test/cf.lua rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/test/cf.lua diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/test/echo.lua b/redis-android/src/main/jni/redis-4.0.8/deps/lua/test/echo.lua similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/test/echo.lua rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/test/echo.lua diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/test/env.lua b/redis-android/src/main/jni/redis-4.0.8/deps/lua/test/env.lua similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/test/env.lua rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/test/env.lua diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/test/factorial.lua b/redis-android/src/main/jni/redis-4.0.8/deps/lua/test/factorial.lua similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/test/factorial.lua rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/test/factorial.lua diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/test/fib.lua b/redis-android/src/main/jni/redis-4.0.8/deps/lua/test/fib.lua similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/test/fib.lua rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/test/fib.lua diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/test/fibfor.lua b/redis-android/src/main/jni/redis-4.0.8/deps/lua/test/fibfor.lua similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/test/fibfor.lua rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/test/fibfor.lua diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/test/globals.lua b/redis-android/src/main/jni/redis-4.0.8/deps/lua/test/globals.lua similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/test/globals.lua rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/test/globals.lua diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/test/hello.lua b/redis-android/src/main/jni/redis-4.0.8/deps/lua/test/hello.lua similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/test/hello.lua rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/test/hello.lua diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/test/life.lua b/redis-android/src/main/jni/redis-4.0.8/deps/lua/test/life.lua similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/test/life.lua rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/test/life.lua diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/test/luac.lua b/redis-android/src/main/jni/redis-4.0.8/deps/lua/test/luac.lua similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/test/luac.lua rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/test/luac.lua diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/test/printf.lua b/redis-android/src/main/jni/redis-4.0.8/deps/lua/test/printf.lua similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/test/printf.lua rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/test/printf.lua diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/test/readonly.lua b/redis-android/src/main/jni/redis-4.0.8/deps/lua/test/readonly.lua similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/test/readonly.lua rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/test/readonly.lua diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/test/sieve.lua b/redis-android/src/main/jni/redis-4.0.8/deps/lua/test/sieve.lua similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/test/sieve.lua rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/test/sieve.lua diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/test/sort.lua b/redis-android/src/main/jni/redis-4.0.8/deps/lua/test/sort.lua similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/test/sort.lua rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/test/sort.lua diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/test/table.lua b/redis-android/src/main/jni/redis-4.0.8/deps/lua/test/table.lua similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/test/table.lua rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/test/table.lua diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/test/trace-calls.lua b/redis-android/src/main/jni/redis-4.0.8/deps/lua/test/trace-calls.lua similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/test/trace-calls.lua rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/test/trace-calls.lua diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/test/trace-globals.lua b/redis-android/src/main/jni/redis-4.0.8/deps/lua/test/trace-globals.lua similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/test/trace-globals.lua rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/test/trace-globals.lua diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/lua/test/xd.lua b/redis-android/src/main/jni/redis-4.0.8/deps/lua/test/xd.lua similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/lua/test/xd.lua rename to redis-android/src/main/jni/redis-4.0.8/deps/lua/test/xd.lua diff --git a/redis-android/src/main/jni/redis-4.0.6/deps/update-jemalloc.sh b/redis-android/src/main/jni/redis-4.0.8/deps/update-jemalloc.sh similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/deps/update-jemalloc.sh rename to redis-android/src/main/jni/redis-4.0.8/deps/update-jemalloc.sh diff --git a/redis-android/src/main/jni/redis-4.0.6/redis.conf b/redis-android/src/main/jni/redis-4.0.8/redis.conf similarity index 98% rename from redis-android/src/main/jni/redis-4.0.6/redis.conf rename to redis-android/src/main/jni/redis-4.0.8/redis.conf index 7afd35a..5398482 100644 --- a/redis-android/src/main/jni/redis-4.0.6/redis.conf +++ b/redis-android/src/main/jni/redis-4.0.8/redis.conf @@ -1154,6 +1154,20 @@ client-output-buffer-limit normal 0 0 0 client-output-buffer-limit slave 256mb 64mb 60 client-output-buffer-limit pubsub 32mb 8mb 60 +# Client query buffers accumulate new commands. They are limited to a fixed +# amount by default in order to avoid that a protocol desynchronization (for +# instance due to a bug in the client) will lead to unbound memory usage in +# the query buffer. However you can configure it here if you have very special +# needs, such us huge multi/exec requests or alike. +# +# client-query-buffer-limit 1gb + +# In the Redis protocol, bulk requests, that are, elements representing single +# strings, are normally limited ot 512 mb. However you can change this limit +# here. +# +# proto-max-bulk-len 512mb + # Redis calls an internal function to perform many background tasks, like # closing connections of clients in timeout, purging expired keys that are # never requested, and so forth. diff --git a/redis-android/src/main/release.c b/redis-android/src/main/jni/redis-4.0.8/release.c similarity index 100% rename from redis-android/src/main/release.c rename to redis-android/src/main/jni/redis-4.0.8/release.c diff --git a/redis-android/src/main/jni/redis-4.0.6/runtest b/redis-android/src/main/jni/redis-4.0.8/runtest similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/runtest rename to redis-android/src/main/jni/redis-4.0.8/runtest diff --git a/redis-android/src/main/jni/redis-4.0.6/runtest-cluster b/redis-android/src/main/jni/redis-4.0.8/runtest-cluster similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/runtest-cluster rename to redis-android/src/main/jni/redis-4.0.8/runtest-cluster diff --git a/redis-android/src/main/jni/redis-4.0.6/runtest-sentinel b/redis-android/src/main/jni/redis-4.0.8/runtest-sentinel similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/runtest-sentinel rename to redis-android/src/main/jni/redis-4.0.8/runtest-sentinel diff --git a/redis-android/src/main/jni/redis-4.0.6/sentinel.conf b/redis-android/src/main/jni/redis-4.0.8/sentinel.conf similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/sentinel.conf rename to redis-android/src/main/jni/redis-4.0.8/sentinel.conf diff --git a/redis-android/src/main/jni/redis-4.0.6/src/.gitignore b/redis-android/src/main/jni/redis-4.0.8/src/.gitignore similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/.gitignore rename to redis-android/src/main/jni/redis-4.0.8/src/.gitignore diff --git a/redis-android/src/main/jni/redis-4.0.6/src/Makefile b/redis-android/src/main/jni/redis-4.0.8/src/Makefile similarity index 95% rename from redis-android/src/main/jni/redis-4.0.6/src/Makefile rename to redis-android/src/main/jni/redis-4.0.8/src/Makefile index d05af21..86e0b3f 100644 --- a/redis-android/src/main/jni/redis-4.0.6/src/Makefile +++ b/redis-android/src/main/jni/redis-4.0.8/src/Makefile @@ -282,11 +282,11 @@ helgrind: src/help.h: @../utils/generate-command-help.rb > help.h -#install: all -# @mkdir -p $(INSTALL_BIN) -# $(REDIS_INSTALL) $(REDIS_SERVER_NAME) $(INSTALL_BIN) -# $(REDIS_INSTALL) $(REDIS_BENCHMARK_NAME) $(INSTALL_BIN) -# $(REDIS_INSTALL) $(REDIS_CLI_NAME) $(INSTALL_BIN) -# $(REDIS_INSTALL) $(REDIS_CHECK_RDB_NAME) $(INSTALL_BIN) -# $(REDIS_INSTALL) $(REDIS_CHECK_AOF_NAME) $(INSTALL_BIN) -# @ln -sf $(REDIS_SERVER_NAME) $(INSTALL_BIN)/$(REDIS_SENTINEL_NAME) +install: all + @mkdir -p $(INSTALL_BIN) + $(REDIS_INSTALL) $(REDIS_SERVER_NAME) $(INSTALL_BIN) + $(REDIS_INSTALL) $(REDIS_BENCHMARK_NAME) $(INSTALL_BIN) + $(REDIS_INSTALL) $(REDIS_CLI_NAME) $(INSTALL_BIN) + $(REDIS_INSTALL) $(REDIS_CHECK_RDB_NAME) $(INSTALL_BIN) + $(REDIS_INSTALL) $(REDIS_CHECK_AOF_NAME) $(INSTALL_BIN) + @ln -sf $(REDIS_SERVER_NAME) $(INSTALL_BIN)/$(REDIS_SENTINEL_NAME) diff --git a/redis-android/src/main/jni/redis-4.0.6/src/adlist.c b/redis-android/src/main/jni/redis-4.0.8/src/adlist.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/adlist.c rename to redis-android/src/main/jni/redis-4.0.8/src/adlist.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/adlist.h b/redis-android/src/main/jni/redis-4.0.8/src/adlist.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/adlist.h rename to redis-android/src/main/jni/redis-4.0.8/src/adlist.h diff --git a/redis-android/src/main/jni/redis-4.0.6/src/ae.c b/redis-android/src/main/jni/redis-4.0.8/src/ae.c similarity index 99% rename from redis-android/src/main/jni/redis-4.0.6/src/ae.c rename to redis-android/src/main/jni/redis-4.0.8/src/ae.c index 265ef79..9e3ff43 100644 --- a/redis-android/src/main/jni/redis-4.0.6/src/ae.c +++ b/redis-android/src/main/jni/redis-4.0.8/src/ae.c @@ -39,8 +39,10 @@ #include #include #include -#include -#include +#ifdef __ANDROID__ + #include + #include +#endif #include "ae.h" #include "zmalloc.h" diff --git a/redis-android/src/main/jni/redis-4.0.6/src/ae.h b/redis-android/src/main/jni/redis-4.0.8/src/ae.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/ae.h rename to redis-android/src/main/jni/redis-4.0.8/src/ae.h diff --git a/redis-android/src/main/jni/redis-4.0.6/src/ae_epoll.c b/redis-android/src/main/jni/redis-4.0.8/src/ae_epoll.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/ae_epoll.c rename to redis-android/src/main/jni/redis-4.0.8/src/ae_epoll.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/ae_evport.c b/redis-android/src/main/jni/redis-4.0.8/src/ae_evport.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/ae_evport.c rename to redis-android/src/main/jni/redis-4.0.8/src/ae_evport.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/ae_kqueue.c b/redis-android/src/main/jni/redis-4.0.8/src/ae_kqueue.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/ae_kqueue.c rename to redis-android/src/main/jni/redis-4.0.8/src/ae_kqueue.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/ae_select.c b/redis-android/src/main/jni/redis-4.0.8/src/ae_select.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/ae_select.c rename to redis-android/src/main/jni/redis-4.0.8/src/ae_select.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/anet.c b/redis-android/src/main/jni/redis-4.0.8/src/anet.c similarity index 99% rename from redis-android/src/main/jni/redis-4.0.6/src/anet.c rename to redis-android/src/main/jni/redis-4.0.8/src/anet.c index c93541f..53a56b0 100644 --- a/redis-android/src/main/jni/redis-4.0.6/src/anet.c +++ b/redis-android/src/main/jni/redis-4.0.8/src/anet.c @@ -488,7 +488,7 @@ static int _anetTcpServer(char *err, int port, char *bindaddr, int af, int backl goto end; } if (p == NULL) { - anetSetError(err, "unable to bind socket, errno: %d", port); + anetSetError(err, "unable to bind socket, errno: %d", errno); goto error; } diff --git a/redis-android/src/main/jni/redis-4.0.6/src/anet.h b/redis-android/src/main/jni/redis-4.0.8/src/anet.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/anet.h rename to redis-android/src/main/jni/redis-4.0.8/src/anet.h diff --git a/redis-android/src/main/jni/redis-4.0.6/src/aof.c b/redis-android/src/main/jni/redis-4.0.8/src/aof.c similarity index 97% rename from redis-android/src/main/jni/redis-4.0.6/src/aof.c rename to redis-android/src/main/jni/redis-4.0.8/src/aof.c index 0593b27..c085d77 100644 --- a/redis-android/src/main/jni/redis-4.0.6/src/aof.c +++ b/redis-android/src/main/jni/redis-4.0.8/src/aof.c @@ -237,11 +237,11 @@ void stopAppendOnly(void) { * at runtime using the CONFIG command. */ int startAppendOnly(void) { char cwd[MAXPATHLEN]; /* Current working dir path for error messages. */ + int newfd; - server.aof_last_fsync = server.unixtime; - server.aof_fd = open(server.aof_filename,O_WRONLY|O_APPEND|O_CREAT,0644); + newfd = open(server.aof_filename,O_WRONLY|O_APPEND|O_CREAT,0644); serverAssert(server.aof_state == AOF_OFF); - if (server.aof_fd == -1) { + if (newfd == -1) { char *cwdp = getcwd(cwd,MAXPATHLEN); serverLog(LL_WARNING, @@ -256,16 +256,46 @@ int startAppendOnly(void) { server.aof_rewrite_scheduled = 1; serverLog(LL_WARNING,"AOF was enabled but there is already a child process saving an RDB file on disk. An AOF background was scheduled to start when possible."); } else if (rewriteAppendOnlyFileBackground() == C_ERR) { - close(server.aof_fd); + close(newfd); serverLog(LL_WARNING,"Redis needs to enable the AOF but can't trigger a background AOF rewrite operation. Check the above logs for more info about the error."); return C_ERR; } /* We correctly switched on AOF, now wait for the rewrite to be complete * in order to append data on disk. */ server.aof_state = AOF_WAIT_REWRITE; + server.aof_last_fsync = server.unixtime; + server.aof_fd = newfd; return C_OK; } +/* This is a wrapper to the write syscall in order to retry on short writes + * or if the syscall gets interrupted. It could look strange that we retry + * on short writes given that we are writing to a block device: normally if + * the first call is short, there is a end-of-space condition, so the next + * is likely to fail. However apparently in modern systems this is no longer + * true, and in general it looks just more resilient to retry the write. If + * there is an actual error condition we'll get it at the next try. */ +ssize_t aofWrite(int fd, const char *buf, size_t len) { + ssize_t nwritten = 0, totwritten = 0; + + while(len) { + nwritten = write(fd, buf, len); + + if (nwritten < 0) { + if (errno == EINTR) { + continue; + } + return totwritten ? totwritten : -1; + } + + len -= nwritten; + buf += nwritten; + totwritten += nwritten; + } + + return totwritten; +} + /* Write the append only file buffer on disk. * * Since we are required to write the AOF before replying to the client, @@ -323,7 +353,7 @@ void flushAppendOnlyFile(int force) { * or alike */ latencyStartMonitor(latency); - nwritten = write(server.aof_fd,server.aof_buf,sdslen(server.aof_buf)); + nwritten = aofWrite(server.aof_fd,server.aof_buf,sdslen(server.aof_buf)); latencyEndMonitor(latency); /* We want to capture different events for delayed writes: * when the delay happens with a pending fsync, or with a saving child @@ -342,7 +372,7 @@ void flushAppendOnlyFile(int force) { /* We performed the write so reset the postponed flush sentinel to zero. */ server.aof_flush_postponed_start = 0; - if (nwritten != (signed)sdslen(server.aof_buf)) { + if (nwritten != (ssize_t)sdslen(server.aof_buf)) { static time_t last_write_error_log = 0; int can_log = 0; @@ -1285,7 +1315,7 @@ int aofCreatePipes(void) { if (pipe(fds) == -1) goto error; /* parent -> children data. */ if (pipe(fds+2) == -1) goto error; /* children -> parent ack. */ - if (pipe(fds+4) == -1) goto error; /* children -> parent ack. */ + if (pipe(fds+4) == -1) goto error; /* parent -> children ack. */ /* Parent -> children data is non blocking. */ if (anetNonBlock(NULL,fds[0]) != ANET_OK) goto error; if (anetNonBlock(NULL,fds[1]) != ANET_OK) goto error; @@ -1499,10 +1529,10 @@ void backgroundRewriteDoneHandler(int exitcode, int bysignal) { if (server.aof_fd == -1) { /* AOF disabled */ - /* Don't care if this fails: oldfd will be -1 and we handle that. - * One notable case of -1 return is if the old file does - * not exist. */ - oldfd = open(server.aof_filename,O_RDONLY|O_NONBLOCK); + /* Don't care if this fails: oldfd will be -1 and we handle that. + * One notable case of -1 return is if the old file does + * not exist. */ + oldfd = open(server.aof_filename,O_RDONLY|O_NONBLOCK); } else { /* AOF enabled */ oldfd = -1; /* We'll set this to the current AOF filedes later. */ diff --git a/redis-android/src/main/jni/redis-4.0.6/src/asciilogo.h b/redis-android/src/main/jni/redis-4.0.8/src/asciilogo.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/asciilogo.h rename to redis-android/src/main/jni/redis-4.0.8/src/asciilogo.h diff --git a/redis-android/src/main/jni/redis-4.0.6/src/atomicvar.h b/redis-android/src/main/jni/redis-4.0.8/src/atomicvar.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/atomicvar.h rename to redis-android/src/main/jni/redis-4.0.8/src/atomicvar.h diff --git a/redis-android/src/main/jni/redis-4.0.6/src/bio.c b/redis-android/src/main/jni/redis-4.0.8/src/bio.c similarity index 99% rename from redis-android/src/main/jni/redis-4.0.6/src/bio.c rename to redis-android/src/main/jni/redis-4.0.8/src/bio.c index 38a3c4c..4a5d197 100644 --- a/redis-android/src/main/jni/redis-4.0.6/src/bio.c +++ b/redis-android/src/main/jni/redis-4.0.8/src/bio.c @@ -59,11 +59,12 @@ #include "server.h" -#include -#include -#include - #include "bio.h" +#ifdef __ANDROID__ + #include + #include + #include +#endif static pthread_t bio_threads[BIO_NUM_OPS]; static pthread_mutex_t bio_mutex[BIO_NUM_OPS]; diff --git a/redis-android/src/main/jni/redis-4.0.6/src/bio.h b/redis-android/src/main/jni/redis-4.0.8/src/bio.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/bio.h rename to redis-android/src/main/jni/redis-4.0.8/src/bio.h diff --git a/redis-android/src/main/jni/redis-4.0.6/src/bitops.c b/redis-android/src/main/jni/redis-4.0.8/src/bitops.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/bitops.c rename to redis-android/src/main/jni/redis-4.0.8/src/bitops.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/blocked.c b/redis-android/src/main/jni/redis-4.0.8/src/blocked.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/blocked.c rename to redis-android/src/main/jni/redis-4.0.8/src/blocked.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/childinfo.c b/redis-android/src/main/jni/redis-4.0.8/src/childinfo.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/childinfo.c rename to redis-android/src/main/jni/redis-4.0.8/src/childinfo.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/cluster.c b/redis-android/src/main/jni/redis-4.0.8/src/cluster.c similarity index 99% rename from redis-android/src/main/jni/redis-4.0.6/src/cluster.c rename to redis-android/src/main/jni/redis-4.0.8/src/cluster.c index 2da0f54..f325c25 100644 --- a/redis-android/src/main/jni/redis-4.0.6/src/cluster.c +++ b/redis-android/src/main/jni/redis-4.0.8/src/cluster.c @@ -4867,14 +4867,16 @@ void migrateCloseTimedoutSockets(void) { dictReleaseIterator(di); } -/* MIGRATE host port key dbid timeout [COPY | REPLACE] +/* MIGRATE host port key dbid timeout [COPY | REPLACE | AUTH password] * * On in the multiple keys form: * - * MIGRATE host port "" dbid timeout [COPY | REPLACE] KEYS key1 key2 ... keyN */ + * MIGRATE host port "" dbid timeout [COPY | REPLACE | AUTH password] KEYS key1 + * key2 ... keyN */ void migrateCommand(client *c) { migrateCachedSocket *cs; - int copy, replace, j; + int copy = 0, replace = 0, j; + char *password = NULL; long timeout; long dbid; robj **ov = NULL; /* Objects to migrate. */ @@ -4889,16 +4891,20 @@ void migrateCommand(client *c) { int first_key = 3; /* Argument index of the first key. */ int num_keys = 1; /* By default only migrate the 'key' argument. */ - /* Initialization */ - copy = 0; - replace = 0; - /* Parse additional options */ for (j = 6; j < c->argc; j++) { + int moreargs = j < c->argc-1; if (!strcasecmp(c->argv[j]->ptr,"copy")) { copy = 1; } else if (!strcasecmp(c->argv[j]->ptr,"replace")) { replace = 1; + } else if (!strcasecmp(c->argv[j]->ptr,"auth")) { + if (!moreargs) { + addReply(c,shared.syntaxerr); + return; + } + j++; + password = c->argv[j]->ptr; } else if (!strcasecmp(c->argv[j]->ptr,"keys")) { if (sdslen(c->argv[3]->ptr) != 0) { addReplyError(c, @@ -4957,6 +4963,14 @@ void migrateCommand(client *c) { rioInitWithBuffer(&cmd,sdsempty()); + /* Authentication */ + if (password) { + serverAssertWithInfo(c,NULL,rioWriteBulkCount(&cmd,'*',2)); + serverAssertWithInfo(c,NULL,rioWriteBulkString(&cmd,"AUTH",4)); + serverAssertWithInfo(c,NULL,rioWriteBulkString(&cmd,password, + sdslen(password))); + } + /* Send the SELECT command if the current DB is not already selected. */ int select = cs->last_dbid != dbid; /* Should we emit SELECT? */ if (select) { @@ -4974,7 +4988,9 @@ void migrateCommand(client *c) { ttl = expireat-mstime(); if (ttl < 1) ttl = 1; } - serverAssertWithInfo(c,NULL,rioWriteBulkCount(&cmd,'*',replace ? 5 : 4)); + serverAssertWithInfo(c,NULL, + rioWriteBulkCount(&cmd,'*',replace ? 5 : 4)); + if (server.cluster_enabled) serverAssertWithInfo(c,NULL, rioWriteBulkString(&cmd,"RESTORE-ASKING",14)); @@ -5017,9 +5033,14 @@ void migrateCommand(client *c) { } } + char buf0[1024]; /* Auth reply. */ char buf1[1024]; /* Select reply. */ char buf2[1024]; /* Restore reply. */ + /* Read the AUTH reply if needed. */ + if (password && syncReadLine(cs->fd, buf0, sizeof(buf0), timeout) <= 0) + goto socket_err; + /* Read the SELECT reply if needed. */ if (select && syncReadLine(cs->fd, buf1, sizeof(buf1), timeout) <= 0) goto socket_err; @@ -5036,13 +5057,21 @@ void migrateCommand(client *c) { socket_error = 1; break; } - if ((select && buf1[0] == '-') || buf2[0] == '-') { + if ((password && buf0[0] == '-') || + (select && buf1[0] == '-') || + buf2[0] == '-') + { /* On error assume that last_dbid is no longer valid. */ if (!error_from_target) { cs->last_dbid = -1; - addReplyErrorFormat(c,"Target instance replied with error: %s", - (select && buf1[0] == '-') ? buf1+1 : buf2+1); + char *errbuf; + if (password && buf0[0] == '-') errbuf = buf0; + else if (select && buf1[0] == '-') errbuf = buf1; + else errbuf = buf2; + error_from_target = 1; + addReplyErrorFormat(c,"Target instance replied with error: %s", + errbuf+1); } } else { if (!copy) { @@ -5107,7 +5136,7 @@ void migrateCommand(client *c) { addReply(c,shared.ok); } else { /* On error we already sent it in the for loop above, and set - * the curretly selected socket to -1 to force SELECT the next time. */ + * the currently selected socket to -1 to force SELECT the next time. */ } sdsfree(cmd.io.buffer.ptr); @@ -5363,7 +5392,8 @@ clusterNode *getNodeByQuery(client *c, struct redisCommand *cmd, robj **argv, in * node is a slave and the request is about an hash slot our master * is serving, we can reply without redirection. */ if (c->flags & CLIENT_READONLY && - cmd->flags & CMD_READONLY && + (cmd->flags & CMD_READONLY || cmd->proc == evalCommand || + cmd->proc == evalShaCommand) && nodeIsSlave(myself) && myself->slaveof == n) { diff --git a/redis-android/src/main/jni/redis-4.0.6/src/cluster.h b/redis-android/src/main/jni/redis-4.0.8/src/cluster.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/cluster.h rename to redis-android/src/main/jni/redis-4.0.8/src/cluster.h diff --git a/redis-android/src/main/jni/redis-4.0.6/src/config.c b/redis-android/src/main/jni/redis-4.0.8/src/config.c similarity index 98% rename from redis-android/src/main/jni/redis-4.0.6/src/config.c rename to redis-android/src/main/jni/redis-4.0.8/src/config.c index 9a31b7b..496936a 100644 --- a/redis-android/src/main/jni/redis-4.0.6/src/config.c +++ b/redis-android/src/main/jni/redis-4.0.8/src/config.c @@ -256,7 +256,6 @@ void loadServerConfigFromString(char *config) { } } else if (!strcasecmp(argv[0],"dir") && argc == 2) { if (chdir(argv[1]) == -1) { - __android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "%s", "config.c:259"); serverLog(LL_WARNING,"Can't chdir to '%s': %s", argv[1], strerror(errno)); exit(1); @@ -329,6 +328,10 @@ void loadServerConfigFromString(char *config) { err = "maxmemory-samples must be 1 or greater"; goto loaderr; } + } else if ((!strcasecmp(argv[0],"proto-max-bulk-len")) && argc == 2) { + server.proto_max_bulk_len = memtoll(argv[1],NULL); + } else if ((!strcasecmp(argv[0],"client-query-buffer-limit")) && argc == 2) { + server.client_max_querybuf_len = memtoll(argv[1],NULL); } else if (!strcasecmp(argv[0],"lfu-log-factor") && argc == 2) { server.lfu_log_factor = atoi(argv[1]); if (server.lfu_log_factor < 0) { @@ -745,10 +748,10 @@ void loadServerConfigFromString(char *config) { return; loaderr: - serverLog(LL_WARNING, DEBUG_TAG, "%s", "\n*** FATAL CONFIG FILE ERROR ***\n"); - serverLog(LL_WARNING, DEBUG_TAG, "Reading the configuration file, at line %d\n", linenum); - serverLog(LL_WARNING, DEBUG_TAG, ">>> '%s'\n", lines[i]); - serverLog(LL_WARNING, DEBUG_TAG, "%s\n", err); + serverLog(LL_WARNING, DEBUG_TAG, "\n*** FATAL CONFIG FILE ERROR ***\n"); + serverLog(LL_WARNING, DEBUG_TAG, "Reading the configuration file, at line %d\n", linenum); + serverLog(LL_WARNING, DEBUG_TAG, ">>> '%s'\n", lines[i]); + serverLog(LL_WARNING, DEBUG_TAG, "%s\n", err); exit(1); } @@ -1133,6 +1136,10 @@ void configSetCommand(client *c) { } freeMemoryIfNeeded(); } + } config_set_memory_field( + "proto-max-bulk-len",server.proto_max_bulk_len) { + } config_set_memory_field( + "client-query-buffer-limit",server.client_max_querybuf_len) { } config_set_memory_field("repl-backlog-size",ll) { resizeReplicationBacklog(ll); } config_set_memory_field("auto-aof-rewrite-min-size",ll) { @@ -1221,6 +1228,8 @@ void configGetCommand(client *c) { /* Numerical values */ config_get_numerical_field("maxmemory",server.maxmemory); + config_get_numerical_field("proto-max-bulk-len",server.proto_max_bulk_len); + config_get_numerical_field("client-query-buffer-limit",server.client_max_querybuf_len); config_get_numerical_field("maxmemory-samples",server.maxmemory_samples); config_get_numerical_field("lfu-log-factor",server.lfu_log_factor); config_get_numerical_field("lfu-decay-time",server.lfu_decay_time); @@ -1993,6 +2002,8 @@ int rewriteConfig(char *path) { rewriteConfigStringOption(state,"requirepass",server.requirepass,NULL); rewriteConfigNumericalOption(state,"maxclients",server.maxclients,CONFIG_DEFAULT_MAX_CLIENTS); rewriteConfigBytesOption(state,"maxmemory",server.maxmemory,CONFIG_DEFAULT_MAXMEMORY); + rewriteConfigBytesOption(state,"proto-max-bulk-len",server.proto_max_bulk_len,CONFIG_DEFAULT_PROTO_MAX_BULK_LEN); + rewriteConfigBytesOption(state,"client-query-buffer-limit",server.client_max_querybuf_len,PROTO_MAX_QUERYBUF_LEN); rewriteConfigEnumOption(state,"maxmemory-policy",server.maxmemory_policy,maxmemory_policy_enum,CONFIG_DEFAULT_MAXMEMORY_POLICY); rewriteConfigNumericalOption(state,"maxmemory-samples",server.maxmemory_samples,CONFIG_DEFAULT_MAXMEMORY_SAMPLES); rewriteConfigNumericalOption(state,"lfu-log-factor",server.lfu_log_factor,CONFIG_DEFAULT_LFU_LOG_FACTOR); diff --git a/redis-android/src/main/jni/redis-4.0.6/src/config.h b/redis-android/src/main/jni/redis-4.0.8/src/config.h similarity index 98% rename from redis-android/src/main/jni/redis-4.0.6/src/config.h rename to redis-android/src/main/jni/redis-4.0.8/src/config.h index fd4bd27..612b4e1 100644 --- a/redis-android/src/main/jni/redis-4.0.6/src/config.h +++ b/redis-android/src/main/jni/redis-4.0.8/src/config.h @@ -30,6 +30,10 @@ #ifndef __CONFIG_H #define __CONFIG_H +#ifdef __ANDROID__ +#include "../redis-android.h" +#endif + #ifdef __APPLE__ #include #endif @@ -96,7 +100,7 @@ /* Define rdb_fsync_range to sync_file_range() on Linux, otherwise we use * the plain fsync() call. */ -/* +#ifndef __ANDROID__ #ifdef __linux__ #if defined(__GLIBC__) && defined(__GLIBC_PREREQ) #if (LINUX_VERSION_CODE >= 0x020611 && __GLIBC_PREREQ(2, 6)) @@ -108,7 +112,7 @@ #endif #endif #endif -*/ +#endif #ifdef HAVE_SYNC_FILE_RANGE #define rdb_fsync_range(fd,off,size) sync_file_range(fd,off,size,SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE) diff --git a/redis-android/src/main/jni/redis-4.0.6/src/crc16.c b/redis-android/src/main/jni/redis-4.0.8/src/crc16.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/crc16.c rename to redis-android/src/main/jni/redis-4.0.8/src/crc16.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/crc64.c b/redis-android/src/main/jni/redis-4.0.8/src/crc64.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/crc64.c rename to redis-android/src/main/jni/redis-4.0.8/src/crc64.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/crc64.h b/redis-android/src/main/jni/redis-4.0.8/src/crc64.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/crc64.h rename to redis-android/src/main/jni/redis-4.0.8/src/crc64.h diff --git a/redis-android/src/main/jni/redis-4.0.6/src/db.c b/redis-android/src/main/jni/redis-4.0.8/src/db.c similarity index 99% rename from redis-android/src/main/jni/redis-4.0.6/src/db.c rename to redis-android/src/main/jni/redis-4.0.8/src/db.c index 0e66ffd..5706167 100644 --- a/redis-android/src/main/jni/redis-4.0.6/src/db.c +++ b/redis-android/src/main/jni/redis-4.0.8/src/db.c @@ -1166,11 +1166,13 @@ int *getKeysUsingCommandTable(struct redisCommand *cmd,robj **argv, int argc, in keys = zmalloc(sizeof(int)*((last - cmd->firstkey)+1)); for (j = cmd->firstkey; j <= last; j += cmd->keystep) { if (j >= argc) { - /* Modules command do not have dispatch time arity checks, so - * we need to handle the case where the user passed an invalid - * number of arguments here. In this case we return no keys - * and expect the module command to report an arity error. */ - if (cmd->flags & CMD_MODULE) { + /* Modules commands, and standard commands with a not fixed number + * of arugments (negative arity parameter) do not have dispatch + * time arity checks, so we need to handle the case where the user + * passed an invalid number of arguments here. In this case we + * return no keys and expect the command implementation to report + * an arity or syntax error. */ + if (cmd->flags & CMD_MODULE || cmd->arity < 0) { zfree(keys); *numkeys = 0; return NULL; diff --git a/redis-android/src/main/jni/redis-4.0.6/src/debug.c b/redis-android/src/main/jni/redis-4.0.8/src/debug.c similarity index 99% rename from redis-android/src/main/jni/redis-4.0.6/src/debug.c rename to redis-android/src/main/jni/redis-4.0.8/src/debug.c index 3b292df..d145102 100644 --- a/redis-android/src/main/jni/redis-4.0.6/src/debug.c +++ b/redis-android/src/main/jni/redis-4.0.8/src/debug.c @@ -1030,7 +1030,7 @@ void sigsegvHandler(int sig, siginfo_t *info, void *secret) { "Redis %s crashed by signal: %d", REDIS_VERSION, sig); if (eip != NULL) { serverLog(LL_WARNING, - "Crashed running the instuction at: %p", eip); + "Crashed running the instruction at: %p", eip); } if (sig == SIGSEGV || sig == SIGBUS) { serverLog(LL_WARNING, diff --git a/redis-android/src/main/jni/redis-4.0.6/src/debugmacro.h b/redis-android/src/main/jni/redis-4.0.8/src/debugmacro.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/debugmacro.h rename to redis-android/src/main/jni/redis-4.0.8/src/debugmacro.h diff --git a/redis-android/src/main/jni/redis-4.0.6/src/defrag.c b/redis-android/src/main/jni/redis-4.0.8/src/defrag.c similarity index 99% rename from redis-android/src/main/jni/redis-4.0.6/src/defrag.c rename to redis-android/src/main/jni/redis-4.0.8/src/defrag.c index 4a1dcef..3f0e662 100644 --- a/redis-android/src/main/jni/redis-4.0.6/src/defrag.c +++ b/redis-android/src/main/jni/redis-4.0.8/src/defrag.c @@ -289,7 +289,7 @@ int defragKey(redisDb *db, dictEntry *de) { /* Dirty code: * I can't search in db->expires for that key after i already released * the pointer it holds it won't be able to do the string compare */ - unsigned int hash = dictGetHash(db->dict, de->key); + uint64_t hash = dictGetHash(db->dict, de->key); replaceSateliteDictKeyPtrAndOrDefragDictEntry(db->expires, keysds, newsds, hash, &defragged); } diff --git a/redis-android/src/main/jni/redis-4.0.6/src/dict.c b/redis-android/src/main/jni/redis-4.0.8/src/dict.c similarity index 98% rename from redis-android/src/main/jni/redis-4.0.6/src/dict.c rename to redis-android/src/main/jni/redis-4.0.8/src/dict.c index 210d50d..97e6368 100644 --- a/redis-android/src/main/jni/redis-4.0.6/src/dict.c +++ b/redis-android/src/main/jni/redis-4.0.8/src/dict.c @@ -66,7 +66,7 @@ static unsigned int dict_force_resize_ratio = 5; static int _dictExpandIfNeeded(dict *ht); static unsigned long _dictNextPower(unsigned long size); -static int _dictKeyIndex(dict *ht, const void *key, unsigned int hash, dictEntry **existing); +static long _dictKeyIndex(dict *ht, const void *key, uint64_t hash, dictEntry **existing); static int _dictInit(dict *ht, dictType *type, void *privDataPtr); /* -------------------------- hash functions -------------------------------- */ @@ -202,7 +202,7 @@ int dictRehash(dict *d, int n) { de = d->ht[0].table[d->rehashidx]; /* Move all the keys in this bucket from the old to the new hash HT */ while(de) { - unsigned int h; + uint64_t h; nextde = de->next; /* Get the index in the new hash table */ @@ -291,7 +291,7 @@ int dictAdd(dict *d, void *key, void *val) */ dictEntry *dictAddRaw(dict *d, void *key, dictEntry **existing) { - int index; + long index; dictEntry *entry; dictht *ht; @@ -362,7 +362,7 @@ dictEntry *dictAddOrFind(dict *d, void *key) { * dictDelete() and dictUnlink(), please check the top comment * of those functions. */ static dictEntry *dictGenericDelete(dict *d, const void *key, int nofree) { - unsigned int h, idx; + uint64_t h, idx; dictEntry *he, *prevHe; int table; @@ -476,7 +476,7 @@ void dictRelease(dict *d) dictEntry *dictFind(dict *d, const void *key) { dictEntry *he; - unsigned int h, idx, table; + uint64_t h, idx, table; if (d->ht[0].used + d->ht[1].used == 0) return NULL; /* dict is empty */ if (dictIsRehashing(d)) _dictRehashStep(d); @@ -610,7 +610,7 @@ void dictReleaseIterator(dictIterator *iter) dictEntry *dictGetRandomKey(dict *d) { dictEntry *he, *orighe; - unsigned int h; + unsigned long h; int listlen, listele; if (dictSize(d) == 0) return NULL; @@ -955,9 +955,9 @@ static unsigned long _dictNextPower(unsigned long size) * * Note that if we are in the process of rehashing the hash table, the * index is always returned in the context of the second (new) hash table. */ -static int _dictKeyIndex(dict *d, const void *key, unsigned int hash, dictEntry **existing) +static long _dictKeyIndex(dict *d, const void *key, uint64_t hash, dictEntry **existing) { - unsigned int idx, table; + unsigned long idx, table; dictEntry *he; if (existing) *existing = NULL; @@ -995,7 +995,7 @@ void dictDisableResize(void) { dict_can_resize = 0; } -unsigned int dictGetHash(dict *d, const void *key) { +uint64_t dictGetHash(dict *d, const void *key) { return dictHashKey(d, key); } @@ -1004,9 +1004,9 @@ unsigned int dictGetHash(dict *d, const void *key) { * the hash value should be provided using dictGetHash. * no string / key comparison is performed. * return value is the reference to the dictEntry if found, or NULL if not found. */ -dictEntry **dictFindEntryRefByPtrAndHash(dict *d, const void *oldptr, unsigned int hash) { +dictEntry **dictFindEntryRefByPtrAndHash(dict *d, const void *oldptr, uint64_t hash) { dictEntry *he, **heref; - unsigned int idx, table; + unsigned long idx, table; if (d->ht[0].used + d->ht[1].used == 0) return NULL; /* dict is empty */ for (table = 0; table <= 1; table++) { diff --git a/redis-android/src/main/jni/redis-4.0.6/src/dict.h b/redis-android/src/main/jni/redis-4.0.8/src/dict.h similarity index 98% rename from redis-android/src/main/jni/redis-4.0.6/src/dict.h rename to redis-android/src/main/jni/redis-4.0.8/src/dict.h index bf316a0..62018cc 100644 --- a/redis-android/src/main/jni/redis-4.0.6/src/dict.h +++ b/redis-android/src/main/jni/redis-4.0.8/src/dict.h @@ -178,8 +178,8 @@ int dictRehashMilliseconds(dict *d, int ms); void dictSetHashFunctionSeed(uint8_t *seed); uint8_t *dictGetHashFunctionSeed(void); unsigned long dictScan(dict *d, unsigned long v, dictScanFunction *fn, dictScanBucketFunction *bucketfn, void *privdata); -unsigned int dictGetHash(dict *d, const void *key); -dictEntry **dictFindEntryRefByPtrAndHash(dict *d, const void *oldptr, unsigned int hash); +uint64_t dictGetHash(dict *d, const void *key); +dictEntry **dictFindEntryRefByPtrAndHash(dict *d, const void *oldptr, uint64_t hash); /* Hash table types */ extern dictType dictTypeHeapStringCopyKey; diff --git a/redis-android/src/main/jni/redis-4.0.6/src/endianconv.c b/redis-android/src/main/jni/redis-4.0.8/src/endianconv.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/endianconv.c rename to redis-android/src/main/jni/redis-4.0.8/src/endianconv.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/endianconv.h b/redis-android/src/main/jni/redis-4.0.8/src/endianconv.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/endianconv.h rename to redis-android/src/main/jni/redis-4.0.8/src/endianconv.h diff --git a/redis-android/src/main/jni/redis-4.0.6/src/evict.c b/redis-android/src/main/jni/redis-4.0.8/src/evict.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/evict.c rename to redis-android/src/main/jni/redis-4.0.8/src/evict.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/expire.c b/redis-android/src/main/jni/redis-4.0.8/src/expire.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/expire.c rename to redis-android/src/main/jni/redis-4.0.8/src/expire.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/fmacros.h b/redis-android/src/main/jni/redis-4.0.8/src/fmacros.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/fmacros.h rename to redis-android/src/main/jni/redis-4.0.8/src/fmacros.h diff --git a/redis-android/src/main/jni/redis-4.0.6/src/geo.c b/redis-android/src/main/jni/redis-4.0.8/src/geo.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/geo.c rename to redis-android/src/main/jni/redis-4.0.8/src/geo.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/geo.h b/redis-android/src/main/jni/redis-4.0.8/src/geo.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/geo.h rename to redis-android/src/main/jni/redis-4.0.8/src/geo.h diff --git a/redis-android/src/main/jni/redis-4.0.6/src/geohash.c b/redis-android/src/main/jni/redis-4.0.8/src/geohash.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/geohash.c rename to redis-android/src/main/jni/redis-4.0.8/src/geohash.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/geohash.h b/redis-android/src/main/jni/redis-4.0.8/src/geohash.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/geohash.h rename to redis-android/src/main/jni/redis-4.0.8/src/geohash.h diff --git a/redis-android/src/main/jni/redis-4.0.6/src/geohash_helper.c b/redis-android/src/main/jni/redis-4.0.8/src/geohash_helper.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/geohash_helper.c rename to redis-android/src/main/jni/redis-4.0.8/src/geohash_helper.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/geohash_helper.h b/redis-android/src/main/jni/redis-4.0.8/src/geohash_helper.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/geohash_helper.h rename to redis-android/src/main/jni/redis-4.0.8/src/geohash_helper.h diff --git a/redis-android/src/main/jni/redis-4.0.6/src/help.h b/redis-android/src/main/jni/redis-4.0.8/src/help.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/help.h rename to redis-android/src/main/jni/redis-4.0.8/src/help.h diff --git a/redis-android/src/main/jni/redis-4.0.6/src/hyperloglog.c b/redis-android/src/main/jni/redis-4.0.8/src/hyperloglog.c similarity index 96% rename from redis-android/src/main/jni/redis-4.0.6/src/hyperloglog.c rename to redis-android/src/main/jni/redis-4.0.8/src/hyperloglog.c index f4b5bd1..ef33979 100644 --- a/redis-android/src/main/jni/redis-4.0.6/src/hyperloglog.c +++ b/redis-android/src/main/jni/redis-4.0.8/src/hyperloglog.c @@ -475,9 +475,8 @@ int hllPatLen(unsigned char *ele, size_t elesize, long *regp) { /* ================== Dense representation implementation ================== */ -/* "Add" the element in the dense hyperloglog data structure. - * Actually nothing is added, but the max 0 pattern counter of the subset - * the element belongs to is incremented if needed. +/* Low level function to set the dense HLL register at 'index' to the + * specified value if the current value is smaller than 'count'. * * 'registers' is expected to have room for HLL_REGISTERS plus an * additional byte on the right. This requirement is met by sds strings @@ -486,12 +485,9 @@ int hllPatLen(unsigned char *ele, size_t elesize, long *regp) { * The function always succeed, however if as a result of the operation * the approximated cardinality changed, 1 is returned. Otherwise 0 * is returned. */ -int hllDenseAdd(uint8_t *registers, unsigned char *ele, size_t elesize) { - uint8_t oldcount, count; - long index; +int hllDenseSet(uint8_t *registers, long index, uint8_t count) { + uint8_t oldcount; - /* Update the register if this element produced a longer run of zeroes. */ - count = hllPatLen(ele,elesize,&index); HLL_DENSE_GET_REGISTER(oldcount,registers,index); if (count > oldcount) { HLL_DENSE_SET_REGISTER(registers,index,count); @@ -501,6 +497,19 @@ int hllDenseAdd(uint8_t *registers, unsigned char *ele, size_t elesize) { } } +/* "Add" the element in the dense hyperloglog data structure. + * Actually nothing is added, but the max 0 pattern counter of the subset + * the element belongs to is incremented if needed. + * + * This is just a wrapper to hllDenseSet(), performing the hashing of the + * element in order to retrieve the index and zero-run count. */ +int hllDenseAdd(uint8_t *registers, unsigned char *ele, size_t elesize) { + long index; + uint8_t count = hllPatLen(ele,elesize,&index); + /* Update the register if this element produced a longer run of zeroes. */ + return hllDenseSet(registers,index,count); +} + /* Compute SUM(2^-reg) in the dense representation. * PE is an array with a pre-computer table of values 2^-reg indexed by reg. * As a side effect the integer pointed by 'ezp' is set to the number @@ -623,9 +632,8 @@ int hllSparseToDense(robj *o) { return C_OK; } -/* "Add" the element in the sparse hyperloglog data structure. - * Actually nothing is added, but the max 0 pattern counter of the subset - * the element belongs to is incremented if needed. +/* Low level function to set the sparse HLL register at 'index' to the + * specified value if the current value is smaller than 'count'. * * The object 'o' is the String object holding the HLL. The function requires * a reference to the object in order to be able to enlarge the string if @@ -639,15 +647,12 @@ int hllSparseToDense(robj *o) { * sparse to dense: this happens when a register requires to be set to a value * not representable with the sparse representation, or when the resulting * size would be greater than server.hll_sparse_max_bytes. */ -int hllSparseAdd(robj *o, unsigned char *ele, size_t elesize) { +int hllSparseSet(robj *o, long index, uint8_t count) { struct hllhdr *hdr; - uint8_t oldcount, count, *sparse, *end, *p, *prev, *next; - long index, first, span; + uint8_t oldcount, *sparse, *end, *p, *prev, *next; + long first, span; long is_zero = 0, is_xzero = 0, is_val = 0, runlen = 0; - /* Update the register if this element produced a longer run of zeroes. */ - count = hllPatLen(ele,elesize,&index); - /* If the count is too big to be representable by the sparse representation * switch to dense representation. */ if (count > HLL_SPARSE_VAL_MAX_VALUE) goto promote; @@ -880,11 +885,24 @@ int hllSparseAdd(robj *o, unsigned char *ele, size_t elesize) { * Note that this in turn means that PFADD will make sure the command * is propagated to slaves / AOF, so if there is a sparse -> dense * convertion, it will be performed in all the slaves as well. */ - int dense_retval = hllDenseAdd(hdr->registers, ele, elesize); + int dense_retval = hllDenseSet(hdr->registers,index,count); serverAssert(dense_retval == 1); return dense_retval; } +/* "Add" the element in the sparse hyperloglog data structure. + * Actually nothing is added, but the max 0 pattern counter of the subset + * the element belongs to is incremented if needed. + * + * This function is actually a wrapper for hllSparseSet(), it only performs + * the hashshing of the elmenet to obtain the index and zeros run length. */ +int hllSparseAdd(robj *o, unsigned char *ele, size_t elesize) { + long index; + uint8_t count = hllPatLen(ele,elesize,&index); + /* Update the register if this element produced a longer run of zeroes. */ + return hllSparseSet(o,index,count); +} + /* Compute SUM(2^-reg) in the sparse representation. * PE is an array with a pre-computer table of values 2^-reg indexed by reg. * As a side effect the integer pointed by 'ezp' is set to the number @@ -1280,9 +1298,10 @@ void pfmergeCommand(client *c) { uint8_t max[HLL_REGISTERS]; struct hllhdr *hdr; int j; + int use_dense = 0; /* Use dense representation as target? */ /* Compute an HLL with M[i] = MAX(M[i]_j). - * We we the maximum into the max array of registers. We'll write + * We store the maximum into the max array of registers. We'll write * it to the target variable later. */ memset(max,0,sizeof(max)); for (j = 1; j < c->argc; j++) { @@ -1291,6 +1310,11 @@ void pfmergeCommand(client *c) { if (o == NULL) continue; /* Assume empty HLL for non existing var. */ if (isHLLObjectOrReply(c,o) != C_OK) return; + /* If at least one involved HLL is dense, use the dense representation + * as target ASAP to save time and avoid the conversion step. */ + hdr = o->ptr; + if (hdr->encoding == HLL_DENSE) use_dense = 1; + /* Merge with this HLL with our 'max' HHL by setting max[i] * to MAX(max[i],hll[i]). */ if (hllMerge(max,o) == C_ERR) { @@ -1314,22 +1338,29 @@ void pfmergeCommand(client *c) { o = dbUnshareStringValue(c->db,c->argv[1],o); } - /* Only support dense objects as destination. */ - if (hllSparseToDense(o) == C_ERR) { + /* Convert the destination object to dense representation if at least + * one of the inputs was dense. */ + if (use_dense && hllSparseToDense(o) == C_ERR) { addReplySds(c,sdsnew(invalid_hll_err)); return; } /* Write the resulting HLL to the destination HLL registers and * invalidate the cached value. */ - hdr = o->ptr; for (j = 0; j < HLL_REGISTERS; j++) { - HLL_DENSE_SET_REGISTER(hdr->registers,j,max[j]); + if (max[j] == 0) continue; + hdr = o->ptr; + switch(hdr->encoding) { + case HLL_DENSE: hllDenseSet(hdr->registers,j,max[j]); break; + case HLL_SPARSE: hllSparseSet(o,j,max[j]); break; + } } + hdr = o->ptr; /* o->ptr may be different now, as a side effect of + last hllSparseSet() call. */ HLL_INVALIDATE_CACHE(hdr); signalModifiedKey(c->db,c->argv[1]); - /* We generate an PFADD event for PFMERGE for semantical simplicity + /* We generate a PFADD event for PFMERGE for semantical simplicity * since in theory this is a mass-add of elements. */ notifyKeyspaceEvent(NOTIFY_STRING,"pfadd",c->argv[1],c->db->id); server.dirty++; diff --git a/redis-android/src/main/jni/redis-4.0.6/src/intset.c b/redis-android/src/main/jni/redis-4.0.8/src/intset.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/intset.c rename to redis-android/src/main/jni/redis-4.0.8/src/intset.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/intset.h b/redis-android/src/main/jni/redis-4.0.8/src/intset.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/intset.h rename to redis-android/src/main/jni/redis-4.0.8/src/intset.h diff --git a/redis-android/src/main/jni/redis-4.0.6/src/latency.c b/redis-android/src/main/jni/redis-4.0.8/src/latency.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/latency.c rename to redis-android/src/main/jni/redis-4.0.8/src/latency.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/latency.h b/redis-android/src/main/jni/redis-4.0.8/src/latency.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/latency.h rename to redis-android/src/main/jni/redis-4.0.8/src/latency.h diff --git a/redis-android/src/main/jni/redis-4.0.6/src/lazyfree.c b/redis-android/src/main/jni/redis-4.0.8/src/lazyfree.c similarity index 88% rename from redis-android/src/main/jni/redis-4.0.6/src/lazyfree.c rename to redis-android/src/main/jni/redis-4.0.8/src/lazyfree.c index 809ebdb..f1de0c8 100644 --- a/redis-android/src/main/jni/redis-4.0.6/src/lazyfree.c +++ b/redis-android/src/main/jni/redis-4.0.8/src/lazyfree.c @@ -64,9 +64,15 @@ int dbAsyncDelete(redisDb *db, robj *key) { robj *val = dictGetVal(de); size_t free_effort = lazyfreeGetFreeEffort(val); - /* If releasing the object is too much work, let's put it into the - * lazy free list. */ - if (free_effort > LAZYFREE_THRESHOLD) { + /* If releasing the object is too much work, do it in the background + * by adding the object to the lazy free list. + * Note that if the object is shared, to reclaim it now it is not + * possible. This rarely happens, however sometimes the implementation + * of parts of the Redis core may call incrRefCount() to protect + * objects, and then call dbDelete(). In this case we'll fall + * through and reach the dictFreeUnlinkedEntry() call, that will be + * equivalent to just calling decrRefCount(). */ + if (free_effort > LAZYFREE_THRESHOLD && val->refcount == 1) { atomicIncr(lazyfree_objects,1); bioCreateBackgroundJob(BIO_LAZY_FREE,val,NULL,NULL); dictSetVal(db->dict,de,NULL); diff --git a/redis-android/src/main/jni/redis-4.0.6/src/lzf.h b/redis-android/src/main/jni/redis-4.0.8/src/lzf.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/lzf.h rename to redis-android/src/main/jni/redis-4.0.8/src/lzf.h diff --git a/redis-android/src/main/jni/redis-4.0.6/src/lzfP.h b/redis-android/src/main/jni/redis-4.0.8/src/lzfP.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/lzfP.h rename to redis-android/src/main/jni/redis-4.0.8/src/lzfP.h diff --git a/redis-android/src/main/jni/redis-4.0.6/src/lzf_c.c b/redis-android/src/main/jni/redis-4.0.8/src/lzf_c.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/lzf_c.c rename to redis-android/src/main/jni/redis-4.0.8/src/lzf_c.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/lzf_d.c b/redis-android/src/main/jni/redis-4.0.8/src/lzf_d.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/lzf_d.c rename to redis-android/src/main/jni/redis-4.0.8/src/lzf_d.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/memtest.c b/redis-android/src/main/jni/redis-4.0.8/src/memtest.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/memtest.c rename to redis-android/src/main/jni/redis-4.0.8/src/memtest.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/mkreleasehdr.sh b/redis-android/src/main/jni/redis-4.0.8/src/mkreleasehdr.sh similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/mkreleasehdr.sh rename to redis-android/src/main/jni/redis-4.0.8/src/mkreleasehdr.sh diff --git a/redis-android/src/main/jni/redis-4.0.6/src/module.c b/redis-android/src/main/jni/redis-4.0.8/src/module.c similarity index 99% rename from redis-android/src/main/jni/redis-4.0.6/src/module.c rename to redis-android/src/main/jni/redis-4.0.8/src/module.c index 8a4c40f..545f1a7 100644 --- a/redis-android/src/main/jni/redis-4.0.6/src/module.c +++ b/redis-android/src/main/jni/redis-4.0.8/src/module.c @@ -1456,6 +1456,20 @@ int RM_DeleteKey(RedisModuleKey *key) { return REDISMODULE_OK; } +/* If the key is open for writing, unlink it (that is delete it in a + * non-blocking way, not reclaiming memory immediately) and setup the key to + * accept new writes as an empty key (that will be created on demand). + * On success REDISMODULE_OK is returned. If the key is not open for + * writing REDISMODULE_ERR is returned. */ +int RM_UnlinkKey(RedisModuleKey *key) { + if (!(key->mode & REDISMODULE_WRITE)) return REDISMODULE_ERR; + if (key->value) { + dbAsyncDelete(key->db,key->key); + key->value = NULL; + } + return REDISMODULE_OK; +} + /* Return the key expire value, as milliseconds of remaining TTL. * If no TTL is associated with the key or if the key is empty, * REDISMODULE_NO_EXPIRE is returned. */ @@ -3024,7 +3038,7 @@ int64_t RM_LoadSigned(RedisModuleIO *io) { void RM_SaveString(RedisModuleIO *io, RedisModuleString *s) { if (io->error) return; /* Save opcode. */ - int retval = rdbSaveLen(io->rio, RDB_MODULE_OPCODE_STRING); + ssize_t retval = rdbSaveLen(io->rio, RDB_MODULE_OPCODE_STRING); if (retval == -1) goto saveerr; io->bytes += retval; /* Save value. */ @@ -3042,7 +3056,7 @@ void RM_SaveString(RedisModuleIO *io, RedisModuleString *s) { void RM_SaveStringBuffer(RedisModuleIO *io, const char *str, size_t len) { if (io->error) return; /* Save opcode. */ - int retval = rdbSaveLen(io->rio, RDB_MODULE_OPCODE_STRING); + ssize_t retval = rdbSaveLen(io->rio, RDB_MODULE_OPCODE_STRING); if (retval == -1) goto saveerr; io->bytes += retval; /* Save value. */ @@ -3960,6 +3974,7 @@ void moduleRegisterCoreAPI(void) { REGISTER_API(Replicate); REGISTER_API(ReplicateVerbatim); REGISTER_API(DeleteKey); + REGISTER_API(UnlinkKey); REGISTER_API(StringSet); REGISTER_API(StringDMA); REGISTER_API(StringTruncate); diff --git a/redis-android/src/main/jni/redis-4.0.6/src/modules/.gitignore b/redis-android/src/main/jni/redis-4.0.8/src/modules/.gitignore similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/modules/.gitignore rename to redis-android/src/main/jni/redis-4.0.8/src/modules/.gitignore diff --git a/redis-android/src/main/jni/redis-4.0.6/src/modules/Makefile b/redis-android/src/main/jni/redis-4.0.8/src/modules/Makefile similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/modules/Makefile rename to redis-android/src/main/jni/redis-4.0.8/src/modules/Makefile diff --git a/redis-android/src/main/jni/redis-4.0.6/src/modules/gendoc.rb b/redis-android/src/main/jni/redis-4.0.8/src/modules/gendoc.rb similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/modules/gendoc.rb rename to redis-android/src/main/jni/redis-4.0.8/src/modules/gendoc.rb diff --git a/redis-android/src/main/jni/redis-4.0.6/src/modules/helloblock.c b/redis-android/src/main/jni/redis-4.0.8/src/modules/helloblock.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/modules/helloblock.c rename to redis-android/src/main/jni/redis-4.0.8/src/modules/helloblock.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/modules/hellotype.c b/redis-android/src/main/jni/redis-4.0.8/src/modules/hellotype.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/modules/hellotype.c rename to redis-android/src/main/jni/redis-4.0.8/src/modules/hellotype.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/modules/helloworld.c b/redis-android/src/main/jni/redis-4.0.8/src/modules/helloworld.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/modules/helloworld.c rename to redis-android/src/main/jni/redis-4.0.8/src/modules/helloworld.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/modules/testmodule.c b/redis-android/src/main/jni/redis-4.0.8/src/modules/testmodule.c similarity index 88% rename from redis-android/src/main/jni/redis-4.0.6/src/modules/testmodule.c rename to redis-android/src/main/jni/redis-4.0.8/src/modules/testmodule.c index a0d706f..956b241 100644 --- a/redis-android/src/main/jni/redis-4.0.6/src/modules/testmodule.c +++ b/redis-android/src/main/jni/redis-4.0.8/src/modules/testmodule.c @@ -120,6 +120,38 @@ int TestStringPrintf(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { return REDISMODULE_OK; } +int failTest(RedisModuleCtx *ctx, const char *msg) { + RedisModule_ReplyWithError(ctx, msg); + return REDISMODULE_ERR; +} +int TestUnlink(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { + RedisModule_AutoMemory(ctx); + REDISMODULE_NOT_USED(argv); + REDISMODULE_NOT_USED(argc); + + RedisModuleKey *k = RedisModule_OpenKey(ctx, RedisModule_CreateStringPrintf(ctx, "unlinked"), REDISMODULE_WRITE | REDISMODULE_READ); + if (!k) return failTest(ctx, "Could not create key"); + + if (REDISMODULE_ERR == RedisModule_StringSet(k, RedisModule_CreateStringPrintf(ctx, "Foobar"))) { + return failTest(ctx, "Could not set string value"); + } + + RedisModuleCallReply *rep = RedisModule_Call(ctx, "EXISTS", "c", "unlinked"); + if (!rep || RedisModule_CallReplyInteger(rep) != 1) { + return failTest(ctx, "Key does not exist before unlink"); + } + + if (REDISMODULE_ERR == RedisModule_UnlinkKey(k)) { + return failTest(ctx, "Could not unlink key"); + } + + rep = RedisModule_Call(ctx, "EXISTS", "c", "unlinked"); + if (!rep || RedisModule_CallReplyInteger(rep) != 0) { + return failTest(ctx, "Could not verify key to be unlinked"); + } + return RedisModule_ReplyWithSimpleString(ctx, "OK"); + +} /* TEST.CTXFLAGS -- Test GetContextFlags. */ int TestCtxFlags(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { @@ -269,6 +301,9 @@ int TestIt(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) { T("test.string.append",""); if (!TestAssertStringReply(ctx,reply,"foobar",6)) goto fail; + T("test.unlink",""); + if (!TestAssertStringReply(ctx,reply,"OK",2)) goto fail; + T("test.string.append.am",""); if (!TestAssertStringReply(ctx,reply,"foobar",6)) goto fail; @@ -310,6 +345,10 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) if (RedisModule_CreateCommand(ctx,"test.ctxflags", TestCtxFlags,"readonly",1,1,1) == REDISMODULE_ERR) return REDISMODULE_ERR; + + if (RedisModule_CreateCommand(ctx,"test.unlink", + TestUnlink,"write deny-oom",1,1,1) == REDISMODULE_ERR) + return REDISMODULE_ERR; if (RedisModule_CreateCommand(ctx,"test.it", TestIt,"readonly",1,1,1) == REDISMODULE_ERR) diff --git a/redis-android/src/main/jni/redis-4.0.6/src/multi.c b/redis-android/src/main/jni/redis-4.0.8/src/multi.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/multi.c rename to redis-android/src/main/jni/redis-4.0.8/src/multi.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/networking.c b/redis-android/src/main/jni/redis-4.0.8/src/networking.c similarity index 99% rename from redis-android/src/main/jni/redis-4.0.6/src/networking.c rename to redis-android/src/main/jni/redis-4.0.8/src/networking.c index 300feaf..cc9993b 100644 --- a/redis-android/src/main/jni/redis-4.0.6/src/networking.c +++ b/redis-android/src/main/jni/redis-4.0.8/src/networking.c @@ -33,7 +33,7 @@ #include #include -static void setProtocolError(const char *errstr, client *c, int pos); +static void setProtocolError(const char *errstr, client *c, long pos); /* Return the size consumed from the allocator, for the specified SDS string, * including internal fragmentation. This function is used in order to compute @@ -939,10 +939,15 @@ int writeToClient(int fd, client *c, int handler_installed) { * scenario think about 'KEYS *' against the loopback interface). * * However if we are over the maxmemory limit we ignore that and - * just deliver as much data as it is possible to deliver. */ + * just deliver as much data as it is possible to deliver. + * + * Moreover, we also send as much as possible if the client is + * a slave (otherwise, on high-speed traffic, the replication + * buffer will grow indefinitely) */ if (totwritten > NET_MAX_WRITES_PER_EVENT && (server.maxmemory == 0 || - zmalloc_used_memory() < server.maxmemory)) break; + zmalloc_used_memory() < server.maxmemory) && + !(c->flags & CLIENT_SLAVE)) break; } server.stat_net_output_bytes += totwritten; if (nwritten == -1) { @@ -1100,7 +1105,6 @@ int processInlineBuffer(client *c) { sdsfree(argv[j]); } } - #ifndef __ANDROID__ zfree(argv); // This line causes error on the VSD231(2014 model) for some reasons #endif @@ -1110,7 +1114,7 @@ int processInlineBuffer(client *c) { /* Helper function. Trims query buffer to make the function that processes * multi bulk requests idempotent. */ #define PROTO_DUMP_LEN 128 -static void setProtocolError(const char *errstr, client *c, int pos) { +static void setProtocolError(const char *errstr, client *c, long pos) { if (server.verbosity <= LL_VERBOSE) { sds client = catClientInfoString(sdsempty(),c); @@ -1151,7 +1155,8 @@ static void setProtocolError(const char *errstr, client *c, int pos) { * to be '*'. Otherwise for inline commands processInlineBuffer() is called. */ int processMultibulkBuffer(client *c) { char *newline = NULL; - int pos = 0, ok; + long pos = 0; + int ok; long long ll; if (c->multibulklen == 0) { @@ -1223,7 +1228,7 @@ int processMultibulkBuffer(client *c) { } ok = string2ll(c->querybuf+pos+1,newline-(c->querybuf+pos+1),&ll); - if (!ok || ll < 0 || ll > 512*1024*1024) { + if (!ok || ll < 0 || ll > server.proto_max_bulk_len) { addReplyError(c,"Protocol error: invalid bulk length"); setProtocolError("invalid bulk length",c,pos); return C_ERR; @@ -1249,7 +1254,7 @@ int processMultibulkBuffer(client *c) { } /* Read bulk argument */ - if (sdslen(c->querybuf)-pos < (unsigned)(c->bulklen+2)) { + if (sdslen(c->querybuf)-pos < (size_t)(c->bulklen+2)) { /* Not enough data (+2 == trailing \r\n) */ break; } else { @@ -1258,7 +1263,7 @@ int processMultibulkBuffer(client *c) { * just use the current sds string. */ if (pos == 0 && c->bulklen >= PROTO_MBULK_BIG_ARG && - (signed) sdslen(c->querybuf) == c->bulklen+2) + sdslen(c->querybuf) == (size_t)(c->bulklen+2)) { c->argv[c->argc++] = createObject(OBJ_STRING,c->querybuf); sdsIncrLen(c->querybuf,-2); /* remove CRLF */ @@ -1369,7 +1374,7 @@ void readQueryFromClient(aeEventLoop *el, int fd, void *privdata, int mask) { if (c->reqtype == PROTO_REQ_MULTIBULK && c->multibulklen && c->bulklen != -1 && c->bulklen >= PROTO_MBULK_BIG_ARG) { - int remaining = (unsigned)(c->bulklen+2)-sdslen(c->querybuf); + ssize_t remaining = (size_t)(c->bulklen+2)-sdslen(c->querybuf); if (remaining < readlen) readlen = remaining; } diff --git a/redis-android/src/main/jni/redis-4.0.6/src/notify.c b/redis-android/src/main/jni/redis-4.0.8/src/notify.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/notify.c rename to redis-android/src/main/jni/redis-4.0.8/src/notify.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/object.c b/redis-android/src/main/jni/redis-4.0.8/src/object.c similarity index 99% rename from redis-android/src/main/jni/redis-4.0.6/src/object.c rename to redis-android/src/main/jni/redis-4.0.8/src/object.c index d2f8d53..910410b 100644 --- a/redis-android/src/main/jni/redis-4.0.6/src/object.c +++ b/redis-android/src/main/jni/redis-4.0.8/src/object.c @@ -727,7 +727,7 @@ size_t objectComputeSize(robj *o, size_t sample_size) { elesize += sizeof(quicklistNode)+ziplistBlobLen(node->zl); samples++; } while ((node = node->next) && samples < sample_size); - asize += (double)elesize/samples*listTypeLength(o); + asize += (double)elesize/samples*ql->len; } else if (o->encoding == OBJ_ENCODING_ZIPLIST) { asize = sizeof(*o)+ziplistBlobLen(o->ptr); } else { diff --git a/redis-android/src/main/jni/redis-4.0.6/src/pqsort.c b/redis-android/src/main/jni/redis-4.0.8/src/pqsort.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/pqsort.c rename to redis-android/src/main/jni/redis-4.0.8/src/pqsort.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/pqsort.h b/redis-android/src/main/jni/redis-4.0.8/src/pqsort.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/pqsort.h rename to redis-android/src/main/jni/redis-4.0.8/src/pqsort.h diff --git a/redis-android/src/main/jni/redis-4.0.6/src/pubsub.c b/redis-android/src/main/jni/redis-4.0.8/src/pubsub.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/pubsub.c rename to redis-android/src/main/jni/redis-4.0.8/src/pubsub.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/quicklist.c b/redis-android/src/main/jni/redis-4.0.8/src/quicklist.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/quicklist.c rename to redis-android/src/main/jni/redis-4.0.8/src/quicklist.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/quicklist.h b/redis-android/src/main/jni/redis-4.0.8/src/quicklist.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/quicklist.h rename to redis-android/src/main/jni/redis-4.0.8/src/quicklist.h diff --git a/redis-android/src/main/jni/redis-4.0.6/src/rand.c b/redis-android/src/main/jni/redis-4.0.8/src/rand.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/rand.c rename to redis-android/src/main/jni/redis-4.0.8/src/rand.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/rand.h b/redis-android/src/main/jni/redis-4.0.8/src/rand.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/rand.h rename to redis-android/src/main/jni/redis-4.0.8/src/rand.h diff --git a/redis-android/src/main/jni/redis-4.0.6/src/rax.c b/redis-android/src/main/jni/redis-4.0.8/src/rax.c similarity index 97% rename from redis-android/src/main/jni/redis-4.0.6/src/rax.c rename to redis-android/src/main/jni/redis-4.0.8/src/rax.c index 78ead7a..4e45fd2 100644 --- a/redis-android/src/main/jni/redis-4.0.6/src/rax.c +++ b/redis-android/src/main/jni/redis-4.0.8/src/rax.c @@ -131,7 +131,7 @@ static inline void raxStackFree(raxStack *ts) { } /* ---------------------------------------------------------------------------- - * Radis tree implementation + * Radix tree implementation * --------------------------------------------------------------------------*/ /* Allocate a new non compressed node with the specified number of children. @@ -186,10 +186,10 @@ raxNode *raxReallocForData(raxNode *n, void *data) { void raxSetData(raxNode *n, void *data) { n->iskey = 1; if (data != NULL) { + n->isnull = 0; void **ndata = (void**) ((char*)n+raxNodeCurrentLength(n)-sizeof(void*)); memcpy(ndata,&data,sizeof(data)); - n->isnull = 0; } else { n->isnull = 1; } @@ -396,6 +396,7 @@ static inline size_t raxLowWalk(rax *rax, unsigned char *s, size_t len, raxNode position to 0 to signal this node represents the searched key. */ } + debugnode("Lookup stop node is",h); if (stopnode) *stopnode = h; if (plink) *plink = parentlink; if (splitpos && h->iscompr) *splitpos = j; @@ -424,18 +425,21 @@ int raxInsert(rax *rax, unsigned char *s, size_t len, void *data, void **old) { * our key. We have just to reallocate the node and make space for the * data pointer. */ if (i == len && (!h->iscompr || j == 0 /* not in the middle if j is 0 */)) { + debugf("### Insert: node representing key exists\n"); + if (!h->iskey || h->isnull) { + h = raxReallocForData(h,data); + if (h) memcpy(parentlink,&h,sizeof(h)); + } + if (h == NULL) { + errno = ENOMEM; + return 0; + } if (h->iskey) { if (old) *old = raxGetData(h); raxSetData(h,data); errno = 0; return 0; /* Element already exists. */ } - h = raxReallocForData(h,data); - if (h == NULL) { - errno = ENOMEM; - return 0; - } - memcpy(parentlink,&h,sizeof(h)); raxSetData(h,data); rax->numele++; return 1; /* Element inserted. */ @@ -734,9 +738,7 @@ int raxInsert(rax *rax, unsigned char *s, size_t len, void *data, void **old) { } /* We walked the radix tree as far as we could, but still there are left - * chars in our string. We need to insert the missing nodes. - * Note: while loop never entered if the node was split by ALGO2, - * since i == len. */ + * chars in our string. We need to insert the missing nodes. */ while(i < len) { raxNode *child; @@ -871,7 +873,8 @@ raxNode *raxRemoveChild(raxNode *parent, raxNode *child) { memmove(((char*)cp)-1,cp,(parent->size-taillen-1)*sizeof(raxNode**)); /* Move the remaining "tail" pointer at the right position as well. */ - memmove(((char*)c)-1,c+1,taillen*sizeof(raxNode**)+parent->iskey*sizeof(void*)); + size_t valuelen = (parent->iskey && !parent->isnull) ? sizeof(void*) : 0; + memmove(((char*)c)-1,c+1,taillen*sizeof(raxNode**)+valuelen); /* 4. Update size. */ parent->size--; @@ -1090,27 +1093,36 @@ int raxRemove(rax *rax, unsigned char *s, size_t len, void **old) { /* This is the core of raxFree(): performs a depth-first scan of the * tree and releases all the nodes found. */ -void raxRecursiveFree(rax *rax, raxNode *n) { +void raxRecursiveFree(rax *rax, raxNode *n, void (*free_callback)(void*)) { + debugnode("free traversing",n); int numchildren = n->iscompr ? 1 : n->size; raxNode **cp = raxNodeLastChildPtr(n); while(numchildren--) { raxNode *child; memcpy(&child,cp,sizeof(child)); - raxRecursiveFree(rax,child); + raxRecursiveFree(rax,child,free_callback); cp--; } debugnode("free depth-first",n); + if (free_callback && n->iskey && !n->isnull) + free_callback(raxGetData(n)); rax_free(n); rax->numnodes--; } -/* Free a whole radix tree. */ -void raxFree(rax *rax) { - raxRecursiveFree(rax,rax->head); +/* Free a whole radix tree, calling the specified callback in order to + * free the auxiliary data. */ +void raxFreeWithCallback(rax *rax, void (*free_callback)(void*)) { + raxRecursiveFree(rax,rax->head,free_callback); assert(rax->numnodes == 0); rax_free(rax); } +/* Free a whole radix tree. */ +void raxFree(rax *rax) { + raxFreeWithCallback(rax,NULL); +} + /* ------------------------------- Iterator --------------------------------- */ /* Initialize a Rax iterator. This call should be performed a single time @@ -1172,7 +1184,7 @@ void raxIteratorDelChars(raxIterator *it, size_t count) { * The function returns 1 on success or 0 on out of memory. */ int raxIteratorNextStep(raxIterator *it, int noup) { if (it->flags & RAX_ITER_EOF) { - return 0; + return 1; } else if (it->flags & RAX_ITER_JUST_SEEKED) { it->flags &= ~RAX_ITER_JUST_SEEKED; return 1; @@ -1184,10 +1196,6 @@ int raxIteratorNextStep(raxIterator *it, int noup) { size_t orig_stack_items = it->stack.items; raxNode *orig_node = it->node; - /* Clear the EOF flag: it will be set again if the EOF condition - * is still valid. */ - it->flags &= ~RAX_ITER_EOF; - while(1) { int children = it->node->iscompr ? 1 : it->node->size; if (!noup && children) { @@ -1288,7 +1296,7 @@ int raxSeekGreatest(raxIterator *it) { * effect to the one of raxIteratorPrevSte(). */ int raxIteratorPrevStep(raxIterator *it, int noup) { if (it->flags & RAX_ITER_EOF) { - return 0; + return 1; } else if (it->flags & RAX_ITER_JUST_SEEKED) { it->flags &= ~RAX_ITER_JUST_SEEKED; return 1; @@ -1409,6 +1417,7 @@ int raxSeek(raxIterator *it, const char *op, unsigned char *ele, size_t len) { it->node = it->rt->head; if (!raxSeekGreatest(it)) return 0; assert(it->node->iskey); + it->data = raxGetData(it->node); return 1; } @@ -1427,6 +1436,7 @@ int raxSeek(raxIterator *it, const char *op, unsigned char *ele, size_t len) { /* We found our node, since the key matches and we have an * "equal" condition. */ if (!raxIteratorAddChars(it,ele,len)) return 0; /* OOM. */ + it->data = raxGetData(it->node); } else if (lt || gt) { /* Exact key not found or eq flag not set. We have to set as current * key the one represented by the node we stopped at, and perform @@ -1499,6 +1509,7 @@ int raxSeek(raxIterator *it, const char *op, unsigned char *ele, size_t len) { * the previous sub-tree. */ if (nodechar < keychar) { if (!raxSeekGreatest(it)) return 0; + it->data = raxGetData(it->node); } else { if (!raxIteratorAddChars(it,it->node->data,it->node->size)) return 0; @@ -1615,8 +1626,8 @@ int raxCompare(raxIterator *iter, const char *op, unsigned char *key, size_t key int eq = 0, lt = 0, gt = 0; if (op[0] == '=' || op[1] == '=') eq = 1; - if (op[1] == '>') gt = 1; - else if (op[1] == '<') lt = 1; + if (op[0] == '>') gt = 1; + else if (op[0] == '<') lt = 1; else if (op[1] != '=') return 0; /* Syntax error. */ size_t minlen = key_len < iter->key_len ? key_len : iter->key_len; @@ -1644,6 +1655,19 @@ void raxStop(raxIterator *it) { raxStackFree(&it->stack); } +/* Return if the iterator is in an EOF state. This happens when raxSeek() + * failed to seek an appropriate element, so that raxNext() or raxPrev() + * will return zero, or when an EOF condition was reached while iterating + * with raxNext() and raxPrev(). */ +int raxEOF(raxIterator *it) { + return it->flags & RAX_ITER_EOF; +} + +/* Return the number of elements inside the radix tree. */ +uint64_t raxSize(rax *rax) { + return rax->numele; +} + /* ----------------------------- Introspection ------------------------------ */ /* This function is mostly used for debugging and learning purposes. diff --git a/redis-android/src/main/jni/redis-4.0.6/src/rax.h b/redis-android/src/main/jni/redis-4.0.8/src/rax.h similarity index 98% rename from redis-android/src/main/jni/redis-4.0.6/src/rax.h rename to redis-android/src/main/jni/redis-4.0.8/src/rax.h index 6f91f4c..b4e2fd9 100644 --- a/redis-android/src/main/jni/redis-4.0.6/src/rax.h +++ b/redis-android/src/main/jni/redis-4.0.8/src/rax.h @@ -148,6 +148,7 @@ int raxInsert(rax *rax, unsigned char *s, size_t len, void *data, void **old); int raxRemove(rax *rax, unsigned char *s, size_t len, void **old); void *raxFind(rax *rax, unsigned char *s, size_t len); void raxFree(rax *rax); +void raxFreeWithCallback(rax *rax, void (*free_callback)(void*)); void raxStart(raxIterator *it, rax *rt); int raxSeek(raxIterator *it, const char *op, unsigned char *ele, size_t len); int raxNext(raxIterator *it); @@ -155,6 +156,8 @@ int raxPrev(raxIterator *it); int raxRandomWalk(raxIterator *it, size_t steps); int raxCompare(raxIterator *iter, const char *op, unsigned char *key, size_t key_len); void raxStop(raxIterator *it); +int raxEOF(raxIterator *it); void raxShow(rax *rax); +uint64_t raxSize(rax *rax); #endif diff --git a/redis-android/src/main/jni/redis-4.0.6/src/rax_malloc.h b/redis-android/src/main/jni/redis-4.0.8/src/rax_malloc.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/rax_malloc.h rename to redis-android/src/main/jni/redis-4.0.8/src/rax_malloc.h diff --git a/redis-android/src/main/jni/redis-4.0.6/src/rdb.c b/redis-android/src/main/jni/redis-4.0.8/src/rdb.c similarity index 99% rename from redis-android/src/main/jni/redis-4.0.6/src/rdb.c rename to redis-android/src/main/jni/redis-4.0.8/src/rdb.c index 7c38011..68bfb90 100644 --- a/redis-android/src/main/jni/redis-4.0.6/src/rdb.c +++ b/redis-android/src/main/jni/redis-4.0.8/src/rdb.c @@ -424,7 +424,7 @@ ssize_t rdbSaveLongLongAsStringObject(rio *rdb, long long value) { } /* Like rdbSaveRawString() gets a Redis object instead. */ -int rdbSaveStringObject(rio *rdb, robj *obj) { +ssize_t rdbSaveStringObject(rio *rdb, robj *obj) { /* Avoid to decode the object, then encode it again, if the * object is already integer encoded. */ if (obj->encoding == OBJ_ENCODING_INT) { @@ -826,21 +826,25 @@ int rdbSaveKeyValuePair(rio *rdb, robj *key, robj *val, } /* Save an AUX field. */ -int rdbSaveAuxField(rio *rdb, void *key, size_t keylen, void *val, size_t vallen) { - if (rdbSaveType(rdb,RDB_OPCODE_AUX) == -1) return -1; - if (rdbSaveRawString(rdb,key,keylen) == -1) return -1; - if (rdbSaveRawString(rdb,val,vallen) == -1) return -1; - return 1; +ssize_t rdbSaveAuxField(rio *rdb, void *key, size_t keylen, void *val, size_t vallen) { + ssize_t ret, len = 0; + if ((ret = rdbSaveType(rdb,RDB_OPCODE_AUX)) == -1) return -1; + len += ret; + if ((ret = rdbSaveRawString(rdb,key,keylen) == -1)) return -1; + len += ret; + if ((ret = rdbSaveRawString(rdb,val,vallen) == -1)) return -1; + len += ret; + return len; } /* Wrapper for rdbSaveAuxField() used when key/val length can be obtained * with strlen(). */ -int rdbSaveAuxFieldStrStr(rio *rdb, char *key, char *val) { +ssize_t rdbSaveAuxFieldStrStr(rio *rdb, char *key, char *val) { return rdbSaveAuxField(rdb,key,strlen(key),val,strlen(val)); } /* Wrapper for strlen(key) + integer type (up to long long range). */ -int rdbSaveAuxFieldStrInt(rio *rdb, char *key, long long val) { +ssize_t rdbSaveAuxFieldStrInt(rio *rdb, char *key, long long val) { char buf[LONG_STR_SIZE]; int vlen = ll2string(buf,sizeof(buf),val); return rdbSaveAuxField(rdb,key,strlen(key),buf,vlen); diff --git a/redis-android/src/main/jni/redis-4.0.6/src/rdb.h b/redis-android/src/main/jni/redis-4.0.8/src/rdb.h similarity index 99% rename from redis-android/src/main/jni/redis-4.0.6/src/rdb.h rename to redis-android/src/main/jni/redis-4.0.8/src/rdb.h index 62a13f4..b48c4b8 100644 --- a/redis-android/src/main/jni/redis-4.0.6/src/rdb.h +++ b/redis-android/src/main/jni/redis-4.0.8/src/rdb.h @@ -139,7 +139,7 @@ robj *rdbLoadObject(int type, rio *rdb); void backgroundSaveDoneHandler(int exitcode, int bysignal); int rdbSaveKeyValuePair(rio *rdb, robj *key, robj *val, long long expiretime, long long now); robj *rdbLoadStringObject(rio *rdb); -int rdbSaveStringObject(rio *rdb, robj *obj); +ssize_t rdbSaveStringObject(rio *rdb, robj *obj); ssize_t rdbSaveRawString(rio *rdb, unsigned char *s, size_t len); void *rdbGenericLoadStringObject(rio *rdb, int flags, size_t *lenptr); int rdbSaveBinaryDoubleValue(rio *rdb, double val); diff --git a/redis-android/src/main/jni/redis-4.0.6/src/redis-benchmark.c b/redis-android/src/main/jni/redis-4.0.8/src/redis-benchmark.c similarity index 99% rename from redis-android/src/main/jni/redis-4.0.6/src/redis-benchmark.c rename to redis-android/src/main/jni/redis-4.0.8/src/redis-benchmark.c index 928ec31..d30879d 100644 --- a/redis-android/src/main/jni/redis-4.0.6/src/redis-benchmark.c +++ b/redis-android/src/main/jni/redis-4.0.8/src/redis-benchmark.c @@ -614,7 +614,7 @@ int showThroughput(struct aeEventLoop *eventLoop, long long id, void *clientData UNUSED(id); UNUSED(clientData); - if (config.liveclients == 0) { + if (config.liveclients == 0 && config.requests_finished != config.requests) { fprintf(stderr,"All clients disconnected... aborting.\n"); exit(1); } diff --git a/redis-android/src/main/jni/redis-4.0.6/src/redis-check-aof.c b/redis-android/src/main/jni/redis-4.0.8/src/redis-check-aof.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/redis-check-aof.c rename to redis-android/src/main/jni/redis-4.0.8/src/redis-check-aof.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/redis-check-rdb.c b/redis-android/src/main/jni/redis-4.0.8/src/redis-check-rdb.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/redis-check-rdb.c rename to redis-android/src/main/jni/redis-4.0.8/src/redis-check-rdb.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/redis-cli.c b/redis-android/src/main/jni/redis-4.0.8/src/redis-cli.c similarity index 99% rename from redis-android/src/main/jni/redis-4.0.6/src/redis-cli.c rename to redis-android/src/main/jni/redis-4.0.8/src/redis-cli.c index bff92d2..b91d0c2 100644 --- a/redis-android/src/main/jni/redis-4.0.6/src/redis-cli.c +++ b/redis-android/src/main/jni/redis-4.0.8/src/redis-cli.c @@ -1386,8 +1386,9 @@ static void repl(void) { /* Only use history and load the rc file when stdin is a tty. */ if (isatty(fileno(stdin))) { historyfile = getDotfilePath(REDIS_CLI_HISTFILE_ENV,REDIS_CLI_HISTFILE_DEFAULT); + //keep in-memory history always regardless if history file can be determined + history = 1; if (historyfile != NULL) { - history = 1; linenoiseHistoryLoad(historyfile); } cliLoadPreferences(); diff --git a/redis-android/src/main/jni/redis-4.0.6/src/redis-trib.rb b/redis-android/src/main/jni/redis-4.0.8/src/redis-trib.rb similarity index 92% rename from redis-android/src/main/jni/redis-4.0.6/src/redis-trib.rb rename to redis-android/src/main/jni/redis-4.0.8/src/redis-trib.rb index 39db979..47b398b 100755 --- a/redis-android/src/main/jni/redis-4.0.6/src/redis-trib.rb +++ b/redis-android/src/main/jni/redis-4.0.8/src/redis-trib.rb @@ -701,7 +701,12 @@ def alloc_slots masters.each{|m| puts m} - # Alloc slots on masters + # Rotating the list sometimes helps to get better initial + # anti-affinity before the optimizer runs. + interleaved.push interleaved.shift + + # Alloc slots on masters. After interleaving to get just the first N + # should be optimal. With slaves is more complex, see later... slots_per_node = ClusterHashSlots.to_f / masters_count first = 0 cursor = 0.0 @@ -769,6 +774,131 @@ def alloc_slots end end end + + optimize_anti_affinity + end + + def optimize_anti_affinity + score,aux = get_anti_affinity_score + return if score == 0 + + xputs ">>> Trying to optimize slaves allocation for anti-affinity" + + maxiter = 500*@nodes.length # Effort is proportional to cluster size... + while maxiter > 0 + score,offenders = get_anti_affinity_score + break if score == 0 # Optimal anti affinity reached + + # We'll try to randomly swap a slave's assigned master causing + # an affinity problem with another random slave, to see if we + # can improve the affinity. + first = offenders.shuffle.first + nodes = @nodes.select{|n| n != first && n.info[:replicate]} + break if nodes.length == 0 + second = nodes.shuffle.first + + first_master = first.info[:replicate] + second_master = second.info[:replicate] + first.set_as_replica(second_master) + second.set_as_replica(first_master) + + new_score,aux = get_anti_affinity_score + # If the change actually makes thing worse, revert. Otherwise + # leave as it is becuase the best solution may need a few + # combined swaps. + if new_score > score + first.set_as_replica(first_master) + second.set_as_replica(second_master) + end + + maxiter -= 1 + end + + score,aux = get_anti_affinity_score + if score == 0 + xputs "[OK] Perfect anti-affinity obtained!" + elsif score >= 10000 + puts "[WARNING] Some slaves are in the same host as their master" + else + puts "[WARNING] Some slaves of the same master are in the same host" + end + end + + # Return the anti-affinity score, which is a measure of the amount of + # violations of anti-affinity in the current cluster layout, that is, how + # badly the masters and slaves are distributed in the different IP + # addresses so that slaves of the same master are not in the master + # host and are also in different hosts. + # + # The score is calculated as follows: + # + # SAME_AS_MASTER = 10000 * each slave in the same IP of its master. + # SAME_AS_SLAVE = 1 * each slave having the same IP as another slave + # of the same master. + # FINAL_SCORE = SAME_AS_MASTER + SAME_AS_SLAVE + # + # So a greater score means a worse anti-affinity level, while zero + # means perfect anti-affinity. + # + # The anti affinity optimizator will try to get a score as low as + # possible. Since we do not want to sacrifice the fact that slaves should + # not be in the same host as the master, we assign 10000 times the score + # to this violation, so that we'll optimize for the second factor only + # if it does not impact the first one. + # + # The function returns two things: the above score, and the list of + # offending slaves, so that the optimizer can try changing the + # configuration of the slaves violating the anti-affinity goals. + def get_anti_affinity_score + score = 0 + offending = [] # List of offending slaves to return to the caller + + # First, split nodes by host + host_to_node = {} + @nodes.each{|n| + host = n.info[:host] + host_to_node[host] = [] if host_to_node[host] == nil + host_to_node[host] << n + } + + # Then, for each set of nodes in the same host, split by + # related nodes (masters and slaves which are involved in + # replication of each other) + host_to_node.each{|host,nodes| + related = {} + nodes.each{|n| + if !n.info[:replicate] + name = n.info[:name] + related[name] = [] if related[name] == nil + related[name] << :m + else + name = n.info[:replicate] + related[name] = [] if related[name] == nil + related[name] << :s + end + } + + # Now it's trivial to check, for each related group having the + # same host, what is their local score. + related.each{|id,types| + next if types.length < 2 + types.sort! # Make sure :m if the first if any + if types[0] == :m + score += 10000 * (types.length-1) + else + score += 1 * types.length + end + + # Populate the list of offending nodes + @nodes.each{|n| + if n.info[:replicate] == id && + n.info[:host] == host + offending << n + end + } + } + } + return score,offending end def flush_nodes_config diff --git a/redis-android/src/main/jni/redis-4.0.6/src/redisassert.h b/redis-android/src/main/jni/redis-4.0.8/src/redisassert.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/redisassert.h rename to redis-android/src/main/jni/redis-4.0.8/src/redisassert.h diff --git a/redis-android/src/main/jni/redis-4.0.6/src/redismodule.h b/redis-android/src/main/jni/redis-4.0.8/src/redismodule.h similarity index 99% rename from redis-android/src/main/jni/redis-4.0.6/src/redismodule.h rename to redis-android/src/main/jni/redis-4.0.8/src/redismodule.h index 672951f..09d681c 100644 --- a/redis-android/src/main/jni/redis-4.0.6/src/redismodule.h +++ b/redis-android/src/main/jni/redis-4.0.8/src/redismodule.h @@ -185,6 +185,7 @@ int REDISMODULE_API_FUNC(RedisModule_ReplicateVerbatim)(RedisModuleCtx *ctx); const char *REDISMODULE_API_FUNC(RedisModule_CallReplyStringPtr)(RedisModuleCallReply *reply, size_t *len); RedisModuleString *REDISMODULE_API_FUNC(RedisModule_CreateStringFromCallReply)(RedisModuleCallReply *reply); int REDISMODULE_API_FUNC(RedisModule_DeleteKey)(RedisModuleKey *key); +int REDISMODULE_API_FUNC(RedisModule_UnlinkKey)(RedisModuleKey *key); int REDISMODULE_API_FUNC(RedisModule_StringSet)(RedisModuleKey *key, RedisModuleString *str); char *REDISMODULE_API_FUNC(RedisModule_StringDMA)(RedisModuleKey *key, size_t *len, int mode); int REDISMODULE_API_FUNC(RedisModule_StringTruncate)(RedisModuleKey *key, size_t newlen); @@ -306,6 +307,7 @@ static int RedisModule_Init(RedisModuleCtx *ctx, const char *name, int ver, int REDISMODULE_GET_API(Replicate); REDISMODULE_GET_API(ReplicateVerbatim); REDISMODULE_GET_API(DeleteKey); + REDISMODULE_GET_API(UnlinkKey); REDISMODULE_GET_API(StringSet); REDISMODULE_GET_API(StringDMA); REDISMODULE_GET_API(StringTruncate); @@ -372,7 +374,7 @@ static int RedisModule_Init(RedisModuleCtx *ctx, const char *name, int ver, int REDISMODULE_GET_API(AbortBlock); #endif - if (RedisModule_IsModuleNameBusy(name)) return REDISMODULE_ERR; + if (RedisModule_IsModuleNameBusy && RedisModule_IsModuleNameBusy(name)) return REDISMODULE_ERR; RedisModule_SetModuleAttribs(ctx,name,ver,apiver); return REDISMODULE_OK; } diff --git a/redis-android/src/main/jni/redis-4.0.6/src/release.c b/redis-android/src/main/jni/redis-4.0.8/src/release.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/release.c rename to redis-android/src/main/jni/redis-4.0.8/src/release.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/replication.c b/redis-android/src/main/jni/redis-4.0.8/src/replication.c similarity index 99% rename from redis-android/src/main/jni/redis-4.0.6/src/replication.c rename to redis-android/src/main/jni/redis-4.0.8/src/replication.c index 43adfd8..398fe59 100644 --- a/redis-android/src/main/jni/redis-4.0.6/src/replication.c +++ b/redis-android/src/main/jni/redis-4.0.8/src/replication.c @@ -31,7 +31,9 @@ #include "server.h" -#include "sync_file_range_flags.h" +#ifdef __ANDROID__ + #include "sync_file_range_flags.h" +#endif #include #include #include @@ -1331,7 +1333,8 @@ char *sendSynchronousCommand(int flags, int fd, ...) { cmd = sdscat(cmd,arg); } cmd = sdscatlen(cmd,"\r\n",2); - + va_end(ap); + /* Transfer command to the server. */ if (syncWrite(fd,cmd,sdslen(cmd),server.repl_syncio_timeout*1000) == -1) @@ -1341,7 +1344,6 @@ char *sendSynchronousCommand(int flags, int fd, ...) { strerror(errno)); } sdsfree(cmd); - va_end(ap); } /* Read the reply from the server. */ @@ -1971,6 +1973,12 @@ void replicationUnsetMaster(void) { * with PSYNC version 2, there is no need for full resync after a * master switch. */ server.slaveseldb = -1; + + /* Once we turn from slave to master, we consider the starting time without + * slaves (that is used to count the replication backlog time to live) as + * starting from now. Otherwise the backlog will be freed after a + * failover if slaves do not connect immediately. */ + server.repl_no_slaves_since = server.unixtime; } /* This function is called when the slave lose the connection with the diff --git a/redis-android/src/main/jni/redis-4.0.6/src/rio.c b/redis-android/src/main/jni/redis-4.0.8/src/rio.c similarity index 99% rename from redis-android/src/main/jni/redis-4.0.6/src/rio.c rename to redis-android/src/main/jni/redis-4.0.8/src/rio.c index 9c7220f..23b9070 100644 --- a/redis-android/src/main/jni/redis-4.0.6/src/rio.c +++ b/redis-android/src/main/jni/redis-4.0.8/src/rio.c @@ -310,7 +310,7 @@ void rioSetAutoSync(rio *r, off_t bytes) { * generating the Redis protocol for the Append Only File. */ /* Write multi bulk count in the format: "*\r\n". */ -size_t rioWriteBulkCount(rio *r, char prefix, int count) { +size_t rioWriteBulkCount(rio *r, char prefix, long count) { char cbuf[128]; int clen; diff --git a/redis-android/src/main/jni/redis-4.0.6/src/rio.h b/redis-android/src/main/jni/redis-4.0.8/src/rio.h similarity index 98% rename from redis-android/src/main/jni/redis-4.0.6/src/rio.h rename to redis-android/src/main/jni/redis-4.0.8/src/rio.h index 6749723..c996c54 100644 --- a/redis-android/src/main/jni/redis-4.0.6/src/rio.h +++ b/redis-android/src/main/jni/redis-4.0.8/src/rio.h @@ -130,7 +130,7 @@ void rioInitWithFdset(rio *r, int *fds, int numfds); void rioFreeFdset(rio *r); -size_t rioWriteBulkCount(rio *r, char prefix, int count); +size_t rioWriteBulkCount(rio *r, char prefix, long count); size_t rioWriteBulkString(rio *r, const char *buf, size_t len); size_t rioWriteBulkLongLong(rio *r, long long l); size_t rioWriteBulkDouble(rio *r, double d); diff --git a/redis-android/src/main/jni/redis-4.0.6/src/scripting.c b/redis-android/src/main/jni/redis-4.0.8/src/scripting.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/scripting.c rename to redis-android/src/main/jni/redis-4.0.8/src/scripting.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/sds.c b/redis-android/src/main/jni/redis-4.0.8/src/sds.c similarity index 98% rename from redis-android/src/main/jni/redis-4.0.6/src/sds.c rename to redis-android/src/main/jni/redis-4.0.8/src/sds.c index ff633c8..603e36a 100644 --- a/redis-android/src/main/jni/redis-4.0.6/src/sds.c +++ b/redis-android/src/main/jni/redis-4.0.8/src/sds.c @@ -175,7 +175,7 @@ void sdsfree(sds s) { * the output will be "6" as the string was modified but the logical length * remains 6 bytes. */ void sdsupdatelen(sds s) { - int reallen = strlen(s); + size_t reallen = strlen(s); sdssetlen(s, reallen); } @@ -319,7 +319,7 @@ void *sdsAllocPtr(sds s) { * ... check for nread <= 0 and handle it ... * sdsIncrLen(s, nread); */ -void sdsIncrLen(sds s, int incr) { +void sdsIncrLen(sds s, ssize_t incr) { unsigned char flags = s[-1]; size_t len; switch(flags&SDS_TYPE_MASK) { @@ -589,7 +589,7 @@ sds sdscatprintf(sds s, const char *fmt, ...) { sds sdscatfmt(sds s, char const *fmt, ...) { size_t initlen = sdslen(s); const char *f = fmt; - int i; + long i; va_list ap; va_start(ap,fmt); @@ -721,7 +721,7 @@ sds sdstrim(sds s, const char *cset) { * s = sdsnew("Hello World"); * sdsrange(s,1,-1); => "ello World" */ -void sdsrange(sds s, int start, int end) { +void sdsrange(sds s, ssize_t start, ssize_t end) { size_t newlen, len = sdslen(s); if (len == 0) return; @@ -735,9 +735,9 @@ void sdsrange(sds s, int start, int end) { } newlen = (start > end) ? 0 : (end-start)+1; if (newlen != 0) { - if (start >= (signed)len) { + if (start >= (ssize_t)len) { newlen = 0; - } else if (end >= (signed)len) { + } else if (end >= (ssize_t)len) { end = len-1; newlen = (start > end) ? 0 : (end-start)+1; } @@ -751,14 +751,14 @@ void sdsrange(sds s, int start, int end) { /* Apply tolower() to every character of the sds string 's'. */ void sdstolower(sds s) { - int len = sdslen(s), j; + size_t len = sdslen(s), j; for (j = 0; j < len; j++) s[j] = tolower(s[j]); } /* Apply toupper() to every character of the sds string 's'. */ void sdstoupper(sds s) { - int len = sdslen(s), j; + size_t len = sdslen(s), j; for (j = 0; j < len; j++) s[j] = toupper(s[j]); } @@ -782,7 +782,7 @@ int sdscmp(const sds s1, const sds s2) { l2 = sdslen(s2); minlen = (l1 < l2) ? l1 : l2; cmp = memcmp(s1,s2,minlen); - if (cmp == 0) return l1-l2; + if (cmp == 0) return l1>l2? 1: (l1 #include @@ -126,7 +128,7 @@ volatile unsigned long lru_clock; /* Server global current LRU time. */ * are not fast commands. */ struct redisCommand redisCommandTable[] = { - {"module",moduleCommand,-2,"as",0,NULL,1,1,1,0,0}, + {"module",moduleCommand,-2,"as",0,NULL,0,0,0,0,0}, {"get",getCommand,2,"rF",0,NULL,1,1,1,0,0}, {"set",setCommand,-3,"wm",0,NULL,1,1,1,0,0}, {"setnx",setnxCommand,3,"wmF",0,NULL,1,1,1,0,0}, @@ -366,18 +368,6 @@ void serverLog(int level, const char *fmt, ...) { vsnprintf(msg, sizeof(msg), fmt, ap); va_end(ap); - - int log_to_stdout = server.logfile[0] == '\0'; -#ifdef __ANDROID__ - if (log_to_stdout) { - const int syslogLevelMap[] = { ANDROID_LOG_DEBUG, ANDROID_LOG_INFO, ANDROID_LOG_WARN, ANDROID_LOG_ERROR }; - level &= 0xff; /* clear flags */ - if (level < server.verbosity) return; - - __android_log_print(syslogLevelMap[level], DEBUG_TAG, "%s", msg); - } -#endif - serverLogRaw(level,msg); } @@ -1096,7 +1086,7 @@ int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) { } } else { /* If there is not a background saving/rewrite in progress check if - * we have to save/rewrite now */ + * we have to save/rewrite now. */ for (j = 0; j < server.saveparamslen; j++) { struct saveparam *sp = server.saveparams+j; @@ -1119,8 +1109,9 @@ int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) { } } - /* Trigger an AOF rewrite if needed */ - if (server.rdb_child_pid == -1 && + /* Trigger an AOF rewrite if needed. */ + if (server.aof_state == AOF_ON && + server.rdb_child_pid == -1 && server.aof_child_pid == -1 && server.aof_rewrite_perc && server.aof_current_size > server.aof_rewrite_min_size) @@ -1202,7 +1193,6 @@ int serverCron(struct aeEventLoop *eventLoop, long long id, void *clientData) { void beforeSleep(struct aeEventLoop *eventLoop) { UNUSED(eventLoop); - /* Call the Redis Cluster before sleep function. Note that this function * may change the state of Redis Cluster (from ok to fail or vice versa), * so it's a good idea to call it before serving the unblocked clients @@ -1390,6 +1380,7 @@ void initServerConfig(void) { server.active_defrag_threshold_upper = CONFIG_DEFAULT_DEFRAG_THRESHOLD_UPPER; server.active_defrag_cycle_min = CONFIG_DEFAULT_DEFRAG_CYCLE_MIN; server.active_defrag_cycle_max = CONFIG_DEFAULT_DEFRAG_CYCLE_MAX; + server.proto_max_bulk_len = CONFIG_DEFAULT_PROTO_MAX_BULK_LEN; server.client_max_querybuf_len = PROTO_MAX_QUERYBUF_LEN; server.saveparams = NULL; server.loading = 0; @@ -2614,7 +2605,6 @@ int prepareForShutdown(int flags) { closeListeningSockets(1); serverLog(LL_WARNING,"%s is now ready to exit, bye bye...", server.sentinel_mode ? "Sentinel" : "Redis"); - kill(server.aof_child_pid,SIGUSR1); return C_OK; } diff --git a/redis-android/src/main/jni/redis-4.0.6/src/server.h b/redis-android/src/main/jni/redis-4.0.8/src/server.h similarity index 99% rename from redis-android/src/main/jni/redis-4.0.6/src/server.h rename to redis-android/src/main/jni/redis-4.0.8/src/server.h index 89453c8..ffce95b 100644 --- a/redis-android/src/main/jni/redis-4.0.6/src/server.h +++ b/redis-android/src/main/jni/redis-4.0.8/src/server.h @@ -160,6 +160,7 @@ typedef long long mstime_t; /* millisecond time type. */ #define CONFIG_DEFAULT_DEFRAG_IGNORE_BYTES (100<<20) /* don't defrag if frag overhead is below 100mb */ #define CONFIG_DEFAULT_DEFRAG_CYCLE_MIN 25 /* 25% CPU min (at lower threshold) */ #define CONFIG_DEFAULT_DEFRAG_CYCLE_MAX 75 /* 75% CPU max (at upper threshold) */ +#define CONFIG_DEFAULT_PROTO_MAX_BULK_LEN (512ll*1024*1024) /* Bulk request max size */ #define ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP 20 /* Loopkups per loop. */ #define ACTIVE_EXPIRE_CYCLE_FAST_DURATION 1000 /* Microseconds */ @@ -1120,6 +1121,7 @@ struct redisServer { int maxmemory_samples; /* Pricision of random sampling */ int lfu_log_factor; /* LFU logarithmic counter factor. */ int lfu_decay_time; /* LFU counter decay factor. */ + long long proto_max_bulk_len; /* Protocol bulk length maximum size. */ /* Blocked clients */ unsigned int bpop_blocked_clients; /* Number of clients blocked by lists */ list *unblocked_clients; /* list of clients to unblock before next loop */ @@ -2022,9 +2024,3 @@ void xorDigest(unsigned char *digest, void *ptr, size_t len); printf("-- MARK %s:%d --\n", __FILE__, __LINE__) #endif - -#ifdef __ANDROID__ -#include -#include -#include "redis-android.h" -#endif diff --git a/redis-android/src/main/jni/redis-4.0.6/src/setproctitle.c b/redis-android/src/main/jni/redis-4.0.8/src/setproctitle.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/setproctitle.c rename to redis-android/src/main/jni/redis-4.0.8/src/setproctitle.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/sha1.c b/redis-android/src/main/jni/redis-4.0.8/src/sha1.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/sha1.c rename to redis-android/src/main/jni/redis-4.0.8/src/sha1.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/sha1.h b/redis-android/src/main/jni/redis-4.0.8/src/sha1.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/sha1.h rename to redis-android/src/main/jni/redis-4.0.8/src/sha1.h diff --git a/redis-android/src/main/jni/redis-4.0.6/src/siphash.c b/redis-android/src/main/jni/redis-4.0.8/src/siphash.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/siphash.c rename to redis-android/src/main/jni/redis-4.0.8/src/siphash.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/slowlog.c b/redis-android/src/main/jni/redis-4.0.8/src/slowlog.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/slowlog.c rename to redis-android/src/main/jni/redis-4.0.8/src/slowlog.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/slowlog.h b/redis-android/src/main/jni/redis-4.0.8/src/slowlog.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/slowlog.h rename to redis-android/src/main/jni/redis-4.0.8/src/slowlog.h diff --git a/redis-android/src/main/jni/redis-4.0.6/src/solarisfixes.h b/redis-android/src/main/jni/redis-4.0.8/src/solarisfixes.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/solarisfixes.h rename to redis-android/src/main/jni/redis-4.0.8/src/solarisfixes.h diff --git a/redis-android/src/main/jni/redis-4.0.6/src/sort.c b/redis-android/src/main/jni/redis-4.0.8/src/sort.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/sort.c rename to redis-android/src/main/jni/redis-4.0.8/src/sort.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/sparkline.c b/redis-android/src/main/jni/redis-4.0.8/src/sparkline.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/sparkline.c rename to redis-android/src/main/jni/redis-4.0.8/src/sparkline.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/sparkline.h b/redis-android/src/main/jni/redis-4.0.8/src/sparkline.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/sparkline.h rename to redis-android/src/main/jni/redis-4.0.8/src/sparkline.h diff --git a/redis-android/src/main/jni/redis-4.0.6/src/sync_file_range_flags.h b/redis-android/src/main/jni/redis-4.0.8/src/sync_file_range_flags.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/sync_file_range_flags.h rename to redis-android/src/main/jni/redis-4.0.8/src/sync_file_range_flags.h diff --git a/redis-android/src/main/jni/redis-4.0.6/src/syncio.c b/redis-android/src/main/jni/redis-4.0.8/src/syncio.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/syncio.c rename to redis-android/src/main/jni/redis-4.0.8/src/syncio.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/t_hash.c b/redis-android/src/main/jni/redis-4.0.8/src/t_hash.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/t_hash.c rename to redis-android/src/main/jni/redis-4.0.8/src/t_hash.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/t_list.c b/redis-android/src/main/jni/redis-4.0.8/src/t_list.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/t_list.c rename to redis-android/src/main/jni/redis-4.0.8/src/t_list.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/t_set.c b/redis-android/src/main/jni/redis-4.0.8/src/t_set.c similarity index 98% rename from redis-android/src/main/jni/redis-4.0.6/src/t_set.c rename to redis-android/src/main/jni/redis-4.0.8/src/t_set.c index d5a801e..8f21f71 100644 --- a/redis-android/src/main/jni/redis-4.0.6/src/t_set.c +++ b/redis-android/src/main/jni/redis-4.0.8/src/t_set.c @@ -407,7 +407,7 @@ void spopWithCountCommand(client *c) { /* Get the count argument */ if (getLongFromObjectOrReply(c,c->argv[2],&l,NULL) != C_OK) return; if (l >= 0) { - count = (unsigned) l; + count = (unsigned long) l; } else { addReply(c,shared.outofrangeerr); return; @@ -626,7 +626,7 @@ void srandmemberWithCountCommand(client *c) { if (getLongFromObjectOrReply(c,c->argv[2],&l,NULL) != C_OK) return; if (l >= 0) { - count = (unsigned) l; + count = (unsigned long) l; } else { /* A negative count means: return the same elements multiple times * (i.e. don't remove the extracted element after every extraction). */ @@ -774,15 +774,21 @@ void srandmemberCommand(client *c) { } int qsortCompareSetsByCardinality(const void *s1, const void *s2) { - return setTypeSize(*(robj**)s1)-setTypeSize(*(robj**)s2); + if (setTypeSize(*(robj**)s1) > setTypeSize(*(robj**)s2)) return 1; + if (setTypeSize(*(robj**)s1) < setTypeSize(*(robj**)s2)) return -1; + return 0; } /* This is used by SDIFF and in this case we can receive NULL that should * be handled as empty sets. */ int qsortCompareSetsByRevCardinality(const void *s1, const void *s2) { robj *o1 = *(robj**)s1, *o2 = *(robj**)s2; + unsigned long first = o1 ? setTypeSize(o1) : 0; + unsigned long second = o2 ? setTypeSize(o2) : 0; - return (o2 ? setTypeSize(o2) : 0) - (o1 ? setTypeSize(o1) : 0); + if (first < second) return 1; + if (first > second) return -1; + return 0; } void sinterGenericCommand(client *c, robj **setkeys, diff --git a/redis-android/src/main/jni/redis-4.0.6/src/t_string.c b/redis-android/src/main/jni/redis-4.0.8/src/t_string.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/t_string.c rename to redis-android/src/main/jni/redis-4.0.8/src/t_string.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/t_zset.c b/redis-android/src/main/jni/redis-4.0.8/src/t_zset.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/t_zset.c rename to redis-android/src/main/jni/redis-4.0.8/src/t_zset.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/testhelp.h b/redis-android/src/main/jni/redis-4.0.8/src/testhelp.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/testhelp.h rename to redis-android/src/main/jni/redis-4.0.8/src/testhelp.h diff --git a/redis-android/src/main/jni/redis-4.0.6/src/util.c b/redis-android/src/main/jni/redis-4.0.8/src/util.c similarity index 99% rename from redis-android/src/main/jni/redis-4.0.6/src/util.c rename to redis-android/src/main/jni/redis-4.0.8/src/util.c index 8d68f0b..36cbc43 100644 --- a/redis-android/src/main/jni/redis-4.0.6/src/util.c +++ b/redis-android/src/main/jni/redis-4.0.8/src/util.c @@ -84,7 +84,7 @@ int stringmatchlen(const char *pattern, int patternLen, } match = 0; while(1) { - if (pattern[0] == '\\') { + if (pattern[0] == '\\' && patternLen >= 2) { pattern++; patternLen--; if (pattern[0] == string[0]) diff --git a/redis-android/src/main/jni/redis-4.0.6/src/util.h b/redis-android/src/main/jni/redis-4.0.8/src/util.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/util.h rename to redis-android/src/main/jni/redis-4.0.8/src/util.h diff --git a/redis-android/src/main/jni/redis-4.0.6/src/valgrind.sup b/redis-android/src/main/jni/redis-4.0.8/src/valgrind.sup similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/valgrind.sup rename to redis-android/src/main/jni/redis-4.0.8/src/valgrind.sup diff --git a/redis-android/src/main/jni/redis-4.0.8/src/version.h b/redis-android/src/main/jni/redis-4.0.8/src/version.h new file mode 100644 index 0000000..901c3ae --- /dev/null +++ b/redis-android/src/main/jni/redis-4.0.8/src/version.h @@ -0,0 +1 @@ +#define REDIS_VERSION "4.0.8" diff --git a/redis-android/src/main/jni/redis-4.0.6/src/wait3.c b/redis-android/src/main/jni/redis-4.0.8/src/wait3.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/wait3.c rename to redis-android/src/main/jni/redis-4.0.8/src/wait3.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/wait3.h b/redis-android/src/main/jni/redis-4.0.8/src/wait3.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/wait3.h rename to redis-android/src/main/jni/redis-4.0.8/src/wait3.h diff --git a/redis-android/src/main/jni/redis-4.0.6/src/ziplist.c b/redis-android/src/main/jni/redis-4.0.8/src/ziplist.c similarity index 99% rename from redis-android/src/main/jni/redis-4.0.6/src/ziplist.c rename to redis-android/src/main/jni/redis-4.0.8/src/ziplist.c index e407937..4d2ee82 100644 --- a/redis-android/src/main/jni/redis-4.0.6/src/ziplist.c +++ b/redis-android/src/main/jni/redis-4.0.8/src/ziplist.c @@ -440,7 +440,7 @@ unsigned int zipStorePrevEntryLength(unsigned char *p, unsigned int len) { if ((prevlensize) == 1) { \ (prevlen) = (ptr)[0]; \ } else if ((prevlensize) == 5) { \ - assert(sizeof((prevlensize)) == 4); \ + assert(sizeof((prevlen)) == 4); \ memcpy(&(prevlen), ((char*)(ptr)) + 1, 4); \ memrev32ifbe(&prevlen); \ } \ diff --git a/redis-android/src/main/jni/redis-4.0.6/src/ziplist.h b/redis-android/src/main/jni/redis-4.0.8/src/ziplist.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/ziplist.h rename to redis-android/src/main/jni/redis-4.0.8/src/ziplist.h diff --git a/redis-android/src/main/jni/redis-4.0.6/src/zipmap.c b/redis-android/src/main/jni/redis-4.0.8/src/zipmap.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/zipmap.c rename to redis-android/src/main/jni/redis-4.0.8/src/zipmap.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/zipmap.h b/redis-android/src/main/jni/redis-4.0.8/src/zipmap.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/zipmap.h rename to redis-android/src/main/jni/redis-4.0.8/src/zipmap.h diff --git a/redis-android/src/main/jni/redis-4.0.6/src/zmalloc.c b/redis-android/src/main/jni/redis-4.0.8/src/zmalloc.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/zmalloc.c rename to redis-android/src/main/jni/redis-4.0.8/src/zmalloc.c diff --git a/redis-android/src/main/jni/redis-4.0.6/src/zmalloc.h b/redis-android/src/main/jni/redis-4.0.8/src/zmalloc.h similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/src/zmalloc.h rename to redis-android/src/main/jni/redis-4.0.8/src/zmalloc.h diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/assets/default.conf b/redis-android/src/main/jni/redis-4.0.8/tests/assets/default.conf similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/assets/default.conf rename to redis-android/src/main/jni/redis-4.0.8/tests/assets/default.conf diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/assets/encodings.rdb b/redis-android/src/main/jni/redis-4.0.8/tests/assets/encodings.rdb similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/assets/encodings.rdb rename to redis-android/src/main/jni/redis-4.0.8/tests/assets/encodings.rdb diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/assets/hash-zipmap.rdb b/redis-android/src/main/jni/redis-4.0.8/tests/assets/hash-zipmap.rdb similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/assets/hash-zipmap.rdb rename to redis-android/src/main/jni/redis-4.0.8/tests/assets/hash-zipmap.rdb diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/cluster/cluster.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/cluster/cluster.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/cluster/cluster.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/cluster/cluster.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/cluster/run.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/cluster/run.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/cluster/run.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/cluster/run.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/cluster/tests/00-base.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/cluster/tests/00-base.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/cluster/tests/00-base.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/cluster/tests/00-base.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/cluster/tests/01-faildet.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/cluster/tests/01-faildet.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/cluster/tests/01-faildet.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/cluster/tests/01-faildet.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/cluster/tests/02-failover.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/cluster/tests/02-failover.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/cluster/tests/02-failover.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/cluster/tests/02-failover.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/cluster/tests/03-failover-loop.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/cluster/tests/03-failover-loop.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/cluster/tests/03-failover-loop.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/cluster/tests/03-failover-loop.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/cluster/tests/04-resharding.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/cluster/tests/04-resharding.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/cluster/tests/04-resharding.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/cluster/tests/04-resharding.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/cluster/tests/05-slave-selection.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/cluster/tests/05-slave-selection.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/cluster/tests/05-slave-selection.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/cluster/tests/05-slave-selection.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/cluster/tests/06-slave-stop-cond.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/cluster/tests/06-slave-stop-cond.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/cluster/tests/06-slave-stop-cond.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/cluster/tests/06-slave-stop-cond.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/cluster/tests/07-replica-migration.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/cluster/tests/07-replica-migration.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/cluster/tests/07-replica-migration.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/cluster/tests/07-replica-migration.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/cluster/tests/08-update-msg.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/cluster/tests/08-update-msg.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/cluster/tests/08-update-msg.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/cluster/tests/08-update-msg.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/cluster/tests/09-pubsub.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/cluster/tests/09-pubsub.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/cluster/tests/09-pubsub.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/cluster/tests/09-pubsub.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/cluster/tests/10-manual-failover.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/cluster/tests/10-manual-failover.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/cluster/tests/10-manual-failover.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/cluster/tests/10-manual-failover.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/cluster/tests/11-manual-takeover.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/cluster/tests/11-manual-takeover.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/cluster/tests/11-manual-takeover.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/cluster/tests/11-manual-takeover.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/cluster/tests/12-replica-migration-2.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/cluster/tests/12-replica-migration-2.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/cluster/tests/12-replica-migration-2.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/cluster/tests/12-replica-migration-2.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/cluster/tests/helpers/onlydots.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/cluster/tests/helpers/onlydots.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/cluster/tests/helpers/onlydots.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/cluster/tests/helpers/onlydots.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/cluster/tests/includes/init-tests.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/cluster/tests/includes/init-tests.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/cluster/tests/includes/init-tests.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/cluster/tests/includes/init-tests.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/cluster/tmp/.gitignore b/redis-android/src/main/jni/redis-4.0.8/tests/cluster/tmp/.gitignore similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/cluster/tmp/.gitignore rename to redis-android/src/main/jni/redis-4.0.8/tests/cluster/tmp/.gitignore diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/helpers/bg_complex_data.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/helpers/bg_complex_data.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/helpers/bg_complex_data.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/helpers/bg_complex_data.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/helpers/gen_write_load.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/helpers/gen_write_load.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/helpers/gen_write_load.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/helpers/gen_write_load.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/instances.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/instances.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/instances.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/instances.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/integration/aof-race.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/integration/aof-race.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/integration/aof-race.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/integration/aof-race.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/integration/aof.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/integration/aof.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/integration/aof.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/integration/aof.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/integration/convert-zipmap-hash-on-load.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/integration/convert-zipmap-hash-on-load.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/integration/convert-zipmap-hash-on-load.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/integration/convert-zipmap-hash-on-load.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/integration/logging.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/integration/logging.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/integration/logging.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/integration/logging.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/integration/psync2-reg.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/integration/psync2-reg.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/integration/psync2-reg.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/integration/psync2-reg.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/integration/psync2.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/integration/psync2.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/integration/psync2.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/integration/psync2.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/integration/rdb.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/integration/rdb.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/integration/rdb.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/integration/rdb.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/integration/redis-cli.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/integration/redis-cli.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/integration/redis-cli.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/integration/redis-cli.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/integration/replication-2.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/integration/replication-2.tcl similarity index 94% rename from redis-android/src/main/jni/redis-4.0.6/tests/integration/replication-2.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/integration/replication-2.tcl index 9446e5c..2ff19c3 100644 --- a/redis-android/src/main/jni/redis-4.0.6/tests/integration/replication-2.tcl +++ b/redis-android/src/main/jni/redis-4.0.8/tests/integration/replication-2.tcl @@ -2,9 +2,12 @@ start_server {tags {"repl"}} { start_server {} { test {First server should have role slave after SLAVEOF} { r -1 slaveof [srv 0 host] [srv 0 port] - after 1000 - s -1 role - } {slave} + wait_for_condition 50 100 { + [s -1 master_link_status] eq {up} + } else { + fail "Replication not started." + } + } test {If min-slaves-to-write is honored, write is accepted} { r config set min-slaves-to-write 1 diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/integration/replication-3.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/integration/replication-3.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/integration/replication-3.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/integration/replication-3.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/integration/replication-4.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/integration/replication-4.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/integration/replication-4.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/integration/replication-4.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/integration/replication-psync.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/integration/replication-psync.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/integration/replication-psync.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/integration/replication-psync.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/integration/replication.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/integration/replication.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/integration/replication.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/integration/replication.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/sentinel/run.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/sentinel/run.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/sentinel/run.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/sentinel/run.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/sentinel/tests/00-base.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/sentinel/tests/00-base.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/sentinel/tests/00-base.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/sentinel/tests/00-base.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/sentinel/tests/01-conf-update.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/sentinel/tests/01-conf-update.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/sentinel/tests/01-conf-update.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/sentinel/tests/01-conf-update.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/sentinel/tests/02-slaves-reconf.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/sentinel/tests/02-slaves-reconf.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/sentinel/tests/02-slaves-reconf.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/sentinel/tests/02-slaves-reconf.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/sentinel/tests/03-runtime-reconf.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/sentinel/tests/03-runtime-reconf.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/sentinel/tests/03-runtime-reconf.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/sentinel/tests/03-runtime-reconf.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/sentinel/tests/04-slave-selection.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/sentinel/tests/04-slave-selection.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/sentinel/tests/04-slave-selection.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/sentinel/tests/04-slave-selection.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/sentinel/tests/05-manual.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/sentinel/tests/05-manual.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/sentinel/tests/05-manual.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/sentinel/tests/05-manual.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/sentinel/tests/06-ckquorum.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/sentinel/tests/06-ckquorum.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/sentinel/tests/06-ckquorum.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/sentinel/tests/06-ckquorum.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/sentinel/tests/07-down-conditions.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/sentinel/tests/07-down-conditions.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/sentinel/tests/07-down-conditions.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/sentinel/tests/07-down-conditions.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/sentinel/tests/includes/init-tests.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/sentinel/tests/includes/init-tests.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/sentinel/tests/includes/init-tests.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/sentinel/tests/includes/init-tests.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/sentinel/tmp/.gitignore b/redis-android/src/main/jni/redis-4.0.8/tests/sentinel/tmp/.gitignore similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/sentinel/tmp/.gitignore rename to redis-android/src/main/jni/redis-4.0.8/tests/sentinel/tmp/.gitignore diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/support/cluster.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/support/cluster.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/support/cluster.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/support/cluster.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/support/redis.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/support/redis.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/support/redis.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/support/redis.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/support/server.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/support/server.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/support/server.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/support/server.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/support/test.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/support/test.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/support/test.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/support/test.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/support/tmpfile.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/support/tmpfile.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/support/tmpfile.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/support/tmpfile.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/support/util.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/support/util.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/support/util.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/support/util.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/test_helper.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/test_helper.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/test_helper.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/test_helper.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/unit/aofrw.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/unit/aofrw.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/unit/aofrw.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/unit/aofrw.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/unit/auth.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/unit/auth.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/unit/auth.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/unit/auth.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/unit/bitfield.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/unit/bitfield.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/unit/bitfield.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/unit/bitfield.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/unit/bitops.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/unit/bitops.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/unit/bitops.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/unit/bitops.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/unit/dump.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/unit/dump.tcl similarity index 92% rename from redis-android/src/main/jni/redis-4.0.6/tests/unit/dump.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/unit/dump.tcl index f5a29a0..8bb0165 100644 --- a/redis-android/src/main/jni/redis-4.0.6/tests/unit/dump.tcl +++ b/redis-android/src/main/jni/redis-4.0.8/tests/unit/dump.tcl @@ -308,4 +308,28 @@ start_server {tags {"dump"}} { } } + test {MIGRATE AUTH: correct and wrong password cases} { + set first [srv 0 client] + r del list + r lpush list a b c d + start_server {tags {"repl"}} { + set second [srv 0 client] + set second_host [srv 0 host] + set second_port [srv 0 port] + $second config set requirepass foobar + $second auth foobar + + assert {[$first exists list] == 1} + assert {[$second exists list] == 0} + set ret [r -1 migrate $second_host $second_port list 9 5000 AUTH foobar] + assert {$ret eq {OK}} + assert {[$second exists list] == 1} + assert {[$second lrange list 0 -1] eq {d c b a}} + + r -1 lpush list a b c d + $second config set requirepass foobar2 + catch {r -1 migrate $second_host $second_port list 9 5000 AUTH foobar} err + assert_match {*invalid password*} $err + } + } } diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/unit/expire.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/unit/expire.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/unit/expire.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/unit/expire.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/unit/geo.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/unit/geo.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/unit/geo.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/unit/geo.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/unit/hyperloglog.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/unit/hyperloglog.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/unit/hyperloglog.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/unit/hyperloglog.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/unit/introspection-2.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/unit/introspection-2.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/unit/introspection-2.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/unit/introspection-2.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/unit/introspection.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/unit/introspection.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/unit/introspection.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/unit/introspection.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/unit/keyspace.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/unit/keyspace.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/unit/keyspace.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/unit/keyspace.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/unit/latency-monitor.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/unit/latency-monitor.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/unit/latency-monitor.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/unit/latency-monitor.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/unit/lazyfree.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/unit/lazyfree.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/unit/lazyfree.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/unit/lazyfree.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/unit/limits.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/unit/limits.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/unit/limits.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/unit/limits.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/unit/maxmemory.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/unit/maxmemory.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/unit/maxmemory.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/unit/maxmemory.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/unit/memefficiency.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/unit/memefficiency.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/unit/memefficiency.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/unit/memefficiency.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/unit/multi.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/unit/multi.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/unit/multi.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/unit/multi.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/unit/obuf-limits.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/unit/obuf-limits.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/unit/obuf-limits.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/unit/obuf-limits.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/unit/other.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/unit/other.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/unit/other.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/unit/other.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/unit/printver.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/unit/printver.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/unit/printver.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/unit/printver.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/unit/protocol.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/unit/protocol.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/unit/protocol.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/unit/protocol.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/unit/pubsub.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/unit/pubsub.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/unit/pubsub.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/unit/pubsub.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/unit/quit.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/unit/quit.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/unit/quit.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/unit/quit.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/unit/scan.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/unit/scan.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/unit/scan.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/unit/scan.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/unit/scripting.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/unit/scripting.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/unit/scripting.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/unit/scripting.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/unit/slowlog.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/unit/slowlog.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/unit/slowlog.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/unit/slowlog.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/unit/sort.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/unit/sort.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/unit/sort.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/unit/sort.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/unit/type/hash.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/unit/type/hash.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/unit/type/hash.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/unit/type/hash.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/unit/type/incr.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/unit/type/incr.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/unit/type/incr.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/unit/type/incr.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/unit/type/list-2.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/unit/type/list-2.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/unit/type/list-2.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/unit/type/list-2.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/unit/type/list-3.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/unit/type/list-3.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/unit/type/list-3.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/unit/type/list-3.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/unit/type/list-common.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/unit/type/list-common.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/unit/type/list-common.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/unit/type/list-common.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/unit/type/list.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/unit/type/list.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/unit/type/list.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/unit/type/list.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/unit/type/set.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/unit/type/set.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/unit/type/set.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/unit/type/set.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/unit/type/string.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/unit/type/string.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/unit/type/string.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/unit/type/string.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/unit/type/zset.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/unit/type/zset.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/unit/type/zset.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/unit/type/zset.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/tests/unit/wait.tcl b/redis-android/src/main/jni/redis-4.0.8/tests/unit/wait.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/tests/unit/wait.tcl rename to redis-android/src/main/jni/redis-4.0.8/tests/unit/wait.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/utils/build-static-symbols.tcl b/redis-android/src/main/jni/redis-4.0.8/utils/build-static-symbols.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/utils/build-static-symbols.tcl rename to redis-android/src/main/jni/redis-4.0.8/utils/build-static-symbols.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/utils/cluster_fail_time.tcl b/redis-android/src/main/jni/redis-4.0.8/utils/cluster_fail_time.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/utils/cluster_fail_time.tcl rename to redis-android/src/main/jni/redis-4.0.8/utils/cluster_fail_time.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/utils/corrupt_rdb.c b/redis-android/src/main/jni/redis-4.0.8/utils/corrupt_rdb.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/utils/corrupt_rdb.c rename to redis-android/src/main/jni/redis-4.0.8/utils/corrupt_rdb.c diff --git a/redis-android/src/main/jni/redis-4.0.6/utils/create-cluster/.gitignore b/redis-android/src/main/jni/redis-4.0.8/utils/create-cluster/.gitignore similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/utils/create-cluster/.gitignore rename to redis-android/src/main/jni/redis-4.0.8/utils/create-cluster/.gitignore diff --git a/redis-android/src/main/jni/redis-4.0.6/utils/create-cluster/README b/redis-android/src/main/jni/redis-4.0.8/utils/create-cluster/README similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/utils/create-cluster/README rename to redis-android/src/main/jni/redis-4.0.8/utils/create-cluster/README diff --git a/redis-android/src/main/jni/redis-4.0.6/utils/create-cluster/create-cluster b/redis-android/src/main/jni/redis-4.0.8/utils/create-cluster/create-cluster similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/utils/create-cluster/create-cluster rename to redis-android/src/main/jni/redis-4.0.8/utils/create-cluster/create-cluster diff --git a/redis-android/src/main/jni/redis-4.0.6/utils/generate-command-help.rb b/redis-android/src/main/jni/redis-4.0.8/utils/generate-command-help.rb similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/utils/generate-command-help.rb rename to redis-android/src/main/jni/redis-4.0.8/utils/generate-command-help.rb diff --git a/redis-android/src/main/jni/redis-4.0.6/utils/graphs/commits-over-time/README.md b/redis-android/src/main/jni/redis-4.0.8/utils/graphs/commits-over-time/README.md similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/utils/graphs/commits-over-time/README.md rename to redis-android/src/main/jni/redis-4.0.8/utils/graphs/commits-over-time/README.md diff --git a/redis-android/src/main/jni/redis-4.0.6/utils/graphs/commits-over-time/genhtml.tcl b/redis-android/src/main/jni/redis-4.0.8/utils/graphs/commits-over-time/genhtml.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/utils/graphs/commits-over-time/genhtml.tcl rename to redis-android/src/main/jni/redis-4.0.8/utils/graphs/commits-over-time/genhtml.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/utils/hashtable/README b/redis-android/src/main/jni/redis-4.0.8/utils/hashtable/README similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/utils/hashtable/README rename to redis-android/src/main/jni/redis-4.0.8/utils/hashtable/README diff --git a/redis-android/src/main/jni/redis-4.0.6/utils/hashtable/rehashing.c b/redis-android/src/main/jni/redis-4.0.8/utils/hashtable/rehashing.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/utils/hashtable/rehashing.c rename to redis-android/src/main/jni/redis-4.0.8/utils/hashtable/rehashing.c diff --git a/redis-android/src/main/jni/redis-4.0.6/utils/hyperloglog/.gitignore b/redis-android/src/main/jni/redis-4.0.8/utils/hyperloglog/.gitignore similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/utils/hyperloglog/.gitignore rename to redis-android/src/main/jni/redis-4.0.8/utils/hyperloglog/.gitignore diff --git a/redis-android/src/main/jni/redis-4.0.6/utils/hyperloglog/hll-err.rb b/redis-android/src/main/jni/redis-4.0.8/utils/hyperloglog/hll-err.rb similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/utils/hyperloglog/hll-err.rb rename to redis-android/src/main/jni/redis-4.0.8/utils/hyperloglog/hll-err.rb diff --git a/redis-android/src/main/jni/redis-4.0.6/utils/hyperloglog/hll-gnuplot-graph.rb b/redis-android/src/main/jni/redis-4.0.8/utils/hyperloglog/hll-gnuplot-graph.rb similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/utils/hyperloglog/hll-gnuplot-graph.rb rename to redis-android/src/main/jni/redis-4.0.8/utils/hyperloglog/hll-gnuplot-graph.rb diff --git a/redis-android/src/main/jni/redis-4.0.6/utils/install_server.sh b/redis-android/src/main/jni/redis-4.0.8/utils/install_server.sh similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/utils/install_server.sh rename to redis-android/src/main/jni/redis-4.0.8/utils/install_server.sh diff --git a/redis-android/src/main/jni/redis-4.0.6/utils/lru/README b/redis-android/src/main/jni/redis-4.0.8/utils/lru/README similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/utils/lru/README rename to redis-android/src/main/jni/redis-4.0.8/utils/lru/README diff --git a/redis-android/src/main/jni/redis-4.0.6/utils/lru/lfu-simulation.c b/redis-android/src/main/jni/redis-4.0.8/utils/lru/lfu-simulation.c similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/utils/lru/lfu-simulation.c rename to redis-android/src/main/jni/redis-4.0.8/utils/lru/lfu-simulation.c diff --git a/redis-android/src/main/jni/redis-4.0.6/utils/lru/test-lru.rb b/redis-android/src/main/jni/redis-4.0.8/utils/lru/test-lru.rb similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/utils/lru/test-lru.rb rename to redis-android/src/main/jni/redis-4.0.8/utils/lru/test-lru.rb diff --git a/redis-android/src/main/jni/redis-4.0.6/utils/redis-copy.rb b/redis-android/src/main/jni/redis-4.0.8/utils/redis-copy.rb similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/utils/redis-copy.rb rename to redis-android/src/main/jni/redis-4.0.8/utils/redis-copy.rb diff --git a/redis-android/src/main/jni/redis-4.0.6/utils/redis-sha1.rb b/redis-android/src/main/jni/redis-4.0.8/utils/redis-sha1.rb similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/utils/redis-sha1.rb rename to redis-android/src/main/jni/redis-4.0.8/utils/redis-sha1.rb diff --git a/redis-android/src/main/jni/redis-4.0.6/utils/redis_init_script b/redis-android/src/main/jni/redis-4.0.8/utils/redis_init_script similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/utils/redis_init_script rename to redis-android/src/main/jni/redis-4.0.8/utils/redis_init_script diff --git a/redis-android/src/main/jni/redis-4.0.6/utils/redis_init_script.tpl b/redis-android/src/main/jni/redis-4.0.8/utils/redis_init_script.tpl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/utils/redis_init_script.tpl rename to redis-android/src/main/jni/redis-4.0.8/utils/redis_init_script.tpl diff --git a/redis-android/src/main/jni/redis-4.0.6/utils/releasetools/01_create_tarball.sh b/redis-android/src/main/jni/redis-4.0.8/utils/releasetools/01_create_tarball.sh similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/utils/releasetools/01_create_tarball.sh rename to redis-android/src/main/jni/redis-4.0.8/utils/releasetools/01_create_tarball.sh diff --git a/redis-android/src/main/jni/redis-4.0.6/utils/releasetools/02_upload_tarball.sh b/redis-android/src/main/jni/redis-4.0.8/utils/releasetools/02_upload_tarball.sh similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/utils/releasetools/02_upload_tarball.sh rename to redis-android/src/main/jni/redis-4.0.8/utils/releasetools/02_upload_tarball.sh diff --git a/redis-android/src/main/jni/redis-4.0.6/utils/releasetools/03_test_release.sh b/redis-android/src/main/jni/redis-4.0.8/utils/releasetools/03_test_release.sh similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/utils/releasetools/03_test_release.sh rename to redis-android/src/main/jni/redis-4.0.8/utils/releasetools/03_test_release.sh diff --git a/redis-android/src/main/jni/redis-4.0.6/utils/releasetools/04_release_hash.sh b/redis-android/src/main/jni/redis-4.0.8/utils/releasetools/04_release_hash.sh similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/utils/releasetools/04_release_hash.sh rename to redis-android/src/main/jni/redis-4.0.8/utils/releasetools/04_release_hash.sh diff --git a/redis-android/src/main/jni/redis-4.0.6/utils/releasetools/changelog.tcl b/redis-android/src/main/jni/redis-4.0.8/utils/releasetools/changelog.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/utils/releasetools/changelog.tcl rename to redis-android/src/main/jni/redis-4.0.8/utils/releasetools/changelog.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/utils/speed-regression.tcl b/redis-android/src/main/jni/redis-4.0.8/utils/speed-regression.tcl similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/utils/speed-regression.tcl rename to redis-android/src/main/jni/redis-4.0.8/utils/speed-regression.tcl diff --git a/redis-android/src/main/jni/redis-4.0.6/utils/whatisdoing.sh b/redis-android/src/main/jni/redis-4.0.8/utils/whatisdoing.sh similarity index 100% rename from redis-android/src/main/jni/redis-4.0.6/utils/whatisdoing.sh rename to redis-android/src/main/jni/redis-4.0.8/utils/whatisdoing.sh diff --git a/redis-android/src/main/jni/redis-android.c b/redis-android/src/main/jni/redis-android.c index 60372b7..2c2da51 100644 --- a/redis-android/src/main/jni/redis-android.c +++ b/redis-android/src/main/jni/redis-android.c @@ -31,4 +31,4 @@ char* convertJStringToChar(JNIEnv* env, jstring j_string) { (*env)->ReleaseStringUTFChars(env, j_string, nativeString); return c_string; -} \ No newline at end of file +} diff --git a/redis-android/src/main/jni/redis-android.h b/redis-android/src/main/jni/redis-android.h index 823137a..c8f39bf 100644 --- a/redis-android/src/main/jni/redis-android.h +++ b/redis-android/src/main/jni/redis-android.h @@ -36,4 +36,4 @@ static JNINativeMethod method_table[] = { JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved); -#endif \ No newline at end of file +#endif diff --git a/redis-android/src/main/jni/release.h b/redis-android/src/main/jni/release.h index cffaf21..9d360fc 100644 --- a/redis-android/src/main/jni/release.h +++ b/redis-android/src/main/jni/release.h @@ -1,3 +1,3 @@ -#define REDIS_GIT_SHA1 "894ddc08" -#define REDIS_GIT_DIRTY " 80" -#define REDIS_BUILD_ID "masashi-macgms.local-1515026948" +#define REDIS_GIT_SHA1 "935cd800" +#define REDIS_GIT_DIRTY " 96" +#define REDIS_BUILD_ID "masashi-macgms.lan-1518567077" diff --git a/redis-android/src/main/libs/arm64-v8a/libredis.so b/redis-android/src/main/libs/arm64-v8a/libredis.so index 8cce2e09002ccf7ec984c70b4d48a6b4ff8406a3..a84357e271e4e1c297116f4db1c92c1615d4e463 100755 GIT binary patch delta 530328 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

cZmFh~vIJRg1rdEM|6 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

{{xZM#DND1)K^n;n=Glt-A4IbF4Ry(b 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

;VM{$JtP2Uk$$yrAg*59cOKn>$~`> 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 LX{q+>vt9oOq1fq} delta 528788 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

0oNt;#&`E8e;5kop)BjJ?E6}Q@5S4j8-?2 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

+0$*H_I~aLBMn#d!kPg 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 diff --git a/redis-android/src/main/libs/armeabi-v7a/redis-cli b/redis-android/src/main/libs/armeabi-v7a/redis-cli index f5cd9689d7f7e75098a15643a97f20b1ccab9dbe..e0d32496c041debc4697ecbebb79e923dc83ed1f 100755 GIT binary patch delta 39041 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

l%Y^ozLy@+;ZRDn>mc{%F^)>J-4$% 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 SY*L@s)!T0&YQK=Ew)_{Y+5!Cl delta 31637 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 diff --git a/redis-android/src/main/libs/arm64-v8a/redis-cli b/redis-android/src/main/libs/arm64-v8a/redis-cli index bd08d8ca860b2bbbbe408eb27a70e83211d06be6..02e734c65c100d49e831dac8d625746b67c76426 100755 GIT binary patch delta 38826 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 delta 38813 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

c4U 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%0D&s@Vb}V&tqTCpW3k6eur2#4u3xXv*a_K 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

sX!a5R3=T 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