|
@@ -0,0 +1,7541 @@
|
|
|
+# HG changeset patch
|
|
|
+# User Ryan VanderMeulen <ryanvm@gmail.com>
|
|
|
+# Date 1484106636 18000
|
|
|
+# Tue Jan 10 22:50:36 2017 -0500
|
|
|
+# Branch THUNDERBIRD_52_VERBRANCH
|
|
|
+# Node ID 301a46b075293261115b39da1ff5f4d06cc08406
|
|
|
+# Parent 15d9d940341f02ef6dcad96899d284619d3d48db
|
|
|
+Bug 1322027 - Update jemalloc 4 to version 4.4.0. r=glandium a=jorgk
|
|
|
+
|
|
|
+diff --git a/build/autoconf/jemalloc.m4 b/build/autoconf/jemalloc.m4
|
|
|
+--- a/build/autoconf/jemalloc.m4
|
|
|
++++ b/build/autoconf/jemalloc.m4
|
|
|
+@@ -83,16 +83,19 @@ if test "$MOZ_BUILD_APP" != js -o -n "$J
|
|
|
+ # their mozconfig.
|
|
|
+ if test "$_MSC_VER"; then
|
|
|
+ ac_configure_args="$ac_configure_args CFLAGS="
|
|
|
+ fi
|
|
|
+
|
|
|
+ # Force disable DSS support in jemalloc.
|
|
|
+ ac_configure_args="$ac_configure_args ac_cv_func_sbrk=false"
|
|
|
+
|
|
|
++ # Force disable hugepage support in jemalloc.
|
|
|
++ ac_configure_args="$ac_configure_args je_cv_thp=no"
|
|
|
++
|
|
|
+ # Make Linux builds munmap freed chunks instead of recycling them.
|
|
|
+ ac_configure_args="$ac_configure_args --enable-munmap"
|
|
|
+
|
|
|
+ # Disable cache oblivious behavior that appears to have a performance
|
|
|
+ # impact on Firefox.
|
|
|
+ ac_configure_args="$ac_configure_args --disable-cache-oblivious"
|
|
|
+
|
|
|
+ if ! test -e memory/jemalloc; then
|
|
|
+diff --git a/memory/jemalloc/src/ChangeLog b/memory/jemalloc/src/ChangeLog
|
|
|
+--- a/memory/jemalloc/src/ChangeLog
|
|
|
++++ b/memory/jemalloc/src/ChangeLog
|
|
|
+@@ -1,14 +1,41 @@
|
|
|
+ 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.4.0 (December 3, 2016)
|
|
|
++
|
|
|
++ New features:
|
|
|
++ - Add configure support for *-*-linux-android. (@cferris1000, @jasone)
|
|
|
++ - Add the --disable-syscall configure option, for use on systems that place
|
|
|
++ security-motivated limitations on syscall(2). (@jasone)
|
|
|
++ - Add support for Debian GNU/kFreeBSD. (@thesam)
|
|
|
++
|
|
|
++ Optimizations:
|
|
|
++ - Add extent serial numbers and use them where appropriate as a sort key that
|
|
|
++ is higher priority than address, so that the allocation policy prefers older
|
|
|
++ extents. This tends to improve locality (decrease fragmentation) when
|
|
|
++ memory grows downward. (@jasone)
|
|
|
++ - Refactor madvise(2) configuration so that MADV_FREE is detected and utilized
|
|
|
++ on Linux 4.5 and newer. (@jasone)
|
|
|
++ - Mark partially purged arena chunks as non-huge-page. This improves
|
|
|
++ interaction with Linux's transparent huge page functionality. (@jasone)
|
|
|
++
|
|
|
++ Bug fixes:
|
|
|
++ - Fix size class computations for edge conditions involving extremely large
|
|
|
++ allocations. This regression was first released in 4.0.0. (@jasone,
|
|
|
++ @ingvarha)
|
|
|
++ - Remove overly restrictive assertions related to the cactive statistic. This
|
|
|
++ regression was first released in 4.1.0. (@jasone)
|
|
|
++ - Implement a more reliable detection scheme for os_unfair_lock on macOS.
|
|
|
++ (@jszakmeister)
|
|
|
++
|
|
|
+ * 4.3.1 (November 7, 2016)
|
|
|
+
|
|
|
+ Bug fixes:
|
|
|
+ - Fix a severe virtual memory leak. This regression was first released in
|
|
|
+ 4.3.0. (@interwq, @jasone)
|
|
|
+ - Refactor atomic and prng APIs to restore support for 32-bit platforms that
|
|
|
+ use pre-C11 toolchains, e.g. FreeBSD's mips. (@jasone)
|
|
|
+
|
|
|
+diff --git a/memory/jemalloc/src/INSTALL b/memory/jemalloc/src/INSTALL
|
|
|
+--- a/memory/jemalloc/src/INSTALL
|
|
|
++++ b/memory/jemalloc/src/INSTALL
|
|
|
+@@ -201,16 +201,21 @@ any of the following arguments (not a de
|
|
|
+ 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.
|
|
|
+
|
|
|
++--disable-syscall
|
|
|
++ Disable use of syscall(2) rather than {open,read,write,close}(2). This is
|
|
|
++ intended as a workaround for systems that place security limitations on
|
|
|
++ syscall(2).
|
|
|
++
|
|
|
+ --with-xslroot=<path>
|
|
|
+ Specify where to find DocBook XSL stylesheets when building the
|
|
|
+ documentation.
|
|
|
+
|
|
|
+ --with-lg-page=<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.
|
|
|
+@@ -322,16 +327,25 @@ 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.
|
|
|
+
|
|
|
++In some cases it may be necessary to work around configuration results that do
|
|
|
++not match reality. For example, Linux 4.5 added support for the MADV_FREE flag
|
|
|
++to madvise(2), which can cause problems if building on a host with MADV_FREE
|
|
|
++support and deploying to a target without. To work around this, use a cache
|
|
|
++file to override the relevant configuration variable defined in configure.ac,
|
|
|
++e.g.:
|
|
|
++
|
|
|
++ echo "je_cv_madv_free=no" > config.cache && ./configure -C
|
|
|
++
|
|
|
+ === Advanced compilation =======================================================
|
|
|
+
|
|
|
+ To build only parts of jemalloc, use the following targets:
|
|
|
+
|
|
|
+ build_lib_shared
|
|
|
+ build_lib_static
|
|
|
+ build_lib
|
|
|
+ build_doc_html
|
|
|
+diff --git a/memory/jemalloc/src/Makefile.in b/memory/jemalloc/src/Makefile.in
|
|
|
+--- a/memory/jemalloc/src/Makefile.in
|
|
|
++++ b/memory/jemalloc/src/Makefile.in
|
|
|
+@@ -161,16 +161,18 @@ TESTS_UNIT := \
|
|
|
+ $(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/pack.c \
|
|
|
++ $(srcroot)test/unit/pages.c \
|
|
|
+ $(srcroot)test/unit/ph.c \
|
|
|
+ $(srcroot)test/unit/prng.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 \
|
|
|
+diff --git a/memory/jemalloc/src/VERSION b/memory/jemalloc/src/VERSION
|
|
|
+--- a/memory/jemalloc/src/VERSION
|
|
|
++++ b/memory/jemalloc/src/VERSION
|
|
|
+@@ -1,1 +1,1 @@
|
|
|
+-4.3.1-0-g0110fa8451af905affd77c3bea0d545fee2251b2
|
|
|
++4.4.0-0-gf1f76357313e7dcad7262f17a48ff0a2e005fcdc
|
|
|
+diff --git a/memory/jemalloc/src/build-aux/config.guess b/memory/jemalloc/src/build-aux/config.guess
|
|
|
+--- a/memory/jemalloc/src/build-aux/config.guess
|
|
|
++++ b/memory/jemalloc/src/build-aux/config.guess
|
|
|
+@@ -1,13 +1,13 @@
|
|
|
+ #! /bin/sh
|
|
|
+ # Attempt to guess a canonical system name.
|
|
|
+-# Copyright 1992-2014 Free Software Foundation, Inc.
|
|
|
++# Copyright 1992-2016 Free Software Foundation, Inc.
|
|
|
+
|
|
|
+-timestamp='2014-03-23'
|
|
|
++timestamp='2016-10-02'
|
|
|
+
|
|
|
+ # 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
|
|
|
+@@ -19,22 +19,22 @@ timestamp='2014-03-23'
|
|
|
+ #
|
|
|
+ # 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.
|
|
|
++# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
|
|
|
+ #
|
|
|
+ # 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
|
|
|
++# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
|
|
|
+ #
|
|
|
+-# Please send patches with a ChangeLog entry to config-patches@gnu.org.
|
|
|
++# Please send patches 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.
|
|
|
+@@ -45,17 +45,17 @@ Operation modes:
|
|
|
+ -v, --version print version number, then exit
|
|
|
+
|
|
|
+ Report bugs and patches to <config-patches@gnu.org>."
|
|
|
+
|
|
|
+ version="\
|
|
|
+ GNU config.guess ($timestamp)
|
|
|
+
|
|
|
+ Originally written by Per Bothner.
|
|
|
+-Copyright 1992-2014 Free Software Foundation, Inc.
|
|
|
++Copyright 1992-2016 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
|
|
|
+@@ -163,135 +163,159 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:$
|
|
|
+ # 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)`
|
|
|
++ UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
|
|
|
++ /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 ;;
|
|
|
++ earmv*)
|
|
|
++ arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
|
|
|
++ endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'`
|
|
|
++ machine=${arch}${endian}-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.
|
|
|
++ # to ELF recently (or will in the future) and ABI.
|
|
|
+ case "${UNAME_MACHINE_ARCH}" in
|
|
|
++ earm*)
|
|
|
++ os=netbsdelf
|
|
|
++ ;;
|
|
|
+ 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
|
|
|
++ # Determine ABI tags.
|
|
|
++ case "${UNAME_MACHINE_ARCH}" in
|
|
|
++ earm*)
|
|
|
++ expr='s/^earmv[0-9]/-eabi/;s/eb$//'
|
|
|
++ abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"`
|
|
|
++ ;;
|
|
|
++ 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/[-_].*/\./'`
|
|
|
++ release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2`
|
|
|
+ ;;
|
|
|
+ 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}"
|
|
|
++ echo "${machine}-${os}${release}${abi}"
|
|
|
+ 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 ;;
|
|
|
++ *:LibertyBSD:*:*)
|
|
|
++ UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`
|
|
|
++ echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${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 ;;
|
|
|
++ *:Sortix:*:*)
|
|
|
++ echo ${UNAME_MACHINE}-unknown-sortix
|
|
|
++ 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" ;;
|
|
|
++ UNAME_MACHINE=alpha ;;
|
|
|
+ "EV4.5 (21064)")
|
|
|
+- UNAME_MACHINE="alpha" ;;
|
|
|
++ UNAME_MACHINE=alpha ;;
|
|
|
+ "LCA4 (21066/21068)")
|
|
|
+- UNAME_MACHINE="alpha" ;;
|
|
|
++ UNAME_MACHINE=alpha ;;
|
|
|
+ "EV5 (21164)")
|
|
|
+- UNAME_MACHINE="alphaev5" ;;
|
|
|
++ UNAME_MACHINE=alphaev5 ;;
|
|
|
+ "EV5.6 (21164A)")
|
|
|
+- UNAME_MACHINE="alphaev56" ;;
|
|
|
++ UNAME_MACHINE=alphaev56 ;;
|
|
|
+ "EV5.6 (21164PC)")
|
|
|
+- UNAME_MACHINE="alphapca56" ;;
|
|
|
++ UNAME_MACHINE=alphapca56 ;;
|
|
|
+ "EV5.7 (21164PC)")
|
|
|
+- UNAME_MACHINE="alphapca57" ;;
|
|
|
++ UNAME_MACHINE=alphapca57 ;;
|
|
|
+ "EV6 (21264)")
|
|
|
+- UNAME_MACHINE="alphaev6" ;;
|
|
|
++ UNAME_MACHINE=alphaev6 ;;
|
|
|
+ "EV6.7 (21264A)")
|
|
|
+- UNAME_MACHINE="alphaev67" ;;
|
|
|
++ UNAME_MACHINE=alphaev67 ;;
|
|
|
+ "EV6.8CB (21264C)")
|
|
|
+- UNAME_MACHINE="alphaev68" ;;
|
|
|
++ UNAME_MACHINE=alphaev68 ;;
|
|
|
+ "EV6.8AL (21264B)")
|
|
|
+- UNAME_MACHINE="alphaev68" ;;
|
|
|
++ UNAME_MACHINE=alphaev68 ;;
|
|
|
+ "EV6.8CX (21264D)")
|
|
|
+- UNAME_MACHINE="alphaev68" ;;
|
|
|
++ UNAME_MACHINE=alphaev68 ;;
|
|
|
+ "EV6.9A (21264/EV69A)")
|
|
|
+- UNAME_MACHINE="alphaev69" ;;
|
|
|
++ UNAME_MACHINE=alphaev69 ;;
|
|
|
+ "EV7 (21364)")
|
|
|
+- UNAME_MACHINE="alphaev7" ;;
|
|
|
++ UNAME_MACHINE=alphaev7 ;;
|
|
|
+ "EV7.9 (21364A)")
|
|
|
+- UNAME_MACHINE="alphaev79" ;;
|
|
|
++ 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'`
|
|
|
++ 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?
|
|
|
+@@ -354,26 +378,26 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:$
|
|
|
+ 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"
|
|
|
++ 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 [ "$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) | \
|
|
|
++ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
|
|
|
+ grep IS_64BIT_ARCH >/dev/null
|
|
|
+ then
|
|
|
+- SUN_ARCH="x86_64"
|
|
|
++ 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.
|
|
|
+@@ -388,17 +412,17 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:$
|
|
|
+ # 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
|
|
|
++ 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
|
|
|
+@@ -574,18 +598,19 @@ EOF
|
|
|
+ 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`
|
|
|
++ if [ -x /usr/bin/lslpp ] ; then
|
|
|
++ IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
|
|
|
++ awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
|
|
|
+ else
|
|
|
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
|
|
|
+ fi
|
|
|
+ echo ${IBM_ARCH}-ibm-aix${IBM_REV}
|
|
|
+ exit ;;
|
|
|
+ *:AIX:*:*)
|
|
|
+ echo rs6000-ibm-aix
|
|
|
+ exit ;;
|
|
|
+@@ -612,23 +637,23 @@ EOF
|
|
|
+ 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
|
|
|
++ 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
|
|
|
++ 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
|
|
|
+@@ -657,39 +682,39 @@ EOF
|
|
|
+ #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`
|
|
|
++ (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" ]
|
|
|
++ 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) |
|
|
|
++ if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) |
|
|
|
+ grep -q __LP64__
|
|
|
+ then
|
|
|
+- HP_ARCH="hppa2.0w"
|
|
|
++ HP_ARCH=hppa2.0w
|
|
|
+ else
|
|
|
+- HP_ARCH="hppa64"
|
|
|
++ 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 ;;
|
|
|
+@@ -784,24 +809,24 @@ EOF
|
|
|
+ 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_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/ /_/'`
|
|
|
++ 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 ;;
|
|
|
+@@ -873,17 +898,17 @@ EOF
|
|
|
+ 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}
|
|
|
++ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``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:*:*)
|
|
|
+@@ -896,17 +921,17 @@ EOF
|
|
|
+ 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
|
|
|
++ 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 \
|
|
|
+@@ -927,28 +952,34 @@ EOF
|
|
|
+ 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 ;;
|
|
|
++ e2k:Linux:*:*)
|
|
|
++ echo ${UNAME_MACHINE}-unknown-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 ;;
|
|
|
++ k1om: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
|
|
|
+@@ -964,16 +995,19 @@ EOF
|
|
|
+ #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; }
|
|
|
+ ;;
|
|
|
++ mips64el:Linux:*:*)
|
|
|
++ echo ${UNAME_MACHINE}-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}
|
|
|
+@@ -996,16 +1030,19 @@ EOF
|
|
|
+ echo powerpc-unknown-linux-${LIBC}
|
|
|
+ exit ;;
|
|
|
+ ppc64le:Linux:*:*)
|
|
|
+ echo powerpc64le-unknown-linux-${LIBC}
|
|
|
+ exit ;;
|
|
|
+ ppcle:Linux:*:*)
|
|
|
+ echo powerpcle-unknown-linux-${LIBC}
|
|
|
+ exit ;;
|
|
|
++ riscv32:Linux:*:* | riscv64:Linux:*:*)
|
|
|
++ echo ${UNAME_MACHINE}-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}
|
|
|
+@@ -1015,17 +1052,17 @@ EOF
|
|
|
+ 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}
|
|
|
++ echo ${UNAME_MACHINE}-pc-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.
|
|
|
+@@ -1094,17 +1131,17 @@ EOF
|
|
|
+ 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
|
|
|
++ # prints for the "djgpp" host, or else GDB configure 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
|
|
|
+@@ -1243,32 +1280,35 @@ EOF
|
|
|
+ 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 ;;
|
|
|
++ SX-ACE:SUPER-UX:*:*)
|
|
|
++ echo sxace-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 [ "$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) | \
|
|
|
++ (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
|
|
|
+@@ -1280,17 +1320,17 @@ EOF
|
|
|
+ # 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
|
|
|
++ 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 ;;
|
|
|
+@@ -1311,17 +1351,17 @@ EOF
|
|
|
+ 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
|
|
|
++ 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
|
|
|
+@@ -1353,44 +1393,46 @@ EOF
|
|
|
+ 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/ .*$//'
|
|
|
++ 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 ;;
|
|
|
++ amd64:Isilon\ OneFS:*:*)
|
|
|
++ echo x86_64-unknown-onefs
|
|
|
++ exit ;;
|
|
|
+ esac
|
|
|
+
|
|
|
+ cat >&2 <<EOF
|
|
|
+ $0: unable to guess system type
|
|
|
+
|
|
|
+-This script, last modified $timestamp, has failed to recognize
|
|
|
+-the operating system you are using. It is advised that you
|
|
|
+-download the most up to date version of the config scripts from
|
|
|
++This script (version $timestamp), has failed to recognize the
|
|
|
++operating system you are using. If your script is old, overwrite
|
|
|
++config.guess and config.sub with the latest versions from:
|
|
|
+
|
|
|
+- http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
|
|
|
++ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
|
|
|
+ and
|
|
|
+- http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
|
|
|
++ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
|
|
|
+
|
|
|
+-If the version you run ($0) is already up to date, please
|
|
|
+-send the following data and any information you think might be
|
|
|
+-pertinent to <config-patches@gnu.org> in order to provide the needed
|
|
|
+-information to handle your system.
|
|
|
++If $0 has already been updated, send the following data and any
|
|
|
++information you think might be pertinent to config-patches@gnu.org to
|
|
|
++provide the necessary 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`
|
|
|
+
|
|
|
+diff --git a/memory/jemalloc/src/build-aux/config.sub b/memory/jemalloc/src/build-aux/config.sub
|
|
|
+--- a/memory/jemalloc/src/build-aux/config.sub
|
|
|
++++ b/memory/jemalloc/src/build-aux/config.sub
|
|
|
+@@ -1,13 +1,13 @@
|
|
|
+ #! /bin/sh
|
|
|
+ # Configuration validation subroutine script.
|
|
|
+-# Copyright 1992-2014 Free Software Foundation, Inc.
|
|
|
++# Copyright 1992-2016 Free Software Foundation, Inc.
|
|
|
+
|
|
|
+-timestamp='2014-05-01'
|
|
|
++timestamp='2016-11-04'
|
|
|
+
|
|
|
+ # 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
|
|
|
+@@ -20,25 +20,25 @@ timestamp='2014-05-01'
|
|
|
+ # 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.
|
|
|
++# Please send patches 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
|
|
|
++# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
|
|
|
+
|
|
|
+ # 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.
|
|
|
+@@ -48,32 +48,31 @@ timestamp='2014-05-01'
|
|
|
+ # 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
|
|
|
++Usage: $0 [OPTION] CPU-MFR-OPSYS or 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 <config-patches@gnu.org>."
|
|
|
+
|
|
|
+ version="\
|
|
|
+ GNU config.sub ($timestamp)
|
|
|
+
|
|
|
+-Copyright 1992-2014 Free Software Foundation, Inc.
|
|
|
++Copyright 1992-2016 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
|
|
|
+@@ -112,18 +111,18 @@ case $# in
|
|
|
+ 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* | \
|
|
|
++ knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
|
|
|
++ kopensolaris*-gnu* | cloudabi*-eabi* | \
|
|
|
+ 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
|
|
|
+ ;;
|
|
|
+@@ -250,22 +249,23 @@ case $basic_machine in
|
|
|
+ | 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 \
|
|
|
++ | ba \
|
|
|
+ | be32 | be64 \
|
|
|
+ | bfin \
|
|
|
+ | c4x | c8051 | clipper \
|
|
|
+ | d10v | d30v | dlx | dsp16xx \
|
|
|
+- | epiphany \
|
|
|
+- | fido | fr30 | frv \
|
|
|
++ | e2k | epiphany \
|
|
|
++ | fido | fr30 | frv | ft32 \
|
|
|
+ | 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 \
|
|
|
+@@ -296,41 +296,47 @@ case $basic_machine in
|
|
|
+ | mt \
|
|
|
+ | msp430 \
|
|
|
+ | nds32 | nds32le | nds32be \
|
|
|
+ | nios | nios2 | nios2eb | nios2el \
|
|
|
+ | ns16k | ns32k \
|
|
|
+ | open8 | or1k | or1knd | or32 \
|
|
|
+ | pdp10 | pdp11 | pj | pjl \
|
|
|
+ | powerpc | powerpc64 | powerpc64le | powerpcle \
|
|
|
++ | pru \
|
|
|
+ | pyramid \
|
|
|
++ | riscv32 | riscv64 \
|
|
|
+ | 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 \
|
|
|
++ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]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 \
|
|
|
++ | visium \
|
|
|
+ | 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
|
|
|
+ ;;
|
|
|
++ leon|leon[3-9])
|
|
|
++ basic_machine=sparc-$basic_machine
|
|
|
++ ;;
|
|
|
+ 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
|
|
|
+@@ -366,22 +372,23 @@ case $basic_machine in
|
|
|
+ 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-* \
|
|
|
++ | ba-* \
|
|
|
+ | be32-* | be64-* \
|
|
|
+ | bfin-* | bs2000-* \
|
|
|
+ | c[123]* | c30-* | [cjt]90-* | c4x-* \
|
|
|
+ | c8051-* | clipper-* | craynv-* | cydra-* \
|
|
|
+ | d10v-* | d30v-* | dlx-* \
|
|
|
+- | elxsi-* \
|
|
|
++ | e2k-* | 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-* \
|
|
|
+@@ -417,30 +424,33 @@ case $basic_machine in
|
|
|
+ | nds32-* | nds32le-* | nds32be-* \
|
|
|
+ | nios-* | nios2-* | nios2eb-* | nios2el-* \
|
|
|
+ | none-* | np1-* | ns16k-* | ns32k-* \
|
|
|
+ | open8-* \
|
|
|
+ | or1k*-* \
|
|
|
+ | orion-* \
|
|
|
+ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
|
|
|
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
|
|
|
++ | pru-* \
|
|
|
+ | pyramid-* \
|
|
|
++ | riscv32-* | riscv64-* \
|
|
|
+ | 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?-* \
|
|
|
++ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \
|
|
|
+ | tahoe-* \
|
|
|
+ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
|
|
|
+ | tile*-* \
|
|
|
+ | tron-* \
|
|
|
+ | ubicom32-* \
|
|
|
+ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
|
|
|
+ | vax-* \
|
|
|
++ | visium-* \
|
|
|
+ | we32k-* \
|
|
|
+ | x86-* | x86_64-* | xc16x-* | xps100-* \
|
|
|
+ | xstormy16-* | xtensa*-* \
|
|
|
+ | ymp-* \
|
|
|
+ | z8k-* | z80-*)
|
|
|
+ ;;
|
|
|
+ # Recognize the basic CPU types without company name, with glob match.
|
|
|
+ xtensa*)
|
|
|
+@@ -507,16 +517,19 @@ case $basic_machine in
|
|
|
+ apollo68bsd)
|
|
|
+ basic_machine=m68k-apollo
|
|
|
+ os=-bsd
|
|
|
+ ;;
|
|
|
+ aros)
|
|
|
+ basic_machine=i386-pc
|
|
|
+ os=-aros
|
|
|
+ ;;
|
|
|
++ asmjs)
|
|
|
++ basic_machine=asmjs-unknown
|
|
|
++ ;;
|
|
|
+ aux)
|
|
|
+ basic_machine=m68k-apple
|
|
|
+ os=-aux
|
|
|
+ ;;
|
|
|
+ balance)
|
|
|
+ basic_machine=ns32k-sequent
|
|
|
+ os=-dynix
|
|
|
+ ;;
|
|
|
+@@ -627,16 +640,24 @@ case $basic_machine in
|
|
|
+ dpx20 | dpx20-*)
|
|
|
+ basic_machine=rs6000-bull
|
|
|
+ os=-bosx
|
|
|
+ ;;
|
|
|
+ dpx2* | dpx2*-bull)
|
|
|
+ basic_machine=m68k-bull
|
|
|
+ os=-sysv3
|
|
|
+ ;;
|
|
|
++ e500v[12])
|
|
|
++ basic_machine=powerpc-unknown
|
|
|
++ os=$os"spe"
|
|
|
++ ;;
|
|
|
++ e500v[12]-*)
|
|
|
++ basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
|
|
|
++ os=$os"spe"
|
|
|
++ ;;
|
|
|
+ ebmon29k)
|
|
|
+ basic_machine=a29k-amd
|
|
|
+ os=-ebmon
|
|
|
+ ;;
|
|
|
+ elxsi)
|
|
|
+ basic_machine=elxsi-elxsi
|
|
|
+ os=-bsd
|
|
|
+ ;;
|
|
|
+@@ -768,16 +789,19 @@ case $basic_machine in
|
|
|
+ os=-irix4
|
|
|
+ ;;
|
|
|
+ esac
|
|
|
+ ;;
|
|
|
+ isi68 | isi)
|
|
|
+ basic_machine=m68k-isi
|
|
|
+ os=-sysv
|
|
|
+ ;;
|
|
|
++ leon-*|leon[3-9]-*)
|
|
|
++ basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
|
|
|
++ ;;
|
|
|
+ m68knommu)
|
|
|
+ basic_machine=m68k-unknown
|
|
|
+ os=-linux
|
|
|
+ ;;
|
|
|
+ m68knommu-*)
|
|
|
+ basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
|
|
|
+ os=-linux
|
|
|
+ ;;
|
|
|
+@@ -823,16 +847,20 @@ case $basic_machine in
|
|
|
+ monitor)
|
|
|
+ basic_machine=m68k-rom68k
|
|
|
+ os=-coff
|
|
|
+ ;;
|
|
|
+ morphos)
|
|
|
+ basic_machine=powerpc-unknown
|
|
|
+ os=-morphos
|
|
|
+ ;;
|
|
|
++ moxiebox)
|
|
|
++ basic_machine=moxie-unknown
|
|
|
++ os=-moxiebox
|
|
|
++ ;;
|
|
|
+ msdos)
|
|
|
+ basic_machine=i386-pc
|
|
|
+ os=-msdos
|
|
|
+ ;;
|
|
|
+ ms1-*)
|
|
|
+ basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
|
|
|
+ ;;
|
|
|
+ msys)
|
|
|
+@@ -999,27 +1027,27 @@ case $basic_machine in
|
|
|
+ ;;
|
|
|
+ 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)
|
|
|
++ ppcle | powerpclittle)
|
|
|
+ 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)
|
|
|
++ ppc64le | powerpc64little)
|
|
|
+ basic_machine=powerpc64le-unknown
|
|
|
+ ;;
|
|
|
+ ppc64le-* | powerpc64little-*)
|
|
|
+ basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
|
|
|
+ ;;
|
|
|
+ ps2)
|
|
|
+ basic_machine=i386-ibm
|
|
|
+ ;;
|
|
|
+@@ -1355,37 +1383,38 @@ case $os in
|
|
|
+ # 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* \
|
|
|
++ | -aos* | -aros* | -cloudabi* | -sortix* \
|
|
|
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
|
|
|
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
|
|
|
+ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
|
|
|
+- | -bitrig* | -openbsd* | -solidbsd* \
|
|
|
++ | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \
|
|
|
+ | -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* \
|
|
|
++ | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
|
|
|
+ | -linux-newlib* | -linux-musl* | -linux-uclibc* \
|
|
|
+- | -uxpv* | -beos* | -mpeix* | -udk* \
|
|
|
++ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
|
|
|
+ | -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*)
|
|
|
++ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
|
|
|
++ | -onefs* | -tirtos* | -phoenix* | -fuchsia*)
|
|
|
+ # Remember, each alternative MUST END IN *, to match a version number.
|
|
|
+ ;;
|
|
|
+ -qnx*)
|
|
|
+ case $basic_machine in
|
|
|
+ x86-* | i*86-*)
|
|
|
+ ;;
|
|
|
+ *)
|
|
|
+ os=-nto$os
|
|
|
+@@ -1399,19 +1428,16 @@ case $os in
|
|
|
+ ;;
|
|
|
+ -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|'`
|
|
|
+@@ -1510,16 +1536,18 @@ case $os in
|
|
|
+ -zvmoe)
|
|
|
+ os=-zvmoe
|
|
|
+ ;;
|
|
|
+ -dicos*)
|
|
|
+ os=-dicos
|
|
|
+ ;;
|
|
|
+ -nacl*)
|
|
|
+ ;;
|
|
|
++ -ios)
|
|
|
++ ;;
|
|
|
+ -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
|
|
|
+ ;;
|
|
|
+diff --git a/memory/jemalloc/src/configure b/memory/jemalloc/src/configure
|
|
|
+--- a/memory/jemalloc/src/configure
|
|
|
++++ b/memory/jemalloc/src/configure
|
|
|
+@@ -782,16 +782,17 @@ enable_valgrind
|
|
|
+ enable_xmalloc
|
|
|
+ enable_cache_oblivious
|
|
|
+ with_lg_tiny_min
|
|
|
+ with_lg_quantum
|
|
|
+ with_lg_page
|
|
|
+ with_lg_page_sizes
|
|
|
+ with_lg_size_class_group
|
|
|
+ with_version
|
|
|
++enable_syscall
|
|
|
+ enable_lazy_lock
|
|
|
+ enable_tls
|
|
|
+ enable_zone_allocator
|
|
|
+ '
|
|
|
+ ac_precious_vars='build_alias
|
|
|
+ host_alias
|
|
|
+ target_alias
|
|
|
+ CC
|
|
|
+@@ -1437,16 +1438,17 @@ Optional Features:
|
|
|
+ --disable-fill Disable support for junk/zero filling, quarantine,
|
|
|
+ and redzones
|
|
|
+ --enable-utrace Enable utrace(2)-based tracing
|
|
|
+ --disable-valgrind Disable support for Valgrind
|
|
|
+ --enable-xmalloc Support xmalloc option
|
|
|
+ --disable-cache-oblivious
|
|
|
+ Disable support for cache-oblivious allocation
|
|
|
+ alignment
|
|
|
++ --disable-syscall Disable use of syscall(2)
|
|
|
+ --enable-lazy-lock Enable lazy locking (only lock when multi-threaded)
|
|
|
+ --disable-tls Disable thread-local storage (__thread keyword)
|
|
|
+ --disable-zone-allocator
|
|
|
+ Disable zone allocator for Darwin
|
|
|
+
|
|
|
+ Optional Packages:
|
|
|
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
|
|
|
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
|
|
|
+@@ -5306,59 +5308,61 @@ fi
|
|
|
+
|
|
|
+
|
|
|
+ CFLAGS="$CFLAGS"
|
|
|
+ default_munmap="1"
|
|
|
+ maps_coalesce="1"
|
|
|
+ case "${host}" in
|
|
|
+ *-*-darwin* | *-*-ios*)
|
|
|
+ abi="macho"
|
|
|
+- $as_echo "#define JEMALLOC_PURGE_MADVISE_FREE " >>confdefs.h
|
|
|
+-
|
|
|
+ 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*)
|
|
|
+ abi="elf"
|
|
|
+ $as_echo "#define JEMALLOC_SYSCTL_VM_OVERCOMMIT " >>confdefs.h
|
|
|
+
|
|
|
+- $as_echo "#define JEMALLOC_PURGE_MADVISE_FREE " >>confdefs.h
|
|
|
+-
|
|
|
+ force_lazy_lock="1"
|
|
|
+ ;;
|
|
|
+ *-*-dragonfly*)
|
|
|
+ abi="elf"
|
|
|
+- $as_echo "#define JEMALLOC_PURGE_MADVISE_FREE " >>confdefs.h
|
|
|
+-
|
|
|
+ ;;
|
|
|
+ *-*-openbsd*)
|
|
|
+ abi="elf"
|
|
|
+- $as_echo "#define JEMALLOC_PURGE_MADVISE_FREE " >>confdefs.h
|
|
|
+-
|
|
|
+ force_tls="0"
|
|
|
+ ;;
|
|
|
+ *-*-bitrig*)
|
|
|
+ abi="elf"
|
|
|
+- $as_echo "#define JEMALLOC_PURGE_MADVISE_FREE " >>confdefs.h
|
|
|
+-
|
|
|
+ ;;
|
|
|
+- *-*-linux*)
|
|
|
++ *-*-linux-android)
|
|
|
+ CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE"
|
|
|
+ abi="elf"
|
|
|
+ $as_echo "#define JEMALLOC_HAS_ALLOCA_H 1" >>confdefs.h
|
|
|
+
|
|
|
+ $as_echo "#define JEMALLOC_PROC_SYS_VM_OVERCOMMIT_MEMORY " >>confdefs.h
|
|
|
+
|
|
|
+- $as_echo "#define JEMALLOC_PURGE_MADVISE_DONTNEED " >>confdefs.h
|
|
|
++ $as_echo "#define JEMALLOC_THREADED_INIT " >>confdefs.h
|
|
|
++
|
|
|
++ $as_echo "#define JEMALLOC_C11ATOMICS 1" >>confdefs.h
|
|
|
++
|
|
|
++ force_tls="0"
|
|
|
++ default_munmap="0"
|
|
|
++ ;;
|
|
|
++ *-*-linux* | *-*-kfreebsd*)
|
|
|
++ CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE"
|
|
|
++ abi="elf"
|
|
|
++ $as_echo "#define JEMALLOC_HAS_ALLOCA_H 1" >>confdefs.h
|
|
|
++
|
|
|
++ $as_echo "#define JEMALLOC_PROC_SYS_VM_OVERCOMMIT_MEMORY " >>confdefs.h
|
|
|
+
|
|
|
+ $as_echo "#define JEMALLOC_THREADED_INIT " >>confdefs.h
|
|
|
+
|
|
|
+ $as_echo "#define JEMALLOC_USE_CXX_THROW " >>confdefs.h
|
|
|
+
|
|
|
+ default_munmap="0"
|
|
|
+ ;;
|
|
|
+ *-*-netbsd*)
|
|
|
+@@ -5383,23 +5387,19 @@ main ()
|
|
|
+ if ac_fn_c_try_compile "$LINENO"; then :
|
|
|
+ abi="elf"
|
|
|
+ else
|
|
|
+ abi="aout"
|
|
|
+ fi
|
|
|
+ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
|
|
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $abi" >&5
|
|
|
+ $as_echo "$abi" >&6; }
|
|
|
+- $as_echo "#define JEMALLOC_PURGE_MADVISE_FREE " >>confdefs.h
|
|
|
+-
|
|
|
+ ;;
|
|
|
+ *-*-solaris2*)
|
|
|
+ abi="elf"
|
|
|
+- $as_echo "#define JEMALLOC_PURGE_MADVISE_FREE " >>confdefs.h
|
|
|
+-
|
|
|
+ RPATH='-Wl,-R,$(1)'
|
|
|
+ CPPFLAGS="$CPPFLAGS -D_POSIX_PTHREAD_SEMANTICS"
|
|
|
+ LIBS="$LIBS -lposix4 -lsocket -lnsl"
|
|
|
+ ;;
|
|
|
+ *-ibm-aix*)
|
|
|
+ if "$LG_SIZEOF_PTR" = "8"; then
|
|
|
+ LD_PRELOAD_VAR="LDR_PRELOAD64"
|
|
|
+ else
|
|
|
+@@ -7826,16 +7826,52 @@ if test "$ac_res" != no; then :
|
|
|
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
|
|
|
+
|
|
|
+ else
|
|
|
+ as_fn_error $? "libpthread is missing" "$LINENO" 5
|
|
|
+ fi
|
|
|
+
|
|
|
+ fi
|
|
|
+
|
|
|
++
|
|
|
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthread_atfork(3) is compilable" >&5
|
|
|
++$as_echo_n "checking whether pthread_atfork(3) is compilable... " >&6; }
|
|
|
++if ${je_cv_pthread_atfork+:} false; then :
|
|
|
++ $as_echo_n "(cached) " >&6
|
|
|
++else
|
|
|
++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
|
|
++/* end confdefs.h. */
|
|
|
++
|
|
|
++#include <pthread.h>
|
|
|
++
|
|
|
++int
|
|
|
++main ()
|
|
|
++{
|
|
|
++
|
|
|
++ pthread_atfork((void *)0, (void *)0, (void *)0);
|
|
|
++
|
|
|
++ ;
|
|
|
++ return 0;
|
|
|
++}
|
|
|
++_ACEOF
|
|
|
++if ac_fn_c_try_link "$LINENO"; then :
|
|
|
++ je_cv_pthread_atfork=yes
|
|
|
++else
|
|
|
++ je_cv_pthread_atfork=no
|
|
|
++fi
|
|
|
++rm -f core conftest.err conftest.$ac_objext \
|
|
|
++ conftest$ac_exeext conftest.$ac_ext
|
|
|
++fi
|
|
|
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $je_cv_pthread_atfork" >&5
|
|
|
++$as_echo "$je_cv_pthread_atfork" >&6; }
|
|
|
++
|
|
|
++ if test "x${je_cv_pthread_atfork}" = "xyes" ; then
|
|
|
++ $as_echo "#define JEMALLOC_HAVE_PTHREAD_ATFORK " >>confdefs.h
|
|
|
++
|
|
|
++ fi
|
|
|
+ fi
|
|
|
+
|
|
|
+ CPPFLAGS="$CPPFLAGS -D_REENTRANT"
|
|
|
+
|
|
|
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing clock_gettime" >&5
|
|
|
+ $as_echo_n "checking for library containing clock_gettime... " >&6; }
|
|
|
+ if ${ac_cv_search_clock_gettime+:} false; then :
|
|
|
+ $as_echo_n "(cached) " >&6
|
|
|
+@@ -8108,17 +8144,31 @@ fi
|
|
|
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $je_cv_mach_absolute_time" >&5
|
|
|
+ $as_echo "$je_cv_mach_absolute_time" >&6; }
|
|
|
+
|
|
|
+ if test "x${je_cv_mach_absolute_time}" = "xyes" ; then
|
|
|
+ $as_echo "#define JEMALLOC_HAVE_MACH_ABSOLUTE_TIME 1" >>confdefs.h
|
|
|
+
|
|
|
+ fi
|
|
|
+
|
|
|
+-SAVED_CFLAGS="${CFLAGS}"
|
|
|
++# Check whether --enable-syscall was given.
|
|
|
++if test "${enable_syscall+set}" = set; then :
|
|
|
++ enableval=$enable_syscall; if test "x$enable_syscall" = "xno" ; then
|
|
|
++ enable_syscall="0"
|
|
|
++else
|
|
|
++ enable_syscall="1"
|
|
|
++fi
|
|
|
++
|
|
|
++else
|
|
|
++ enable_syscall="1"
|
|
|
++
|
|
|
++fi
|
|
|
++
|
|
|
++if test "x$enable_syscall" = "x1" ; then
|
|
|
++ SAVED_CFLAGS="${CFLAGS}"
|
|
|
+
|
|
|
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether compiler supports -Werror" >&5
|
|
|
+ $as_echo_n "checking whether compiler supports -Werror... " >&6; }
|
|
|
+ TCFLAGS="${CFLAGS}"
|
|
|
+ if test "x${CFLAGS}" = "x" ; then
|
|
|
+ CFLAGS="-Werror"
|
|
|
+ else
|
|
|
+ CFLAGS="${CFLAGS} -Werror"
|
|
|
+@@ -8178,20 +8228,21 @@ else
|
|
|
+ je_cv_syscall=no
|
|
|
+ fi
|
|
|
+ rm -f core conftest.err conftest.$ac_objext \
|
|
|
+ conftest$ac_exeext conftest.$ac_ext
|
|
|
+ fi
|
|
|
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $je_cv_syscall" >&5
|
|
|
+ $as_echo "$je_cv_syscall" >&6; }
|
|
|
+
|
|
|
+-CFLAGS="${SAVED_CFLAGS}"
|
|
|
+-if test "x$je_cv_syscall" = "xyes" ; then
|
|
|
+- $as_echo "#define JEMALLOC_HAVE_SYSCALL " >>confdefs.h
|
|
|
+-
|
|
|
++ CFLAGS="${SAVED_CFLAGS}"
|
|
|
++ if test "x$je_cv_syscall" = "xyes" ; then
|
|
|
++ $as_echo "#define JEMALLOC_USE_SYSCALL " >>confdefs.h
|
|
|
++
|
|
|
++ fi
|
|
|
+ fi
|
|
|
+
|
|
|
+ ac_fn_c_check_func "$LINENO" "secure_getenv" "ac_cv_func_secure_getenv"
|
|
|
+ if test "x$ac_cv_func_secure_getenv" = xyes; then :
|
|
|
+ have_secure_getenv="1"
|
|
|
+ else
|
|
|
+ have_secure_getenv="0"
|
|
|
+
|
|
|
+@@ -8568,19 +8619,17 @@ else
|
|
|
+ /* end confdefs.h. */
|
|
|
+
|
|
|
+ #include <sys/mman.h>
|
|
|
+
|
|
|
+ int
|
|
|
+ main ()
|
|
|
+ {
|
|
|
+
|
|
|
+- {
|
|
|
+- madvise((void *)0, 0, 0);
|
|
|
+- }
|
|
|
++ madvise((void *)0, 0, 0);
|
|
|
+
|
|
|
+ ;
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ _ACEOF
|
|
|
+ if ac_fn_c_try_link "$LINENO"; then :
|
|
|
+ je_cv_madvise=yes
|
|
|
+ else
|
|
|
+@@ -8590,16 +8639,128 @@ rm -f core conftest.err conftest.$ac_obj
|
|
|
+ conftest$ac_exeext conftest.$ac_ext
|
|
|
+ fi
|
|
|
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $je_cv_madvise" >&5
|
|
|
+ $as_echo "$je_cv_madvise" >&6; }
|
|
|
+
|
|
|
+ if test "x${je_cv_madvise}" = "xyes" ; then
|
|
|
+ $as_echo "#define JEMALLOC_HAVE_MADVISE " >>confdefs.h
|
|
|
+
|
|
|
++
|
|
|
++
|
|
|
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether madvise(..., MADV_FREE) is compilable" >&5
|
|
|
++$as_echo_n "checking whether madvise(..., MADV_FREE) is compilable... " >&6; }
|
|
|
++if ${je_cv_madv_free+:} false; then :
|
|
|
++ $as_echo_n "(cached) " >&6
|
|
|
++else
|
|
|
++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
|
|
++/* end confdefs.h. */
|
|
|
++
|
|
|
++#include <sys/mman.h>
|
|
|
++
|
|
|
++int
|
|
|
++main ()
|
|
|
++{
|
|
|
++
|
|
|
++ madvise((void *)0, 0, MADV_FREE);
|
|
|
++
|
|
|
++ ;
|
|
|
++ return 0;
|
|
|
++}
|
|
|
++_ACEOF
|
|
|
++if ac_fn_c_try_link "$LINENO"; then :
|
|
|
++ je_cv_madv_free=yes
|
|
|
++else
|
|
|
++ je_cv_madv_free=no
|
|
|
++fi
|
|
|
++rm -f core conftest.err conftest.$ac_objext \
|
|
|
++ conftest$ac_exeext conftest.$ac_ext
|
|
|
++fi
|
|
|
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $je_cv_madv_free" >&5
|
|
|
++$as_echo "$je_cv_madv_free" >&6; }
|
|
|
++
|
|
|
++ if test "x${je_cv_madv_free}" = "xyes" ; then
|
|
|
++ $as_echo "#define JEMALLOC_PURGE_MADVISE_FREE " >>confdefs.h
|
|
|
++
|
|
|
++ fi
|
|
|
++
|
|
|
++
|
|
|
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether madvise(..., MADV_DONTNEED) is compilable" >&5
|
|
|
++$as_echo_n "checking whether madvise(..., MADV_DONTNEED) is compilable... " >&6; }
|
|
|
++if ${je_cv_madv_dontneed+:} false; then :
|
|
|
++ $as_echo_n "(cached) " >&6
|
|
|
++else
|
|
|
++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
|
|
++/* end confdefs.h. */
|
|
|
++
|
|
|
++#include <sys/mman.h>
|
|
|
++
|
|
|
++int
|
|
|
++main ()
|
|
|
++{
|
|
|
++
|
|
|
++ madvise((void *)0, 0, MADV_DONTNEED);
|
|
|
++
|
|
|
++ ;
|
|
|
++ return 0;
|
|
|
++}
|
|
|
++_ACEOF
|
|
|
++if ac_fn_c_try_link "$LINENO"; then :
|
|
|
++ je_cv_madv_dontneed=yes
|
|
|
++else
|
|
|
++ je_cv_madv_dontneed=no
|
|
|
++fi
|
|
|
++rm -f core conftest.err conftest.$ac_objext \
|
|
|
++ conftest$ac_exeext conftest.$ac_ext
|
|
|
++fi
|
|
|
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $je_cv_madv_dontneed" >&5
|
|
|
++$as_echo "$je_cv_madv_dontneed" >&6; }
|
|
|
++
|
|
|
++ if test "x${je_cv_madv_dontneed}" = "xyes" ; then
|
|
|
++ $as_echo "#define JEMALLOC_PURGE_MADVISE_DONTNEED " >>confdefs.h
|
|
|
++
|
|
|
++ fi
|
|
|
++
|
|
|
++
|
|
|
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether madvise(..., MADV_[NO]HUGEPAGE) is compilable" >&5
|
|
|
++$as_echo_n "checking whether madvise(..., MADV_[NO]HUGEPAGE) is compilable... " >&6; }
|
|
|
++if ${je_cv_thp+:} false; then :
|
|
|
++ $as_echo_n "(cached) " >&6
|
|
|
++else
|
|
|
++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
|
|
++/* end confdefs.h. */
|
|
|
++
|
|
|
++#include <sys/mman.h>
|
|
|
++
|
|
|
++int
|
|
|
++main ()
|
|
|
++{
|
|
|
++
|
|
|
++ madvise((void *)0, 0, MADV_HUGEPAGE);
|
|
|
++ madvise((void *)0, 0, MADV_NOHUGEPAGE);
|
|
|
++
|
|
|
++ ;
|
|
|
++ return 0;
|
|
|
++}
|
|
|
++_ACEOF
|
|
|
++if ac_fn_c_try_link "$LINENO"; then :
|
|
|
++ je_cv_thp=yes
|
|
|
++else
|
|
|
++ je_cv_thp=no
|
|
|
++fi
|
|
|
++rm -f core conftest.err conftest.$ac_objext \
|
|
|
++ conftest$ac_exeext conftest.$ac_ext
|
|
|
++fi
|
|
|
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $je_cv_thp" >&5
|
|
|
++$as_echo "$je_cv_thp" >&6; }
|
|
|
++
|
|
|
++ if test "x${je_cv_thp}" = "xyes" ; then
|
|
|
++ $as_echo "#define JEMALLOC_THP " >>confdefs.h
|
|
|
++
|
|
|
++ fi
|
|
|
+ fi
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ if test "x${je_cv_atomic9}" != "xyes" -a "x${je_cv_osatomic}" != "xyes" ; then
|
|
|
+
|
|
|
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to force 32-bit __sync_{add,sub}_and_fetch()" >&5
|
|
|
+@@ -8741,24 +8902,29 @@ fi
|
|
|
+ $as_echo_n "checking whether Darwin os_unfair_lock_*() is compilable... " >&6; }
|
|
|
+ if ${je_cv_os_unfair_lock+:} false; then :
|
|
|
+ $as_echo_n "(cached) " >&6
|
|
|
+ else
|
|
|
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
|
|
+ /* end confdefs.h. */
|
|
|
+
|
|
|
+ #include <os/lock.h>
|
|
|
+-
|
|
|
+-int
|
|
|
+-main ()
|
|
|
+-{
|
|
|
+-
|
|
|
++#include <AvailabilityMacros.h>
|
|
|
++
|
|
|
++int
|
|
|
++main ()
|
|
|
++{
|
|
|
++
|
|
|
++ #if MAC_OS_X_VERSION_MIN_REQUIRED < 101200
|
|
|
++ #error "os_unfair_lock is not supported"
|
|
|
++ #else
|
|
|
+ os_unfair_lock lock = OS_UNFAIR_LOCK_INIT;
|
|
|
+ os_unfair_lock_lock(&lock);
|
|
|
+ os_unfair_lock_unlock(&lock);
|
|
|
++ #endif
|
|
|
+
|
|
|
+ ;
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ _ACEOF
|
|
|
+ if ac_fn_c_try_link "$LINENO"; then :
|
|
|
+ je_cv_os_unfair_lock=yes
|
|
|
+ else
|
|
|
+diff --git a/memory/jemalloc/src/configure.ac b/memory/jemalloc/src/configure.ac
|
|
|
+--- a/memory/jemalloc/src/configure.ac
|
|
|
++++ b/memory/jemalloc/src/configure.ac
|
|
|
+@@ -166,17 +166,16 @@ if test "x${je_cv_cray}" = "xyes" ; then
|
|
|
+ ])],
|
|
|
+ [je_cv_cray_84=yes],
|
|
|
+ [je_cv_cray_84=no])])
|
|
|
+ fi
|
|
|
+
|
|
|
+ if test "x$CFLAGS" = "x" ; then
|
|
|
+ no_CFLAGS="yes"
|
|
|
+ if test "x$GCC" = "xyes" ; then
|
|
|
+-dnl JE_CFLAGS_APPEND([-std=gnu99])
|
|
|
+ JE_CFLAGS_APPEND([-std=gnu11])
|
|
|
+ if test "x$je_cv_cflags_appended" = "x-std=gnu11" ; then
|
|
|
+ AC_DEFINE_UNQUOTED([JEMALLOC_HAS_RESTRICT])
|
|
|
+ else
|
|
|
+ JE_CFLAGS_APPEND([-std=gnu99])
|
|
|
+ if test "x$je_cv_cflags_appended" = "x-std=gnu99" ; then
|
|
|
+ AC_DEFINE_UNQUOTED([JEMALLOC_HAS_RESTRICT])
|
|
|
+ fi
|
|
|
+@@ -350,73 +349,76 @@ dnl Define cpp macros in CPPFLAGS, rathe
|
|
|
+ dnl definitions need to be seen before any headers are included, which is a pain
|
|
|
+ dnl to make happen otherwise.
|
|
|
+ CFLAGS="$CFLAGS"
|
|
|
+ default_munmap="1"
|
|
|
+ maps_coalesce="1"
|
|
|
+ case "${host}" in
|
|
|
+ *-*-darwin* | *-*-ios*)
|
|
|
+ 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*)
|
|
|
+ abi="elf"
|
|
|
+ AC_DEFINE([JEMALLOC_SYSCTL_VM_OVERCOMMIT], [ ])
|
|
|
+- AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ])
|
|
|
+ force_lazy_lock="1"
|
|
|
+ ;;
|
|
|
+ *-*-dragonfly*)
|
|
|
+ abi="elf"
|
|
|
+- AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ])
|
|
|
+ ;;
|
|
|
+ *-*-openbsd*)
|
|
|
+ abi="elf"
|
|
|
+- AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ])
|
|
|
+ force_tls="0"
|
|
|
+ ;;
|
|
|
+ *-*-bitrig*)
|
|
|
+ abi="elf"
|
|
|
+- AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ])
|
|
|
+ ;;
|
|
|
+- *-*-linux*)
|
|
|
++ *-*-linux-android)
|
|
|
+ dnl syscall(2) and secure_getenv(3) are exposed by _GNU_SOURCE.
|
|
|
+ CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE"
|
|
|
+ abi="elf"
|
|
|
+ AC_DEFINE([JEMALLOC_HAS_ALLOCA_H])
|
|
|
+ AC_DEFINE([JEMALLOC_PROC_SYS_VM_OVERCOMMIT_MEMORY], [ ])
|
|
|
+- AC_DEFINE([JEMALLOC_PURGE_MADVISE_DONTNEED], [ ])
|
|
|
++ AC_DEFINE([JEMALLOC_THREADED_INIT], [ ])
|
|
|
++ AC_DEFINE([JEMALLOC_C11ATOMICS])
|
|
|
++ force_tls="0"
|
|
|
++ default_munmap="0"
|
|
|
++ ;;
|
|
|
++ *-*-linux* | *-*-kfreebsd*)
|
|
|
++ dnl syscall(2) and secure_getenv(3) are exposed by _GNU_SOURCE.
|
|
|
++ CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE"
|
|
|
++ abi="elf"
|
|
|
++ AC_DEFINE([JEMALLOC_HAS_ALLOCA_H])
|
|
|
++ AC_DEFINE([JEMALLOC_PROC_SYS_VM_OVERCOMMIT_MEMORY], [ ])
|
|
|
+ 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
|
|
|
+ ]])],
|
|
|
+ [abi="elf"],
|
|
|
+ [abi="aout"])
|
|
|
+ AC_MSG_RESULT([$abi])
|
|
|
+- AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ])
|
|
|
+ ;;
|
|
|
+ *-*-solaris2*)
|
|
|
+ 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
|
|
|
+@@ -1322,16 +1324,24 @@ 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]))])
|
|
|
++ JE_COMPILABLE([pthread_atfork(3)], [
|
|
|
++#include <pthread.h>
|
|
|
++], [
|
|
|
++ pthread_atfork((void *)0, (void *)0, (void *)0);
|
|
|
++], [je_cv_pthread_atfork])
|
|
|
++ if test "x${je_cv_pthread_atfork}" = "xyes" ; then
|
|
|
++ AC_DEFINE([JEMALLOC_HAVE_PTHREAD_ATFORK], [ ])
|
|
|
++ fi
|
|
|
+ fi
|
|
|
+
|
|
|
+ CPPFLAGS="$CPPFLAGS -D_REENTRANT"
|
|
|
+
|
|
|
+ dnl Check whether clock_gettime(2) is in libc or librt.
|
|
|
+ AC_SEARCH_LIBS([clock_gettime], [rt])
|
|
|
+
|
|
|
+ dnl Cray wrapper compiler often adds `-lrt` when using `-static`. Check with
|
|
|
+@@ -1381,30 +1391,43 @@ JE_COMPILABLE([mach_absolute_time()], [
|
|
|
+ #include <mach/mach_time.h>
|
|
|
+ ], [
|
|
|
+ mach_absolute_time();
|
|
|
+ ], [je_cv_mach_absolute_time])
|
|
|
+ if test "x${je_cv_mach_absolute_time}" = "xyes" ; then
|
|
|
+ AC_DEFINE([JEMALLOC_HAVE_MACH_ABSOLUTE_TIME])
|
|
|
+ fi
|
|
|
+
|
|
|
+-dnl Check if syscall(2) is usable. Treat warnings as errors, so that e.g. OS X
|
|
|
+-dnl 10.12's deprecation warning prevents use.
|
|
|
+-SAVED_CFLAGS="${CFLAGS}"
|
|
|
+-JE_CFLAGS_APPEND([-Werror])
|
|
|
+-JE_COMPILABLE([syscall(2)], [
|
|
|
++dnl Use syscall(2) (if available) by default.
|
|
|
++AC_ARG_ENABLE([syscall],
|
|
|
++ [AS_HELP_STRING([--disable-syscall], [Disable use of syscall(2)])],
|
|
|
++[if test "x$enable_syscall" = "xno" ; then
|
|
|
++ enable_syscall="0"
|
|
|
++else
|
|
|
++ enable_syscall="1"
|
|
|
++fi
|
|
|
++],
|
|
|
++[enable_syscall="1"]
|
|
|
++)
|
|
|
++if test "x$enable_syscall" = "x1" ; then
|
|
|
++ dnl Check if syscall(2) is usable. Treat warnings as errors, so that e.g. OS
|
|
|
++ dnl X 10.12's deprecation warning prevents use.
|
|
|
++ SAVED_CFLAGS="${CFLAGS}"
|
|
|
++ JE_CFLAGS_APPEND([-Werror])
|
|
|
++ JE_COMPILABLE([syscall(2)], [
|
|
|
+ #include <sys/syscall.h>
|
|
|
+ #include <unistd.h>
|
|
|
+ ], [
|
|
|
+ syscall(SYS_write, 2, "hello", 5);
|
|
|
+ ],
|
|
|
+- [je_cv_syscall])
|
|
|
+-CFLAGS="${SAVED_CFLAGS}"
|
|
|
+-if test "x$je_cv_syscall" = "xyes" ; then
|
|
|
+- AC_DEFINE([JEMALLOC_HAVE_SYSCALL], [ ])
|
|
|
++ [je_cv_syscall])
|
|
|
++ CFLAGS="${SAVED_CFLAGS}"
|
|
|
++ if test "x$je_cv_syscall" = "xyes" ; then
|
|
|
++ AC_DEFINE([JEMALLOC_USE_SYSCALL], [ ])
|
|
|
++ fi
|
|
|
+ fi
|
|
|
+
|
|
|
+ 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
|
|
|
+@@ -1594,22 +1617,51 @@ if test "x${je_cv_osatomic}" = "xyes" ;
|
|
|
+ fi
|
|
|
+
|
|
|
+ dnl ============================================================================
|
|
|
+ dnl Check for madvise(2).
|
|
|
+
|
|
|
+ JE_COMPILABLE([madvise(2)], [
|
|
|
+ #include <sys/mman.h>
|
|
|
+ ], [
|
|
|
+- {
|
|
|
+- madvise((void *)0, 0, 0);
|
|
|
+- }
|
|
|
++ madvise((void *)0, 0, 0);
|
|
|
+ ], [je_cv_madvise])
|
|
|
+ if test "x${je_cv_madvise}" = "xyes" ; then
|
|
|
+ AC_DEFINE([JEMALLOC_HAVE_MADVISE], [ ])
|
|
|
++
|
|
|
++ dnl Check for madvise(..., MADV_FREE).
|
|
|
++ JE_COMPILABLE([madvise(..., MADV_FREE)], [
|
|
|
++#include <sys/mman.h>
|
|
|
++], [
|
|
|
++ madvise((void *)0, 0, MADV_FREE);
|
|
|
++], [je_cv_madv_free])
|
|
|
++ if test "x${je_cv_madv_free}" = "xyes" ; then
|
|
|
++ AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ])
|
|
|
++ fi
|
|
|
++
|
|
|
++ dnl Check for madvise(..., MADV_DONTNEED).
|
|
|
++ JE_COMPILABLE([madvise(..., MADV_DONTNEED)], [
|
|
|
++#include <sys/mman.h>
|
|
|
++], [
|
|
|
++ madvise((void *)0, 0, MADV_DONTNEED);
|
|
|
++], [je_cv_madv_dontneed])
|
|
|
++ if test "x${je_cv_madv_dontneed}" = "xyes" ; then
|
|
|
++ AC_DEFINE([JEMALLOC_PURGE_MADVISE_DONTNEED], [ ])
|
|
|
++ fi
|
|
|
++
|
|
|
++ dnl Check for madvise(..., MADV_[NO]HUGEPAGE).
|
|
|
++ JE_COMPILABLE([madvise(..., MADV_[[NO]]HUGEPAGE)], [
|
|
|
++#include <sys/mman.h>
|
|
|
++], [
|
|
|
++ madvise((void *)0, 0, MADV_HUGEPAGE);
|
|
|
++ madvise((void *)0, 0, MADV_NOHUGEPAGE);
|
|
|
++], [je_cv_thp])
|
|
|
++ if test "x${je_cv_thp}" = "xyes" ; then
|
|
|
++ AC_DEFINE([JEMALLOC_THP], [ ])
|
|
|
++ fi
|
|
|
+ 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()],
|
|
|
+@@ -1664,20 +1716,25 @@ if test "x${je_cv_builtin_clz}" = "xyes"
|
|
|
+ AC_DEFINE([JEMALLOC_HAVE_BUILTIN_CLZ], [ ])
|
|
|
+ fi
|
|
|
+
|
|
|
+ dnl ============================================================================
|
|
|
+ dnl Check for os_unfair_lock operations as provided on Darwin.
|
|
|
+
|
|
|
+ JE_COMPILABLE([Darwin os_unfair_lock_*()], [
|
|
|
+ #include <os/lock.h>
|
|
|
++#include <AvailabilityMacros.h>
|
|
|
+ ], [
|
|
|
++ #if MAC_OS_X_VERSION_MIN_REQUIRED < 101200
|
|
|
++ #error "os_unfair_lock is not supported"
|
|
|
++ #else
|
|
|
+ os_unfair_lock lock = OS_UNFAIR_LOCK_INIT;
|
|
|
+ os_unfair_lock_lock(&lock);
|
|
|
+ os_unfair_lock_unlock(&lock);
|
|
|
++ #endif
|
|
|
+ ], [je_cv_os_unfair_lock])
|
|
|
+ if test "x${je_cv_os_unfair_lock}" = "xyes" ; then
|
|
|
+ AC_DEFINE([JEMALLOC_OS_UNFAIR_LOCK], [ ])
|
|
|
+ fi
|
|
|
+
|
|
|
+ dnl ============================================================================
|
|
|
+ dnl Check for spinlock(3) operations as provided on Darwin.
|
|
|
+
|
|
|
+diff --git a/memory/jemalloc/src/doc/jemalloc.xml.in b/memory/jemalloc/src/doc/jemalloc.xml.in
|
|
|
+--- a/memory/jemalloc/src/doc/jemalloc.xml.in
|
|
|
++++ b/memory/jemalloc/src/doc/jemalloc.xml.in
|
|
|
+@@ -401,17 +401,17 @@ mallctl("arenas.nbins", &nbins, &len, NU
|
|
|
+
|
|
|
+ miblen = 4;
|
|
|
+ mallctlnametomib("arenas.bin.0.size", mib, &miblen);
|
|
|
+ for (i = 0; i < nbins; i++) {
|
|
|
+ size_t bin_size;
|
|
|
+
|
|
|
+ mib[2] = i;
|
|
|
+ len = sizeof(bin_size);
|
|
|
+- mallctlbymib(mib, miblen, &bin_size, &len, NULL, 0);
|
|
|
++ mallctlbymib(mib, miblen, (void *)&bin_size, &len, NULL, 0);
|
|
|
+ /* Do something with bin_size... */
|
|
|
+ }]]></programlisting></para>
|
|
|
+
|
|
|
+ <para>The <function>malloc_stats_print()</function> function writes
|
|
|
+ summary statistics via the <parameter>write_cb</parameter> callback
|
|
|
+ function pointer and <parameter>cbopaque</parameter> data passed to
|
|
|
+ <parameter>write_cb</parameter>, or <function>malloc_message()</function>
|
|
|
+ if <parameter>write_cb</parameter> is <constant>NULL</constant>. The
|
|
|
+diff --git a/memory/jemalloc/src/include/jemalloc/internal/arena.h b/memory/jemalloc/src/include/jemalloc/internal/arena.h
|
|
|
+--- a/memory/jemalloc/src/include/jemalloc/internal/arena.h
|
|
|
++++ b/memory/jemalloc/src/include/jemalloc/internal/arena.h
|
|
|
+@@ -186,16 +186,24 @@ 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;
|
|
|
+
|
|
|
+ /*
|
|
|
++ * True if memory could be backed by transparent huge pages. This is
|
|
|
++ * only directly relevant to Linux, since it is the only supported
|
|
|
++ * platform on which jemalloc interacts with explicit transparent huge
|
|
|
++ * page controls.
|
|
|
++ */
|
|
|
++ bool hugepage;
|
|
|
++
|
|
|
++ /*
|
|
|
+ * 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. */
|
|
|
+ };
|
|
|
+
|
|
|
+@@ -369,20 +377,22 @@ struct arena_s {
|
|
|
+ /*
|
|
|
+ * PRNG state for cache index randomization of large allocation base
|
|
|
+ * pointers.
|
|
|
+ */
|
|
|
+ size_t offset_state;
|
|
|
+
|
|
|
+ dss_prec_t dss_prec;
|
|
|
+
|
|
|
+-
|
|
|
+ /* Extant arena chunks. */
|
|
|
+ ql_head(extent_node_t) achunks;
|
|
|
+
|
|
|
++ /* Extent serial number generator state. */
|
|
|
++ size_t extent_sn_next;
|
|
|
++
|
|
|
+ /*
|
|
|
+ * 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
|
|
|
+@@ -448,19 +458,19 @@ struct arena_s {
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 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_szsnad_cached;
|
|
|
+ extent_tree_t chunks_ad_cached;
|
|
|
+- extent_tree_t chunks_szad_retained;
|
|
|
++ extent_tree_t chunks_szsnad_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. */
|
|
|
+@@ -517,23 +527,23 @@ extern run_quantize_t *run_quantize_ceil
|
|
|
+ #endif
|
|
|
+ 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(tsdn_t *tsdn, arena_t *arena);
|
|
|
+ void arena_node_dalloc(tsdn_t *tsdn, arena_t *arena, extent_node_t *node);
|
|
|
+ void *arena_chunk_alloc_huge(tsdn_t *tsdn, arena_t *arena, size_t usize,
|
|
|
+- size_t alignment, bool *zero);
|
|
|
++ size_t alignment, size_t *sn, bool *zero);
|
|
|
+ void arena_chunk_dalloc_huge(tsdn_t *tsdn, arena_t *arena, void *chunk,
|
|
|
+- size_t usize);
|
|
|
++ size_t usize, size_t sn);
|
|
|
+ void arena_chunk_ralloc_huge_similar(tsdn_t *tsdn, arena_t *arena,
|
|
|
+ void *chunk, size_t oldsize, size_t usize);
|
|
|
+ void arena_chunk_ralloc_huge_shrink(tsdn_t *tsdn, arena_t *arena,
|
|
|
+- void *chunk, size_t oldsize, size_t usize);
|
|
|
++ void *chunk, size_t oldsize, size_t usize, size_t sn);
|
|
|
+ bool arena_chunk_ralloc_huge_expand(tsdn_t *tsdn, arena_t *arena,
|
|
|
+ void *chunk, size_t oldsize, size_t usize, bool *zero);
|
|
|
+ ssize_t arena_lg_dirty_mult_get(tsdn_t *tsdn, arena_t *arena);
|
|
|
+ bool arena_lg_dirty_mult_set(tsdn_t *tsdn, arena_t *arena,
|
|
|
+ ssize_t lg_dirty_mult);
|
|
|
+ ssize_t arena_decay_time_get(tsdn_t *tsdn, arena_t *arena);
|
|
|
+ bool arena_decay_time_set(tsdn_t *tsdn, arena_t *arena, ssize_t decay_time);
|
|
|
+ void arena_purge(tsdn_t *tsdn, arena_t *arena, bool all);
|
|
|
+@@ -596,16 +606,17 @@ void arena_basic_stats_merge(tsdn_t *tsd
|
|
|
+ void arena_stats_merge(tsdn_t *tsdn, arena_t *arena, unsigned *nthreads,
|
|
|
+ const char **dss, ssize_t *lg_dirty_mult, ssize_t *decay_time,
|
|
|
+ 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 arena_nthreads_get(arena_t *arena, bool internal);
|
|
|
+ void arena_nthreads_inc(arena_t *arena, bool internal);
|
|
|
+ void arena_nthreads_dec(arena_t *arena, bool internal);
|
|
|
++size_t arena_extent_sn_next(arena_t *arena);
|
|
|
+ arena_t *arena_new(tsdn_t *tsdn, unsigned ind);
|
|
|
+ void arena_boot(void);
|
|
|
+ void arena_prefork0(tsdn_t *tsdn, arena_t *arena);
|
|
|
+ void arena_prefork1(tsdn_t *tsdn, arena_t *arena);
|
|
|
+ void arena_prefork2(tsdn_t *tsdn, arena_t *arena);
|
|
|
+ void arena_prefork3(tsdn_t *tsdn, arena_t *arena);
|
|
|
+ void arena_postfork_parent(tsdn_t *tsdn, arena_t *arena);
|
|
|
+ void arena_postfork_child(tsdn_t *tsdn, arena_t *arena);
|
|
|
+diff --git a/memory/jemalloc/src/include/jemalloc/internal/chunk.h b/memory/jemalloc/src/include/jemalloc/internal/chunk.h
|
|
|
+--- a/memory/jemalloc/src/include/jemalloc/internal/chunk.h
|
|
|
++++ b/memory/jemalloc/src/include/jemalloc/internal/chunk.h
|
|
|
+@@ -53,25 +53,26 @@ chunk_hooks_t chunk_hooks_set(tsdn_t *ts
|
|
|
+ const chunk_hooks_t *chunk_hooks);
|
|
|
+
|
|
|
+ bool chunk_register(tsdn_t *tsdn, 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(tsdn_t *tsdn, arena_t *arena,
|
|
|
+ chunk_hooks_t *chunk_hooks, void *new_addr, size_t size, size_t alignment,
|
|
|
+- bool *zero, bool *commit, bool dalloc_node);
|
|
|
++ size_t *sn, bool *zero, bool *commit, bool dalloc_node);
|
|
|
+ void *chunk_alloc_wrapper(tsdn_t *tsdn, arena_t *arena,
|
|
|
+ chunk_hooks_t *chunk_hooks, void *new_addr, size_t size, size_t alignment,
|
|
|
+- bool *zero, bool *commit);
|
|
|
++ size_t *sn, bool *zero, bool *commit);
|
|
|
+ void chunk_dalloc_cache(tsdn_t *tsdn, arena_t *arena,
|
|
|
+- chunk_hooks_t *chunk_hooks, void *chunk, size_t size, bool committed);
|
|
|
++ chunk_hooks_t *chunk_hooks, void *chunk, size_t size, size_t sn,
|
|
|
++ bool committed);
|
|
|
+ void chunk_dalloc_wrapper(tsdn_t *tsdn, arena_t *arena,
|
|
|
+- chunk_hooks_t *chunk_hooks, void *chunk, size_t size, bool zeroed,
|
|
|
+- bool committed);
|
|
|
++ chunk_hooks_t *chunk_hooks, void *chunk, size_t size, size_t sn,
|
|
|
++ bool zeroed, bool committed);
|
|
|
+ bool chunk_purge_wrapper(tsdn_t *tsdn, arena_t *arena,
|
|
|
+ chunk_hooks_t *chunk_hooks, void *chunk, size_t size, size_t offset,
|
|
|
+ size_t length);
|
|
|
+ bool chunk_boot(void);
|
|
|
+
|
|
|
+ #endif /* JEMALLOC_H_EXTERNS */
|
|
|
+ /******************************************************************************/
|
|
|
+ #ifdef JEMALLOC_H_INLINES
|
|
|
+diff --git a/memory/jemalloc/src/include/jemalloc/internal/extent.h b/memory/jemalloc/src/include/jemalloc/internal/extent.h
|
|
|
+--- a/memory/jemalloc/src/include/jemalloc/internal/extent.h
|
|
|
++++ b/memory/jemalloc/src/include/jemalloc/internal/extent.h
|
|
|
+@@ -14,16 +14,30 @@ struct extent_node_s {
|
|
|
+
|
|
|
+ /* Pointer to the extent that this tree node is responsible for. */
|
|
|
+ void *en_addr;
|
|
|
+
|
|
|
+ /* Total region size. */
|
|
|
+ size_t en_size;
|
|
|
+
|
|
|
+ /*
|
|
|
++ * Serial number (potentially non-unique).
|
|
|
++ *
|
|
|
++ * In principle serial numbers can wrap around on 32-bit systems if
|
|
|
++ * JEMALLOC_MUNMAP is defined, but as long as comparison functions fall
|
|
|
++ * back on address comparison for equal serial numbers, stable (if
|
|
|
++ * imperfect) ordering is maintained.
|
|
|
++ *
|
|
|
++ * Serial numbers may not be unique even in the absence of wrap-around,
|
|
|
++ * e.g. when splitting an extent and assigning the same serial number to
|
|
|
++ * both resulting adjacent extents.
|
|
|
++ */
|
|
|
++ size_t en_sn;
|
|
|
++
|
|
|
++ /*
|
|
|
+ * 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
|
|
|
+@@ -40,57 +54,59 @@ struct extent_node_s {
|
|
|
+ /* 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 the size/sn/address-ordered tree. */
|
|
|
++ rb_node(extent_node_t) szsnad_link;
|
|
|
+
|
|
|
+ /* Linkage for arena's achunks, 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_szsnad_, 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);
|
|
|
++size_t extent_node_sn_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_sn_set(extent_node_t *node, size_t sn);
|
|
|
+ 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);
|
|
|
++ size_t size, size_t sn, 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 *
|
|
|
+@@ -109,16 +125,23 @@ extent_node_addr_get(const extent_node_t
|
|
|
+
|
|
|
+ JEMALLOC_INLINE size_t
|
|
|
+ extent_node_size_get(const extent_node_t *node)
|
|
|
+ {
|
|
|
+
|
|
|
+ return (node->en_size);
|
|
|
+ }
|
|
|
+
|
|
|
++JEMALLOC_INLINE size_t
|
|
|
++extent_node_sn_get(const extent_node_t *node)
|
|
|
++{
|
|
|
++
|
|
|
++ return (node->en_sn);
|
|
|
++}
|
|
|
++
|
|
|
+ JEMALLOC_INLINE bool
|
|
|
+ extent_node_zeroed_get(const extent_node_t *node)
|
|
|
+ {
|
|
|
+
|
|
|
+ return (node->en_zeroed);
|
|
|
+ }
|
|
|
+
|
|
|
+ JEMALLOC_INLINE bool
|
|
|
+@@ -160,16 +183,23 @@ extent_node_addr_set(extent_node_t *node
|
|
|
+ JEMALLOC_INLINE void
|
|
|
+ extent_node_size_set(extent_node_t *node, size_t size)
|
|
|
+ {
|
|
|
+
|
|
|
+ node->en_size = size;
|
|
|
+ }
|
|
|
+
|
|
|
+ JEMALLOC_INLINE void
|
|
|
++extent_node_sn_set(extent_node_t *node, size_t sn)
|
|
|
++{
|
|
|
++
|
|
|
++ node->en_sn = sn;
|
|
|
++}
|
|
|
++
|
|
|
++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)
|
|
|
+@@ -189,22 +219,23 @@ 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)
|
|
|
++ size_t sn, bool zeroed, bool committed)
|
|
|
+ {
|
|
|
+
|
|
|
+ extent_node_arena_set(node, arena);
|
|
|
+ extent_node_addr_set(node, addr);
|
|
|
+ extent_node_size_set(node, size);
|
|
|
++ extent_node_sn_set(node, sn);
|
|
|
+ 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
|
|
|
+diff --git a/memory/jemalloc/src/include/jemalloc/internal/jemalloc_internal.h.in b/memory/jemalloc/src/include/jemalloc/internal/jemalloc_internal.h.in
|
|
|
+--- a/memory/jemalloc/src/include/jemalloc/internal/jemalloc_internal.h.in
|
|
|
++++ b/memory/jemalloc/src/include/jemalloc/internal/jemalloc_internal.h.in
|
|
|
+@@ -332,25 +332,25 @@ typedef unsigned szind_t;
|
|
|
+ ((void *)((uintptr_t)(a) & ~PAGE_MASK))
|
|
|
+
|
|
|
+ /* 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))))
|
|
|
++ ((void *)((uintptr_t)(a) & ((~(alignment)) + 1)))
|
|
|
+
|
|
|
+ /* 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)))
|
|
|
++ (((s) + (alignment - 1)) & ((~(alignment)) + 1))
|
|
|
+
|
|
|
+ /* Declare a variable-length array. */
|
|
|
+ #if __STDC_VERSION__ < 199901L
|
|
|
+ # ifdef _MSC_VER
|
|
|
+ # include <malloc.h>
|
|
|
+ # define alloca _alloca
|
|
|
+ # else
|
|
|
+ # ifdef JEMALLOC_HAS_ALLOCA_H
|
|
|
+diff --git a/memory/jemalloc/src/include/jemalloc/internal/jemalloc_internal_defs.h.in b/memory/jemalloc/src/include/jemalloc/internal/jemalloc_internal_defs.h.in
|
|
|
+--- a/memory/jemalloc/src/include/jemalloc/internal/jemalloc_internal_defs.h.in
|
|
|
++++ b/memory/jemalloc/src/include/jemalloc/internal/jemalloc_internal_defs.h.in
|
|
|
+@@ -51,44 +51,42 @@
|
|
|
+ #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 os_unfair_lock_*() functions are available, as provided by Darwin.
|
|
|
+ */
|
|
|
+ #undef JEMALLOC_OS_UNFAIR_LOCK
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Defined if OSSpin*() functions are available, as provided by Darwin, and
|
|
|
+ * documented in the spinlock(3) manual page.
|
|
|
+ */
|
|
|
+ #undef JEMALLOC_OSSPIN
|
|
|
+
|
|
|
+-/* Defined if syscall(2) is available. */
|
|
|
+-#undef JEMALLOC_HAVE_SYSCALL
|
|
|
++/* Defined if syscall(2) is usable. */
|
|
|
++#undef JEMALLOC_USE_SYSCALL
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Defined if secure_getenv(3) is available.
|
|
|
+ */
|
|
|
+ #undef JEMALLOC_HAVE_SECURE_GETENV
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Defined if issetugid(2) is available.
|
|
|
+ */
|
|
|
+ #undef JEMALLOC_HAVE_ISSETUGID
|
|
|
+
|
|
|
++/* Defined if pthread_atfork(3) is available. */
|
|
|
++#undef JEMALLOC_HAVE_PTHREAD_ATFORK
|
|
|
++
|
|
|
+ /*
|
|
|
+ * Defined if clock_gettime(CLOCK_MONOTONIC_COARSE, ...) is available.
|
|
|
+ */
|
|
|
+ #undef JEMALLOC_HAVE_CLOCK_MONOTONIC_COARSE
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Defined if clock_gettime(CLOCK_MONOTONIC, ...) is available.
|
|
|
+ */
|
|
|
+@@ -247,28 +245,36 @@
|
|
|
+ * Methods for determining whether the OS overcommits.
|
|
|
+ * JEMALLOC_PROC_SYS_VM_OVERCOMMIT_MEMORY: Linux's
|
|
|
+ * /proc/sys/vm.overcommit_memory file.
|
|
|
+ * JEMALLOC_SYSCTL_VM_OVERCOMMIT: FreeBSD's vm.overcommit sysctl.
|
|
|
+ */
|
|
|
+ #undef JEMALLOC_SYSCTL_VM_OVERCOMMIT
|
|
|
+ #undef JEMALLOC_PROC_SYS_VM_OVERCOMMIT_MEMORY
|
|
|
+
|
|
|
++/* Defined if madvise(2) is available. */
|
|
|
++#undef JEMALLOC_HAVE_MADVISE
|
|
|
++
|
|
|
+ /*
|
|
|
+ * 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.
|
|
|
++ * madvise(..., MADV_FREE) : This marks pages as being unused, such that they
|
|
|
++ * will be discarded rather than swapped out.
|
|
|
++ * madvise(..., MADV_DONTNEED) : This immediately discards pages, such that
|
|
|
++ * new pages will be demand-zeroed if the
|
|
|
++ * address region is later touched.
|
|
|
+ */
|
|
|
++#undef JEMALLOC_PURGE_MADVISE_FREE
|
|
|
+ #undef JEMALLOC_PURGE_MADVISE_DONTNEED
|
|
|
+-#undef JEMALLOC_PURGE_MADVISE_FREE
|
|
|
++
|
|
|
++/*
|
|
|
++ * Defined if transparent huge pages are supported via the MADV_[NO]HUGEPAGE
|
|
|
++ * arguments to madvise(2).
|
|
|
++ */
|
|
|
++#undef JEMALLOC_THP
|
|
|
+
|
|
|
+ /* 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. */
|
|
|
+diff --git a/memory/jemalloc/src/include/jemalloc/internal/pages.h b/memory/jemalloc/src/include/jemalloc/internal/pages.h
|
|
|
+--- a/memory/jemalloc/src/include/jemalloc/internal/pages.h
|
|
|
++++ b/memory/jemalloc/src/include/jemalloc/internal/pages.h
|
|
|
+@@ -11,16 +11,18 @@
|
|
|
+
|
|
|
+ void *pages_map(void *addr, size_t size, bool *commit);
|
|
|
+ void pages_unmap(void *addr, size_t size);
|
|
|
+ void *pages_trim(void *addr, size_t alloc_size, size_t leadsize,
|
|
|
+ size_t size, bool *commit);
|
|
|
+ bool pages_commit(void *addr, size_t size);
|
|
|
+ bool pages_decommit(void *addr, size_t size);
|
|
|
+ bool pages_purge(void *addr, size_t size);
|
|
|
++bool pages_huge(void *addr, size_t size);
|
|
|
++bool pages_nohuge(void *addr, size_t size);
|
|
|
+ void pages_boot(void);
|
|
|
+
|
|
|
+ #endif /* JEMALLOC_H_EXTERNS */
|
|
|
+ /******************************************************************************/
|
|
|
+ #ifdef JEMALLOC_H_INLINES
|
|
|
+
|
|
|
+ #endif /* JEMALLOC_H_INLINES */
|
|
|
+ /******************************************************************************/
|
|
|
+diff --git a/memory/jemalloc/src/include/jemalloc/internal/private_symbols.txt b/memory/jemalloc/src/include/jemalloc/internal/private_symbols.txt
|
|
|
+--- a/memory/jemalloc/src/include/jemalloc/internal/private_symbols.txt
|
|
|
++++ b/memory/jemalloc/src/include/jemalloc/internal/private_symbols.txt
|
|
|
+@@ -31,16 +31,17 @@ arena_dalloc_small
|
|
|
+ arena_decay_tick
|
|
|
+ arena_decay_ticks
|
|
|
+ arena_decay_time_default_get
|
|
|
+ arena_decay_time_default_set
|
|
|
+ arena_decay_time_get
|
|
|
+ arena_decay_time_set
|
|
|
+ arena_dss_prec_get
|
|
|
+ arena_dss_prec_set
|
|
|
++arena_extent_sn_next
|
|
|
+ arena_get
|
|
|
+ arena_ichoose
|
|
|
+ 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
|
|
|
+@@ -213,16 +214,18 @@ extent_node_committed_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_sn_get
|
|
|
++extent_node_sn_set
|
|
|
+ extent_node_zeroed_get
|
|
|
+ extent_node_zeroed_set
|
|
|
+ extent_tree_ad_destroy
|
|
|
+ extent_tree_ad_destroy_recurse
|
|
|
+ extent_tree_ad_empty
|
|
|
+ extent_tree_ad_first
|
|
|
+ extent_tree_ad_insert
|
|
|
+ extent_tree_ad_iter
|
|
|
+@@ -234,35 +237,35 @@ 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_destroy
|
|
|
+-extent_tree_szad_destroy_recurse
|
|
|
+-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
|
|
|
++extent_tree_szsnad_destroy
|
|
|
++extent_tree_szsnad_destroy_recurse
|
|
|
++extent_tree_szsnad_empty
|
|
|
++extent_tree_szsnad_first
|
|
|
++extent_tree_szsnad_insert
|
|
|
++extent_tree_szsnad_iter
|
|
|
++extent_tree_szsnad_iter_recurse
|
|
|
++extent_tree_szsnad_iter_start
|
|
|
++extent_tree_szsnad_last
|
|
|
++extent_tree_szsnad_new
|
|
|
++extent_tree_szsnad_next
|
|
|
++extent_tree_szsnad_nsearch
|
|
|
++extent_tree_szsnad_prev
|
|
|
++extent_tree_szsnad_psearch
|
|
|
++extent_tree_szsnad_remove
|
|
|
++extent_tree_szsnad_reverse_iter
|
|
|
++extent_tree_szsnad_reverse_iter_recurse
|
|
|
++extent_tree_szsnad_reverse_iter_start
|
|
|
++extent_tree_szsnad_search
|
|
|
+ ffs_llu
|
|
|
+ ffs_lu
|
|
|
+ ffs_u
|
|
|
+ ffs_u32
|
|
|
+ ffs_u64
|
|
|
+ ffs_zu
|
|
|
+ get_errno
|
|
|
+ hash
|
|
|
+@@ -389,17 +392,19 @@ opt_stats_print
|
|
|
+ opt_tcache
|
|
|
+ opt_utrace
|
|
|
+ opt_xmalloc
|
|
|
+ opt_zero
|
|
|
+ p2rz
|
|
|
+ pages_boot
|
|
|
+ pages_commit
|
|
|
+ pages_decommit
|
|
|
++pages_huge
|
|
|
+ pages_map
|
|
|
++pages_nohuge
|
|
|
+ pages_purge
|
|
|
+ pages_trim
|
|
|
+ pages_unmap
|
|
|
+ pind2sz
|
|
|
+ pind2sz_compute
|
|
|
+ pind2sz_lookup
|
|
|
+ pind2sz_tab
|
|
|
+ pow2_ceil_u32
|
|
|
+diff --git a/memory/jemalloc/src/include/jemalloc/internal/stats.h b/memory/jemalloc/src/include/jemalloc/internal/stats.h
|
|
|
+--- a/memory/jemalloc/src/include/jemalloc/internal/stats.h
|
|
|
++++ b/memory/jemalloc/src/include/jemalloc/internal/stats.h
|
|
|
+@@ -170,32 +170,28 @@ stats_cactive_get(void)
|
|
|
+ {
|
|
|
+
|
|
|
+ return (atomic_read_z(&stats_cactive));
|
|
|
+ }
|
|
|
+
|
|
|
+ JEMALLOC_INLINE void
|
|
|
+ stats_cactive_add(size_t size)
|
|
|
+ {
|
|
|
+- UNUSED size_t cactive;
|
|
|
+
|
|
|
+ assert(size > 0);
|
|
|
+ assert((size & chunksize_mask) == 0);
|
|
|
+
|
|
|
+- cactive = atomic_add_z(&stats_cactive, size);
|
|
|
+- assert(cactive - size < cactive);
|
|
|
++ atomic_add_z(&stats_cactive, size);
|
|
|
+ }
|
|
|
+
|
|
|
+ JEMALLOC_INLINE void
|
|
|
+ stats_cactive_sub(size_t size)
|
|
|
+ {
|
|
|
+- UNUSED size_t cactive;
|
|
|
+
|
|
|
+ assert(size > 0);
|
|
|
+ assert((size & chunksize_mask) == 0);
|
|
|
+
|
|
|
+- cactive = atomic_sub_z(&stats_cactive, size);
|
|
|
+- assert(cactive + size > cactive);
|
|
|
++ atomic_sub_z(&stats_cactive, size);
|
|
|
+ }
|
|
|
+ #endif
|
|
|
+
|
|
|
+ #endif /* JEMALLOC_H_INLINES */
|
|
|
+ /******************************************************************************/
|
|
|
+diff --git a/memory/jemalloc/src/include/jemalloc/internal/util.h b/memory/jemalloc/src/include/jemalloc/internal/util.h
|
|
|
+--- a/memory/jemalloc/src/include/jemalloc/internal/util.h
|
|
|
++++ b/memory/jemalloc/src/include/jemalloc/internal/util.h
|
|
|
+@@ -36,18 +36,22 @@
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 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
|
|
|
+
|
|
|
+ /* Junk fill patterns. */
|
|
|
+-#define JEMALLOC_ALLOC_JUNK ((uint8_t)0xa5)
|
|
|
+-#define JEMALLOC_FREE_JUNK ((uint8_t)0x5a)
|
|
|
++#ifndef JEMALLOC_ALLOC_JUNK
|
|
|
++# define JEMALLOC_ALLOC_JUNK ((uint8_t)0xa5)
|
|
|
++#endif
|
|
|
++#ifndef JEMALLOC_FREE_JUNK
|
|
|
++# define JEMALLOC_FREE_JUNK ((uint8_t)0x5a)
|
|
|
++#endif
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Wrap a cpp argument that contains commas such that it isn't broken up into
|
|
|
+ * multiple arguments.
|
|
|
+ */
|
|
|
+ #define JEMALLOC_ARG_CONCAT(...) __VA_ARGS__
|
|
|
+
|
|
|
+ /*
|
|
|
+diff --git a/memory/jemalloc/src/include/jemalloc/internal/valgrind.h b/memory/jemalloc/src/include/jemalloc/internal/valgrind.h
|
|
|
+--- a/memory/jemalloc/src/include/jemalloc/internal/valgrind.h
|
|
|
++++ b/memory/jemalloc/src/include/jemalloc/internal/valgrind.h
|
|
|
+@@ -31,36 +31,50 @@
|
|
|
+ * Valgrind reports errors, there are no extra stack frames in the backtraces.
|
|
|
+ */
|
|
|
+ #define JEMALLOC_VALGRIND_MALLOC(cond, tsdn, ptr, usize, zero) do { \
|
|
|
+ if (unlikely(in_valgrind && cond)) { \
|
|
|
+ VALGRIND_MALLOCLIKE_BLOCK(ptr, usize, p2rz(tsdn, ptr), \
|
|
|
+ zero); \
|
|
|
+ } \
|
|
|
+ } while (0)
|
|
|
+-#define JEMALLOC_VALGRIND_REALLOC(maybe_moved, tsdn, ptr, usize, \
|
|
|
+- ptr_maybe_null, old_ptr, old_usize, old_rzsize, old_ptr_maybe_null, \
|
|
|
+- zero) do { \
|
|
|
++#define JEMALLOC_VALGRIND_REALLOC_MOVED_no(ptr, old_ptr) \
|
|
|
++ (false)
|
|
|
++#define JEMALLOC_VALGRIND_REALLOC_MOVED_maybe(ptr, old_ptr) \
|
|
|
++ ((ptr) != (old_ptr))
|
|
|
++#define JEMALLOC_VALGRIND_REALLOC_PTR_NULL_no(ptr) \
|
|
|
++ (false)
|
|
|
++#define JEMALLOC_VALGRIND_REALLOC_PTR_NULL_maybe(ptr) \
|
|
|
++ (ptr == NULL)
|
|
|
++#define JEMALLOC_VALGRIND_REALLOC_OLD_PTR_NULL_no(old_ptr) \
|
|
|
++ (false)
|
|
|
++#define JEMALLOC_VALGRIND_REALLOC_OLD_PTR_NULL_maybe(old_ptr) \
|
|
|
++ (old_ptr == NULL)
|
|
|
++#define JEMALLOC_VALGRIND_REALLOC(moved, tsdn, ptr, usize, ptr_null, \
|
|
|
++ old_ptr, old_usize, old_rzsize, old_ptr_null, zero) do { \
|
|
|
+ if (unlikely(in_valgrind)) { \
|
|
|
+ size_t rzsize = p2rz(tsdn, ptr); \
|
|
|
+ \
|
|
|
+- if (!maybe_moved || ptr == old_ptr) { \
|
|
|
++ if (!JEMALLOC_VALGRIND_REALLOC_MOVED_##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) { \
|
|
|
++ if (!JEMALLOC_VALGRIND_REALLOC_OLD_PTR_NULL_## \
|
|
|
++ old_ptr_null(old_ptr)) { \
|
|
|
+ valgrind_freelike_block(old_ptr, \
|
|
|
+ old_rzsize); \
|
|
|
+ } \
|
|
|
+- if (!ptr_maybe_null || ptr != NULL) { \
|
|
|
++ if (!JEMALLOC_VALGRIND_REALLOC_PTR_NULL_## \
|
|
|
++ ptr_null(ptr)) { \
|
|
|
+ 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); \
|
|
|
+diff --git a/memory/jemalloc/src/msvc/projects/vc2015/test_threads/test_threads.cpp b/memory/jemalloc/src/msvc/projects/vc2015/test_threads/test_threads.cpp
|
|
|
+--- a/memory/jemalloc/src/msvc/projects/vc2015/test_threads/test_threads.cpp
|
|
|
++++ b/memory/jemalloc/src/msvc/projects/vc2015/test_threads/test_threads.cpp
|
|
|
+@@ -16,29 +16,29 @@ using std::thread;
|
|
|
+ using std::uniform_int_distribution;
|
|
|
+ using std::minstd_rand;
|
|
|
+
|
|
|
+ int test_threads()
|
|
|
+ {
|
|
|
+ je_malloc_conf = "narenas:3";
|
|
|
+ int narenas = 0;
|
|
|
+ size_t sz = sizeof(narenas);
|
|
|
+- je_mallctl("opt.narenas", &narenas, &sz, NULL, 0);
|
|
|
++ je_mallctl("opt.narenas", (void *)&narenas, &sz, NULL, 0);
|
|
|
+ if (narenas != 3) {
|
|
|
+ printf("Error: unexpected number of arenas: %d\n", narenas);
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ static const int sizes[] = { 7, 16, 32, 60, 91, 100, 120, 144, 169, 199, 255, 400, 670, 900, 917, 1025, 3333, 5190, 13131, 49192, 99999, 123123, 255265, 2333111 };
|
|
|
+ static const int numSizes = (int)(sizeof(sizes) / sizeof(sizes[0]));
|
|
|
+ vector<thread> workers;
|
|
|
+ static const int numThreads = narenas + 1, numAllocsMax = 25, numIter1 = 50, numIter2 = 50;
|
|
|
+ je_malloc_stats_print(NULL, NULL, NULL);
|
|
|
+ size_t allocated1;
|
|
|
+ size_t sz1 = sizeof(allocated1);
|
|
|
+- je_mallctl("stats.active", &allocated1, &sz1, NULL, 0);
|
|
|
++ je_mallctl("stats.active", (void *)&allocated1, &sz1, NULL, 0);
|
|
|
+ printf("\nPress Enter to start threads...\n");
|
|
|
+ getchar();
|
|
|
+ printf("Starting %d threads x %d x %d iterations...\n", numThreads, numIter1, numIter2);
|
|
|
+ for (int i = 0; i < numThreads; i++) {
|
|
|
+ workers.emplace_back([tid=i]() {
|
|
|
+ uniform_int_distribution<int> sizeDist(0, numSizes - 1);
|
|
|
+ minstd_rand rnd(tid * 17);
|
|
|
+ uint8_t* ptrs[numAllocsMax];
|
|
|
+@@ -73,17 +73,17 @@ int test_threads()
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ for (thread& t : workers) {
|
|
|
+ t.join();
|
|
|
+ }
|
|
|
+ je_malloc_stats_print(NULL, NULL, NULL);
|
|
|
+ size_t allocated2;
|
|
|
+- je_mallctl("stats.active", &allocated2, &sz1, NULL, 0);
|
|
|
++ je_mallctl("stats.active", (void *)&allocated2, &sz1, NULL, 0);
|
|
|
+ size_t leaked = allocated2 - allocated1;
|
|
|
+ printf("\nDone. Leaked: %zd bytes\n", leaked);
|
|
|
+ bool failed = leaked > 65536; // in case C++ runtime allocated something (e.g. iostream locale or facet)
|
|
|
+ printf("\nTest %s!\n", (failed ? "FAILED" : "successful"));
|
|
|
+ printf("\nPress Enter to continue...\n");
|
|
|
+ getchar();
|
|
|
+ return failed ? 1 : 0;
|
|
|
+ }
|
|
|
+diff --git a/memory/jemalloc/src/src/arena.c b/memory/jemalloc/src/src/arena.c
|
|
|
+--- a/memory/jemalloc/src/src/arena.c
|
|
|
++++ b/memory/jemalloc/src/src/arena.c
|
|
|
+@@ -33,49 +33,89 @@ unsigned nhclasses; /* Number of huge si
|
|
|
+ static void arena_chunk_dalloc(tsdn_t *tsdn, arena_t *arena,
|
|
|
+ arena_chunk_t *chunk);
|
|
|
+ static void arena_purge_to_limit(tsdn_t *tsdn, arena_t *arena,
|
|
|
+ size_t ndirty_limit);
|
|
|
+ static void arena_run_dalloc(tsdn_t *tsdn, arena_t *arena, arena_run_t *run,
|
|
|
+ bool dirty, bool cleaned, bool decommitted);
|
|
|
+ static void arena_dalloc_bin_run(tsdn_t *tsdn, 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);
|
|
|
++static void arena_bin_lower_run(arena_t *arena, arena_run_t *run,
|
|
|
++ arena_bin_t *bin);
|
|
|
+
|
|
|
+ /******************************************************************************/
|
|
|
+
|
|
|
+ JEMALLOC_INLINE_C size_t
|
|
|
+ arena_miscelm_size_get(const arena_chunk_map_misc_t *miscelm)
|
|
|
+ {
|
|
|
+ arena_chunk_t *chunk;
|
|
|
+ size_t pageind, mapbits;
|
|
|
+
|
|
|
+ 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 const extent_node_t *
|
|
|
++arena_miscelm_extent_get(const arena_chunk_map_misc_t *miscelm)
|
|
|
++{
|
|
|
++ arena_chunk_t *chunk;
|
|
|
++
|
|
|
++ chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(miscelm);
|
|
|
++ return (&chunk->node);
|
|
|
++}
|
|
|
++
|
|
|
+ JEMALLOC_INLINE_C int
|
|
|
+-arena_run_addr_comp(const arena_chunk_map_misc_t *a,
|
|
|
++arena_sn_comp(const arena_chunk_map_misc_t *a, const arena_chunk_map_misc_t *b)
|
|
|
++{
|
|
|
++ size_t a_sn, b_sn;
|
|
|
++
|
|
|
++ assert(a != NULL);
|
|
|
++ assert(b != NULL);
|
|
|
++
|
|
|
++ a_sn = extent_node_sn_get(arena_miscelm_extent_get(a));
|
|
|
++ b_sn = extent_node_sn_get(arena_miscelm_extent_get(b));
|
|
|
++
|
|
|
++ return ((a_sn > b_sn) - (a_sn < b_sn));
|
|
|
++}
|
|
|
++
|
|
|
++JEMALLOC_INLINE_C int
|
|
|
++arena_ad_comp(const arena_chunk_map_misc_t *a,
|
|
|
+ const 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));
|
|
|
+ }
|
|
|
+
|
|
|
++JEMALLOC_INLINE_C int
|
|
|
++arena_snad_comp(const arena_chunk_map_misc_t *a,
|
|
|
++ const arena_chunk_map_misc_t *b)
|
|
|
++{
|
|
|
++ int ret;
|
|
|
++
|
|
|
++ assert(a != NULL);
|
|
|
++ assert(b != NULL);
|
|
|
++
|
|
|
++ ret = arena_sn_comp(a, b);
|
|
|
++ if (ret != 0)
|
|
|
++ return (ret);
|
|
|
++
|
|
|
++ ret = arena_ad_comp(a, b);
|
|
|
++ return (ret);
|
|
|
++}
|
|
|
++
|
|
|
+ /* Generate pairing heap functions. */
|
|
|
+ ph_gen(static UNUSED, arena_run_heap_, arena_run_heap_t, arena_chunk_map_misc_t,
|
|
|
+- ph_link, arena_run_addr_comp)
|
|
|
++ ph_link, arena_snad_comp)
|
|
|
+
|
|
|
+ #ifdef JEMALLOC_JET
|
|
|
+ #undef run_quantize_floor
|
|
|
+ #define run_quantize_floor JEMALLOC_N(n_run_quantize_floor)
|
|
|
+ #endif
|
|
|
+ static size_t
|
|
|
+ run_quantize_floor(size_t size)
|
|
|
+ {
|
|
|
+@@ -524,77 +564,80 @@ arena_chunk_init_spare(arena_t *arena)
|
|
|
+ assert(arena_mapbits_dirty_get(chunk, map_bias) ==
|
|
|
+ arena_mapbits_dirty_get(chunk, chunk_npages-1));
|
|
|
+
|
|
|
+ return (chunk);
|
|
|
+ }
|
|
|
+
|
|
|
+ static bool
|
|
|
+ arena_chunk_register(tsdn_t *tsdn, arena_t *arena, arena_chunk_t *chunk,
|
|
|
+- bool zero)
|
|
|
++ size_t sn, 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_init(&chunk->node, arena, chunk, chunksize, sn, zero, true);
|
|
|
+ extent_node_achunk_set(&chunk->node, true);
|
|
|
+ return (chunk_register(tsdn, chunk, &chunk->node));
|
|
|
+ }
|
|
|
+
|
|
|
+ static arena_chunk_t *
|
|
|
+ arena_chunk_alloc_internal_hard(tsdn_t *tsdn, arena_t *arena,
|
|
|
+ chunk_hooks_t *chunk_hooks, bool *zero, bool *commit)
|
|
|
+ {
|
|
|
+ arena_chunk_t *chunk;
|
|
|
++ size_t sn;
|
|
|
+
|
|
|
+ malloc_mutex_unlock(tsdn, &arena->lock);
|
|
|
+
|
|
|
+ chunk = (arena_chunk_t *)chunk_alloc_wrapper(tsdn, arena, chunk_hooks,
|
|
|
+- NULL, chunksize, chunksize, zero, commit);
|
|
|
++ NULL, chunksize, chunksize, &sn, zero, commit);
|
|
|
+ if (chunk != NULL && !*commit) {
|
|
|
+ /* Commit header. */
|
|
|
+ if (chunk_hooks->commit(chunk, chunksize, 0, map_bias <<
|
|
|
+ LG_PAGE, arena->ind)) {
|
|
|
+ chunk_dalloc_wrapper(tsdn, arena, chunk_hooks,
|
|
|
+- (void *)chunk, chunksize, *zero, *commit);
|
|
|
++ (void *)chunk, chunksize, sn, *zero, *commit);
|
|
|
+ chunk = NULL;
|
|
|
+ }
|
|
|
+ }
|
|
|
+- if (chunk != NULL && arena_chunk_register(tsdn, arena, chunk, *zero)) {
|
|
|
++ if (chunk != NULL && arena_chunk_register(tsdn, arena, chunk, sn,
|
|
|
++ *zero)) {
|
|
|
+ if (!*commit) {
|
|
|
+ /* Undo commit of header. */
|
|
|
+ chunk_hooks->decommit(chunk, chunksize, 0, map_bias <<
|
|
|
+ LG_PAGE, arena->ind);
|
|
|
+ }
|
|
|
+ chunk_dalloc_wrapper(tsdn, arena, chunk_hooks, (void *)chunk,
|
|
|
+- chunksize, *zero, *commit);
|
|
|
++ chunksize, sn, *zero, *commit);
|
|
|
+ chunk = NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ malloc_mutex_lock(tsdn, &arena->lock);
|
|
|
+ return (chunk);
|
|
|
+ }
|
|
|
+
|
|
|
+ static arena_chunk_t *
|
|
|
+ arena_chunk_alloc_internal(tsdn_t *tsdn, arena_t *arena, bool *zero,
|
|
|
+ bool *commit)
|
|
|
+ {
|
|
|
+ arena_chunk_t *chunk;
|
|
|
+ chunk_hooks_t chunk_hooks = CHUNK_HOOKS_INITIALIZER;
|
|
|
++ size_t sn;
|
|
|
+
|
|
|
+ chunk = chunk_alloc_cache(tsdn, arena, &chunk_hooks, NULL, chunksize,
|
|
|
+- chunksize, zero, commit, true);
|
|
|
++ chunksize, &sn, zero, commit, true);
|
|
|
+ if (chunk != NULL) {
|
|
|
+- if (arena_chunk_register(tsdn, arena, chunk, *zero)) {
|
|
|
++ if (arena_chunk_register(tsdn, arena, chunk, sn, *zero)) {
|
|
|
+ chunk_dalloc_cache(tsdn, arena, &chunk_hooks, chunk,
|
|
|
+- chunksize, true);
|
|
|
++ chunksize, sn, true);
|
|
|
+ return (NULL);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (chunk == NULL) {
|
|
|
+ chunk = arena_chunk_alloc_internal_hard(tsdn, arena,
|
|
|
+ &chunk_hooks, zero, commit);
|
|
|
+ }
|
|
|
+
|
|
|
+@@ -616,16 +659,18 @@ arena_chunk_init_hard(tsdn_t *tsdn, aren
|
|
|
+ assert(arena->spare == NULL);
|
|
|
+
|
|
|
+ zero = false;
|
|
|
+ commit = false;
|
|
|
+ chunk = arena_chunk_alloc_internal(tsdn, arena, &zero, &commit);
|
|
|
+ if (chunk == NULL)
|
|
|
+ return (NULL);
|
|
|
+
|
|
|
++ chunk->hugepage = true;
|
|
|
++
|
|
|
+ /*
|
|
|
+ * Initialize the map to contain one maximal free untouched run. Mark
|
|
|
+ * the pages as zeroed if arena_chunk_alloc_internal() 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,
|
|
|
+@@ -679,36 +724,47 @@ arena_chunk_alloc(tsdn_t *tsdn, arena_t
|
|
|
+ arena_avail_insert(arena, chunk, map_bias, chunk_npages-map_bias);
|
|
|
+
|
|
|
+ return (chunk);
|
|
|
+ }
|
|
|
+
|
|
|
+ static void
|
|
|
+ arena_chunk_discard(tsdn_t *tsdn, arena_t *arena, arena_chunk_t *chunk)
|
|
|
+ {
|
|
|
++ size_t sn, hugepage;
|
|
|
+ bool committed;
|
|
|
+ chunk_hooks_t chunk_hooks = CHUNK_HOOKS_INITIALIZER;
|
|
|
+
|
|
|
+ chunk_deregister(chunk, &chunk->node);
|
|
|
+
|
|
|
++ sn = extent_node_sn_get(&chunk->node);
|
|
|
++ hugepage = chunk->hugepage;
|
|
|
+ committed = (arena_mapbits_decommitted_get(chunk, 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(tsdn, arena);
|
|
|
+ chunk_hooks.decommit(chunk, chunksize, 0, map_bias << LG_PAGE,
|
|
|
+ arena->ind);
|
|
|
+ }
|
|
|
++ if (!hugepage) {
|
|
|
++ /*
|
|
|
++ * Convert chunk back to the default state, so that all
|
|
|
++ * subsequent chunk allocations start out with chunks that can
|
|
|
++ * be backed by transparent huge pages.
|
|
|
++ */
|
|
|
++ pages_huge(chunk, chunksize);
|
|
|
++ }
|
|
|
+
|
|
|
+ chunk_dalloc_cache(tsdn, arena, &chunk_hooks, (void *)chunk, chunksize,
|
|
|
+- committed);
|
|
|
++ sn, committed);
|
|
|
+
|
|
|
+ if (config_stats) {
|
|
|
+ arena->stats.mapped -= chunksize;
|
|
|
+ arena->stats.metadata_mapped -= (map_bias << LG_PAGE);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ static void
|
|
|
+@@ -854,82 +910,83 @@ arena_node_dalloc(tsdn_t *tsdn, arena_t
|
|
|
+ malloc_mutex_lock(tsdn, &arena->node_cache_mtx);
|
|
|
+ ql_elm_new(node, ql_link);
|
|
|
+ ql_tail_insert(&arena->node_cache, node, ql_link);
|
|
|
+ malloc_mutex_unlock(tsdn, &arena->node_cache_mtx);
|
|
|
+ }
|
|
|
+
|
|
|
+ static void *
|
|
|
+ arena_chunk_alloc_huge_hard(tsdn_t *tsdn, arena_t *arena,
|
|
|
+- chunk_hooks_t *chunk_hooks, size_t usize, size_t alignment, bool *zero,
|
|
|
+- size_t csize)
|
|
|
++ chunk_hooks_t *chunk_hooks, size_t usize, size_t alignment, size_t *sn,
|
|
|
++ bool *zero, size_t csize)
|
|
|
+ {
|
|
|
+ void *ret;
|
|
|
+ bool commit = true;
|
|
|
+
|
|
|
+ ret = chunk_alloc_wrapper(tsdn, arena, chunk_hooks, NULL, csize,
|
|
|
+- alignment, zero, &commit);
|
|
|
++ alignment, sn, zero, &commit);
|
|
|
+ if (ret == NULL) {
|
|
|
+ /* Revert optimistic stats updates. */
|
|
|
+ malloc_mutex_lock(tsdn, &arena->lock);
|
|
|
+ if (config_stats) {
|
|
|
+ arena_huge_malloc_stats_update_undo(arena, usize);
|
|
|
+ arena->stats.mapped -= usize;
|
|
|
+ }
|
|
|
+ arena_nactive_sub(arena, usize >> LG_PAGE);
|
|
|
+ malloc_mutex_unlock(tsdn, &arena->lock);
|
|
|
+ }
|
|
|
+
|
|
|
+ return (ret);
|
|
|
+ }
|
|
|
+
|
|
|
+ void *
|
|
|
+ arena_chunk_alloc_huge(tsdn_t *tsdn, arena_t *arena, size_t usize,
|
|
|
+- size_t alignment, bool *zero)
|
|
|
++ size_t alignment, size_t *sn, bool *zero)
|
|
|
+ {
|
|
|
+ void *ret;
|
|
|
+ chunk_hooks_t chunk_hooks = CHUNK_HOOKS_INITIALIZER;
|
|
|
+ size_t csize = CHUNK_CEILING(usize);
|
|
|
+ bool commit = true;
|
|
|
+
|
|
|
+ malloc_mutex_lock(tsdn, &arena->lock);
|
|
|
+
|
|
|
+ /* Optimistically update stats. */
|
|
|
+ if (config_stats) {
|
|
|
+ arena_huge_malloc_stats_update(arena, usize);
|
|
|
+ arena->stats.mapped += usize;
|
|
|
+ }
|
|
|
+ arena_nactive_add(arena, usize >> LG_PAGE);
|
|
|
+
|
|
|
+ ret = chunk_alloc_cache(tsdn, arena, &chunk_hooks, NULL, csize,
|
|
|
+- alignment, zero, &commit, true);
|
|
|
++ alignment, sn, zero, &commit, true);
|
|
|
+ malloc_mutex_unlock(tsdn, &arena->lock);
|
|
|
+ if (ret == NULL) {
|
|
|
+ ret = arena_chunk_alloc_huge_hard(tsdn, arena, &chunk_hooks,
|
|
|
+- usize, alignment, zero, csize);
|
|
|
++ usize, alignment, sn, zero, csize);
|
|
|
+ }
|
|
|
+
|
|
|
+ return (ret);
|
|
|
+ }
|
|
|
+
|
|
|
+ void
|
|
|
+-arena_chunk_dalloc_huge(tsdn_t *tsdn, arena_t *arena, void *chunk, size_t usize)
|
|
|
++arena_chunk_dalloc_huge(tsdn_t *tsdn, arena_t *arena, void *chunk, size_t usize,
|
|
|
++ size_t sn)
|
|
|
+ {
|
|
|
+ chunk_hooks_t chunk_hooks = CHUNK_HOOKS_INITIALIZER;
|
|
|
+ size_t csize;
|
|
|
+
|
|
|
+ csize = CHUNK_CEILING(usize);
|
|
|
+ malloc_mutex_lock(tsdn, &arena->lock);
|
|
|
+ if (config_stats) {
|
|
|
+ arena_huge_dalloc_stats_update(arena, usize);
|
|
|
+ arena->stats.mapped -= usize;
|
|
|
+ }
|
|
|
+ arena_nactive_sub(arena, usize >> LG_PAGE);
|
|
|
+
|
|
|
+- chunk_dalloc_cache(tsdn, arena, &chunk_hooks, chunk, csize, true);
|
|
|
++ chunk_dalloc_cache(tsdn, arena, &chunk_hooks, chunk, csize, sn, true);
|
|
|
+ malloc_mutex_unlock(tsdn, &arena->lock);
|
|
|
+ }
|
|
|
+
|
|
|
+ void
|
|
|
+ arena_chunk_ralloc_huge_similar(tsdn_t *tsdn, arena_t *arena, void *chunk,
|
|
|
+ size_t oldsize, size_t usize)
|
|
|
+ {
|
|
|
+
|
|
|
+@@ -943,17 +1000,17 @@ arena_chunk_ralloc_huge_similar(tsdn_t *
|
|
|
+ arena_nactive_add(arena, (usize - oldsize) >> LG_PAGE);
|
|
|
+ else
|
|
|
+ arena_nactive_sub(arena, (oldsize - usize) >> LG_PAGE);
|
|
|
+ malloc_mutex_unlock(tsdn, &arena->lock);
|
|
|
+ }
|
|
|
+
|
|
|
+ void
|
|
|
+ arena_chunk_ralloc_huge_shrink(tsdn_t *tsdn, arena_t *arena, void *chunk,
|
|
|
+- size_t oldsize, size_t usize)
|
|
|
++ size_t oldsize, size_t usize, size_t sn)
|
|
|
+ {
|
|
|
+ size_t udiff = oldsize - usize;
|
|
|
+ size_t cdiff = CHUNK_CEILING(oldsize) - CHUNK_CEILING(usize);
|
|
|
+
|
|
|
+ malloc_mutex_lock(tsdn, &arena->lock);
|
|
|
+ if (config_stats) {
|
|
|
+ arena_huge_ralloc_stats_update(arena, oldsize, usize);
|
|
|
+ if (cdiff != 0)
|
|
|
+@@ -962,81 +1019,82 @@ arena_chunk_ralloc_huge_shrink(tsdn_t *t
|
|
|
+ arena_nactive_sub(arena, 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(tsdn, arena, &chunk_hooks, nchunk, cdiff,
|
|
|
+- true);
|
|
|
++ sn, true);
|
|
|
+ }
|
|
|
+ malloc_mutex_unlock(tsdn, &arena->lock);
|
|
|
+ }
|
|
|
+
|
|
|
+ static bool
|
|
|
+ arena_chunk_ralloc_huge_expand_hard(tsdn_t *tsdn, 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)
|
|
|
++ size_t *sn, bool *zero, void *nchunk, size_t udiff, size_t cdiff)
|
|
|
+ {
|
|
|
+ bool err;
|
|
|
+ bool commit = true;
|
|
|
+
|
|
|
+ err = (chunk_alloc_wrapper(tsdn, arena, chunk_hooks, nchunk, cdiff,
|
|
|
+- chunksize, zero, &commit) == NULL);
|
|
|
++ chunksize, sn, zero, &commit) == NULL);
|
|
|
+ if (err) {
|
|
|
+ /* Revert optimistic stats updates. */
|
|
|
+ malloc_mutex_lock(tsdn, &arena->lock);
|
|
|
+ if (config_stats) {
|
|
|
+ arena_huge_ralloc_stats_update_undo(arena, oldsize,
|
|
|
+ usize);
|
|
|
+ arena->stats.mapped -= cdiff;
|
|
|
+ }
|
|
|
+ arena_nactive_sub(arena, udiff >> LG_PAGE);
|
|
|
+ malloc_mutex_unlock(tsdn, &arena->lock);
|
|
|
+ } else if (chunk_hooks->merge(chunk, CHUNK_CEILING(oldsize), nchunk,
|
|
|
+ cdiff, true, arena->ind)) {
|
|
|
+ chunk_dalloc_wrapper(tsdn, arena, chunk_hooks, nchunk, cdiff,
|
|
|
+- *zero, true);
|
|
|
++ *sn, *zero, true);
|
|
|
+ err = true;
|
|
|
+ }
|
|
|
+ return (err);
|
|
|
+ }
|
|
|
+
|
|
|
+ bool
|
|
|
+ arena_chunk_ralloc_huge_expand(tsdn_t *tsdn, arena_t *arena, void *chunk,
|
|
|
+ size_t oldsize, size_t usize, bool *zero)
|
|
|
+ {
|
|
|
+ bool err;
|
|
|
+ chunk_hooks_t chunk_hooks = chunk_hooks_get(tsdn, arena);
|
|
|
+ void *nchunk = (void *)((uintptr_t)chunk + CHUNK_CEILING(oldsize));
|
|
|
+ size_t udiff = usize - oldsize;
|
|
|
+ size_t cdiff = CHUNK_CEILING(usize) - CHUNK_CEILING(oldsize);
|
|
|
++ size_t sn;
|
|
|
+ bool commit = true;
|
|
|
+
|
|
|
+ malloc_mutex_lock(tsdn, &arena->lock);
|
|
|
+
|
|
|
+ /* Optimistically update stats. */
|
|
|
+ if (config_stats) {
|
|
|
+ arena_huge_ralloc_stats_update(arena, oldsize, usize);
|
|
|
+ arena->stats.mapped += cdiff;
|
|
|
+ }
|
|
|
+ arena_nactive_add(arena, udiff >> LG_PAGE);
|
|
|
+
|
|
|
+ err = (chunk_alloc_cache(tsdn, arena, &chunk_hooks, nchunk, cdiff,
|
|
|
+- chunksize, zero, &commit, true) == NULL);
|
|
|
++ chunksize, &sn, zero, &commit, true) == NULL);
|
|
|
+ malloc_mutex_unlock(tsdn, &arena->lock);
|
|
|
+ if (err) {
|
|
|
+ err = arena_chunk_ralloc_huge_expand_hard(tsdn, arena,
|
|
|
+- &chunk_hooks, chunk, oldsize, usize, zero, nchunk, udiff,
|
|
|
+- cdiff);
|
|
|
++ &chunk_hooks, chunk, oldsize, usize, &sn, zero, nchunk,
|
|
|
++ udiff, cdiff);
|
|
|
+ } else if (chunk_hooks.merge(chunk, CHUNK_CEILING(oldsize), nchunk,
|
|
|
+ cdiff, true, arena->ind)) {
|
|
|
+ chunk_dalloc_wrapper(tsdn, arena, &chunk_hooks, nchunk, cdiff,
|
|
|
+- *zero, true);
|
|
|
++ sn, *zero, true);
|
|
|
+ err = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ return (err);
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Do first-best-fit run selection, i.e. select the lowest run that best fits.
|
|
|
+@@ -1514,16 +1572,17 @@ arena_stash_dirty(tsdn_t *tsdn, arena_t
|
|
|
+ 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;
|
|
|
++ size_t sn;
|
|
|
+ bool zero, commit;
|
|
|
+ UNUSED void *chunk;
|
|
|
+
|
|
|
+ npages = extent_node_size_get(chunkselm) >> LG_PAGE;
|
|
|
+ if (opt_purge == purge_mode_decay && arena->ndirty -
|
|
|
+ (nstashed + npages) < ndirty_limit)
|
|
|
+ break;
|
|
|
+
|
|
|
+@@ -1531,18 +1590,18 @@ arena_stash_dirty(tsdn_t *tsdn, arena_t
|
|
|
+ /*
|
|
|
+ * Allocate. chunkselm remains valid due to the
|
|
|
+ * dalloc_node=false argument to chunk_alloc_cache().
|
|
|
+ */
|
|
|
+ zero = false;
|
|
|
+ commit = false;
|
|
|
+ chunk = chunk_alloc_cache(tsdn, arena, chunk_hooks,
|
|
|
+ extent_node_addr_get(chunkselm),
|
|
|
+- extent_node_size_get(chunkselm), chunksize, &zero,
|
|
|
+- &commit, false);
|
|
|
++ extent_node_size_get(chunkselm), chunksize, &sn,
|
|
|
++ &zero, &commit, 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);
|
|
|
+ assert(npages == (extent_node_size_get(chunkselm) >>
|
|
|
+ LG_PAGE));
|
|
|
+ chunkselm = chunkselm_next;
|
|
|
+ } else {
|
|
|
+@@ -1629,16 +1688,27 @@ arena_purge_stashed(tsdn_t *tsdn, arena_
|
|
|
+ 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;
|
|
|
+
|
|
|
++ /*
|
|
|
++ * If this is the first run purged within chunk, mark
|
|
|
++ * the chunk as non-huge. This will prevent all use of
|
|
|
++ * transparent huge pages for this chunk until the chunk
|
|
|
++ * as a whole is deallocated.
|
|
|
++ */
|
|
|
++ if (chunk->hugepage) {
|
|
|
++ pages_nohuge(chunk, chunksize);
|
|
|
++ chunk->hugepage = false;
|
|
|
++ }
|
|
|
++
|
|
|
+ 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;
|
|
|
+@@ -1698,23 +1768,24 @@ arena_unstash_purged(tsdn_t *tsdn, arena
|
|
|
+ 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);
|
|
|
++ size_t sn = extent_node_sn_get(chunkselm);
|
|
|
+ bool zeroed = extent_node_zeroed_get(chunkselm);
|
|
|
+ bool committed = extent_node_committed_get(chunkselm);
|
|
|
+ extent_node_dirty_remove(chunkselm);
|
|
|
+ arena_node_dalloc(tsdn, arena, chunkselm);
|
|
|
+ chunkselm = chunkselm_next;
|
|
|
+ chunk_dalloc_wrapper(tsdn, arena, chunk_hooks, addr,
|
|
|
+- size, zeroed, committed);
|
|
|
++ size, sn, 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);
|
|
|
+@@ -2310,17 +2381,17 @@ arena_bin_malloc_hard(tsdn_t *tsdn, aren
|
|
|
+ * 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(tsdn, arena, chunk, run,
|
|
|
+ bin);
|
|
|
+ } else
|
|
|
+- arena_bin_lower_run(arena, chunk, run, bin);
|
|
|
++ arena_bin_lower_run(arena, run, bin);
|
|
|
+ }
|
|
|
+ return (ret);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (run == NULL)
|
|
|
+ return (NULL);
|
|
|
+
|
|
|
+ bin->runcur = run;
|
|
|
+@@ -2815,26 +2886,28 @@ arena_dalloc_bin_run(tsdn_t *tsdn, arena
|
|
|
+ malloc_mutex_unlock(tsdn, &arena->lock);
|
|
|
+ /****************************/
|
|
|
+ malloc_mutex_lock(tsdn, &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)
|
|
|
++arena_bin_lower_run(arena_t *arena, 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.
|
|
|
++ * Make sure that if bin->runcur is non-NULL, it refers to the
|
|
|
++ * oldest/lowest non-full run. It is okay to NULL runcur out rather
|
|
|
++ * than proactively keeping it pointing at the oldest/lowest non-full
|
|
|
++ * run.
|
|
|
+ */
|
|
|
+- if ((uintptr_t)run < (uintptr_t)bin->runcur) {
|
|
|
++ if (bin->runcur != NULL &&
|
|
|
++ arena_snad_comp(arena_run_to_miscelm(bin->runcur),
|
|
|
++ arena_run_to_miscelm(run)) > 0) {
|
|
|
+ /* 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);
|
|
|
+@@ -2860,17 +2933,17 @@ arena_dalloc_bin_locked_impl(tsdn_t *tsd
|
|
|
+ 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(tsdn, arena, chunk, run, bin);
|
|
|
+ } else if (run->nfree == 1 && run != bin->runcur)
|
|
|
+- arena_bin_lower_run(arena, chunk, run, bin);
|
|
|
++ arena_bin_lower_run(arena, run, bin);
|
|
|
+
|
|
|
+ if (config_stats) {
|
|
|
+ bin->stats.ndalloc++;
|
|
|
+ bin->stats.curregs--;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ void
|
|
|
+@@ -3447,16 +3520,23 @@ arena_nthreads_inc(arena_t *arena, bool
|
|
|
+
|
|
|
+ void
|
|
|
+ arena_nthreads_dec(arena_t *arena, bool internal)
|
|
|
+ {
|
|
|
+
|
|
|
+ atomic_sub_u(&arena->nthreads[internal], 1);
|
|
|
+ }
|
|
|
+
|
|
|
++size_t
|
|
|
++arena_extent_sn_next(arena_t *arena)
|
|
|
++{
|
|
|
++
|
|
|
++ return (atomic_add_z(&arena->extent_sn_next, 1) - 1);
|
|
|
++}
|
|
|
++
|
|
|
+ arena_t *
|
|
|
+ arena_new(tsdn_t *tsdn, unsigned ind)
|
|
|
+ {
|
|
|
+ arena_t *arena;
|
|
|
+ unsigned i;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Allocate arena, arena->lstats, and arena->hstats contiguously, mainly
|
|
|
+@@ -3506,16 +3586,18 @@ arena_new(tsdn_t *tsdn, unsigned ind)
|
|
|
+ arena->offset_state = config_debug ? ind :
|
|
|
+ (size_t)(uintptr_t)arena;
|
|
|
+ }
|
|
|
+
|
|
|
+ arena->dss_prec = chunk_dss_prec_get();
|
|
|
+
|
|
|
+ ql_new(&arena->achunks);
|
|
|
+
|
|
|
++ arena->extent_sn_next = 0;
|
|
|
++
|
|
|
+ arena->spare = NULL;
|
|
|
+
|
|
|
+ arena->lg_dirty_mult = arena_lg_dirty_mult_default_get();
|
|
|
+ arena->purging = false;
|
|
|
+ arena->nactive = 0;
|
|
|
+ arena->ndirty = 0;
|
|
|
+
|
|
|
+ for (i = 0; i < NPSIZES; i++)
|
|
|
+@@ -3527,19 +3609,19 @@ arena_new(tsdn_t *tsdn, unsigned ind)
|
|
|
+ if (opt_purge == purge_mode_decay)
|
|
|
+ arena_decay_init(arena, arena_decay_time_default_get());
|
|
|
+
|
|
|
+ ql_new(&arena->huge);
|
|
|
+ if (malloc_mutex_init(&arena->huge_mtx, "arena_huge",
|
|
|
+ WITNESS_RANK_ARENA_HUGE))
|
|
|
+ return (NULL);
|
|
|
+
|
|
|
+- extent_tree_szad_new(&arena->chunks_szad_cached);
|
|
|
++ extent_tree_szsnad_new(&arena->chunks_szsnad_cached);
|
|
|
+ extent_tree_ad_new(&arena->chunks_ad_cached);
|
|
|
+- extent_tree_szad_new(&arena->chunks_szad_retained);
|
|
|
++ extent_tree_szsnad_new(&arena->chunks_szsnad_retained);
|
|
|
+ extent_tree_ad_new(&arena->chunks_ad_retained);
|
|
|
+ if (malloc_mutex_init(&arena->chunks_mtx, "arena_chunks",
|
|
|
+ WITNESS_RANK_ARENA_CHUNKS))
|
|
|
+ return (NULL);
|
|
|
+ ql_new(&arena->node_cache);
|
|
|
+ if (malloc_mutex_init(&arena->node_cache_mtx, "arena_node_cache",
|
|
|
+ WITNESS_RANK_ARENA_NODE_CACHE))
|
|
|
+ return (NULL);
|
|
|
+diff --git a/memory/jemalloc/src/src/base.c b/memory/jemalloc/src/src/base.c
|
|
|
+--- a/memory/jemalloc/src/src/base.c
|
|
|
++++ b/memory/jemalloc/src/src/base.c
|
|
|
+@@ -1,16 +1,17 @@
|
|
|
+ #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 size_t base_extent_sn_next;
|
|
|
++static extent_tree_t base_avail_szsnad;
|
|
|
+ static extent_node_t *base_nodes;
|
|
|
+ static size_t base_allocated;
|
|
|
+ static size_t base_resident;
|
|
|
+ static size_t base_mapped;
|
|
|
+
|
|
|
+ /******************************************************************************/
|
|
|
+
|
|
|
+ static extent_node_t *
|
|
|
+@@ -34,16 +35,24 @@ base_node_dalloc(tsdn_t *tsdn, extent_no
|
|
|
+
|
|
|
+ malloc_mutex_assert_owner(tsdn, &base_mtx);
|
|
|
+
|
|
|
+ JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(node, sizeof(extent_node_t));
|
|
|
+ *(extent_node_t **)node = base_nodes;
|
|
|
+ base_nodes = node;
|
|
|
+ }
|
|
|
+
|
|
|
++static void
|
|
|
++base_extent_node_init(extent_node_t *node, void *addr, size_t size)
|
|
|
++{
|
|
|
++ size_t sn = atomic_add_z(&base_extent_sn_next, 1) - 1;
|
|
|
++
|
|
|
++ extent_node_init(node, NULL, addr, size, sn, true, true);
|
|
|
++}
|
|
|
++
|
|
|
+ static extent_node_t *
|
|
|
+ base_chunk_alloc(tsdn_t *tsdn, size_t minsize)
|
|
|
+ {
|
|
|
+ extent_node_t *node;
|
|
|
+ size_t csize, nsize;
|
|
|
+ void *addr;
|
|
|
+
|
|
|
+ malloc_mutex_assert_owner(tsdn, &base_mtx);
|
|
|
+@@ -63,17 +72,17 @@ base_chunk_alloc(tsdn_t *tsdn, size_t mi
|
|
|
+ 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);
|
|
|
++ base_extent_node_init(node, addr, csize);
|
|
|
+ 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.
|
|
|
+ */
|
|
|
+@@ -87,36 +96,36 @@ base_alloc(tsdn_t *tsdn, size_t size)
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 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);
|
|
|
++ extent_node_init(&key, NULL, NULL, usize, 0, false, false);
|
|
|
+ malloc_mutex_lock(tsdn, &base_mtx);
|
|
|
+- node = extent_tree_szad_nsearch(&base_avail_szad, &key);
|
|
|
++ node = extent_tree_szsnad_nsearch(&base_avail_szsnad, &key);
|
|
|
+ if (node != NULL) {
|
|
|
+ /* Use existing space. */
|
|
|
+- extent_tree_szad_remove(&base_avail_szad, node);
|
|
|
++ extent_tree_szsnad_remove(&base_avail_szsnad, node);
|
|
|
+ } else {
|
|
|
+ /* Try to allocate more space. */
|
|
|
+ node = base_chunk_alloc(tsdn, 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);
|
|
|
++ extent_tree_szsnad_insert(&base_avail_szsnad, node);
|
|
|
+ } else
|
|
|
+ base_node_dalloc(tsdn, node);
|
|
|
+ if (config_stats) {
|
|
|
+ base_allocated += csize;
|
|
|
+ /*
|
|
|
+ * Add one PAGE to base_resident for every page boundary that is
|
|
|
+ * crossed by the new allocation.
|
|
|
+ */
|
|
|
+@@ -144,17 +153,18 @@ base_stats_get(tsdn_t *tsdn, size_t *all
|
|
|
+ }
|
|
|
+
|
|
|
+ bool
|
|
|
+ base_boot(void)
|
|
|
+ {
|
|
|
+
|
|
|
+ if (malloc_mutex_init(&base_mtx, "base", WITNESS_RANK_BASE))
|
|
|
+ return (true);
|
|
|
+- extent_tree_szad_new(&base_avail_szad);
|
|
|
++ base_extent_sn_next = 0;
|
|
|
++ extent_tree_szsnad_new(&base_avail_szsnad);
|
|
|
+ base_nodes = NULL;
|
|
|
+
|
|
|
+ return (false);
|
|
|
+ }
|
|
|
+
|
|
|
+ void
|
|
|
+ base_prefork(tsdn_t *tsdn)
|
|
|
+ {
|
|
|
+diff --git a/memory/jemalloc/src/src/chunk.c b/memory/jemalloc/src/src/chunk.c
|
|
|
+--- a/memory/jemalloc/src/src/chunk.c
|
|
|
++++ b/memory/jemalloc/src/src/chunk.c
|
|
|
+@@ -45,19 +45,19 @@ const chunk_hooks_t chunk_hooks_default
|
|
|
+
|
|
|
+ /******************************************************************************/
|
|
|
+ /*
|
|
|
+ * Function prototypes for static functions that are referenced prior to
|
|
|
+ * definition.
|
|
|
+ */
|
|
|
+
|
|
|
+ static void chunk_record(tsdn_t *tsdn, 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);
|
|
|
++ chunk_hooks_t *chunk_hooks, extent_tree_t *chunks_szsnad,
|
|
|
++ extent_tree_t *chunks_ad, bool cache, void *chunk, size_t size, size_t sn,
|
|
|
++ bool zeroed, bool committed);
|
|
|
+
|
|
|
+ /******************************************************************************/
|
|
|
+
|
|
|
+ static chunk_hooks_t
|
|
|
+ chunk_hooks_get_locked(arena_t *arena)
|
|
|
+ {
|
|
|
+
|
|
|
+ return (arena->chunk_hooks);
|
|
|
+@@ -178,135 +178,137 @@ chunk_deregister(const void *chunk, cons
|
|
|
+ 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.
|
|
|
++ * Do first-best-fit chunk selection, i.e. select the oldest/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)
|
|
|
++chunk_first_best_fit(arena_t *arena, extent_tree_t *chunks_szsnad, 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));
|
|
|
++ extent_node_init(&key, arena, NULL, size, 0, false, false);
|
|
|
++ return (extent_tree_szsnad_nsearch(chunks_szsnad, &key));
|
|
|
+ }
|
|
|
+
|
|
|
+ static void *
|
|
|
+ chunk_recycle(tsdn_t *tsdn, 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)
|
|
|
++ extent_tree_t *chunks_szsnad, extent_tree_t *chunks_ad, bool cache,
|
|
|
++ void *new_addr, size_t size, size_t alignment, size_t *sn, bool *zero,
|
|
|
++ bool *commit, bool dalloc_node)
|
|
|
+ {
|
|
|
+ void *ret;
|
|
|
+ extent_node_t *node;
|
|
|
+ size_t alloc_size, leadsize, trailsize;
|
|
|
+ bool zeroed, committed;
|
|
|
+
|
|
|
++ assert(CHUNK_CEILING(size) == size);
|
|
|
++ assert(alignment > 0);
|
|
|
+ assert(new_addr == NULL || alignment == chunksize);
|
|
|
++ assert(CHUNK_ADDR2BASE(new_addr) == new_addr);
|
|
|
+ /*
|
|
|
+ * 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));
|
|
|
++ alloc_size = size + CHUNK_CEILING(alignment) - chunksize;
|
|
|
+ /* Beware size_t wrap-around. */
|
|
|
+ if (alloc_size < size)
|
|
|
+ return (NULL);
|
|
|
+ malloc_mutex_lock(tsdn, &arena->chunks_mtx);
|
|
|
+ chunk_hooks_assure_initialized_locked(tsdn, arena, chunk_hooks);
|
|
|
+ if (new_addr != NULL) {
|
|
|
+ extent_node_t key;
|
|
|
+- extent_node_init(&key, arena, new_addr, alloc_size, false,
|
|
|
++ extent_node_init(&key, arena, new_addr, alloc_size, 0, false,
|
|
|
+ false);
|
|
|
+ node = extent_tree_ad_search(chunks_ad, &key);
|
|
|
+ } else {
|
|
|
+- node = chunk_first_best_fit(arena, chunks_szad, chunks_ad,
|
|
|
+- alloc_size);
|
|
|
++ node = chunk_first_best_fit(arena, chunks_szsnad, alloc_size);
|
|
|
+ }
|
|
|
+ if (node == NULL || (new_addr != NULL && extent_node_size_get(node) <
|
|
|
+ size)) {
|
|
|
+ malloc_mutex_unlock(tsdn, &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);
|
|
|
++ *sn = extent_node_sn_get(node);
|
|
|
+ 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(tsdn, &arena->chunks_mtx);
|
|
|
+ return (NULL);
|
|
|
+ }
|
|
|
+ /* Remove node from the tree. */
|
|
|
+- extent_tree_szad_remove(chunks_szad, node);
|
|
|
++ extent_tree_szsnad_remove(chunks_szsnad, 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_szsnad_insert(chunks_szsnad, 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(tsdn, arena, node);
|
|
|
+ malloc_mutex_unlock(tsdn, &arena->chunks_mtx);
|
|
|
+- chunk_record(tsdn, arena, chunk_hooks, chunks_szad,
|
|
|
+- chunks_ad, cache, ret, size + trailsize, zeroed,
|
|
|
+- committed);
|
|
|
++ chunk_record(tsdn, arena, chunk_hooks, chunks_szsnad,
|
|
|
++ chunks_ad, cache, ret, size + trailsize, *sn,
|
|
|
++ zeroed, committed);
|
|
|
+ return (NULL);
|
|
|
+ }
|
|
|
+ /* Insert the trailing space as a smaller chunk. */
|
|
|
+ if (node == NULL) {
|
|
|
+ node = arena_node_alloc(tsdn, arena);
|
|
|
+ if (node == NULL) {
|
|
|
+ malloc_mutex_unlock(tsdn, &arena->chunks_mtx);
|
|
|
+ chunk_record(tsdn, arena, chunk_hooks,
|
|
|
+- chunks_szad, chunks_ad, cache, ret, size +
|
|
|
+- trailsize, zeroed, committed);
|
|
|
++ chunks_szsnad, chunks_ad, cache, ret, size
|
|
|
++ + trailsize, *sn, zeroed, committed);
|
|
|
+ return (NULL);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ extent_node_init(node, arena, (void *)((uintptr_t)(ret) + size),
|
|
|
+- trailsize, zeroed, committed);
|
|
|
+- extent_tree_szad_insert(chunks_szad, node);
|
|
|
++ trailsize, *sn, zeroed, committed);
|
|
|
++ extent_tree_szsnad_insert(chunks_szsnad, 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(tsdn, &arena->chunks_mtx);
|
|
|
+- chunk_record(tsdn, arena, chunk_hooks, chunks_szad, chunks_ad,
|
|
|
+- cache, ret, size, zeroed, committed);
|
|
|
++ chunk_record(tsdn, arena, chunk_hooks, chunks_szsnad, chunks_ad,
|
|
|
++ cache, ret, size, *sn, zeroed, committed);
|
|
|
+ return (NULL);
|
|
|
+ }
|
|
|
+ malloc_mutex_unlock(tsdn, &arena->chunks_mtx);
|
|
|
+
|
|
|
+ assert(dalloc_node || node != NULL);
|
|
|
+ if (dalloc_node && node != NULL)
|
|
|
+ arena_node_dalloc(tsdn, arena, node);
|
|
|
+ if (*zero) {
|
|
|
+@@ -380,29 +382,29 @@ chunk_alloc_base(size_t size)
|
|
|
+ if (config_valgrind)
|
|
|
+ JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(ret, size);
|
|
|
+
|
|
|
+ return (ret);
|
|
|
+ }
|
|
|
+
|
|
|
+ void *
|
|
|
+ chunk_alloc_cache(tsdn_t *tsdn, arena_t *arena, chunk_hooks_t *chunk_hooks,
|
|
|
+- void *new_addr, size_t size, size_t alignment, bool *zero, bool *commit,
|
|
|
+- bool dalloc_node)
|
|
|
++ void *new_addr, size_t size, size_t alignment, size_t *sn, bool *zero,
|
|
|
++ bool *commit, bool dalloc_node)
|
|
|
+ {
|
|
|
+ void *ret;
|
|
|
+
|
|
|
+ assert(size != 0);
|
|
|
+ assert((size & chunksize_mask) == 0);
|
|
|
+ assert(alignment != 0);
|
|
|
+ assert((alignment & chunksize_mask) == 0);
|
|
|
+
|
|
|
+ ret = chunk_recycle(tsdn, arena, chunk_hooks,
|
|
|
+- &arena->chunks_szad_cached, &arena->chunks_ad_cached, true,
|
|
|
+- new_addr, size, alignment, zero, commit, dalloc_node);
|
|
|
++ &arena->chunks_szsnad_cached, &arena->chunks_ad_cached, true,
|
|
|
++ new_addr, size, alignment, sn, zero, commit, dalloc_node);
|
|
|
+ if (ret == NULL)
|
|
|
+ return (NULL);
|
|
|
+ if (config_valgrind)
|
|
|
+ JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(ret, size);
|
|
|
+ return (ret);
|
|
|
+ }
|
|
|
+
|
|
|
+ static arena_t *
|
|
|
+@@ -446,102 +448,108 @@ chunk_alloc_default(void *new_addr, size
|
|
|
+ arena = chunk_arena_get(tsdn, arena_ind);
|
|
|
+
|
|
|
+ return (chunk_alloc_default_impl(tsdn, arena, new_addr, size, alignment,
|
|
|
+ zero, commit));
|
|
|
+ }
|
|
|
+
|
|
|
+ static void *
|
|
|
+ chunk_alloc_retained(tsdn_t *tsdn, arena_t *arena, chunk_hooks_t *chunk_hooks,
|
|
|
+- void *new_addr, size_t size, size_t alignment, bool *zero, bool *commit)
|
|
|
++ void *new_addr, size_t size, size_t alignment, size_t *sn, bool *zero,
|
|
|
++ bool *commit)
|
|
|
+ {
|
|
|
+ void *ret;
|
|
|
+
|
|
|
+ assert(size != 0);
|
|
|
+ assert((size & chunksize_mask) == 0);
|
|
|
+ assert(alignment != 0);
|
|
|
+ assert((alignment & chunksize_mask) == 0);
|
|
|
+
|
|
|
+ ret = chunk_recycle(tsdn, arena, chunk_hooks,
|
|
|
+- &arena->chunks_szad_retained, &arena->chunks_ad_retained, false,
|
|
|
+- new_addr, size, alignment, zero, commit, true);
|
|
|
++ &arena->chunks_szsnad_retained, &arena->chunks_ad_retained, false,
|
|
|
++ new_addr, size, alignment, sn, zero, commit, true);
|
|
|
+
|
|
|
+ if (config_stats && ret != NULL)
|
|
|
+ arena->stats.retained -= size;
|
|
|
+
|
|
|
+ return (ret);
|
|
|
+ }
|
|
|
+
|
|
|
+ void *
|
|
|
+ chunk_alloc_wrapper(tsdn_t *tsdn, arena_t *arena, chunk_hooks_t *chunk_hooks,
|
|
|
+- void *new_addr, size_t size, size_t alignment, bool *zero, bool *commit)
|
|
|
++ void *new_addr, size_t size, size_t alignment, size_t *sn, bool *zero,
|
|
|
++ bool *commit)
|
|
|
+ {
|
|
|
+ void *ret;
|
|
|
+
|
|
|
+ chunk_hooks_assure_initialized(tsdn, arena, chunk_hooks);
|
|
|
+
|
|
|
+ ret = chunk_alloc_retained(tsdn, arena, chunk_hooks, new_addr, size,
|
|
|
+- alignment, zero, commit);
|
|
|
++ alignment, sn, zero, commit);
|
|
|
+ if (ret == NULL) {
|
|
|
+ if (chunk_hooks->alloc == chunk_alloc_default) {
|
|
|
+ /* Call directly to propagate tsdn. */
|
|
|
+ ret = chunk_alloc_default_impl(tsdn, arena, new_addr,
|
|
|
+ size, alignment, zero, commit);
|
|
|
+ } else {
|
|
|
+ ret = chunk_hooks->alloc(new_addr, size, alignment,
|
|
|
+ zero, commit, arena->ind);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (ret == NULL)
|
|
|
+ return (NULL);
|
|
|
+
|
|
|
++ *sn = arena_extent_sn_next(arena);
|
|
|
++
|
|
|
+ if (config_valgrind && chunk_hooks->alloc !=
|
|
|
+ chunk_alloc_default)
|
|
|
+ JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(ret, chunksize);
|
|
|
+ }
|
|
|
+
|
|
|
+ return (ret);
|
|
|
+ }
|
|
|
+
|
|
|
+ static void
|
|
|
+ chunk_record(tsdn_t *tsdn, 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)
|
|
|
++ extent_tree_t *chunks_szsnad, extent_tree_t *chunks_ad, bool cache,
|
|
|
++ void *chunk, size_t size, size_t sn, 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(tsdn, &arena->chunks_mtx);
|
|
|
+ chunk_hooks_assure_initialized_locked(tsdn, arena, chunk_hooks);
|
|
|
+- extent_node_init(&key, arena, (void *)((uintptr_t)chunk + size), 0,
|
|
|
++ extent_node_init(&key, arena, (void *)((uintptr_t)chunk + size), 0, 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.
|
|
|
++ * remove/insert from/into chunks_szsnad.
|
|
|
+ */
|
|
|
+- extent_tree_szad_remove(chunks_szad, node);
|
|
|
++ extent_tree_szsnad_remove(chunks_szsnad, 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));
|
|
|
++ if (sn < extent_node_sn_get(node))
|
|
|
++ extent_node_sn_set(node, sn);
|
|
|
+ extent_node_zeroed_set(node, extent_node_zeroed_get(node) &&
|
|
|
+ !unzeroed);
|
|
|
+- extent_tree_szad_insert(chunks_szad, node);
|
|
|
++ extent_tree_szsnad_insert(chunks_szsnad, node);
|
|
|
+ arena_chunk_cache_maybe_insert(arena, node, cache);
|
|
|
+ } else {
|
|
|
+ /* Coalescing forward failed, so insert a new node. */
|
|
|
+ node = arena_node_alloc(tsdn, arena);
|
|
|
+ if (node == NULL) {
|
|
|
+ /*
|
|
|
+ * Node allocation failed, which is an exceedingly
|
|
|
+ * unlikely failure. Leak chunk after making sure its
|
|
|
+@@ -549,67 +557,70 @@ chunk_record(tsdn_t *tsdn, arena_t *aren
|
|
|
+ * a virtual memory leak.
|
|
|
+ */
|
|
|
+ if (cache) {
|
|
|
+ chunk_purge_wrapper(tsdn, arena, chunk_hooks,
|
|
|
+ chunk, size, 0, size);
|
|
|
+ }
|
|
|
+ goto label_return;
|
|
|
+ }
|
|
|
+- extent_node_init(node, arena, chunk, size, !unzeroed,
|
|
|
++ extent_node_init(node, arena, chunk, size, sn, !unzeroed,
|
|
|
+ committed);
|
|
|
+ extent_tree_ad_insert(chunks_ad, node);
|
|
|
+- extent_tree_szad_insert(chunks_szad, node);
|
|
|
++ extent_tree_szsnad_insert(chunks_szsnad, 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.
|
|
|
++ * remove/insert node from/into chunks_szsnad.
|
|
|
+ */
|
|
|
+- extent_tree_szad_remove(chunks_szad, prev);
|
|
|
++ extent_tree_szsnad_remove(chunks_szsnad, prev);
|
|
|
+ extent_tree_ad_remove(chunks_ad, prev);
|
|
|
+ arena_chunk_cache_maybe_remove(arena, prev, cache);
|
|
|
+- extent_tree_szad_remove(chunks_szad, node);
|
|
|
++ extent_tree_szsnad_remove(chunks_szsnad, 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));
|
|
|
++ if (extent_node_sn_get(prev) < extent_node_sn_get(node))
|
|
|
++ extent_node_sn_set(node, extent_node_sn_get(prev));
|
|
|
+ extent_node_zeroed_set(node, extent_node_zeroed_get(prev) &&
|
|
|
+ extent_node_zeroed_get(node));
|
|
|
+- extent_tree_szad_insert(chunks_szad, node);
|
|
|
++ extent_tree_szsnad_insert(chunks_szsnad, node);
|
|
|
+ arena_chunk_cache_maybe_insert(arena, node, cache);
|
|
|
+
|
|
|
+ arena_node_dalloc(tsdn, arena, prev);
|
|
|
+ }
|
|
|
+
|
|
|
+ label_return:
|
|
|
+ malloc_mutex_unlock(tsdn, &arena->chunks_mtx);
|
|
|
+ }
|
|
|
+
|
|
|
+ void
|
|
|
+ chunk_dalloc_cache(tsdn_t *tsdn, arena_t *arena, chunk_hooks_t *chunk_hooks,
|
|
|
+- void *chunk, size_t size, bool committed)
|
|
|
++ void *chunk, size_t size, size_t sn, bool committed)
|
|
|
+ {
|
|
|
+
|
|
|
+ assert(chunk != NULL);
|
|
|
+ assert(CHUNK_ADDR2BASE(chunk) == chunk);
|
|
|
+ assert(size != 0);
|
|
|
+ assert((size & chunksize_mask) == 0);
|
|
|
+
|
|
|
+- chunk_record(tsdn, arena, chunk_hooks, &arena->chunks_szad_cached,
|
|
|
+- &arena->chunks_ad_cached, true, chunk, size, false, committed);
|
|
|
++ chunk_record(tsdn, arena, chunk_hooks, &arena->chunks_szsnad_cached,
|
|
|
++ &arena->chunks_ad_cached, true, chunk, size, sn, false,
|
|
|
++ committed);
|
|
|
+ arena_maybe_purge(tsdn, arena);
|
|
|
+ }
|
|
|
+
|
|
|
+ static bool
|
|
|
+ chunk_dalloc_default_impl(void *chunk, size_t size)
|
|
|
+ {
|
|
|
+
|
|
|
+ if (!have_dss || !chunk_in_dss(chunk))
|
|
|
+@@ -622,17 +633,17 @@ chunk_dalloc_default(void *chunk, size_t
|
|
|
+ unsigned arena_ind)
|
|
|
+ {
|
|
|
+
|
|
|
+ return (chunk_dalloc_default_impl(chunk, size));
|
|
|
+ }
|
|
|
+
|
|
|
+ void
|
|
|
+ chunk_dalloc_wrapper(tsdn_t *tsdn, arena_t *arena, chunk_hooks_t *chunk_hooks,
|
|
|
+- void *chunk, size_t size, bool zeroed, bool committed)
|
|
|
++ void *chunk, size_t size, size_t sn, bool zeroed, bool committed)
|
|
|
+ {
|
|
|
+ bool err;
|
|
|
+
|
|
|
+ assert(chunk != NULL);
|
|
|
+ assert(CHUNK_ADDR2BASE(chunk) == chunk);
|
|
|
+ assert(size != 0);
|
|
|
+ assert((size & chunksize_mask) == 0);
|
|
|
+
|
|
|
+@@ -648,18 +659,19 @@ chunk_dalloc_wrapper(tsdn_t *tsdn, arena
|
|
|
+ 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(tsdn, arena, chunk_hooks, &arena->chunks_szad_retained,
|
|
|
+- &arena->chunks_ad_retained, false, chunk, size, zeroed, committed);
|
|
|
++ chunk_record(tsdn, arena, chunk_hooks, &arena->chunks_szsnad_retained,
|
|
|
++ &arena->chunks_ad_retained, false, chunk, size, sn, zeroed,
|
|
|
++ committed);
|
|
|
+
|
|
|
+ if (config_stats)
|
|
|
+ arena->stats.retained += size;
|
|
|
+ }
|
|
|
+
|
|
|
+ static bool
|
|
|
+ chunk_commit_default(void *chunk, size_t size, size_t offset, size_t length,
|
|
|
+ unsigned arena_ind)
|
|
|
+diff --git a/memory/jemalloc/src/src/chunk_dss.c b/memory/jemalloc/src/src/chunk_dss.c
|
|
|
+--- a/memory/jemalloc/src/src/chunk_dss.c
|
|
|
++++ b/memory/jemalloc/src/src/chunk_dss.c
|
|
|
+@@ -157,17 +157,18 @@ chunk_alloc_dss(tsdn_t *tsdn, arena_t *a
|
|
|
+ dss_prev = chunk_dss_sbrk(incr);
|
|
|
+ if (dss_prev == max_cur) {
|
|
|
+ /* Success. */
|
|
|
+ if (cpad_size != 0) {
|
|
|
+ chunk_hooks_t chunk_hooks =
|
|
|
+ CHUNK_HOOKS_INITIALIZER;
|
|
|
+ chunk_dalloc_wrapper(tsdn, arena,
|
|
|
+ &chunk_hooks, cpad, cpad_size,
|
|
|
+- false, true);
|
|
|
++ arena_extent_sn_next(arena), false,
|
|
|
++ true);
|
|
|
+ }
|
|
|
+ if (*zero) {
|
|
|
+ JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(
|
|
|
+ ret, size);
|
|
|
+ memset(ret, 0, size);
|
|
|
+ }
|
|
|
+ if (!*commit)
|
|
|
+ *commit = pages_decommit(ret, size);
|
|
|
+diff --git a/memory/jemalloc/src/src/extent.c b/memory/jemalloc/src/src/extent.c
|
|
|
+--- a/memory/jemalloc/src/src/extent.c
|
|
|
++++ b/memory/jemalloc/src/src/extent.c
|
|
|
+@@ -1,53 +1,77 @@
|
|
|
+ #define JEMALLOC_EXTENT_C_
|
|
|
+ #include "jemalloc/internal/jemalloc_internal.h"
|
|
|
+
|
|
|
+ /******************************************************************************/
|
|
|
+
|
|
|
++/*
|
|
|
++ * Round down to the nearest chunk size that can actually be requested during
|
|
|
++ * normal huge allocation.
|
|
|
++ */
|
|
|
+ JEMALLOC_INLINE_C size_t
|
|
|
+ extent_quantize(size_t size)
|
|
|
+ {
|
|
|
++ size_t ret;
|
|
|
++ szind_t ind;
|
|
|
+
|
|
|
+- /*
|
|
|
+- * Round down to the nearest chunk size that can actually be requested
|
|
|
+- * during normal huge allocation.
|
|
|
+- */
|
|
|
+- return (index2size(size2index(size + 1) - 1));
|
|
|
++ assert(size > 0);
|
|
|
++
|
|
|
++ ind = size2index(size + 1);
|
|
|
++ if (ind == 0) {
|
|
|
++ /* Avoid underflow. */
|
|
|
++ return (index2size(0));
|
|
|
++ }
|
|
|
++ ret = index2size(ind - 1);
|
|
|
++ assert(ret <= size);
|
|
|
++ return (ret);
|
|
|
+ }
|
|
|
+
|
|
|
+ JEMALLOC_INLINE_C int
|
|
|
+-extent_szad_comp(const extent_node_t *a, const extent_node_t *b)
|
|
|
++extent_sz_comp(const extent_node_t *a, const 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);
|
|
|
++ return ((a_qsize > b_qsize) - (a_qsize < b_qsize));
|
|
|
+ }
|
|
|
+
|
|
|
+-/* 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_sn_comp(const extent_node_t *a, const extent_node_t *b)
|
|
|
++{
|
|
|
++ size_t a_sn = extent_node_sn_get(a);
|
|
|
++ size_t b_sn = extent_node_sn_get(b);
|
|
|
++
|
|
|
++ return ((a_sn > b_sn) - (a_sn < b_sn));
|
|
|
++}
|
|
|
+
|
|
|
+ JEMALLOC_INLINE_C int
|
|
|
+ extent_ad_comp(const extent_node_t *a, const 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));
|
|
|
+ }
|
|
|
+
|
|
|
++JEMALLOC_INLINE_C int
|
|
|
++extent_szsnad_comp(const extent_node_t *a, const extent_node_t *b)
|
|
|
++{
|
|
|
++ int ret;
|
|
|
++
|
|
|
++ ret = extent_sz_comp(a, b);
|
|
|
++ if (ret != 0)
|
|
|
++ return (ret);
|
|
|
++
|
|
|
++ ret = extent_sn_comp(a, b);
|
|
|
++ if (ret != 0)
|
|
|
++ return (ret);
|
|
|
++
|
|
|
++ ret = extent_ad_comp(a, b);
|
|
|
++ return (ret);
|
|
|
++}
|
|
|
++
|
|
|
++/* Generate red-black tree functions. */
|
|
|
++rb_gen(, extent_tree_szsnad_, extent_tree_t, extent_node_t, szsnad_link,
|
|
|
++ extent_szsnad_comp)
|
|
|
++
|
|
|
+ /* Generate red-black tree functions. */
|
|
|
+ rb_gen(, extent_tree_ad_, extent_tree_t, extent_node_t, ad_link, extent_ad_comp)
|
|
|
+diff --git a/memory/jemalloc/src/src/huge.c b/memory/jemalloc/src/src/huge.c
|
|
|
+--- a/memory/jemalloc/src/src/huge.c
|
|
|
++++ b/memory/jemalloc/src/src/huge.c
|
|
|
+@@ -51,51 +51,53 @@ huge_malloc(tsdn_t *tsdn, arena_t *arena
|
|
|
+ void *
|
|
|
+ huge_palloc(tsdn_t *tsdn, arena_t *arena, size_t usize, size_t alignment,
|
|
|
+ bool zero)
|
|
|
+ {
|
|
|
+ void *ret;
|
|
|
+ size_t ausize;
|
|
|
+ arena_t *iarena;
|
|
|
+ extent_node_t *node;
|
|
|
++ size_t sn;
|
|
|
+ bool is_zeroed;
|
|
|
+
|
|
|
+ /* Allocate one or more contiguous chunks for this request. */
|
|
|
+
|
|
|
+ assert(!tsdn_null(tsdn) || arena != NULL);
|
|
|
+
|
|
|
+ ausize = sa2u(usize, alignment);
|
|
|
+ if (unlikely(ausize == 0 || ausize > HUGE_MAXCLASS))
|
|
|
+ return (NULL);
|
|
|
+ assert(ausize >= chunksize);
|
|
|
+
|
|
|
+ /* Allocate an extent node with which to track the chunk. */
|
|
|
+- iarena = (!tsdn_null(tsdn)) ? arena_ichoose(tsdn_tsd(tsdn), NULL) : a0get();
|
|
|
++ iarena = (!tsdn_null(tsdn)) ? arena_ichoose(tsdn_tsd(tsdn), NULL) :
|
|
|
++ a0get();
|
|
|
+ node = ipallocztm(tsdn, CACHELINE_CEILING(sizeof(extent_node_t)),
|
|
|
+ CACHELINE, false, NULL, true, iarena);
|
|
|
+ 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;
|
|
|
+ if (likely(!tsdn_null(tsdn)))
|
|
|
+ arena = arena_choose(tsdn_tsd(tsdn), arena);
|
|
|
+ if (unlikely(arena == NULL) || (ret = arena_chunk_alloc_huge(tsdn,
|
|
|
+- arena, usize, alignment, &is_zeroed)) == NULL) {
|
|
|
++ arena, usize, alignment, &sn, &is_zeroed)) == NULL) {
|
|
|
+ idalloctm(tsdn, node, NULL, true, true);
|
|
|
+ return (NULL);
|
|
|
+ }
|
|
|
+
|
|
|
+- extent_node_init(node, arena, ret, usize, is_zeroed, true);
|
|
|
++ extent_node_init(node, arena, ret, usize, sn, is_zeroed, true);
|
|
|
+
|
|
|
+ if (huge_node_set(tsdn, ret, node)) {
|
|
|
+- arena_chunk_dalloc_huge(tsdn, arena, ret, usize);
|
|
|
++ arena_chunk_dalloc_huge(tsdn, arena, ret, usize, sn);
|
|
|
+ idalloctm(tsdn, node, NULL, true, true);
|
|
|
+ return (NULL);
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Insert node into huge. */
|
|
|
+ malloc_mutex_lock(tsdn, &arena->huge_mtx);
|
|
|
+ ql_elm_new(node, ql_link);
|
|
|
+ ql_tail_insert(&arena->huge, node, ql_link);
|
|
|
+@@ -240,17 +242,18 @@ huge_ralloc_no_move_shrink(tsdn_t *tsdn,
|
|
|
+ huge_node_unset(ptr, node);
|
|
|
+ extent_node_size_set(node, usize);
|
|
|
+ huge_node_reset(tsdn, ptr, node);
|
|
|
+ /* Update zeroed. */
|
|
|
+ extent_node_zeroed_set(node, post_zeroed);
|
|
|
+ malloc_mutex_unlock(tsdn, &arena->huge_mtx);
|
|
|
+
|
|
|
+ /* Zap the excess chunks. */
|
|
|
+- arena_chunk_ralloc_huge_shrink(tsdn, arena, ptr, oldsize, usize);
|
|
|
++ arena_chunk_ralloc_huge_shrink(tsdn, arena, ptr, oldsize, usize,
|
|
|
++ extent_node_sn_get(node));
|
|
|
+
|
|
|
+ return (false);
|
|
|
+ }
|
|
|
+
|
|
|
+ static bool
|
|
|
+ huge_ralloc_no_move_expand(tsdn_t *tsdn, void *ptr, size_t oldsize,
|
|
|
+ size_t usize, bool zero) {
|
|
|
+ extent_node_t *node;
|
|
|
+@@ -402,17 +405,18 @@ huge_dalloc(tsdn_t *tsdn, void *ptr)
|
|
|
+ huge_node_unset(ptr, node);
|
|
|
+ malloc_mutex_lock(tsdn, &arena->huge_mtx);
|
|
|
+ ql_remove(&arena->huge, node, ql_link);
|
|
|
+ malloc_mutex_unlock(tsdn, &arena->huge_mtx);
|
|
|
+
|
|
|
+ huge_dalloc_junk(extent_node_addr_get(node),
|
|
|
+ extent_node_size_get(node));
|
|
|
+ arena_chunk_dalloc_huge(tsdn, extent_node_arena_get(node),
|
|
|
+- extent_node_addr_get(node), extent_node_size_get(node));
|
|
|
++ extent_node_addr_get(node), extent_node_size_get(node),
|
|
|
++ extent_node_sn_get(node));
|
|
|
+ idalloctm(tsdn, node, NULL, true, true);
|
|
|
+
|
|
|
+ arena_decay_tick(tsdn, arena);
|
|
|
+ }
|
|
|
+
|
|
|
+ arena_t *
|
|
|
+ huge_aalloc(const void *ptr)
|
|
|
+ {
|
|
|
+diff --git a/memory/jemalloc/src/src/jemalloc.c b/memory/jemalloc/src/src/jemalloc.c
|
|
|
+--- a/memory/jemalloc/src/src/jemalloc.c
|
|
|
++++ b/memory/jemalloc/src/src/jemalloc.c
|
|
|
+@@ -1051,51 +1051,62 @@ malloc_conf_init(void)
|
|
|
+ else { \
|
|
|
+ malloc_conf_error( \
|
|
|
+ "Invalid conf value", \
|
|
|
+ k, klen, v, vlen); \
|
|
|
+ } \
|
|
|
+ if (cont) \
|
|
|
+ continue; \
|
|
|
+ }
|
|
|
+-#define CONF_HANDLE_T_U(t, o, n, min, max, clip) \
|
|
|
++#define CONF_MIN_no(um, min) false
|
|
|
++#define CONF_MIN_yes(um, min) ((um) < (min))
|
|
|
++#define CONF_MAX_no(um, max) false
|
|
|
++#define CONF_MAX_yes(um, max) ((um) > (max))
|
|
|
++#define CONF_HANDLE_T_U(t, o, n, min, max, check_min, check_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)) \
|
|
|
++ if (CONF_MIN_##check_min(um, \
|
|
|
++ (min))) \
|
|
|
+ o = (t)(min); \
|
|
|
+- else if (um > (max)) \
|
|
|
++ else if (CONF_MAX_##check_max( \
|
|
|
++ um, (max))) \
|
|
|
+ o = (t)(max); \
|
|
|
+ else \
|
|
|
+ o = (t)um; \
|
|
|
+ } else { \
|
|
|
+- if (((min) != 0 && um < (min)) \
|
|
|
+- || um > (max)) { \
|
|
|
++ if (CONF_MIN_##check_min(um, \
|
|
|
++ (min)) || \
|
|
|
++ CONF_MAX_##check_max(um, \
|
|
|
++ (max))) { \
|
|
|
+ malloc_conf_error( \
|
|
|
+ "Out-of-range " \
|
|
|
+ "conf value", \
|
|
|
+ k, klen, v, vlen); \
|
|
|
+ } else \
|
|
|
+ o = (t)um; \
|
|
|
+ } \
|
|
|
+ continue; \
|
|
|
+ }
|
|
|
+-#define CONF_HANDLE_UNSIGNED(o, n, min, max, clip) \
|
|
|
+- CONF_HANDLE_T_U(unsigned, o, n, min, max, clip)
|
|
|
+-#define CONF_HANDLE_SIZE_T(o, n, min, max, clip) \
|
|
|
+- CONF_HANDLE_T_U(size_t, o, n, min, max, clip)
|
|
|
++#define CONF_HANDLE_UNSIGNED(o, n, min, max, check_min, check_max, \
|
|
|
++ clip) \
|
|
|
++ CONF_HANDLE_T_U(unsigned, o, n, min, max, \
|
|
|
++ check_min, check_max, clip)
|
|
|
++#define CONF_HANDLE_SIZE_T(o, n, min, max, check_min, check_max, clip) \
|
|
|
++ CONF_HANDLE_T_U(size_t, o, n, min, max, \
|
|
|
++ check_min, check_max, clip)
|
|
|
+ #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 -\
|
|
|
+@@ -1128,17 +1139,17 @@ malloc_conf_init(void)
|
|
|
+ * 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)
|
|
|
++ (sizeof(size_t) << 3) - 1, yes, yes, 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(
|
|
|
+@@ -1154,17 +1165,17 @@ malloc_conf_init(void)
|
|
|
+ }
|
|
|
+ if (!match) {
|
|
|
+ malloc_conf_error("Invalid conf value",
|
|
|
+ k, klen, v, vlen);
|
|
|
+ }
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ CONF_HANDLE_UNSIGNED(opt_narenas, "narenas", 1,
|
|
|
+- UINT_MAX, false)
|
|
|
++ UINT_MAX, yes, no, false)
|
|
|
+ if (strncmp("purge", k, klen) == 0) {
|
|
|
+ int i;
|
|
|
+ bool match = false;
|
|
|
+ for (i = 0; i < purge_mode_limit; i++) {
|
|
|
+ if (strncmp(purge_mode_names[i], v,
|
|
|
+ vlen) == 0) {
|
|
|
+ opt_purge = (purge_mode_t)i;
|
|
|
+ match = true;
|
|
|
+@@ -1225,17 +1236,17 @@ malloc_conf_init(void)
|
|
|
+ } else {
|
|
|
+ malloc_conf_error(
|
|
|
+ "Invalid conf value", k,
|
|
|
+ klen, v, vlen);
|
|
|
+ }
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ CONF_HANDLE_SIZE_T(opt_quarantine, "quarantine",
|
|
|
+- 0, SIZE_T_MAX, false)
|
|
|
++ 0, SIZE_T_MAX, no, no, 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)
|
|
|
+@@ -1262,34 +1273,41 @@ malloc_conf_init(void)
|
|
|
+ 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)
|
|
|
++ "lg_prof_sample", 0, (sizeof(uint64_t) << 3)
|
|
|
++ - 1, no, yes, 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_MATCH_VALUE
|
|
|
+ #undef CONF_HANDLE_BOOL
|
|
|
++#undef CONF_MIN_no
|
|
|
++#undef CONF_MIN_yes
|
|
|
++#undef CONF_MAX_no
|
|
|
++#undef CONF_MAX_yes
|
|
|
++#undef CONF_HANDLE_T_U
|
|
|
++#undef CONF_HANDLE_UNSIGNED
|
|
|
+ #undef CONF_HANDLE_SIZE_T
|
|
|
+ #undef CONF_HANDLE_SSIZE_T
|
|
|
+ #undef CONF_HANDLE_CHAR_P
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ static bool
|
|
|
+@@ -1388,18 +1406,19 @@ malloc_init_hard_a0(void)
|
|
|
+ static bool
|
|
|
+ malloc_init_hard_recursible(void)
|
|
|
+ {
|
|
|
+
|
|
|
+ malloc_init_state = malloc_init_recursible;
|
|
|
+
|
|
|
+ ncpus = malloc_ncpus();
|
|
|
+
|
|
|
+-#if (!defined(JEMALLOC_MUTEX_INIT_CB) && !defined(JEMALLOC_ZONE) \
|
|
|
+- && !defined(_WIN32) && !defined(__native_client__))
|
|
|
++#if (defined(JEMALLOC_HAVE_PTHREAD_ATFORK) && !defined(JEMALLOC_MUTEX_INIT_CB) \
|
|
|
++ && !defined(JEMALLOC_ZONE) && !defined(_WIN32) && \
|
|
|
++ !defined(__native_client__))
|
|
|
+ /* LinuxThreads' pthread_atfork() allocates. */
|
|
|
+ if (pthread_atfork(jemalloc_prefork, jemalloc_postfork_parent,
|
|
|
+ jemalloc_postfork_child) != 0) {
|
|
|
+ malloc_write("<jemalloc>: Error in pthread_atfork()\n");
|
|
|
+ if (opt_abort)
|
|
|
+ abort();
|
|
|
+ return (true);
|
|
|
+ }
|
|
|
+@@ -1968,18 +1987,18 @@ je_realloc(void *ptr, size_t size)
|
|
|
+ tsd_t *tsd;
|
|
|
+
|
|
|
+ assert(usize == isalloc(tsdn, ret, config_prof));
|
|
|
+ tsd = tsdn_tsd(tsdn);
|
|
|
+ *tsd_thread_allocatedp_get(tsd) += usize;
|
|
|
+ *tsd_thread_deallocatedp_get(tsd) += old_usize;
|
|
|
+ }
|
|
|
+ UTRACE(ptr, size, ret);
|
|
|
+- JEMALLOC_VALGRIND_REALLOC(true, tsdn, ret, usize, true, ptr, old_usize,
|
|
|
+- old_rzsize, true, false);
|
|
|
++ JEMALLOC_VALGRIND_REALLOC(maybe, tsdn, ret, usize, maybe, ptr,
|
|
|
++ old_usize, old_rzsize, maybe, false);
|
|
|
+ witness_assert_lockless(tsdn);
|
|
|
+ return (ret);
|
|
|
+ }
|
|
|
+
|
|
|
+ JEMALLOC_EXPORT void JEMALLOC_NOTHROW
|
|
|
+ je_free(void *ptr)
|
|
|
+ {
|
|
|
+
|
|
|
+@@ -2395,18 +2414,18 @@ je_rallocx(void *ptr, size_t size, int f
|
|
|
+ }
|
|
|
+ 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, tsd_tsdn(tsd), p, usize, false, ptr,
|
|
|
+- old_usize, old_rzsize, false, zero);
|
|
|
++ JEMALLOC_VALGRIND_REALLOC(maybe, tsd_tsdn(tsd), p, usize, no, ptr,
|
|
|
++ old_usize, old_rzsize, no, zero);
|
|
|
+ witness_assert_lockless(tsd_tsdn(tsd));
|
|
|
+ return (p);
|
|
|
+ label_oom:
|
|
|
+ if (config_xmalloc && unlikely(opt_xmalloc)) {
|
|
|
+ malloc_write("<jemalloc>: Error in rallocx(): out of memory\n");
|
|
|
+ abort();
|
|
|
+ }
|
|
|
+ UTRACE(ptr, size, 0);
|
|
|
+@@ -2538,18 +2557,18 @@ je_xallocx(void *ptr, size_t size, size_
|
|
|
+ }
|
|
|
+ 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, tsd_tsdn(tsd), ptr, usize, false, ptr,
|
|
|
+- old_usize, old_rzsize, false, zero);
|
|
|
++ JEMALLOC_VALGRIND_REALLOC(no, tsd_tsdn(tsd), ptr, usize, no, ptr,
|
|
|
++ old_usize, old_rzsize, no, zero);
|
|
|
+ label_not_resized:
|
|
|
+ UTRACE(ptr, size, ptr);
|
|
|
+ witness_assert_lockless(tsd_tsdn(tsd));
|
|
|
+ return (usize);
|
|
|
+ }
|
|
|
+
|
|
|
+ JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW
|
|
|
+ JEMALLOC_ATTR(pure)
|
|
|
+diff --git a/memory/jemalloc/src/src/pages.c b/memory/jemalloc/src/src/pages.c
|
|
|
+--- a/memory/jemalloc/src/src/pages.c
|
|
|
++++ b/memory/jemalloc/src/src/pages.c
|
|
|
+@@ -165,37 +165,66 @@ pages_decommit(void *addr, size_t size)
|
|
|
+ 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
|
|
|
++#elif (defined(JEMALLOC_PURGE_MADVISE_FREE) || \
|
|
|
++ defined(JEMALLOC_PURGE_MADVISE_DONTNEED))
|
|
|
++# if defined(JEMALLOC_PURGE_MADVISE_FREE)
|
|
|
++# define JEMALLOC_MADV_PURGE MADV_FREE
|
|
|
++# define JEMALLOC_MADV_ZEROS false
|
|
|
++# elif defined(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."
|
|
|
++# 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);
|
|
|
+ }
|
|
|
+
|
|
|
++bool
|
|
|
++pages_huge(void *addr, size_t size)
|
|
|
++{
|
|
|
++
|
|
|
++ assert(PAGE_ADDR2BASE(addr) == addr);
|
|
|
++ assert(PAGE_CEILING(size) == size);
|
|
|
++
|
|
|
++#ifdef JEMALLOC_THP
|
|
|
++ return (madvise(addr, size, MADV_HUGEPAGE) != 0);
|
|
|
++#else
|
|
|
++ return (false);
|
|
|
++#endif
|
|
|
++}
|
|
|
++
|
|
|
++bool
|
|
|
++pages_nohuge(void *addr, size_t size)
|
|
|
++{
|
|
|
++
|
|
|
++ assert(PAGE_ADDR2BASE(addr) == addr);
|
|
|
++ assert(PAGE_CEILING(size) == size);
|
|
|
++
|
|
|
++#ifdef JEMALLOC_THP
|
|
|
++ return (madvise(addr, size, MADV_NOHUGEPAGE) != 0);
|
|
|
++#else
|
|
|
++ return (false);
|
|
|
++#endif
|
|
|
++}
|
|
|
++
|
|
|
+ #ifdef JEMALLOC_SYSCTL_VM_OVERCOMMIT
|
|
|
+ static bool
|
|
|
+ os_overcommits_sysctl(void)
|
|
|
+ {
|
|
|
+ int vm_overcommit;
|
|
|
+ size_t sz;
|
|
|
+
|
|
|
+ sz = sizeof(vm_overcommit);
|
|
|
+@@ -214,31 +243,31 @@ os_overcommits_sysctl(void)
|
|
|
+ */
|
|
|
+ static bool
|
|
|
+ os_overcommits_proc(void)
|
|
|
+ {
|
|
|
+ int fd;
|
|
|
+ char buf[1];
|
|
|
+ ssize_t nread;
|
|
|
+
|
|
|
+-#if defined(JEMALLOC_HAVE_SYSCALL) && defined(SYS_open)
|
|
|
++#if defined(JEMALLOC_USE_SYSCALL) && defined(SYS_open)
|
|
|
+ fd = (int)syscall(SYS_open, "/proc/sys/vm/overcommit_memory", O_RDONLY);
|
|
|
+ #else
|
|
|
+ fd = open("/proc/sys/vm/overcommit_memory", O_RDONLY);
|
|
|
+ #endif
|
|
|
+ if (fd == -1)
|
|
|
+ return (false); /* Error. */
|
|
|
+
|
|
|
+-#if defined(JEMALLOC_HAVE_SYSCALL) && defined(SYS_read)
|
|
|
++#if defined(JEMALLOC_USE_SYSCALL) && defined(SYS_read)
|
|
|
+ nread = (ssize_t)syscall(SYS_read, fd, &buf, sizeof(buf));
|
|
|
+ #else
|
|
|
+ nread = read(fd, &buf, sizeof(buf));
|
|
|
+ #endif
|
|
|
+
|
|
|
+-#if defined(JEMALLOC_HAVE_SYSCALL) && defined(SYS_close)
|
|
|
++#if defined(JEMALLOC_USE_SYSCALL) && defined(SYS_close)
|
|
|
+ syscall(SYS_close, fd);
|
|
|
+ #else
|
|
|
+ close(fd);
|
|
|
+ #endif
|
|
|
+
|
|
|
+ if (nread < 1)
|
|
|
+ return (false); /* Error. */
|
|
|
+ /*
|
|
|
+diff --git a/memory/jemalloc/src/src/stats.c b/memory/jemalloc/src/src/stats.c
|
|
|
+--- a/memory/jemalloc/src/src/stats.c
|
|
|
++++ b/memory/jemalloc/src/src/stats.c
|
|
|
+@@ -1,33 +1,33 @@
|
|
|
+ #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); \
|
|
|
++ xmallctl(n, (void *)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); \
|
|
|
++ xmallctlbymib(mib, miblen, (void *)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); \
|
|
|
++ xmallctlbymib(mib, miblen, (void *)v, &sz, NULL, 0); \
|
|
|
+ } while (0)
|
|
|
+
|
|
|
+ /******************************************************************************/
|
|
|
+ /* Data. */
|
|
|
+
|
|
|
+ bool opt_stats_print = false;
|
|
|
+
|
|
|
+ size_t stats_cactive = 0;
|
|
|
+@@ -642,17 +642,17 @@ stats_general_print(void (*write_cb)(voi
|
|
|
+ } else { \
|
|
|
+ malloc_cprintf(write_cb, cbopaque, \
|
|
|
+ " opt."#n": %s\n", bv ? "true" : "false"); \
|
|
|
+ } \
|
|
|
+ }
|
|
|
+ #define OPT_WRITE_BOOL_MUTABLE(n, m, c) { \
|
|
|
+ bool bv2; \
|
|
|
+ if (je_mallctl("opt."#n, (void *)&bv, &bsz, NULL, 0) == 0 && \
|
|
|
+- je_mallctl(#m, &bv2, &bsz, NULL, 0) == 0) { \
|
|
|
++ je_mallctl(#m, &bv2, (void *)&bsz, NULL, 0) == 0) { \
|
|
|
+ if (json) { \
|
|
|
+ malloc_cprintf(write_cb, cbopaque, \
|
|
|
+ "\t\t\t\""#n"\": %s%s\n", bv ? "true" : \
|
|
|
+ "false", (c)); \
|
|
|
+ } else { \
|
|
|
+ malloc_cprintf(write_cb, cbopaque, \
|
|
|
+ " opt."#n": %s ("#m": %s)\n", bv ? "true" \
|
|
|
+ : "false", bv2 ? "true" : "false"); \
|
|
|
+@@ -687,17 +687,17 @@ stats_general_print(void (*write_cb)(voi
|
|
|
+ } else { \
|
|
|
+ malloc_cprintf(write_cb, cbopaque, \
|
|
|
+ " opt."#n": %zd\n", ssv); \
|
|
|
+ } \
|
|
|
+ }
|
|
|
+ #define OPT_WRITE_SSIZE_T_MUTABLE(n, m, c) { \
|
|
|
+ ssize_t ssv2; \
|
|
|
+ if (je_mallctl("opt."#n, (void *)&ssv, &sssz, NULL, 0) == 0 && \
|
|
|
+- je_mallctl(#m, &ssv2, &sssz, NULL, 0) == 0) { \
|
|
|
++ je_mallctl(#m, (void *)&ssv2, &sssz, NULL, 0) == 0) { \
|
|
|
+ if (json) { \
|
|
|
+ malloc_cprintf(write_cb, cbopaque, \
|
|
|
+ "\t\t\t\""#n"\": %zd%s\n", ssv, (c)); \
|
|
|
+ } else { \
|
|
|
+ malloc_cprintf(write_cb, cbopaque, \
|
|
|
+ " opt."#n": %zd ("#m": %zd)\n", \
|
|
|
+ ssv, ssv2); \
|
|
|
+ } \
|
|
|
+@@ -1079,17 +1079,18 @@ stats_print(void (*write_cb)(void *, con
|
|
|
+ * 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));
|
|
|
++ err = je_mallctl("epoch", (void *)&epoch, &u64sz, (void *)&epoch,
|
|
|
++ sizeof(uint64_t));
|
|
|
+ if (err != 0) {
|
|
|
+ if (err == EAGAIN) {
|
|
|
+ malloc_write("<jemalloc>: Memory allocation failure in "
|
|
|
+ "mallctl(\"epoch\", ...)\n");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ malloc_write("<jemalloc>: Failure in mallctl(\"epoch\", "
|
|
|
+ "...)\n");
|
|
|
+diff --git a/memory/jemalloc/src/src/tcache.c b/memory/jemalloc/src/src/tcache.c
|
|
|
+--- a/memory/jemalloc/src/src/tcache.c
|
|
|
++++ b/memory/jemalloc/src/src/tcache.c
|
|
|
+@@ -512,22 +512,22 @@ bool
|
|
|
+ tcache_boot(tsdn_t *tsdn)
|
|
|
+ {
|
|
|
+ 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)
|
|
|
++ if (opt_lg_tcache_max < 0 || (ZU(1) << opt_lg_tcache_max) < SMALL_MAXCLASS)
|
|
|
+ tcache_maxclass = SMALL_MAXCLASS;
|
|
|
+- else if ((1U << opt_lg_tcache_max) > large_maxclass)
|
|
|
++ else if ((ZU(1) << opt_lg_tcache_max) > large_maxclass)
|
|
|
+ tcache_maxclass = large_maxclass;
|
|
|
+ else
|
|
|
+- tcache_maxclass = (1U << opt_lg_tcache_max);
|
|
|
++ tcache_maxclass = (ZU(1) << opt_lg_tcache_max);
|
|
|
+
|
|
|
+ nhbins = size2index(tcache_maxclass) + 1;
|
|
|
+
|
|
|
+ /* Initialize tcache_bin_info. */
|
|
|
+ tcache_bin_info = (tcache_bin_info_t *)base_alloc(tsdn, nhbins *
|
|
|
+ sizeof(tcache_bin_info_t));
|
|
|
+ if (tcache_bin_info == NULL)
|
|
|
+ return (true);
|
|
|
+diff --git a/memory/jemalloc/src/src/util.c b/memory/jemalloc/src/src/util.c
|
|
|
+--- a/memory/jemalloc/src/src/util.c
|
|
|
++++ b/memory/jemalloc/src/src/util.c
|
|
|
+@@ -44,17 +44,17 @@ static char *x2s(uintmax_t x, bool alt_f
|
|
|
+
|
|
|
+ /******************************************************************************/
|
|
|
+
|
|
|
+ /* malloc_message() setup. */
|
|
|
+ static void
|
|
|
+ wrtmessage(void *cbopaque, const char *s)
|
|
|
+ {
|
|
|
+
|
|
|
+-#if defined(JEMALLOC_HAVE_SYSCALL) && defined(SYS_write)
|
|
|
++#if defined(JEMALLOC_USE_SYSCALL) && defined(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.
|
|
|
+ *
|
|
|
+ * syscall() returns long or int, depending on platform, so capture the
|
|
|
+ * unused result in the widest plausible type to avoid compiler
|
|
|
+ * warnings.
|
|
|
+@@ -195,17 +195,17 @@ malloc_strtoumax(const char *restrict np
|
|
|
+ /* Overflow. */
|
|
|
+ set_errno(ERANGE);
|
|
|
+ ret = UINTMAX_MAX;
|
|
|
+ goto label_return;
|
|
|
+ }
|
|
|
+ p++;
|
|
|
+ }
|
|
|
+ if (neg)
|
|
|
+- ret = -ret;
|
|
|
++ ret = (uintmax_t)(-((intmax_t)ret));
|
|
|
+
|
|
|
+ if (p == ns) {
|
|
|
+ /* No conversion performed. */
|
|
|
+ set_errno(EINVAL);
|
|
|
+ ret = UINTMAX_MAX;
|
|
|
+ goto label_return;
|
|
|
+ }
|
|
|
+
|
|
|
+diff --git a/memory/jemalloc/src/test/integration/MALLOCX_ARENA.c b/memory/jemalloc/src/test/integration/MALLOCX_ARENA.c
|
|
|
+--- a/memory/jemalloc/src/test/integration/MALLOCX_ARENA.c
|
|
|
++++ b/memory/jemalloc/src/test/integration/MALLOCX_ARENA.c
|
|
|
+@@ -14,18 +14,18 @@ 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");
|
|
|
++ assert_d_eq(mallctl("arenas.extend", (void *)&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];
|
|
|
+diff --git a/memory/jemalloc/src/test/integration/allocated.c b/memory/jemalloc/src/test/integration/allocated.c
|
|
|
+--- a/memory/jemalloc/src/test/integration/allocated.c
|
|
|
++++ b/memory/jemalloc/src/test/integration/allocated.c
|
|
|
+@@ -13,75 +13,76 @@ 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 = mallctl("thread.allocated", (void *)&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 = mallctl("thread.allocatedp", (void *)&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 = mallctl("thread.deallocated", (void *)&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 = mallctl("thread.deallocatedp", (void *)&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);
|
|
|
++ mallctl("thread.allocated", (void *)&a1, &sz, NULL, 0);
|
|
|
+ sz = sizeof(ap1);
|
|
|
+- mallctl("thread.allocatedp", &ap1, &sz, NULL, 0);
|
|
|
++ mallctl("thread.allocatedp", (void *)&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);
|
|
|
++ mallctl("thread.deallocated", (void *)&d1, &sz, NULL, 0);
|
|
|
+ sz = sizeof(dp1);
|
|
|
+- mallctl("thread.deallocatedp", &dp1, &sz, NULL, 0);
|
|
|
++ mallctl("thread.deallocatedp", (void *)&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 "
|
|
|
+diff --git a/memory/jemalloc/src/test/integration/chunk.c b/memory/jemalloc/src/test/integration/chunk.c
|
|
|
+--- a/memory/jemalloc/src/test/integration/chunk.c
|
|
|
++++ b/memory/jemalloc/src/test/integration/chunk.c
|
|
|
+@@ -132,55 +132,56 @@ TEST_BEGIN(test_chunk)
|
|
|
+ chunk_decommit,
|
|
|
+ chunk_purge,
|
|
|
+ chunk_split,
|
|
|
+ chunk_merge
|
|
|
+ };
|
|
|
+ bool xallocx_success_a, xallocx_success_b, xallocx_success_c;
|
|
|
+
|
|
|
+ sz = sizeof(unsigned);
|
|
|
+- assert_d_eq(mallctl("arenas.extend", &arena_ind, &sz, NULL, 0), 0,
|
|
|
+- "Unexpected mallctl() failure");
|
|
|
++ assert_d_eq(mallctl("arenas.extend", (void *)&arena_ind, &sz, NULL, 0),
|
|
|
++ 0, "Unexpected mallctl() failure");
|
|
|
+ flags = MALLOCX_ARENA(arena_ind) | MALLOCX_TCACHE_NONE;
|
|
|
+
|
|
|
+ /* Install custom chunk hooks. */
|
|
|
+ hooks_miblen = sizeof(hooks_mib)/sizeof(size_t);
|
|
|
+ assert_d_eq(mallctlnametomib("arena.0.chunk_hooks", hooks_mib,
|
|
|
+ &hooks_miblen), 0, "Unexpected mallctlnametomib() failure");
|
|
|
+ hooks_mib[1] = (size_t)arena_ind;
|
|
|
+ old_size = sizeof(chunk_hooks_t);
|
|
|
+ new_size = sizeof(chunk_hooks_t);
|
|
|
+- assert_d_eq(mallctlbymib(hooks_mib, hooks_miblen, &old_hooks, &old_size,
|
|
|
+- &new_hooks, new_size), 0, "Unexpected chunk_hooks error");
|
|
|
++ assert_d_eq(mallctlbymib(hooks_mib, hooks_miblen, (void *)&old_hooks,
|
|
|
++ &old_size, (void *)&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");
|
|
|
++ assert_d_eq(mallctl("arenas.lrun.0.size", (void *)&large0, &sz, NULL,
|
|
|
++ 0), 0, "Unexpected arenas.lrun.0.size failure");
|
|
|
++ assert_d_eq(mallctl("arenas.lrun.1.size", (void *)&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");
|
|
|
++ assert_d_eq(mallctl("arenas.hchunk.0.size", (void *)&huge0, &sz, NULL,
|
|
|
++ 0), 0, "Unexpected arenas.hchunk.0.size failure");
|
|
|
++ assert_d_eq(mallctl("arenas.hchunk.1.size", (void *)&huge1, &sz, NULL,
|
|
|
++ 0), 0, "Unexpected arenas.hchunk.1.size failure");
|
|
|
++ assert_d_eq(mallctl("arenas.hchunk.2.size", (void *)&huge2, &sz, NULL,
|
|
|
++ 0), 0, "Unexpected arenas.hchunk.2.size failure");
|
|
|
+
|
|
|
+ /* Test dalloc/decommit/purge cascade. */
|
|
|
+ purge_miblen = sizeof(purge_mib)/sizeof(size_t);
|
|
|
+ assert_d_eq(mallctlnametomib("arena.0.purge", purge_mib, &purge_miblen),
|
|
|
+ 0, "Unexpected mallctlnametomib() failure");
|
|
|
+ purge_mib[1] = (size_t)arena_ind;
|
|
|
+ do_dalloc = false;
|
|
|
+ do_decommit = false;
|
|
|
+@@ -260,19 +261,19 @@ TEST_BEGIN(test_chunk)
|
|
|
+
|
|
|
+ /* Make sure non-huge allocation succeeds. */
|
|
|
+ p = mallocx(42, flags);
|
|
|
+ assert_ptr_not_null(p, "Unexpected mallocx() error");
|
|
|
+ dallocx(p, flags);
|
|
|
+
|
|
|
+ /* Restore chunk hooks. */
|
|
|
+ assert_d_eq(mallctlbymib(hooks_mib, hooks_miblen, NULL, NULL,
|
|
|
+- &old_hooks, new_size), 0, "Unexpected chunk_hooks error");
|
|
|
+- assert_d_eq(mallctlbymib(hooks_mib, hooks_miblen, &old_hooks, &old_size,
|
|
|
+- NULL, 0), 0, "Unexpected chunk_hooks error");
|
|
|
++ (void *)&old_hooks, new_size), 0, "Unexpected chunk_hooks error");
|
|
|
++ assert_d_eq(mallctlbymib(hooks_mib, hooks_miblen, (void *)&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");
|
|
|
+diff --git a/memory/jemalloc/src/test/integration/mallocx.c b/memory/jemalloc/src/test/integration/mallocx.c
|
|
|
+--- a/memory/jemalloc/src/test/integration/mallocx.c
|
|
|
++++ b/memory/jemalloc/src/test/integration/mallocx.c
|
|
|
+@@ -6,17 +6,17 @@ const char *malloc_conf = "junk:false";
|
|
|
+
|
|
|
+ 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,
|
|
|
++ assert_d_eq(mallctl(cmd, (void *)&ret, &z, NULL, 0), 0,
|
|
|
+ "Unexpected mallctl(\"%s\", ...) failure", cmd);
|
|
|
+
|
|
|
+ return (ret);
|
|
|
+ }
|
|
|
+
|
|
|
+ static unsigned
|
|
|
+ get_nhuge(void)
|
|
|
+ {
|
|
|
+@@ -32,17 +32,17 @@ get_size_impl(const char *cmd, size_t in
|
|
|
+ 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),
|
|
|
++ assert_d_eq(mallctlbymib(mib, miblen, (void *)&ret, &z, NULL, 0),
|
|
|
+ 0, "Unexpected mallctlbymib([\"%s\", %zu], ...) failure", cmd, ind);
|
|
|
+
|
|
|
+ return (ret);
|
|
|
+ }
|
|
|
+
|
|
|
+ static size_t
|
|
|
+ get_huge_size(size_t ind)
|
|
|
+ {
|
|
|
+diff --git a/memory/jemalloc/src/test/integration/overflow.c b/memory/jemalloc/src/test/integration/overflow.c
|
|
|
+--- a/memory/jemalloc/src/test/integration/overflow.c
|
|
|
++++ b/memory/jemalloc/src/test/integration/overflow.c
|
|
|
+@@ -3,27 +3,27 @@
|
|
|
+ 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");
|
|
|
++ assert_d_eq(mallctl("arenas.nhchunks", (void *)&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_d_eq(mallctlbymib(mib, miblen, (void *)&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");
|
|
|
+diff --git a/memory/jemalloc/src/test/integration/rallocx.c b/memory/jemalloc/src/test/integration/rallocx.c
|
|
|
+--- a/memory/jemalloc/src/test/integration/rallocx.c
|
|
|
++++ b/memory/jemalloc/src/test/integration/rallocx.c
|
|
|
+@@ -2,17 +2,17 @@
|
|
|
+
|
|
|
+ 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,
|
|
|
++ assert_d_eq(mallctl(cmd, (void *)&ret, &z, NULL, 0), 0,
|
|
|
+ "Unexpected mallctl(\"%s\", ...) failure", cmd);
|
|
|
+
|
|
|
+ return (ret);
|
|
|
+ }
|
|
|
+
|
|
|
+ static unsigned
|
|
|
+ get_nhuge(void)
|
|
|
+ {
|
|
|
+@@ -28,17 +28,17 @@ get_size_impl(const char *cmd, size_t in
|
|
|
+ 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),
|
|
|
++ assert_d_eq(mallctlbymib(mib, miblen, (void *)&ret, &z, NULL, 0),
|
|
|
+ 0, "Unexpected mallctlbymib([\"%s\", %zu], ...) failure", cmd, ind);
|
|
|
+
|
|
|
+ return (ret);
|
|
|
+ }
|
|
|
+
|
|
|
+ static size_t
|
|
|
+ get_huge_size(size_t ind)
|
|
|
+ {
|
|
|
+diff --git a/memory/jemalloc/src/test/integration/sdallocx.c b/memory/jemalloc/src/test/integration/sdallocx.c
|
|
|
+--- a/memory/jemalloc/src/test/integration/sdallocx.c
|
|
|
++++ b/memory/jemalloc/src/test/integration/sdallocx.c
|
|
|
+@@ -1,12 +1,12 @@
|
|
|
+ #include "test/jemalloc_test.h"
|
|
|
+
|
|
|
+-#define MAXALIGN (((size_t)1) << 25)
|
|
|
+-#define NITER 4
|
|
|
++#define MAXALIGN (((size_t)1) << 22)
|
|
|
++#define NITER 3
|
|
|
+
|
|
|
+ TEST_BEGIN(test_basic)
|
|
|
+ {
|
|
|
+ void *ptr = mallocx(64, 0);
|
|
|
+ sdallocx(ptr, 64, 0);
|
|
|
+ }
|
|
|
+ TEST_END
|
|
|
+
|
|
|
+diff --git a/memory/jemalloc/src/test/integration/thread_arena.c b/memory/jemalloc/src/test/integration/thread_arena.c
|
|
|
+--- a/memory/jemalloc/src/test/integration/thread_arena.c
|
|
|
++++ b/memory/jemalloc/src/test/integration/thread_arena.c
|
|
|
+@@ -11,26 +11,27 @@ thd_start(void *arg)
|
|
|
+ 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)))) {
|
|
|
++ if ((err = mallctl("thread.arena", (void *)&arena_ind, &size,
|
|
|
++ (void *)&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))) {
|
|
|
++ if ((err = mallctl("thread.arena", (void *)&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");
|
|
|
+
|
|
|
+@@ -45,17 +46,18 @@ TEST_BEGIN(test_thread_arena)
|
|
|
+ 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))) {
|
|
|
++ if ((err = mallctl("thread.arena", (void *)&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,
|
|
|
+diff --git a/memory/jemalloc/src/test/integration/thread_tcache_enabled.c b/memory/jemalloc/src/test/integration/thread_tcache_enabled.c
|
|
|
+--- a/memory/jemalloc/src/test/integration/thread_tcache_enabled.c
|
|
|
++++ b/memory/jemalloc/src/test/integration/thread_tcache_enabled.c
|
|
|
+@@ -11,74 +11,75 @@ static const bool config_tcache =
|
|
|
+ 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 = mallctl("thread.tcache.enabled", (void *)&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_d_eq(mallctl("thread.tcache.enabled", (void *)&e0, &sz,
|
|
|
++ (void *)&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_d_eq(mallctl("thread.tcache.enabled", (void *)&e0, &sz,
|
|
|
++ (void *)&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_d_eq(mallctl("thread.tcache.enabled", (void *)&e0, &sz,
|
|
|
++ (void *)&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_d_eq(mallctl("thread.tcache.enabled", (void *)&e0, &sz,
|
|
|
++ (void *)&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_d_eq(mallctl("thread.tcache.enabled", (void *)&e0, &sz,
|
|
|
++ (void *)&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_d_eq(mallctl("thread.tcache.enabled", (void *)&e0, &sz,
|
|
|
++ (void *)&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_d_eq(mallctl("thread.tcache.enabled", (void *)&e0, &sz,
|
|
|
++ (void *)&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_d_eq(mallctl("thread.tcache.enabled", (void *)&e0, &sz,
|
|
|
++ (void *)&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_d_eq(mallctl("thread.tcache.enabled", (void *)&e0, &sz,
|
|
|
++ (void *)&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);
|
|
|
+ }
|
|
|
+diff --git a/memory/jemalloc/src/test/integration/xallocx.c b/memory/jemalloc/src/test/integration/xallocx.c
|
|
|
+--- a/memory/jemalloc/src/test/integration/xallocx.c
|
|
|
++++ b/memory/jemalloc/src/test/integration/xallocx.c
|
|
|
+@@ -11,18 +11,18 @@ const char *malloc_conf = "junk:false";
|
|
|
+ */
|
|
|
+ static unsigned
|
|
|
+ arena_ind(void)
|
|
|
+ {
|
|
|
+ static unsigned ind = 0;
|
|
|
+
|
|
|
+ if (ind == 0) {
|
|
|
+ size_t sz = sizeof(ind);
|
|
|
+- assert_d_eq(mallctl("arenas.extend", &ind, &sz, NULL, 0), 0,
|
|
|
+- "Unexpected mallctl failure creating arena");
|
|
|
++ assert_d_eq(mallctl("arenas.extend", (void *)&ind, &sz, NULL,
|
|
|
++ 0), 0, "Unexpected mallctl failure creating arena");
|
|
|
+ }
|
|
|
+
|
|
|
+ return (ind);
|
|
|
+ }
|
|
|
+
|
|
|
+ TEST_BEGIN(test_same_size)
|
|
|
+ {
|
|
|
+ void *p;
|
|
|
+@@ -73,17 +73,17 @@ 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,
|
|
|
++ assert_d_eq(mallctl(cmd, (void *)&ret, &z, NULL, 0), 0,
|
|
|
+ "Unexpected mallctl(\"%s\", ...) failure", cmd);
|
|
|
+
|
|
|
+ return (ret);
|
|
|
+ }
|
|
|
+
|
|
|
+ static unsigned
|
|
|
+ get_nsmall(void)
|
|
|
+ {
|
|
|
+@@ -113,17 +113,17 @@ get_size_impl(const char *cmd, size_t in
|
|
|
+ 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),
|
|
|
++ assert_d_eq(mallctlbymib(mib, miblen, (void *)&ret, &z, NULL, 0),
|
|
|
+ 0, "Unexpected mallctlbymib([\"%s\", %zu], ...) failure", cmd, ind);
|
|
|
+
|
|
|
+ return (ret);
|
|
|
+ }
|
|
|
+
|
|
|
+ static size_t
|
|
|
+ get_small_size(size_t ind)
|
|
|
+ {
|
|
|
+diff --git a/memory/jemalloc/src/test/unit/arena_reset.c b/memory/jemalloc/src/test/unit/arena_reset.c
|
|
|
+--- a/memory/jemalloc/src/test/unit/arena_reset.c
|
|
|
++++ b/memory/jemalloc/src/test/unit/arena_reset.c
|
|
|
+@@ -6,17 +6,17 @@ const char *malloc_conf = "prof:true,lg_
|
|
|
+
|
|
|
+ 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,
|
|
|
++ assert_d_eq(mallctl(cmd, (void *)&ret, &z, NULL, 0), 0,
|
|
|
+ "Unexpected mallctl(\"%s\", ...) failure", cmd);
|
|
|
+
|
|
|
+ return (ret);
|
|
|
+ }
|
|
|
+
|
|
|
+ static unsigned
|
|
|
+ get_nsmall(void)
|
|
|
+ {
|
|
|
+@@ -46,17 +46,17 @@ get_size_impl(const char *cmd, size_t in
|
|
|
+ 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),
|
|
|
++ assert_d_eq(mallctlbymib(mib, miblen, (void *)&ret, &z, NULL, 0),
|
|
|
+ 0, "Unexpected mallctlbymib([\"%s\", %zu], ...) failure", cmd, ind);
|
|
|
+
|
|
|
+ return (ret);
|
|
|
+ }
|
|
|
+
|
|
|
+ static size_t
|
|
|
+ get_small_size(size_t ind)
|
|
|
+ {
|
|
|
+@@ -87,18 +87,18 @@ TEST_BEGIN(test_arena_reset)
|
|
|
+ int flags;
|
|
|
+ size_t mib[3];
|
|
|
+ tsdn_t *tsdn;
|
|
|
+
|
|
|
+ test_skip_if((config_valgrind && unlikely(in_valgrind)) || (config_fill
|
|
|
+ && unlikely(opt_quarantine)));
|
|
|
+
|
|
|
+ sz = sizeof(unsigned);
|
|
|
+- assert_d_eq(mallctl("arenas.extend", &arena_ind, &sz, NULL, 0), 0,
|
|
|
+- "Unexpected mallctl() failure");
|
|
|
++ assert_d_eq(mallctl("arenas.extend", (void *)&arena_ind, &sz, NULL, 0),
|
|
|
++ 0, "Unexpected mallctl() failure");
|
|
|
+
|
|
|
+ flags = MALLOCX_ARENA(arena_ind) | MALLOCX_TCACHE_NONE;
|
|
|
+
|
|
|
+ nsmall = get_nsmall();
|
|
|
+ nlarge = get_nlarge();
|
|
|
+ nhuge = get_nhuge() > NHUGE ? NHUGE : get_nhuge();
|
|
|
+ nptrs = nsmall + nlarge + nhuge;
|
|
|
+ ptrs = (void **)malloc(nptrs * sizeof(void *));
|
|
|
+diff --git a/memory/jemalloc/src/test/unit/decay.c b/memory/jemalloc/src/test/unit/decay.c
|
|
|
+--- a/memory/jemalloc/src/test/unit/decay.c
|
|
|
++++ b/memory/jemalloc/src/test/unit/decay.c
|
|
|
+@@ -35,20 +35,20 @@ TEST_BEGIN(test_decay_ticks)
|
|
|
+
|
|
|
+ test_skip_if(opt_purge != purge_mode_decay);
|
|
|
+
|
|
|
+ decay_ticker = decay_ticker_get(tsd_fetch(), 0);
|
|
|
+ assert_ptr_not_null(decay_ticker,
|
|
|
+ "Unexpected failure getting decay ticker");
|
|
|
+
|
|
|
+ sz = sizeof(size_t);
|
|
|
+- assert_d_eq(mallctl("arenas.hchunk.0.size", &huge0, &sz, NULL, 0), 0,
|
|
|
+- "Unexpected mallctl failure");
|
|
|
+- assert_d_eq(mallctl("arenas.lrun.0.size", &large0, &sz, NULL, 0), 0,
|
|
|
+- "Unexpected mallctl failure");
|
|
|
++ assert_d_eq(mallctl("arenas.hchunk.0.size", (void *)&huge0, &sz, NULL,
|
|
|
++ 0), 0, "Unexpected mallctl failure");
|
|
|
++ assert_d_eq(mallctl("arenas.lrun.0.size", (void *)&large0, &sz, NULL,
|
|
|
++ 0), 0, "Unexpected mallctl failure");
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Test the standard APIs using a huge size class, since we can't
|
|
|
+ * control tcache interactions (except by completely disabling tcache
|
|
|
+ * for the entire test program).
|
|
|
+ */
|
|
|
+
|
|
|
+ /* malloc(). */
|
|
|
+@@ -170,35 +170,35 @@ TEST_BEGIN(test_decay_ticks)
|
|
|
+ */
|
|
|
+ if (config_tcache) {
|
|
|
+ unsigned tcache_ind, i;
|
|
|
+ size_t tcache_sizes[2];
|
|
|
+ tcache_sizes[0] = large0;
|
|
|
+ tcache_sizes[1] = 1;
|
|
|
+
|
|
|
+ sz = sizeof(unsigned);
|
|
|
+- assert_d_eq(mallctl("tcache.create", &tcache_ind, &sz, NULL, 0),
|
|
|
+- 0, "Unexpected mallctl failure");
|
|
|
++ assert_d_eq(mallctl("tcache.create", (void *)&tcache_ind, &sz,
|
|
|
++ NULL, 0), 0, "Unexpected mallctl failure");
|
|
|
+
|
|
|
+ for (i = 0; i < sizeof(tcache_sizes) / sizeof(size_t); i++) {
|
|
|
+ sz = tcache_sizes[i];
|
|
|
+
|
|
|
+ /* tcache fill. */
|
|
|
+ tick0 = ticker_read(decay_ticker);
|
|
|
+ p = mallocx(sz, MALLOCX_TCACHE(tcache_ind));
|
|
|
+ assert_ptr_not_null(p, "Unexpected mallocx() failure");
|
|
|
+ tick1 = ticker_read(decay_ticker);
|
|
|
+ assert_u32_ne(tick1, tick0,
|
|
|
+ "Expected ticker to tick during tcache fill "
|
|
|
+ "(sz=%zu)", sz);
|
|
|
+ /* tcache flush. */
|
|
|
+ dallocx(p, MALLOCX_TCACHE(tcache_ind));
|
|
|
+ tick0 = ticker_read(decay_ticker);
|
|
|
+ assert_d_eq(mallctl("tcache.flush", NULL, NULL,
|
|
|
+- &tcache_ind, sizeof(unsigned)), 0,
|
|
|
++ (void *)&tcache_ind, sizeof(unsigned)), 0,
|
|
|
+ "Unexpected mallctl failure");
|
|
|
+ tick1 = ticker_read(decay_ticker);
|
|
|
+ assert_u32_ne(tick1, tick0,
|
|
|
+ "Expected ticker to tick during tcache flush "
|
|
|
+ "(sz=%zu)", sz);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+@@ -223,32 +223,32 @@ TEST_BEGIN(test_decay_ticker)
|
|
|
+ * objects, restore the clock, then [md]allocx() in a tight loop to
|
|
|
+ * verify the ticker triggers purging.
|
|
|
+ */
|
|
|
+
|
|
|
+ if (config_tcache) {
|
|
|
+ size_t tcache_max;
|
|
|
+
|
|
|
+ sz = sizeof(size_t);
|
|
|
+- assert_d_eq(mallctl("arenas.tcache_max", &tcache_max, &sz, NULL,
|
|
|
+- 0), 0, "Unexpected mallctl failure");
|
|
|
++ assert_d_eq(mallctl("arenas.tcache_max", (void *)&tcache_max,
|
|
|
++ &sz, NULL, 0), 0, "Unexpected mallctl failure");
|
|
|
+ large = nallocx(tcache_max + 1, flags);
|
|
|
+ } else {
|
|
|
+ sz = sizeof(size_t);
|
|
|
+- assert_d_eq(mallctl("arenas.lrun.0.size", &large, &sz, NULL, 0),
|
|
|
+- 0, "Unexpected mallctl failure");
|
|
|
++ assert_d_eq(mallctl("arenas.lrun.0.size", (void *)&large, &sz,
|
|
|
++ NULL, 0), 0, "Unexpected mallctl 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(uint64_t)), 0,
|
|
|
+- "Unexpected mallctl failure");
|
|
|
++ assert_d_eq(mallctl("epoch", NULL, NULL, (void *)&epoch,
|
|
|
++ sizeof(uint64_t)), 0, "Unexpected mallctl failure");
|
|
|
+ sz = sizeof(uint64_t);
|
|
|
+- assert_d_eq(mallctl("stats.arenas.0.npurge", &npurge0, &sz, NULL, 0),
|
|
|
+- config_stats ? 0 : ENOENT, "Unexpected mallctl result");
|
|
|
++ assert_d_eq(mallctl("stats.arenas.0.npurge", (void *)&npurge0, &sz,
|
|
|
++ NULL, 0), config_stats ? 0 : ENOENT, "Unexpected mallctl result");
|
|
|
+
|
|
|
+ for (i = 0; i < NPS; i++) {
|
|
|
+ ps[i] = mallocx(large, flags);
|
|
|
+ assert_ptr_not_null(ps[i], "Unexpected mallocx() failure");
|
|
|
+ }
|
|
|
+
|
|
|
+ nupdates_mock = 0;
|
|
|
+ nstime_init(&time_mock, 0);
|
|
|
+@@ -278,21 +278,21 @@ TEST_BEGIN(test_decay_ticker)
|
|
|
+ nstime_copy(&deadline, &time);
|
|
|
+ nstime_add(&deadline, &decay_time);
|
|
|
+ do {
|
|
|
+ for (i = 0; i < DECAY_NTICKS_PER_UPDATE / 2; i++) {
|
|
|
+ void *p = mallocx(1, flags);
|
|
|
+ assert_ptr_not_null(p, "Unexpected mallocx() failure");
|
|
|
+ dallocx(p, flags);
|
|
|
+ }
|
|
|
+- assert_d_eq(mallctl("epoch", NULL, NULL, &epoch,
|
|
|
++ assert_d_eq(mallctl("epoch", NULL, NULL, (void *)&epoch,
|
|
|
+ sizeof(uint64_t)), 0, "Unexpected mallctl failure");
|
|
|
+ sz = sizeof(uint64_t);
|
|
|
+- assert_d_eq(mallctl("stats.arenas.0.npurge", &npurge1, &sz,
|
|
|
+- NULL, 0), config_stats ? 0 : ENOENT,
|
|
|
++ assert_d_eq(mallctl("stats.arenas.0.npurge", (void *)&npurge1,
|
|
|
++ &sz, NULL, 0), config_stats ? 0 : ENOENT,
|
|
|
+ "Unexpected mallctl result");
|
|
|
+
|
|
|
+ nstime_update(&time);
|
|
|
+ } while (nstime_compare(&time, &deadline) <= 0 && npurge1 == npurge0);
|
|
|
+
|
|
|
+ if (config_stats)
|
|
|
+ assert_u64_gt(npurge1, npurge0, "Expected purging to occur");
|
|
|
+ #undef NPS
|
|
|
+@@ -308,26 +308,26 @@ TEST_BEGIN(test_decay_nonmonotonic)
|
|
|
+ uint64_t npurge0 = 0;
|
|
|
+ uint64_t npurge1 = 0;
|
|
|
+ size_t sz, large0;
|
|
|
+ unsigned i, nupdates0;
|
|
|
+
|
|
|
+ test_skip_if(opt_purge != purge_mode_decay);
|
|
|
+
|
|
|
+ sz = sizeof(size_t);
|
|
|
+- assert_d_eq(mallctl("arenas.lrun.0.size", &large0, &sz, NULL, 0), 0,
|
|
|
+- "Unexpected mallctl failure");
|
|
|
++ assert_d_eq(mallctl("arenas.lrun.0.size", (void *)&large0, &sz, NULL,
|
|
|
++ 0), 0, "Unexpected mallctl 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(uint64_t)), 0,
|
|
|
+- "Unexpected mallctl failure");
|
|
|
++ assert_d_eq(mallctl("epoch", NULL, NULL, (void *)&epoch,
|
|
|
++ sizeof(uint64_t)), 0, "Unexpected mallctl failure");
|
|
|
+ sz = sizeof(uint64_t);
|
|
|
+- assert_d_eq(mallctl("stats.arenas.0.npurge", &npurge0, &sz, NULL, 0),
|
|
|
+- config_stats ? 0 : ENOENT, "Unexpected mallctl result");
|
|
|
++ assert_d_eq(mallctl("stats.arenas.0.npurge", (void *)&npurge0, &sz,
|
|
|
++ NULL, 0), config_stats ? 0 : ENOENT, "Unexpected mallctl result");
|
|
|
+
|
|
|
+ nupdates_mock = 0;
|
|
|
+ nstime_init(&time_mock, 0);
|
|
|
+ nstime_update(&time_mock);
|
|
|
+ monotonic_mock = false;
|
|
|
+
|
|
|
+ nstime_monotonic_orig = nstime_monotonic;
|
|
|
+ nstime_update_orig = nstime_update;
|
|
|
+@@ -343,21 +343,21 @@ TEST_BEGIN(test_decay_nonmonotonic)
|
|
|
+ dallocx(ps[i], flags);
|
|
|
+ nupdates0 = nupdates_mock;
|
|
|
+ assert_d_eq(mallctl("arena.0.decay", NULL, NULL, NULL, 0), 0,
|
|
|
+ "Unexpected arena.0.decay failure");
|
|
|
+ assert_u_gt(nupdates_mock, nupdates0,
|
|
|
+ "Expected nstime_update() to be called");
|
|
|
+ }
|
|
|
+
|
|
|
+- assert_d_eq(mallctl("epoch", NULL, NULL, &epoch, sizeof(uint64_t)), 0,
|
|
|
+- "Unexpected mallctl failure");
|
|
|
++ assert_d_eq(mallctl("epoch", NULL, NULL, (void *)&epoch,
|
|
|
++ sizeof(uint64_t)), 0, "Unexpected mallctl failure");
|
|
|
+ sz = sizeof(uint64_t);
|
|
|
+- assert_d_eq(mallctl("stats.arenas.0.npurge", &npurge1, &sz, NULL, 0),
|
|
|
+- config_stats ? 0 : ENOENT, "Unexpected mallctl result");
|
|
|
++ assert_d_eq(mallctl("stats.arenas.0.npurge", (void *)&npurge1, &sz,
|
|
|
++ NULL, 0), config_stats ? 0 : ENOENT, "Unexpected mallctl result");
|
|
|
+
|
|
|
+ if (config_stats)
|
|
|
+ assert_u64_eq(npurge0, npurge1, "Unexpected purging occurred");
|
|
|
+
|
|
|
+ nstime_monotonic = nstime_monotonic_orig;
|
|
|
+ nstime_update = nstime_update_orig;
|
|
|
+ #undef NPS
|
|
|
+ }
|
|
|
+diff --git a/memory/jemalloc/src/test/unit/mallctl.c b/memory/jemalloc/src/test/unit/mallctl.c
|
|
|
+--- a/memory/jemalloc/src/test/unit/mallctl.c
|
|
|
++++ b/memory/jemalloc/src/test/unit/mallctl.c
|
|
|
+@@ -7,26 +7,28 @@ TEST_BEGIN(test_mallctl_errors)
|
|
|
+
|
|
|
+ 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");
|
|
|
++ assert_d_eq(mallctl("epoch", NULL, NULL, (void *)&epoch,
|
|
|
++ sizeof(epoch)-1), EINVAL,
|
|
|
++ "mallctl() should return EINVAL for input size mismatch");
|
|
|
++ assert_d_eq(mallctl("epoch", NULL, NULL, (void *)&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,
|
|
|
++ assert_d_eq(mallctl("epoch", (void *)&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,
|
|
|
++ assert_d_eq(mallctl("epoch", (void *)&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;
|
|
|
+@@ -51,55 +53,58 @@ TEST_BEGIN(test_mallctlbymib_errors)
|
|
|
+ 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,
|
|
|
++ assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, (void *)&epoch,
|
|
|
+ sizeof(epoch)-1), EINVAL,
|
|
|
+ "mallctlbymib() should return EINVAL for input size mismatch");
|
|
|
+- assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, &epoch,
|
|
|
++ assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, (void *)&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,
|
|
|
++ assert_d_eq(mallctlbymib(mib, miblen, (void *)&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,
|
|
|
++ assert_d_eq(mallctlbymib(mib, miblen, (void *)&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,
|
|
|
++ assert_d_eq(mallctl("epoch", (void *)&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_d_eq(mallctl("epoch", NULL, NULL, (void *)&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_d_eq(mallctl("epoch", (void *)&old_epoch, &sz,
|
|
|
++ (void *)&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;
|
|
|
+@@ -115,18 +120,18 @@ TEST_BEGIN(test_mallctlnametomib_short_m
|
|
|
+ TEST_END
|
|
|
+
|
|
|
+ TEST_BEGIN(test_mallctl_config)
|
|
|
+ {
|
|
|
+
|
|
|
+ #define TEST_MALLCTL_CONFIG(config, t) do { \
|
|
|
+ t oldval; \
|
|
|
+ size_t sz = sizeof(oldval); \
|
|
|
+- assert_d_eq(mallctl("config."#config, &oldval, &sz, NULL, 0), \
|
|
|
+- 0, "Unexpected mallctl() failure"); \
|
|
|
++ assert_d_eq(mallctl("config."#config, (void *)&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, bool);
|
|
|
+ TEST_MALLCTL_CONFIG(debug, bool);
|
|
|
+ TEST_MALLCTL_CONFIG(fill, bool);
|
|
|
+ TEST_MALLCTL_CONFIG(lazy_lock, bool);
|
|
|
+@@ -149,17 +154,18 @@ 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); \
|
|
|
++ int result = mallctl("opt."#opt, (void *)&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);
|
|
|
+@@ -192,29 +198,29 @@ 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,
|
|
|
++ assert_d_eq(mallctl("arenas.nbins", (void *)&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");
|
|
|
++ assert_d_eq(mallctlbymib(mib, miblen, (void *)&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;
|
|
|
+@@ -253,35 +259,35 @@ TEST_BEGIN(test_tcache)
|
|
|
+ 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);
|
|
|
++ assert_d_eq(mallctl("tcache.create", (void *)&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);
|
|
|
++ assert_d_eq(mallctl("tcache.destroy", NULL, NULL,
|
|
|
++ (void *)&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);
|
|
|
++ assert_d_eq(mallctl("tcache.create", (void *)&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],
|
|
|
++ assert_d_eq(mallctl("tcache.flush", NULL, NULL, (void *)&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",
|
|
|
+@@ -316,107 +322,110 @@ TEST_BEGIN(test_tcache)
|
|
|
+ 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],
|
|
|
++ assert_d_eq(mallctl("tcache.flush", NULL, NULL, (void *)&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);
|
|
|
++ assert_d_eq(mallctl("tcache.destroy", NULL, NULL,
|
|
|
++ (void *)&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_d_eq(mallctl("arenas.narenas", (void *)&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");
|
|
|
++ assert_d_eq(mallctl("thread.arena", (void *)&arena_old, &sz,
|
|
|
++ (void *)&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");
|
|
|
++ assert_d_eq(mallctl("thread.arena", (void *)&arena_old, &sz,
|
|
|
++ (void *)&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);
|
|
|
+
|
|
|
+ test_skip_if(opt_purge != purge_mode_ratio);
|
|
|
+
|
|
|
+- assert_d_eq(mallctl("arena.0.lg_dirty_mult", &orig_lg_dirty_mult, &sz,
|
|
|
+- NULL, 0), 0, "Unexpected mallctl() failure");
|
|
|
++ assert_d_eq(mallctl("arena.0.lg_dirty_mult",
|
|
|
++ (void *)&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,
|
|
|
++ (void *)&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,
|
|
|
++ (void *)&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_d_eq(mallctl("arena.0.lg_dirty_mult",
|
|
|
++ (void *)&old_lg_dirty_mult, &sz, (void *)&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_decay_time)
|
|
|
+ {
|
|
|
+ ssize_t decay_time, orig_decay_time, prev_decay_time;
|
|
|
+ size_t sz = sizeof(ssize_t);
|
|
|
+
|
|
|
+ test_skip_if(opt_purge != purge_mode_decay);
|
|
|
+
|
|
|
+- assert_d_eq(mallctl("arena.0.decay_time", &orig_decay_time, &sz,
|
|
|
++ assert_d_eq(mallctl("arena.0.decay_time", (void *)&orig_decay_time, &sz,
|
|
|
+ NULL, 0), 0, "Unexpected mallctl() failure");
|
|
|
+
|
|
|
+ decay_time = -2;
|
|
|
+ assert_d_eq(mallctl("arena.0.decay_time", NULL, NULL,
|
|
|
+- &decay_time, sizeof(ssize_t)), EFAULT,
|
|
|
++ (void *)&decay_time, sizeof(ssize_t)), EFAULT,
|
|
|
+ "Unexpected mallctl() success");
|
|
|
+
|
|
|
+ decay_time = 0x7fffffff;
|
|
|
+ assert_d_eq(mallctl("arena.0.decay_time", NULL, NULL,
|
|
|
+- &decay_time, sizeof(ssize_t)), 0,
|
|
|
++ (void *)&decay_time, sizeof(ssize_t)), 0,
|
|
|
+ "Unexpected mallctl() failure");
|
|
|
+
|
|
|
+ for (prev_decay_time = decay_time, decay_time = -1;
|
|
|
+ decay_time < 20; prev_decay_time = decay_time, decay_time++) {
|
|
|
+ ssize_t old_decay_time;
|
|
|
+
|
|
|
+- assert_d_eq(mallctl("arena.0.decay_time", &old_decay_time,
|
|
|
+- &sz, &decay_time, sizeof(ssize_t)), 0,
|
|
|
++ assert_d_eq(mallctl("arena.0.decay_time", (void *)&old_decay_time,
|
|
|
++ &sz, (void *)&decay_time, sizeof(ssize_t)), 0,
|
|
|
+ "Unexpected mallctl() failure");
|
|
|
+ assert_zd_eq(old_decay_time, prev_decay_time,
|
|
|
+ "Unexpected old arena.0.decay_time");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ TEST_END
|
|
|
+
|
|
|
+ TEST_BEGIN(test_arena_i_purge)
|
|
|
+@@ -424,18 +433,18 @@ 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(mallctl("arenas.narenas", (void *)&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
|
|
|
+
|
|
|
+@@ -444,18 +453,18 @@ TEST_BEGIN(test_arena_i_decay)
|
|
|
+ unsigned narenas;
|
|
|
+ size_t sz = sizeof(unsigned);
|
|
|
+ size_t mib[3];
|
|
|
+ size_t miblen = 3;
|
|
|
+
|
|
|
+ assert_d_eq(mallctl("arena.0.decay", 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(mallctl("arenas.narenas", (void *)&narenas, &sz, NULL, 0),
|
|
|
++ 0, "Unexpected mallctl() failure");
|
|
|
+ assert_d_eq(mallctlnametomib("arena.0.decay", 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
|
|
|
+
|
|
|
+@@ -466,138 +475,142 @@ TEST_BEGIN(test_arena_i_dss)
|
|
|
+ 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_d_eq(mallctlbymib(mib, miblen, (void *)&dss_prec_old, &sz,
|
|
|
++ (void *)&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, (void *)&dss_prec_new, &sz,
|
|
|
++ (void *)&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_d_eq(mallctlbymib(mib, miblen, (void *)&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_d_eq(mallctlbymib(mib, miblen, (void *)&dss_prec_old, &sz,
|
|
|
++ (void *)&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, (void *)&dss_prec_new, &sz,
|
|
|
++ (void *)&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_d_eq(mallctlbymib(mib, miblen, (void *)&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");
|
|
|
++ assert_d_eq(mallctl("arenas.narenas", (void *)&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");
|
|
|
++ assert_d_eq(mallctl("arenas.initialized", (void *)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);
|
|
|
+
|
|
|
+ test_skip_if(opt_purge != purge_mode_ratio);
|
|
|
+
|
|
|
+- assert_d_eq(mallctl("arenas.lg_dirty_mult", &orig_lg_dirty_mult, &sz,
|
|
|
+- NULL, 0), 0, "Unexpected mallctl() failure");
|
|
|
++ assert_d_eq(mallctl("arenas.lg_dirty_mult", (void *)&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,
|
|
|
++ (void *)&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,
|
|
|
++ (void *)&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_d_eq(mallctl("arenas.lg_dirty_mult",
|
|
|
++ (void *)&old_lg_dirty_mult, &sz, (void *)&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_decay_time)
|
|
|
+ {
|
|
|
+ ssize_t decay_time, orig_decay_time, prev_decay_time;
|
|
|
+ size_t sz = sizeof(ssize_t);
|
|
|
+
|
|
|
+ test_skip_if(opt_purge != purge_mode_decay);
|
|
|
+
|
|
|
+- assert_d_eq(mallctl("arenas.decay_time", &orig_decay_time, &sz,
|
|
|
++ assert_d_eq(mallctl("arenas.decay_time", (void *)&orig_decay_time, &sz,
|
|
|
+ NULL, 0), 0, "Unexpected mallctl() failure");
|
|
|
+
|
|
|
+ decay_time = -2;
|
|
|
+ assert_d_eq(mallctl("arenas.decay_time", NULL, NULL,
|
|
|
+- &decay_time, sizeof(ssize_t)), EFAULT,
|
|
|
++ (void *)&decay_time, sizeof(ssize_t)), EFAULT,
|
|
|
+ "Unexpected mallctl() success");
|
|
|
+
|
|
|
+ decay_time = 0x7fffffff;
|
|
|
+ assert_d_eq(mallctl("arenas.decay_time", NULL, NULL,
|
|
|
+- &decay_time, sizeof(ssize_t)), 0,
|
|
|
++ (void *)&decay_time, sizeof(ssize_t)), 0,
|
|
|
+ "Expected mallctl() failure");
|
|
|
+
|
|
|
+ for (prev_decay_time = decay_time, decay_time = -1;
|
|
|
+ decay_time < 20; prev_decay_time = decay_time, decay_time++) {
|
|
|
+ ssize_t old_decay_time;
|
|
|
+
|
|
|
+- assert_d_eq(mallctl("arenas.decay_time", &old_decay_time,
|
|
|
+- &sz, &decay_time, sizeof(ssize_t)), 0,
|
|
|
+- "Unexpected mallctl() failure");
|
|
|
++ assert_d_eq(mallctl("arenas.decay_time",
|
|
|
++ (void *)&old_decay_time, &sz, (void *)&decay_time,
|
|
|
++ sizeof(ssize_t)), 0, "Unexpected mallctl() failure");
|
|
|
+ assert_zd_eq(old_decay_time, prev_decay_time,
|
|
|
+ "Unexpected old arenas.decay_time");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ 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_d_eq(mallctl("arenas."#name, (void *)&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);
|
|
|
+@@ -607,18 +620,18 @@ TEST_BEGIN(test_arenas_constants)
|
|
|
+ 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_d_eq(mallctl("arenas.bin.0."#name, (void *)&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
|
|
|
+@@ -626,70 +639,70 @@ TEST_BEGIN(test_arenas_bin_constants)
|
|
|
+ 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_d_eq(mallctl("arenas.lrun.0."#name, (void *)&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_d_eq(mallctl("arenas.hchunk.0."#name, (void *)&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,
|
|
|
++ assert_d_eq(mallctl("arenas.narenas", (void *)&narenas_before, &sz,
|
|
|
++ NULL, 0), 0, "Unexpected mallctl() failure");
|
|
|
++ assert_d_eq(mallctl("arenas.extend", (void *)&arena, &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_d_eq(mallctl("arenas.narenas", (void *)&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"); \
|
|
|
++ assert_d_eq(mallctl("stats.arenas.0."#name, (void *)&name, &sz, \
|
|
|
++ NULL, 0), 0, "Unexpected mallctl() failure"); \
|
|
|
+ } while (0)
|
|
|
+
|
|
|
+ TEST_STATS_ARENAS(unsigned, nthreads);
|
|
|
+ TEST_STATS_ARENAS(const char *, dss);
|
|
|
+ TEST_STATS_ARENAS(ssize_t, lg_dirty_mult);
|
|
|
+ TEST_STATS_ARENAS(ssize_t, decay_time);
|
|
|
+ TEST_STATS_ARENAS(size_t, pactive);
|
|
|
+ TEST_STATS_ARENAS(size_t, pdirty);
|
|
|
+diff --git a/memory/jemalloc/src/test/unit/pack.c b/memory/jemalloc/src/test/unit/pack.c
|
|
|
+new file mode 100644
|
|
|
+--- /dev/null
|
|
|
++++ b/memory/jemalloc/src/test/unit/pack.c
|
|
|
+@@ -0,0 +1,206 @@
|
|
|
++#include "test/jemalloc_test.h"
|
|
|
++
|
|
|
++const char *malloc_conf =
|
|
|
++ /* Use smallest possible chunk size. */
|
|
|
++ "lg_chunk:0"
|
|
|
++ /* Immediately purge to minimize fragmentation. */
|
|
|
++ ",lg_dirty_mult:-1"
|
|
|
++ ",decay_time:-1"
|
|
|
++ ;
|
|
|
++
|
|
|
++/*
|
|
|
++ * Size class that is a divisor of the page size, ideally 4+ regions per run.
|
|
|
++ */
|
|
|
++#if LG_PAGE <= 14
|
|
|
++#define SZ (ZU(1) << (LG_PAGE - 2))
|
|
|
++#else
|
|
|
++#define SZ 4096
|
|
|
++#endif
|
|
|
++
|
|
|
++/*
|
|
|
++ * Number of chunks to consume at high water mark. Should be at least 2 so that
|
|
|
++ * if mmap()ed memory grows downward, downward growth of mmap()ed memory is
|
|
|
++ * tested.
|
|
|
++ */
|
|
|
++#define NCHUNKS 8
|
|
|
++
|
|
|
++static unsigned
|
|
|
++binind_compute(void)
|
|
|
++{
|
|
|
++ size_t sz;
|
|
|
++ unsigned nbins, i;
|
|
|
++
|
|
|
++ sz = sizeof(nbins);
|
|
|
++ assert_d_eq(mallctl("arenas.nbins", (void *)&nbins, &sz, NULL, 0), 0,
|
|
|
++ "Unexpected mallctl failure");
|
|
|
++
|
|
|
++ for (i = 0; i < nbins; i++) {
|
|
|
++ size_t mib[4];
|
|
|
++ size_t miblen = sizeof(mib)/sizeof(size_t);
|
|
|
++ size_t size;
|
|
|
++
|
|
|
++ assert_d_eq(mallctlnametomib("arenas.bin.0.size", mib,
|
|
|
++ &miblen), 0, "Unexpected mallctlnametomb failure");
|
|
|
++ mib[2] = (size_t)i;
|
|
|
++
|
|
|
++ sz = sizeof(size);
|
|
|
++ assert_d_eq(mallctlbymib(mib, miblen, (void *)&size, &sz, NULL,
|
|
|
++ 0), 0, "Unexpected mallctlbymib failure");
|
|
|
++ if (size == SZ)
|
|
|
++ return (i);
|
|
|
++ }
|
|
|
++
|
|
|
++ test_fail("Unable to compute nregs_per_run");
|
|
|
++ return (0);
|
|
|
++}
|
|
|
++
|
|
|
++static size_t
|
|
|
++nregs_per_run_compute(void)
|
|
|
++{
|
|
|
++ uint32_t nregs;
|
|
|
++ size_t sz;
|
|
|
++ unsigned binind = binind_compute();
|
|
|
++ size_t mib[4];
|
|
|
++ size_t miblen = sizeof(mib)/sizeof(size_t);
|
|
|
++
|
|
|
++ assert_d_eq(mallctlnametomib("arenas.bin.0.nregs", mib, &miblen), 0,
|
|
|
++ "Unexpected mallctlnametomb failure");
|
|
|
++ mib[2] = (size_t)binind;
|
|
|
++ sz = sizeof(nregs);
|
|
|
++ assert_d_eq(mallctlbymib(mib, miblen, (void *)&nregs, &sz, NULL,
|
|
|
++ 0), 0, "Unexpected mallctlbymib failure");
|
|
|
++ return (nregs);
|
|
|
++}
|
|
|
++
|
|
|
++static size_t
|
|
|
++npages_per_run_compute(void)
|
|
|
++{
|
|
|
++ size_t sz;
|
|
|
++ unsigned binind = binind_compute();
|
|
|
++ size_t mib[4];
|
|
|
++ size_t miblen = sizeof(mib)/sizeof(size_t);
|
|
|
++ size_t run_size;
|
|
|
++
|
|
|
++ assert_d_eq(mallctlnametomib("arenas.bin.0.run_size", mib, &miblen), 0,
|
|
|
++ "Unexpected mallctlnametomb failure");
|
|
|
++ mib[2] = (size_t)binind;
|
|
|
++ sz = sizeof(run_size);
|
|
|
++ assert_d_eq(mallctlbymib(mib, miblen, (void *)&run_size, &sz, NULL,
|
|
|
++ 0), 0, "Unexpected mallctlbymib failure");
|
|
|
++ return (run_size >> LG_PAGE);
|
|
|
++}
|
|
|
++
|
|
|
++static size_t
|
|
|
++npages_per_chunk_compute(void)
|
|
|
++{
|
|
|
++
|
|
|
++ return ((chunksize >> LG_PAGE) - map_bias);
|
|
|
++}
|
|
|
++
|
|
|
++static size_t
|
|
|
++nruns_per_chunk_compute(void)
|
|
|
++{
|
|
|
++
|
|
|
++ return (npages_per_chunk_compute() / npages_per_run_compute());
|
|
|
++}
|
|
|
++
|
|
|
++static unsigned
|
|
|
++arenas_extend_mallctl(void)
|
|
|
++{
|
|
|
++ unsigned arena_ind;
|
|
|
++ size_t sz;
|
|
|
++
|
|
|
++ sz = sizeof(arena_ind);
|
|
|
++ assert_d_eq(mallctl("arenas.extend", (void *)&arena_ind, &sz, NULL, 0),
|
|
|
++ 0, "Error in arenas.extend");
|
|
|
++
|
|
|
++ return (arena_ind);
|
|
|
++}
|
|
|
++
|
|
|
++static void
|
|
|
++arena_reset_mallctl(unsigned arena_ind)
|
|
|
++{
|
|
|
++ size_t mib[3];
|
|
|
++ size_t miblen = sizeof(mib)/sizeof(size_t);
|
|
|
++
|
|
|
++ assert_d_eq(mallctlnametomib("arena.0.reset", mib, &miblen), 0,
|
|
|
++ "Unexpected mallctlnametomib() failure");
|
|
|
++ mib[1] = (size_t)arena_ind;
|
|
|
++ assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, NULL, 0), 0,
|
|
|
++ "Unexpected mallctlbymib() failure");
|
|
|
++}
|
|
|
++
|
|
|
++TEST_BEGIN(test_pack)
|
|
|
++{
|
|
|
++ unsigned arena_ind = arenas_extend_mallctl();
|
|
|
++ size_t nregs_per_run = nregs_per_run_compute();
|
|
|
++ size_t nruns_per_chunk = nruns_per_chunk_compute();
|
|
|
++ size_t nruns = nruns_per_chunk * NCHUNKS;
|
|
|
++ size_t nregs = nregs_per_run * nruns;
|
|
|
++ VARIABLE_ARRAY(void *, ptrs, nregs);
|
|
|
++ size_t i, j, offset;
|
|
|
++
|
|
|
++ /* Fill matrix. */
|
|
|
++ for (i = offset = 0; i < nruns; i++) {
|
|
|
++ for (j = 0; j < nregs_per_run; j++) {
|
|
|
++ void *p = mallocx(SZ, MALLOCX_ARENA(arena_ind) |
|
|
|
++ MALLOCX_TCACHE_NONE);
|
|
|
++ assert_ptr_not_null(p,
|
|
|
++ "Unexpected mallocx(%zu, MALLOCX_ARENA(%u) |"
|
|
|
++ " MALLOCX_TCACHE_NONE) failure, run=%zu, reg=%zu",
|
|
|
++ SZ, arena_ind, i, j);
|
|
|
++ ptrs[(i * nregs_per_run) + j] = p;
|
|
|
++ }
|
|
|
++ }
|
|
|
++
|
|
|
++ /*
|
|
|
++ * Free all but one region of each run, but rotate which region is
|
|
|
++ * preserved, so that subsequent allocations exercise the within-run
|
|
|
++ * layout policy.
|
|
|
++ */
|
|
|
++ offset = 0;
|
|
|
++ for (i = offset = 0;
|
|
|
++ i < nruns;
|
|
|
++ i++, offset = (offset + 1) % nregs_per_run) {
|
|
|
++ for (j = 0; j < nregs_per_run; j++) {
|
|
|
++ void *p = ptrs[(i * nregs_per_run) + j];
|
|
|
++ if (offset == j)
|
|
|
++ continue;
|
|
|
++ dallocx(p, MALLOCX_ARENA(arena_ind) |
|
|
|
++ MALLOCX_TCACHE_NONE);
|
|
|
++ }
|
|
|
++ }
|
|
|
++
|
|
|
++ /*
|
|
|
++ * Logically refill matrix, skipping preserved regions and verifying
|
|
|
++ * that the matrix is unmodified.
|
|
|
++ */
|
|
|
++ offset = 0;
|
|
|
++ for (i = offset = 0;
|
|
|
++ i < nruns;
|
|
|
++ i++, offset = (offset + 1) % nregs_per_run) {
|
|
|
++ for (j = 0; j < nregs_per_run; j++) {
|
|
|
++ void *p;
|
|
|
++
|
|
|
++ if (offset == j)
|
|
|
++ continue;
|
|
|
++ p = mallocx(SZ, MALLOCX_ARENA(arena_ind) |
|
|
|
++ MALLOCX_TCACHE_NONE);
|
|
|
++ assert_ptr_eq(p, ptrs[(i * nregs_per_run) + j],
|
|
|
++ "Unexpected refill discrepancy, run=%zu, reg=%zu\n",
|
|
|
++ i, j);
|
|
|
++ }
|
|
|
++ }
|
|
|
++
|
|
|
++ /* Clean up. */
|
|
|
++ arena_reset_mallctl(arena_ind);
|
|
|
++}
|
|
|
++TEST_END
|
|
|
++
|
|
|
++int
|
|
|
++main(void)
|
|
|
++{
|
|
|
++
|
|
|
++ return (test(
|
|
|
++ test_pack));
|
|
|
++}
|
|
|
+diff --git a/memory/jemalloc/src/test/unit/pages.c b/memory/jemalloc/src/test/unit/pages.c
|
|
|
+new file mode 100644
|
|
|
+--- /dev/null
|
|
|
++++ b/memory/jemalloc/src/test/unit/pages.c
|
|
|
+@@ -0,0 +1,27 @@
|
|
|
++#include "test/jemalloc_test.h"
|
|
|
++
|
|
|
++TEST_BEGIN(test_pages_huge)
|
|
|
++{
|
|
|
++ bool commit;
|
|
|
++ void *pages;
|
|
|
++
|
|
|
++ commit = true;
|
|
|
++ pages = pages_map(NULL, PAGE, &commit);
|
|
|
++ assert_ptr_not_null(pages, "Unexpected pages_map() error");
|
|
|
++
|
|
|
++ assert_false(pages_huge(pages, PAGE),
|
|
|
++ "Unexpected pages_huge() result");
|
|
|
++ assert_false(pages_nohuge(pages, PAGE),
|
|
|
++ "Unexpected pages_nohuge() result");
|
|
|
++
|
|
|
++ pages_unmap(pages, PAGE);
|
|
|
++}
|
|
|
++TEST_END
|
|
|
++
|
|
|
++int
|
|
|
++main(void)
|
|
|
++{
|
|
|
++
|
|
|
++ return (test(
|
|
|
++ test_pages_huge));
|
|
|
++}
|
|
|
+diff --git a/memory/jemalloc/src/test/unit/prof_accum.c b/memory/jemalloc/src/test/unit/prof_accum.c
|
|
|
+--- a/memory/jemalloc/src/test/unit/prof_accum.c
|
|
|
++++ b/memory/jemalloc/src/test/unit/prof_accum.c
|
|
|
+@@ -63,18 +63,19 @@ 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");
|
|
|
++ assert_d_eq(mallctl("prof.active", NULL, NULL, (void *)&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++)
|
|
|
+diff --git a/memory/jemalloc/src/test/unit/prof_active.c b/memory/jemalloc/src/test/unit/prof_active.c
|
|
|
+--- a/memory/jemalloc/src/test/unit/prof_active.c
|
|
|
++++ b/memory/jemalloc/src/test/unit/prof_active.c
|
|
|
+@@ -7,31 +7,32 @@ const char *malloc_conf =
|
|
|
+
|
|
|
+ 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,
|
|
|
++ assert_d_eq(mallctl(name, (void *)&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,
|
|
|
++ assert_d_eq(mallctl(name, (void *)&old, &sz, (void *)&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,
|
|
|
+diff --git a/memory/jemalloc/src/test/unit/prof_gdump.c b/memory/jemalloc/src/test/unit/prof_gdump.c
|
|
|
+--- a/memory/jemalloc/src/test/unit/prof_gdump.c
|
|
|
++++ b/memory/jemalloc/src/test/unit/prof_gdump.c
|
|
|
+@@ -23,46 +23,47 @@ 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");
|
|
|
++ assert_d_eq(mallctl("prof.active", NULL, NULL, (void *)&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,
|
|
|
++ assert_d_eq(mallctl("prof.gdump", (void *)&gdump_old, &sz,
|
|
|
++ (void *)&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,
|
|
|
++ assert_d_eq(mallctl("prof.gdump", (void *)&gdump_old, &sz,
|
|
|
++ (void *)&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);
|
|
|
+diff --git a/memory/jemalloc/src/test/unit/prof_idump.c b/memory/jemalloc/src/test/unit/prof_idump.c
|
|
|
+--- a/memory/jemalloc/src/test/unit/prof_idump.c
|
|
|
++++ b/memory/jemalloc/src/test/unit/prof_idump.c
|
|
|
+@@ -24,18 +24,19 @@ prof_dump_open_intercept(bool propagate_
|
|
|
+ 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");
|
|
|
++ assert_d_eq(mallctl("prof.active", NULL, NULL, (void *)&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");
|
|
|
+diff --git a/memory/jemalloc/src/test/unit/prof_reset.c b/memory/jemalloc/src/test/unit/prof_reset.c
|
|
|
+--- a/memory/jemalloc/src/test/unit/prof_reset.c
|
|
|
++++ b/memory/jemalloc/src/test/unit/prof_reset.c
|
|
|
+@@ -15,52 +15,53 @@ prof_dump_open_intercept(bool propagate_
|
|
|
+
|
|
|
+ return (fd);
|
|
|
+ }
|
|
|
+
|
|
|
+ static void
|
|
|
+ set_prof_active(bool active)
|
|
|
+ {
|
|
|
+
|
|
|
+- assert_d_eq(mallctl("prof.active", NULL, NULL, &active, sizeof(active)),
|
|
|
+- 0, "Unexpected mallctl failure");
|
|
|
++ assert_d_eq(mallctl("prof.active", NULL, NULL, (void *)&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,
|
|
|
++ assert_d_eq(mallctl("prof.lg_sample", (void *)&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,
|
|
|
++ (void *)&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,
|
|
|
++ assert_d_eq(mallctl("opt.lg_prof_sample", (void *)&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\"");
|
|
|
+
|
|
|
+diff --git a/memory/jemalloc/src/test/unit/prof_thread_name.c b/memory/jemalloc/src/test/unit/prof_thread_name.c
|
|
|
+--- a/memory/jemalloc/src/test/unit/prof_thread_name.c
|
|
|
++++ b/memory/jemalloc/src/test/unit/prof_thread_name.c
|
|
|
+@@ -7,32 +7,33 @@ const char *malloc_conf = "prof:true,pro
|
|
|
+ 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",
|
|
|
++ assert_d_eq(mallctl("thread.prof.name", (void *)&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,
|
|
|
++ assert_d_eq(mallctl("thread.prof.name", NULL, NULL,
|
|
|
++ (void *)&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)
|
|
|
+@@ -41,36 +42,37 @@ TEST_BEGIN(test_prof_thread_name_validat
|
|
|
+
|
|
|
+ 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,
|
|
|
++ assert_d_eq(mallctl("thread.prof.name", NULL, NULL,
|
|
|
++ (void *)&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,
|
|
|
++ assert_d_eq(mallctl("thread.prof.name", NULL, NULL,
|
|
|
++ (void *)&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,
|
|
|
++ assert_d_eq(mallctl("thread.prof.name",
|
|
|
++ (void *)&thread_name_old, &sz, (void *)&thread_name,
|
|
|
++ sizeof(thread_name)), EPERM,
|
|
|
+ "Unexpected mallctl result writing \"%s\" to "
|
|
|
+ "thread.prof.name", thread_name);
|
|
|
+ }
|
|
|
+
|
|
|
+ mallctl_thread_name_set("");
|
|
|
+ }
|
|
|
+ TEST_END
|
|
|
+
|
|
|
+diff --git a/memory/jemalloc/src/test/unit/run_quantize.c b/memory/jemalloc/src/test/unit/run_quantize.c
|
|
|
+--- a/memory/jemalloc/src/test/unit/run_quantize.c
|
|
|
++++ b/memory/jemalloc/src/test/unit/run_quantize.c
|
|
|
+@@ -8,26 +8,26 @@ TEST_BEGIN(test_small_run_size)
|
|
|
+ size_t miblen = sizeof(mib) / sizeof(size_t);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Iterate over all small size classes, get their run sizes, and verify
|
|
|
+ * that the quantized size is the same as the run size.
|
|
|
+ */
|
|
|
+
|
|
|
+ sz = sizeof(unsigned);
|
|
|
+- assert_d_eq(mallctl("arenas.nbins", &nbins, &sz, NULL, 0), 0,
|
|
|
++ assert_d_eq(mallctl("arenas.nbins", (void *)&nbins, &sz, NULL, 0), 0,
|
|
|
+ "Unexpected mallctl failure");
|
|
|
+
|
|
|
+ assert_d_eq(mallctlnametomib("arenas.bin.0.run_size", mib, &miblen), 0,
|
|
|
+ "Unexpected mallctlnametomib failure");
|
|
|
+ for (i = 0; i < nbins; i++) {
|
|
|
+ mib[2] = i;
|
|
|
+ sz = sizeof(size_t);
|
|
|
+- assert_d_eq(mallctlbymib(mib, miblen, &run_size, &sz, NULL, 0),
|
|
|
+- 0, "Unexpected mallctlbymib failure");
|
|
|
++ assert_d_eq(mallctlbymib(mib, miblen, (void *)&run_size, &sz,
|
|
|
++ NULL, 0), 0, "Unexpected mallctlbymib failure");
|
|
|
+ assert_zu_eq(run_size, run_quantize_floor(run_size),
|
|
|
+ "Small run quantization should be a no-op (run_size=%zu)",
|
|
|
+ run_size);
|
|
|
+ assert_zu_eq(run_size, run_quantize_ceil(run_size),
|
|
|
+ "Small run quantization should be a no-op (run_size=%zu)",
|
|
|
+ run_size);
|
|
|
+ }
|
|
|
+ }
|
|
|
+@@ -42,32 +42,32 @@ TEST_BEGIN(test_large_run_size)
|
|
|
+ size_t miblen = sizeof(mib) / sizeof(size_t);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Iterate over all large size classes, get their run sizes, and verify
|
|
|
+ * that the quantized size is the same as the run size.
|
|
|
+ */
|
|
|
+
|
|
|
+ sz = sizeof(bool);
|
|
|
+- assert_d_eq(mallctl("config.cache_oblivious", &cache_oblivious, &sz,
|
|
|
+- NULL, 0), 0, "Unexpected mallctl failure");
|
|
|
++ assert_d_eq(mallctl("config.cache_oblivious", (void *)&cache_oblivious,
|
|
|
++ &sz, NULL, 0), 0, "Unexpected mallctl failure");
|
|
|
+
|
|
|
+ sz = sizeof(unsigned);
|
|
|
+- assert_d_eq(mallctl("arenas.nlruns", &nlruns, &sz, NULL, 0), 0,
|
|
|
++ assert_d_eq(mallctl("arenas.nlruns", (void *)&nlruns, &sz, NULL, 0), 0,
|
|
|
+ "Unexpected mallctl failure");
|
|
|
+
|
|
|
+ assert_d_eq(mallctlnametomib("arenas.lrun.0.size", mib, &miblen), 0,
|
|
|
+ "Unexpected mallctlnametomib failure");
|
|
|
+ for (i = 0; i < nlruns; i++) {
|
|
|
+ size_t lrun_size, run_size, floor, ceil;
|
|
|
+
|
|
|
+ mib[2] = i;
|
|
|
+ sz = sizeof(size_t);
|
|
|
+- assert_d_eq(mallctlbymib(mib, miblen, &lrun_size, &sz, NULL, 0),
|
|
|
+- 0, "Unexpected mallctlbymib failure");
|
|
|
++ assert_d_eq(mallctlbymib(mib, miblen, (void *)&lrun_size, &sz,
|
|
|
++ NULL, 0), 0, "Unexpected mallctlbymib failure");
|
|
|
+ run_size = cache_oblivious ? lrun_size + PAGE : lrun_size;
|
|
|
+ floor = run_quantize_floor(run_size);
|
|
|
+ ceil = run_quantize_ceil(run_size);
|
|
|
+
|
|
|
+ assert_zu_eq(run_size, floor,
|
|
|
+ "Large run quantization should be a no-op for precise "
|
|
|
+ "size (lrun_size=%zu, run_size=%zu)", lrun_size, run_size);
|
|
|
+ assert_zu_eq(run_size, ceil,
|
|
|
+@@ -97,21 +97,21 @@ TEST_BEGIN(test_monotonic)
|
|
|
+ size_t sz, floor_prev, ceil_prev;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Iterate over all run sizes and verify that
|
|
|
+ * run_quantize_{floor,ceil}() are monotonic.
|
|
|
+ */
|
|
|
+
|
|
|
+ sz = sizeof(unsigned);
|
|
|
+- assert_d_eq(mallctl("arenas.nbins", &nbins, &sz, NULL, 0), 0,
|
|
|
++ assert_d_eq(mallctl("arenas.nbins", (void *)&nbins, &sz, NULL, 0), 0,
|
|
|
+ "Unexpected mallctl failure");
|
|
|
+
|
|
|
+ sz = sizeof(unsigned);
|
|
|
+- assert_d_eq(mallctl("arenas.nlruns", &nlruns, &sz, NULL, 0), 0,
|
|
|
++ assert_d_eq(mallctl("arenas.nlruns", (void *)&nlruns, &sz, NULL, 0), 0,
|
|
|
+ "Unexpected mallctl failure");
|
|
|
+
|
|
|
+ floor_prev = 0;
|
|
|
+ ceil_prev = 0;
|
|
|
+ for (i = 1; i <= chunksize >> LG_PAGE; i++) {
|
|
|
+ size_t run_size, floor, ceil;
|
|
|
+
|
|
|
+ run_size = i << LG_PAGE;
|
|
|
+diff --git a/memory/jemalloc/src/test/unit/size_classes.c b/memory/jemalloc/src/test/unit/size_classes.c
|
|
|
+--- a/memory/jemalloc/src/test/unit/size_classes.c
|
|
|
++++ b/memory/jemalloc/src/test/unit/size_classes.c
|
|
|
+@@ -3,27 +3,27 @@
|
|
|
+ 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");
|
|
|
++ assert_d_eq(mallctl("arenas.nhchunks", (void *)&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_d_eq(mallctlbymib(mib, miblen, (void *)&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;
|
|
|
+diff --git a/memory/jemalloc/src/test/unit/stats.c b/memory/jemalloc/src/test/unit/stats.c
|
|
|
+--- a/memory/jemalloc/src/test/unit/stats.c
|
|
|
++++ b/memory/jemalloc/src/test/unit/stats.c
|
|
|
+@@ -2,28 +2,28 @@
|
|
|
+
|
|
|
+ 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");
|
|
|
++ assert_d_eq(mallctl("stats.cactive", (void *)&cactive, &sz, NULL, 0),
|
|
|
++ expected, "Unexpected mallctl() result");
|
|
|
+
|
|
|
+ sz = sizeof(size_t);
|
|
|
+- assert_d_eq(mallctl("stats.allocated", &allocated, &sz, NULL, 0),
|
|
|
++ assert_d_eq(mallctl("stats.allocated", (void *)&allocated, &sz, NULL,
|
|
|
++ 0), expected, "Unexpected mallctl() result");
|
|
|
++ assert_d_eq(mallctl("stats.active", (void *)&active, &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),
|
|
|
++ assert_d_eq(mallctl("stats.resident", (void *)&resident, &sz, NULL, 0),
|
|
|
+ expected, "Unexpected mallctl() result");
|
|
|
+- assert_d_eq(mallctl("stats.mapped", &mapped, &sz, NULL, 0), expected,
|
|
|
+- "Unexpected mallctl() result");
|
|
|
++ assert_d_eq(mallctl("stats.mapped", (void *)&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");
|
|
|
+@@ -40,29 +40,29 @@ TEST_BEGIN(test_stats_huge)
|
|
|
+ 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");
|
|
|
++ assert_d_eq(mallctl("epoch", NULL, NULL, (void *)&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");
|
|
|
++ assert_d_eq(mallctl("stats.arenas.0.huge.allocated", (void *)&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");
|
|
|
++ assert_d_eq(mallctl("stats.arenas.0.huge.nmalloc", (void *)&nmalloc,
|
|
|
++ &sz, NULL, 0), expected, "Unexpected mallctl() result");
|
|
|
++ assert_d_eq(mallctl("stats.arenas.0.huge.ndalloc", (void *)&ndalloc,
|
|
|
++ &sz, NULL, 0), expected, "Unexpected mallctl() result");
|
|
|
++ assert_d_eq(mallctl("stats.arenas.0.huge.nrequests", (void *)&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");
|
|
|
+@@ -78,46 +78,46 @@ TEST_BEGIN(test_stats_arenas_summary)
|
|
|
+ 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");
|
|
|
++ assert_d_eq(mallctl("thread.arena", NULL, NULL, (void *)&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");
|
|
|
+
|
|
|
+ dallocx(little, 0);
|
|
|
+ dallocx(large, 0);
|
|
|
+ dallocx(huge, 0);
|
|
|
+
|
|
|
+ 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");
|
|
|
++ assert_d_eq(mallctl("epoch", NULL, NULL, (void *)&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");
|
|
|
++ assert_d_eq(mallctl("stats.arenas.0.mapped", (void *)&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");
|
|
|
++ assert_d_eq(mallctl("stats.arenas.0.npurge", (void *)&npurge, &sz, NULL,
|
|
|
++ 0), expected, "Unexepected mallctl() result");
|
|
|
++ assert_d_eq(mallctl("stats.arenas.0.nmadvise", (void *)&nmadvise, &sz,
|
|
|
++ NULL, 0), expected, "Unexepected mallctl() result");
|
|
|
++ assert_d_eq(mallctl("stats.arenas.0.purged", (void *)&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");
|
|
|
+ }
|
|
|
+ }
|
|
|
+@@ -145,38 +145,40 @@ TEST_BEGIN(test_stats_arenas_small)
|
|
|
+ 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");
|
|
|
++ assert_d_eq(mallctl("thread.arena", NULL, NULL, (void *)&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");
|
|
|
++ assert_d_eq(mallctl("epoch", NULL, NULL, (void *)&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");
|
|
|
++ assert_d_eq(mallctl("stats.arenas.0.small.allocated",
|
|
|
++ (void *)&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");
|
|
|
++ assert_d_eq(mallctl("stats.arenas.0.small.nmalloc", (void *)&nmalloc,
|
|
|
++ &sz, NULL, 0), expected, "Unexpected mallctl() result");
|
|
|
++ assert_d_eq(mallctl("stats.arenas.0.small.ndalloc", (void *)&ndalloc,
|
|
|
++ &sz, NULL, 0), expected, "Unexpected mallctl() result");
|
|
|
++ assert_d_eq(mallctl("stats.arenas.0.small.nrequests",
|
|
|
++ (void *)&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");
|
|
|
+@@ -192,35 +194,37 @@ 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");
|
|
|
++ assert_d_eq(mallctl("thread.arena", NULL, NULL, (void *)&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");
|
|
|
++ assert_d_eq(mallctl("epoch", NULL, NULL, (void *)&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");
|
|
|
++ assert_d_eq(mallctl("stats.arenas.0.large.allocated",
|
|
|
++ (void *)&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");
|
|
|
++ assert_d_eq(mallctl("stats.arenas.0.large.nmalloc", (void *)&nmalloc,
|
|
|
++ &sz, NULL, 0), expected, "Unexpected mallctl() result");
|
|
|
++ assert_d_eq(mallctl("stats.arenas.0.large.ndalloc", (void *)&ndalloc,
|
|
|
++ &sz, NULL, 0), expected, "Unexpected mallctl() result");
|
|
|
++ assert_d_eq(mallctl("stats.arenas.0.large.nrequests",
|
|
|
++ (void *)&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 greater than zero");
|
|
|
+ assert_u64_ge(nmalloc, ndalloc,
|
|
|
+ "nmalloc should be at least as large as ndalloc");
|
|
|
+@@ -236,33 +240,33 @@ 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");
|
|
|
++ assert_d_eq(mallctl("thread.arena", NULL, NULL, (void *)&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");
|
|
|
++ assert_d_eq(mallctl("epoch", NULL, NULL, (void *)&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");
|
|
|
++ assert_d_eq(mallctl("stats.arenas.0.huge.allocated", (void *)&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.nmalloc", (void *)&nmalloc,
|
|
|
++ &sz, NULL, 0), expected, "Unexpected mallctl() result");
|
|
|
++ assert_d_eq(mallctl("stats.arenas.0.huge.ndalloc", (void *)&ndalloc,
|
|
|
++ &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 greater than zero");
|
|
|
+ assert_u64_ge(nmalloc, ndalloc,
|
|
|
+ "nmalloc should be at least as large as ndalloc");
|
|
|
+@@ -277,54 +281,55 @@ 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");
|
|
|
++ assert_d_eq(mallctl("thread.arena", NULL, NULL, (void *)&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");
|
|
|
++ assert_d_eq(mallctl("epoch", NULL, NULL, (void *)&epoch, sizeof(epoch)),
|
|
|
++ 0, "Unexpected mallctl() failure");
|
|
|
+
|
|
|
+ sz = sizeof(uint64_t);
|
|
|
+- assert_d_eq(mallctl("stats.arenas.0.bins.0.nfills", &nfills, &sz,
|
|
|
+- NULL, 0), config_tcache ? expected : ENOENT,
|
|
|
++ assert_d_eq(mallctl("stats.arenas.0.bins.0.nmalloc", (void *)&nmalloc,
|
|
|
++ &sz, NULL, 0), expected, "Unexpected mallctl() result");
|
|
|
++ assert_d_eq(mallctl("stats.arenas.0.bins.0.ndalloc", (void *)&ndalloc,
|
|
|
++ &sz, NULL, 0), expected, "Unexpected mallctl() result");
|
|
|
++ assert_d_eq(mallctl("stats.arenas.0.bins.0.nrequests",
|
|
|
++ (void *)&nrequests, &sz, NULL, 0), expected,
|
|
|
+ "Unexpected mallctl() result");
|
|
|
+- assert_d_eq(mallctl("stats.arenas.0.bins.0.nflushes", &nflushes, &sz,
|
|
|
+- NULL, 0), config_tcache ? expected : ENOENT,
|
|
|
++ sz = sizeof(size_t);
|
|
|
++ assert_d_eq(mallctl("stats.arenas.0.bins.0.curregs", (void *)&curregs,
|
|
|
++ &sz, NULL, 0), expected, "Unexpected mallctl() result");
|
|
|
++
|
|
|
++ sz = sizeof(uint64_t);
|
|
|
++ assert_d_eq(mallctl("stats.arenas.0.bins.0.nfills", (void *)&nfills,
|
|
|
++ &sz, NULL, 0), config_tcache ? expected : ENOENT,
|
|
|
++ "Unexpected mallctl() result");
|
|
|
++ assert_d_eq(mallctl("stats.arenas.0.bins.0.nflushes", (void *)&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,
|
|
|
++ assert_d_eq(mallctl("stats.arenas.0.bins.0.nruns", (void *)&nruns, &sz,
|
|
|
+ NULL, 0), expected, "Unexpected mallctl() result");
|
|
|
++ assert_d_eq(mallctl("stats.arenas.0.bins.0.nreruns", (void *)&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");
|
|
|
++ assert_d_eq(mallctl("stats.arenas.0.bins.0.curruns", (void *)&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");
|
|
|
+@@ -350,35 +355,36 @@ 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");
|
|
|
++ assert_d_eq(mallctl("thread.arena", NULL, NULL, (void *)&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");
|
|
|
++ assert_d_eq(mallctl("epoch", NULL, NULL, (void *)&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");
|
|
|
++ assert_d_eq(mallctl("stats.arenas.0.lruns.0.nmalloc", (void *)&nmalloc,
|
|
|
++ &sz, NULL, 0), expected, "Unexpected mallctl() result");
|
|
|
++ assert_d_eq(mallctl("stats.arenas.0.lruns.0.ndalloc", (void *)&ndalloc,
|
|
|
++ &sz, NULL, 0), expected, "Unexpected mallctl() result");
|
|
|
++ assert_d_eq(mallctl("stats.arenas.0.lruns.0.nrequests",
|
|
|
++ (void *)&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");
|
|
|
++ assert_d_eq(mallctl("stats.arenas.0.lruns.0.curruns", (void *)&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");
|
|
|
+@@ -394,33 +400,36 @@ 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");
|
|
|
++ assert_d_eq(mallctl("thread.arena", NULL, NULL, (void *)&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");
|
|
|
++ assert_d_eq(mallctl("epoch", NULL, NULL, (void *)&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");
|
|
|
++ assert_d_eq(mallctl("stats.arenas.0.hchunks.0.nmalloc",
|
|
|
++ (void *)&nmalloc, &sz, NULL, 0), expected,
|
|
|
++ "Unexpected mallctl() result");
|
|
|
++ assert_d_eq(mallctl("stats.arenas.0.hchunks.0.ndalloc",
|
|
|
++ (void *)&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");
|
|
|
++ assert_d_eq(mallctl("stats.arenas.0.hchunks.0.curhchunks",
|
|
|
++ (void *)&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");
|
|
|
+diff --git a/memory/jemalloc/src/test/unit/tsd.c b/memory/jemalloc/src/test/unit/tsd.c
|
|
|
+--- a/memory/jemalloc/src/test/unit/tsd.c
|
|
|
++++ b/memory/jemalloc/src/test/unit/tsd.c
|
|
|
+@@ -74,17 +74,17 @@ thd_start(void *arg)
|
|
|
+
|
|
|
+ free(p);
|
|
|
+ return (NULL);
|
|
|
+ }
|
|
|
+
|
|
|
+ TEST_BEGIN(test_tsd_main_thread)
|
|
|
+ {
|
|
|
+
|
|
|
+- thd_start((void *) 0xa5f3e329);
|
|
|
++ thd_start((void *)(uintptr_t)0xa5f3e329);
|
|
|
+ }
|
|
|
+ TEST_END
|
|
|
+
|
|
|
+ TEST_BEGIN(test_tsd_sub_thread)
|
|
|
+ {
|
|
|
+ thd_t thd;
|
|
|
+
|
|
|
+ data_cleanup_executed = false;
|
|
|
+diff --git a/memory/jemalloc/src/test/unit/util.c b/memory/jemalloc/src/test/unit/util.c
|
|
|
+--- a/memory/jemalloc/src/test/unit/util.c
|
|
|
++++ b/memory/jemalloc/src/test/unit/util.c
|
|
|
+@@ -70,35 +70,36 @@ TEST_BEGIN(test_malloc_strtoumax)
|
|
|
+ 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)
|
|
|
++#define KSMAX(x) ((uintmax_t)(intmax_t)x##LL)
|
|
|
+ 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)},
|
|
|
++ {"-42", "", 0, ERR(0), KSMAX(-42)},
|
|
|
+ {"042", "", 0, ERR(0), KUMAX(042)},
|
|
|
+ {"+042", "", 0, ERR(0), KUMAX(042)},
|
|
|
+- {"-042", "", 0, ERR(0), KUMAX(-042)},
|
|
|
++ {"-042", "", 0, ERR(0), KSMAX(-042)},
|
|
|
+ {"0x42", "", 0, ERR(0), KUMAX(0x42)},
|
|
|
+ {"+0x42", "", 0, ERR(0), KUMAX(0x42)},
|
|
|
+- {"-0x42", "", 0, ERR(0), KUMAX(-0x42)},
|
|
|
++ {"-0x42", "", 0, ERR(0), KSMAX(-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)},
|
|
|
+@@ -125,16 +126,17 @@ TEST_BEGIN(test_malloc_strtoumax)
|
|
|
+ {"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
|
|
|
++#undef KSMAX
|
|
|
+ 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;
|
|
|
+
|
|
|
+diff --git a/memory/jemalloc/upstream.info b/memory/jemalloc/upstream.info
|
|
|
+--- a/memory/jemalloc/upstream.info
|
|
|
++++ b/memory/jemalloc/upstream.info
|
|
|
+@@ -1,2 +1,2 @@
|
|
|
+ UPSTREAM_REPO=https://github.com/jemalloc/jemalloc
|
|
|
+-UPSTREAM_COMMIT=4.3.1
|
|
|
++UPSTREAM_COMMIT=4.4.0
|