dnl Process this file with autoconf to produce a configure script.
AC_PREREQ(2.68)
AC_INIT([Makefile.in])

AC_CONFIG_AUX_DIR([build-aux])

dnl ============================================================================
dnl Custom macro definitions.

dnl JE_CONCAT_VVV(r, a, b)
dnl
dnl Set $r to the concatenation of $a and $b, with a space separating them iff
dnl both $a and $b are non-empty.
AC_DEFUN([JE_CONCAT_VVV],
if test "x[$]{$2}" = "x" -o "x[$]{$3}" = "x" ; then
  $1="[$]{$2}[$]{$3}"
else
  $1="[$]{$2} [$]{$3}"
fi
)

dnl JE_APPEND_VS(a, b)
dnl
dnl Set $a to the concatenation of $a and b, with a space separating them iff
dnl both $a and b are non-empty.
AC_DEFUN([JE_APPEND_VS],
  T_APPEND_V=$2
  JE_CONCAT_VVV($1, $1, T_APPEND_V)
)

CONFIGURE_CFLAGS=
SPECIFIED_CFLAGS="${CFLAGS}"
dnl JE_CFLAGS_ADD(cflag)
dnl
dnl CFLAGS is the concatenation of CONFIGURE_CFLAGS and SPECIFIED_CFLAGS
dnl (ignoring EXTRA_CFLAGS, which does not impact configure tests.  This macro
dnl appends to CONFIGURE_CFLAGS and regenerates CFLAGS.
AC_DEFUN([JE_CFLAGS_ADD],
[
AC_MSG_CHECKING([whether compiler supports $1])
T_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}"
JE_APPEND_VS(CONFIGURE_CFLAGS, $1)
JE_CONCAT_VVV(CFLAGS, CONFIGURE_CFLAGS, SPECIFIED_CFLAGS)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
[[
]], [[
    return 0;
]])],
              [je_cv_cflags_added=$1]
              AC_MSG_RESULT([yes]),
              [je_cv_cflags_added=]
              AC_MSG_RESULT([no])
              [CONFIGURE_CFLAGS="${T_CONFIGURE_CFLAGS}"]
)
JE_CONCAT_VVV(CFLAGS, CONFIGURE_CFLAGS, SPECIFIED_CFLAGS)
])

dnl JE_CFLAGS_SAVE()
dnl JE_CFLAGS_RESTORE()
dnl
dnl Save/restore CFLAGS.  Nesting is not supported.
AC_DEFUN([JE_CFLAGS_SAVE],
SAVED_CONFIGURE_CFLAGS="${CONFIGURE_CFLAGS}"
)
AC_DEFUN([JE_CFLAGS_RESTORE],
CONFIGURE_CFLAGS="${SAVED_CONFIGURE_CFLAGS}"
JE_CONCAT_VVV(CFLAGS, CONFIGURE_CFLAGS, SPECIFIED_CFLAGS)
)

CONFIGURE_CXXFLAGS=
SPECIFIED_CXXFLAGS="${CXXFLAGS}"
dnl JE_CXXFLAGS_ADD(cxxflag)
AC_DEFUN([JE_CXXFLAGS_ADD],
[
AC_MSG_CHECKING([whether compiler supports $1])
T_CONFIGURE_CXXFLAGS="${CONFIGURE_CXXFLAGS}"
JE_APPEND_VS(CONFIGURE_CXXFLAGS, $1)
JE_CONCAT_VVV(CXXFLAGS, CONFIGURE_CXXFLAGS, SPECIFIED_CXXFLAGS)
AC_LANG_PUSH([C++])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
[[
]], [[
    return 0;
]])],
              [je_cv_cxxflags_added=$1]
              AC_MSG_RESULT([yes]),
              [je_cv_cxxflags_added=]
              AC_MSG_RESULT([no])
              [CONFIGURE_CXXFLAGS="${T_CONFIGURE_CXXFLAGS}"]
)
AC_LANG_POP([C++])
JE_CONCAT_VVV(CXXFLAGS, CONFIGURE_CXXFLAGS, SPECIFIED_CXXFLAGS)
])

CONFIGURE_LDFLAGS=
SPECIFIED_LDFLAGS="${LDFLAGS}"
dnl JE_LDFLAGS_ADD(ldflag)
dnl
dnl LDFLAGS is the concatenation of CONFIGURE_LDFLAGS and SPECIFIED_LDFLAGS
dnl This macro appends to CONFIGURE_LDFLAGS and regenerates LDFLAGS.
AC_DEFUN([JE_LDFLAGS_ADD],
[
AC_MSG_CHECKING([whether linker supports $1])
T_CONFIGURE_LDFLAGS="${CONFIGURE_LDFLAGS}"
JE_APPEND_VS(CONFIGURE_LDFLAGS, $1)
JE_CONCAT_VVV(LDFLAGS, CONFIGURE_LDFLAGS, SPECIFIED_LDFLAGS)
AC_LINK_IFELSE([AC_LANG_PROGRAM(
[[
]], [[
    return 0;
]])],
              [je_cv_ldflags_added=$1]
              AC_MSG_RESULT([yes]),
              [je_cv_ldflags_added=]
              AC_MSG_RESULT([no])
              [CONFIGURE_LDFLAGS="${T_CONFIGURE_LDFLAGS}"]
)
JE_CONCAT_VVV(LDFLAGS, CONFIGURE_LDFLAGS, SPECIFIED_LDFLAGS)
])

dnl JE_COMPILABLE(label, hcode, mcode, rvar)
dnl
dnl Use AC_LINK_IFELSE() rather than AC_COMPILE_IFELSE() so that linker errors
dnl cause failure.
AC_DEFUN([JE_COMPILABLE],
[
AC_CACHE_CHECK([whether $1 is compilable],
               [$4],
               [AC_LINK_IFELSE([AC_LANG_PROGRAM([$2],
                                                [$3])],
                               [$4=yes],
                               [$4=no])])
])

dnl ============================================================================

CONFIG=`echo ${ac_configure_args} | sed -e 's#'"'"'\([^ ]*\)'"'"'#\1#g'`
AC_SUBST([CONFIG])

dnl Library revision.
rev=2
AC_SUBST([rev])

srcroot=$srcdir
if test "x${srcroot}" = "x." ; then
  srcroot=""
else
  srcroot="${srcroot}/"
fi
AC_SUBST([srcroot])
abs_srcroot="`cd \"${srcdir}\"; pwd`/"
AC_SUBST([abs_srcroot])

objroot=""
AC_SUBST([objroot])
abs_objroot="`pwd`/"
AC_SUBST([abs_objroot])

dnl Munge install path variables.
case "$prefix" in
   "NONE" ) prefix="/usr/local" ;;
esac
case "$exec_prefix" in
   "NONE" ) exec_prefix=$prefix ;;
esac
PREFIX=$prefix
AC_SUBST([PREFIX])
BINDIR=`eval echo "\"$bindir\""`
BINDIR=`eval echo "\"$BINDIR\""`
AC_SUBST([BINDIR])
INCLUDEDIR=`eval echo "\"$includedir\""`
INCLUDEDIR=`eval echo "\"$INCLUDEDIR\""`
AC_SUBST([INCLUDEDIR])
LIBDIR=`eval echo "\"$libdir\""`
LIBDIR=`eval echo "\"$LIBDIR\""`
AC_SUBST([LIBDIR])
DATADIR=`eval echo "\"$datadir\""`
DATADIR=`eval echo "\"$DATADIR\""`
AC_SUBST([DATADIR])
MANDIR=`eval echo "\"$mandir\""`
MANDIR=`eval echo "\"$MANDIR\""`
AC_SUBST([MANDIR])

dnl Support for building documentation.
AC_PATH_PROG([XSLTPROC], [xsltproc], [false], [$PATH])
if test -d "/usr/share/xml/docbook/stylesheet/docbook-xsl" ; then
  DEFAULT_XSLROOT="/usr/share/xml/docbook/stylesheet/docbook-xsl"
elif test -d "/usr/share/sgml/docbook/xsl-stylesheets" ; then
  DEFAULT_XSLROOT="/usr/share/sgml/docbook/xsl-stylesheets"
else
  dnl Documentation building will fail if this default gets used.
  DEFAULT_XSLROOT=""
fi
AC_ARG_WITH([xslroot],
  [AS_HELP_STRING([--with-xslroot=<path>], [XSL stylesheet root path])], [
if test "x$with_xslroot" = "xno" ; then
  XSLROOT="${DEFAULT_XSLROOT}"
else
  XSLROOT="${with_xslroot}"
fi
],
  XSLROOT="${DEFAULT_XSLROOT}"
)
if test "x$XSLTPROC" = "xfalse" ; then
  XSLROOT=""
fi
AC_SUBST([XSLROOT])

dnl If CFLAGS isn't defined, set CFLAGS to something reasonable.  Otherwise,
dnl just prevent autoconf from molesting CFLAGS.
CFLAGS=$CFLAGS
AC_PROG_CC

if test "x$GCC" != "xyes" ; then
  AC_CACHE_CHECK([whether compiler is MSVC],
                 [je_cv_msvc],
                 [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],
                                                     [
#ifndef _MSC_VER
  int fail[-1];
#endif
])],
                               [je_cv_msvc=yes],
                               [je_cv_msvc=no])])
fi

dnl check if a cray prgenv wrapper compiler is being used
je_cv_cray_prgenv_wrapper=""
if test "x${PE_ENV}" != "x" ; then
  case "${CC}" in
    CC|cc)
	je_cv_cray_prgenv_wrapper="yes"
	;;
    *)
       ;;
  esac
fi

AC_CACHE_CHECK([whether compiler is cray],
              [je_cv_cray],
              [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],
                                                  [
#ifndef _CRAYC
  int fail[-1];
#endif
])],
                            [je_cv_cray=yes],
                            [je_cv_cray=no])])

if test "x${je_cv_cray}" = "xyes" ; then
  AC_CACHE_CHECK([whether cray compiler version is 8.4],
                [je_cv_cray_84],
                [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],
                                                      [
#if !(_RELEASE_MAJOR == 8 && _RELEASE_MINOR == 4)
  int fail[-1];
#endif
])],
                              [je_cv_cray_84=yes],
                              [je_cv_cray_84=no])])
fi

if test "x$GCC" = "xyes" ; then
  JE_CFLAGS_ADD([-std=gnu11])
  if test "x$je_cv_cflags_added" = "x-std=gnu11" ; then
    AC_DEFINE_UNQUOTED([JEMALLOC_HAS_RESTRICT], [ ], [ ])
  else
    JE_CFLAGS_ADD([-std=gnu99])
    if test "x$je_cv_cflags_added" = "x-std=gnu99" ; then
      AC_DEFINE_UNQUOTED([JEMALLOC_HAS_RESTRICT], [ ], [ ])
    fi
  fi
  JE_CFLAGS_ADD([-Werror=unknown-warning-option])
  JE_CFLAGS_ADD([-Wall])
  JE_CFLAGS_ADD([-Wextra])
  JE_CFLAGS_ADD([-Wshorten-64-to-32])
  JE_CFLAGS_ADD([-Wsign-compare])
  JE_CFLAGS_ADD([-Wundef])
  JE_CFLAGS_ADD([-Wno-format-zero-length])
  JE_CFLAGS_ADD([-Wpointer-arith])
  dnl This warning triggers on the use of the universal zero initializer, which
  dnl is a very handy idiom for things like the tcache static initializer (which
  dnl has lots of nested structs).  See the discussion at.
  dnl https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53119
  JE_CFLAGS_ADD([-Wno-missing-braces])
  dnl This one too.
  JE_CFLAGS_ADD([-Wno-missing-field-initializers])
  JE_CFLAGS_ADD([-Wno-missing-attributes])
  JE_CFLAGS_ADD([-pipe])
  JE_CFLAGS_ADD([-g3])
elif test "x$je_cv_msvc" = "xyes" ; then
  CC="$CC -nologo"
  JE_CFLAGS_ADD([-Zi])
  JE_CFLAGS_ADD([-MT])
  JE_CFLAGS_ADD([-W3])
  JE_CFLAGS_ADD([-FS])
  JE_APPEND_VS(CPPFLAGS, -I${srcdir}/include/msvc_compat)
fi
if test "x$je_cv_cray" = "xyes" ; then
  dnl cray compiler 8.4 has an inlining bug
  if test "x$je_cv_cray_84" = "xyes" ; then
    JE_CFLAGS_ADD([-hipa2])
    JE_CFLAGS_ADD([-hnognu])
  fi
  dnl ignore unreachable code warning
  JE_CFLAGS_ADD([-hnomessage=128])
  dnl ignore redefinition of "malloc", "free", etc warning
  JE_CFLAGS_ADD([-hnomessage=1357])
fi
AC_SUBST([CONFIGURE_CFLAGS])
AC_SUBST([SPECIFIED_CFLAGS])
AC_SUBST([EXTRA_CFLAGS])
AC_PROG_CPP

AC_ARG_ENABLE([cxx],
  [AS_HELP_STRING([--disable-cxx], [Disable C++ integration])],
if test "x$enable_cxx" = "xno" ; then
  enable_cxx="0"
else
  enable_cxx="1"
fi
,
enable_cxx="1"
)
AC_ARG_WITH([cxx_stdlib],
  [AS_HELP_STRING([--with-cxx-stdlib=<libstdc++|libcxx>],
  [Specify the C++ standard library to link (default: probe for libstdc++)])],
  [case "${with_cxx_stdlib}" in
    libstdc++|libcxx) ;;
    *) AC_MSG_ERROR([bad value ${with_cxx_stdlib} for --with-cxx-stdlib]) ;;
  esac],
  [with_cxx_stdlib=""]
)
if test "x$enable_cxx" = "x1" ; then
  dnl Require at least c++14, which is the first version to support sized
  dnl deallocation.  C++ support is not compiled otherwise.
  m4_include([m4/ax_cxx_compile_stdcxx.m4])
  AX_CXX_COMPILE_STDCXX([17], [noext], [optional])
  if test "x${HAVE_CXX17}" != "x1"; then
    AX_CXX_COMPILE_STDCXX([14], [noext], [optional])
  fi
  if test "x${HAVE_CXX14}" = "x1" -o "x${HAVE_CXX17}" = "x1"; then
    JE_CXXFLAGS_ADD([-Wall])
    JE_CXXFLAGS_ADD([-Wextra])
    JE_CXXFLAGS_ADD([-g3])

    SAVED_LIBS="${LIBS}"
    case "${with_cxx_stdlib}" in
      libstdc++)
        JE_APPEND_VS(LIBS, -lstdc++)
        ;;
      libcxx)
        JE_APPEND_VS(LIBS, -lc++)
        ;;
      *)
        dnl Probe for libstdc++ (the default when --with-cxx-stdlib is not given).
        JE_APPEND_VS(LIBS, -lstdc++)
        JE_COMPILABLE([libstdc++ linkage], [
#include <stdlib.h>
], [[
	int *arr = (int *)malloc(sizeof(int) * 42);
	if (arr == NULL)
		return 1;
]], [je_cv_libstdcxx])
        if test "x${je_cv_libstdcxx}" = "xno" ; then
          LIBS="${SAVED_LIBS}"
        fi
        ;;
    esac
  else
    enable_cxx="0"
  fi
fi
if test "x$enable_cxx" = "x1"; then
  AC_DEFINE([JEMALLOC_ENABLE_CXX], [ ], [ ])
fi
if test "x$enable_cxx" = "x1"; then
  dnl Now check whether the C++ compiler has exceptions enabled.
  AC_LANG_PUSH([C++])
  SAVED_CXXFLAGS="${CXXFLAGS}"
  CXXFLAGS="${CXXFLAGS} ${EXTRA_CXXFLAGS}"
  JE_COMPILABLE([C++ exception support], [
#include <new>
], [
	try {
		throw std::bad_alloc();
	} catch (const std::bad_alloc &) {
	}
], [je_cv_cxx_exceptions])
  CXXFLAGS="${SAVED_CXXFLAGS}"
  AC_LANG_POP([C++])
  if test "x${je_cv_cxx_exceptions}" = "xyes" ; then
    AC_DEFINE([JEMALLOC_HAVE_CXX_EXCEPTIONS], [ ], [ ])
    enable_cxx_exceptions="1"
  else
    enable_cxx_exceptions="0"
  fi
fi

dnl Do not enable infallible-new by default. When enabled, the throwing
dnl operator new aborts on OOM (with size logged) instead of throwing
dnl std::bad_alloc; nothrow new still returns null. With LTO this lets the
dnl compiler prove operator new doesn't throw and elide exception cleanup.
AC_ARG_ENABLE([cxx-infallible-new],
  [AS_HELP_STRING([--enable-cxx-infallible-new],
    [Abort on OOM in throwing operator new instead of throwing std::bad_alloc])],
[if test "x$enable_cxx_infallible_new" = "xno" ; then
  enable_cxx_infallible_new="0"
else
  enable_cxx_infallible_new="1"
fi
],
[enable_cxx_infallible_new="0"]
)
if test "x$enable_cxx" != "x1" ; then
  enable_cxx_infallible_new="0"
fi
if test "x$enable_cxx_infallible_new" = "x1" ; then
  AC_DEFINE([JEMALLOC_INFALLIBLE_NEW], [ ], [ ])
fi
AC_SUBST([enable_cxx])
AC_SUBST([enable_cxx_exceptions])
AC_SUBST([enable_cxx_infallible_new])
AC_SUBST([CONFIGURE_CXXFLAGS])
AC_SUBST([SPECIFIED_CXXFLAGS])
AC_SUBST([EXTRA_CXXFLAGS])

AC_C_BIGENDIAN([ac_cv_big_endian=1], [ac_cv_big_endian=0])
if test "x${ac_cv_big_endian}" = "x1" ; then
  AC_DEFINE_UNQUOTED([JEMALLOC_BIG_ENDIAN], [ ], [ ])
fi

if test "x${je_cv_msvc}" = "xyes" -a "x${ac_cv_header_inttypes_h}" = "xno"; then
  JE_APPEND_VS(CPPFLAGS, -I${srcdir}/include/msvc_compat/C99)
fi

if test "x${je_cv_msvc}" = "xyes" ; then
  LG_SIZEOF_PTR=LG_SIZEOF_PTR_WIN
  AC_MSG_RESULT([Using a predefined value for sizeof(void *): 4 for 32-bit, 8 for 64-bit])
else
  AC_CHECK_SIZEOF([void *])
  if test "x${ac_cv_sizeof_void_p}" = "x8" ; then
    LG_SIZEOF_PTR=3
  elif test "x${ac_cv_sizeof_void_p}" = "x4" ; then
    LG_SIZEOF_PTR=2
  else
    AC_MSG_ERROR([Unsupported pointer size: ${ac_cv_sizeof_void_p}])
  fi
fi
AC_DEFINE_UNQUOTED([LG_SIZEOF_PTR], [$LG_SIZEOF_PTR], [ ])

AC_CHECK_SIZEOF([int])
if test "x${ac_cv_sizeof_int}" = "x8" ; then
  LG_SIZEOF_INT=3
elif test "x${ac_cv_sizeof_int}" = "x4" ; then
  LG_SIZEOF_INT=2
else
  AC_MSG_ERROR([Unsupported int size: ${ac_cv_sizeof_int}])
fi
AC_DEFINE_UNQUOTED([LG_SIZEOF_INT], [$LG_SIZEOF_INT], [ ])

AC_CHECK_SIZEOF([long])
if test "x${ac_cv_sizeof_long}" = "x8" ; then
  LG_SIZEOF_LONG=3
elif test "x${ac_cv_sizeof_long}" = "x4" ; then
  LG_SIZEOF_LONG=2
else
  AC_MSG_ERROR([Unsupported long size: ${ac_cv_sizeof_long}])
fi
AC_DEFINE_UNQUOTED([LG_SIZEOF_LONG], [$LG_SIZEOF_LONG], [ ])

AC_CHECK_SIZEOF([long long])
if test "x${ac_cv_sizeof_long_long}" = "x8" ; then
  LG_SIZEOF_LONG_LONG=3
elif test "x${ac_cv_sizeof_long_long}" = "x4" ; then
  LG_SIZEOF_LONG_LONG=2
else
  AC_MSG_ERROR([Unsupported long long size: ${ac_cv_sizeof_long_long}])
fi
AC_DEFINE_UNQUOTED([LG_SIZEOF_LONG_LONG], [$LG_SIZEOF_LONG_LONG], [ ])

AC_CHECK_SIZEOF([intmax_t])
if test "x${ac_cv_sizeof_intmax_t}" = "x16" ; then
  LG_SIZEOF_INTMAX_T=4
elif test "x${ac_cv_sizeof_intmax_t}" = "x8" ; then
  LG_SIZEOF_INTMAX_T=3
elif test "x${ac_cv_sizeof_intmax_t}" = "x4" ; then
  LG_SIZEOF_INTMAX_T=2
else
  AC_MSG_ERROR([Unsupported intmax_t size: ${ac_cv_sizeof_intmax_t}])
fi
AC_DEFINE_UNQUOTED([LG_SIZEOF_INTMAX_T], [$LG_SIZEOF_INTMAX_T], [ ])

AC_CANONICAL_HOST
dnl CPU-specific settings.
CPU_SPINWAIT=""
case "${host_cpu}" in
  i686|x86_64)
	HAVE_CPU_SPINWAIT=1
	if test "x${je_cv_msvc}" = "xyes" ; then
	    AC_CACHE_VAL([je_cv_pause_msvc],
	      [JE_COMPILABLE([pause instruction MSVC], [],
					[[_mm_pause(); return 0;]],
					[je_cv_pause_msvc])])
	    if test "x${je_cv_pause_msvc}" = "xyes" ; then
		CPU_SPINWAIT='_mm_pause()'
	    fi
	else
	    AC_CACHE_VAL([je_cv_pause],
	      [JE_COMPILABLE([pause instruction], [],
					[[__asm__ volatile("pause"); return 0;]],
					[je_cv_pause])])
	    if test "x${je_cv_pause}" = "xyes" ; then
		CPU_SPINWAIT='__asm__ volatile("pause")'
	    fi
	fi
	;;
  aarch64|arm*)
	HAVE_CPU_SPINWAIT=1
	dnl isb is a better equivalent to the pause instruction on x86.
	AC_CACHE_VAL([je_cv_isb],
	  [JE_COMPILABLE([isb instruction], [],
			[[__asm__ volatile("isb"); return 0;]],
			[je_cv_isb])])
	if test "x${je_cv_isb}" = "xyes" ; then
	    CPU_SPINWAIT='__asm__ volatile("isb")'
	fi
	;;
  *)
	HAVE_CPU_SPINWAIT=0
	;;
esac
AC_DEFINE_UNQUOTED([HAVE_CPU_SPINWAIT], [$HAVE_CPU_SPINWAIT], [ ])
AC_DEFINE_UNQUOTED([CPU_SPINWAIT], [$CPU_SPINWAIT], [ ])

dnl LG_VADDR: number of significant virtual address bits. Auto-detected when --with-lg-vaddr is left unset.
AC_ARG_WITH([lg_vaddr],
  [AS_HELP_STRING([--with-lg-vaddr=<lg-vaddr>], [Number of significant virtual address bits])],
  [LG_VADDR="$with_lg_vaddr"], [LG_VADDR="detect"])

if test "x$LG_VADDR" = "xdetect"; then
  case "${host_cpu}" in
    aarch64)
      AC_MSG_CHECKING([number of significant virtual address bits])
      if test "x${LG_SIZEOF_PTR}" = "x2" ; then
        #aarch64 ILP32
        LG_VADDR=32
      else
        #aarch64 LP64
        LG_VADDR=48
      fi
      AC_MSG_RESULT([$LG_VADDR])
      ;;
    x86_64)
      AC_CACHE_CHECK([number of significant virtual address bits],
                     [je_cv_lg_vaddr],
                     AC_RUN_IFELSE([AC_LANG_PROGRAM(
[[
#include <stdio.h>
#ifdef _WIN32
#include <limits.h>
#include <intrin.h>
typedef unsigned __int32 uint32_t;
#else
#include <stdint.h>
#endif
]], [[
	uint32_t r[[4]];
	uint32_t eax_in = 0x80000008U;
#ifdef _WIN32
	__cpuid((int *)r, (int)eax_in);
#else
	asm volatile ("cpuid"
	    : "=a" (r[[0]]), "=b" (r[[1]]), "=c" (r[[2]]), "=d" (r[[3]])
	    : "a" (eax_in), "c" (0)
	);
#endif
	uint32_t eax_out = r[[0]];
	uint32_t vaddr = ((eax_out & 0x0000ff00U) >> 8);
	FILE *f = fopen("conftest.out", "w");
	if (f == NULL) {
		return 1;
	}
	if (vaddr > (sizeof(void *) << 3)) {
		vaddr = sizeof(void *) << 3;
	}
	fprintf(f, "%u", vaddr);
	fclose(f);
	return 0;
]])],
                   [je_cv_lg_vaddr=`cat conftest.out`],
                   [je_cv_lg_vaddr=error],
                   [je_cv_lg_vaddr=57]))
      if test "x${je_cv_lg_vaddr}" = "xerror" ; then
        AC_MSG_ERROR([cannot determine number of significant virtual address bits])
      fi
      if test "x${je_cv_lg_vaddr}" != "x" ; then
        LG_VADDR="${je_cv_lg_vaddr}"
      fi
      ;;
    *)
      AC_MSG_CHECKING([number of significant virtual address bits])
      if test "x${LG_SIZEOF_PTR}" = "x3" ; then
        LG_VADDR=64
      elif test "x${LG_SIZEOF_PTR}" = "x2" ; then
        LG_VADDR=32
      elif test "x${LG_SIZEOF_PTR}" = "xLG_SIZEOF_PTR_WIN" ; then
        LG_VADDR="(1U << (LG_SIZEOF_PTR_WIN+3))"
      else
        AC_MSG_ERROR([Unsupported lg(pointer size): ${LG_SIZEOF_PTR}])
      fi
      AC_MSG_RESULT([$LG_VADDR])
      ;;
  esac
fi
AC_DEFINE_UNQUOTED([LG_VADDR], [$LG_VADDR], [ ])

dnl rdtscp feature probe for x86_64
case "${host_cpu}" in
  x86_64)
    AC_CACHE_CHECK([rdtscp support],
		   [je_cv_rdtscp],
		   AC_RUN_IFELSE([AC_LANG_PROGRAM(
[[
#include <stdint.h>
]],
[[
      unsigned int dx;
      asm volatile("rdtscp" : "=d"(dx) ::);
      return 0;
]])],
    [je_cv_rdtscp=yes],
    [je_cv_rdtscp=no],
    [je_cv_rdtscp=no]))
    if test "x${je_cv_rdtscp}" = "xyes"; then
      AC_DEFINE([JEMALLOC_HAVE_RDTSCP], [ ], [ ])
    fi
    ;;
esac

AC_CACHE_CHECK([asm volatile support],
               [je_cv_asm_volatile],
               AC_RUN_IFELSE([AC_LANG_PROGRAM(
[[
]],
[[
      void* ptr;
      asm volatile("" : "+r"(ptr));
      return 0;
]])],
[je_cv_asm_volatile=yes],
[je_cv_asm_volatile=no],
[je_cv_asm_volatile=no]))
if test "x${je_cv_asm_volatile}" = "xyes"; then
  AC_DEFINE([JEMALLOC_HAVE_ASM_VOLATILE], [ ], [ ])
fi
AC_CACHE_CHECK([__int128 support],
               [je_cv_int128],
               AC_RUN_IFELSE([AC_LANG_PROGRAM(
[[
]],
[[
      __int128 temp = 0;
      return temp;
]])],
[je_cv_int128=yes],
[je_cv_int128=no],
[je_cv_int128=no]))
if test "x${je_cv_int128}" = "xyes"; then
  AC_DEFINE([JEMALLOC_HAVE_INT128], [ ], [ ])
fi

LD_PRELOAD_VAR="LD_PRELOAD"
so="so"
importlib="${so}"
o="$ac_objext"
a="a"
exe="$ac_exeext"
libprefix="lib"
link_whole_archive="0"
DSO_LDFLAGS='-shared -Wl,-soname,$(@F)'
RPATH='-Wl,-rpath,$(1)'
SOREV="${so}.${rev}"
PIC_CFLAGS='-fPIC -DPIC'
CTARGET='-o $@'
LDTARGET='-o $@'
TEST_LD_MODE=
EXTRA_LDFLAGS=
ARFLAGS='crus'
AROUT=' $@'
CC_MM=1

if test "x$je_cv_cray_prgenv_wrapper" = "xyes" ; then
  TEST_LD_MODE='-dynamic'
fi

if test "x${je_cv_cray}" = "xyes" ; then
  CC_MM=
fi

AN_MAKEVAR([AR], [AC_PROG_AR])
AN_PROGRAM([ar], [AC_PROG_AR])
AC_DEFUN([AC_PROG_AR], [AC_CHECK_TOOL(AR, ar, :)])
AC_PROG_AR

AN_MAKEVAR([NM], [AC_PROG_NM])
AN_PROGRAM([nm], [AC_PROG_NM])
AC_DEFUN([AC_PROG_NM], [AC_CHECK_TOOL(NM, nm, :)])
AC_PROG_NM

AC_PROG_AWK

dnl ============================================================================
dnl jemalloc version.
dnl

AC_ARG_WITH([version],
  [AS_HELP_STRING([--with-version=<major>.<minor>.<bugfix>-<nrev>-g<gid>],
   [Version string])],
  [
    echo "${with_version}" | grep ['^[0-9]\{1,\}\.[0-9]\{1,\}\.[0-9]\{1,\}-[0-9]\{1,\}-g[0-9a-f]\{1,\}$'] 2>&1 1>/dev/null
    if test $? -eq 0 ; then
      echo "$with_version" > "${objroot}VERSION"
    else
      echo "${with_version}" | grep ['^VERSION$'] 2>&1 1>/dev/null
      if test $? -ne 0 ; then
        AC_MSG_ERROR([${with_version} does not match <major>.<minor>.<bugfix>-<nrev>-g<gid> or VERSION])
      fi
    fi
  ], [
    dnl Set VERSION if source directory is inside a git repository.
    if test "x`test ! \"${srcroot}\" && cd \"${srcroot}\"; git rev-parse --is-inside-work-tree 2>/dev/null`" = "xtrue" ; then
      dnl Pattern globs aren't powerful enough to match both single- and
      dnl double-digit version numbers, so iterate over patterns to support up
      dnl to version 99.99.99 without any accidental matches.
      for pattern in ['[0-9].[0-9].[0-9]' '[0-9].[0-9].[0-9][0-9]' \
                     '[0-9].[0-9][0-9].[0-9]' '[0-9].[0-9][0-9].[0-9][0-9]' \
                     '[0-9][0-9].[0-9].[0-9]' '[0-9][0-9].[0-9].[0-9][0-9]' \
                     '[0-9][0-9].[0-9][0-9].[0-9]' \
                     '[0-9][0-9].[0-9][0-9].[0-9][0-9]']; do
        (test ! "${srcroot}" && cd "${srcroot}"; git describe --long --abbrev=40 --match="${pattern}") > "${objroot}VERSION.tmp" 2>/dev/null
        if test $? -eq 0 ; then
          mv "${objroot}VERSION.tmp" "${objroot}VERSION"
          break
        fi
      done
    fi
    rm -f "${objroot}VERSION.tmp"
  ])

if test ! -e "${objroot}VERSION" ; then
  if test ! -e "${srcroot}VERSION" ; then
    AC_MSG_RESULT(
      [Missing VERSION file, and unable to generate it; creating bogus VERSION])
    echo "0.0.0-0-g000000missing_version_try_git_fetch_tags" > "${objroot}VERSION"
  else
    cp ${srcroot}VERSION ${objroot}VERSION
  fi
fi
jemalloc_version=`cat "${objroot}VERSION"`
jemalloc_version_major=`echo ${jemalloc_version} | tr ".g-" " " | awk '{print [$]1}'`
jemalloc_version_minor=`echo ${jemalloc_version} | tr ".g-" " " | awk '{print [$]2}'`
jemalloc_version_bugfix=`echo ${jemalloc_version} | tr ".g-" " " | awk '{print [$]3}'`
jemalloc_version_nrev=`echo ${jemalloc_version} | tr ".g-" " " | awk '{print [$]4}'`
jemalloc_version_gid=`echo ${jemalloc_version} | tr ".g-" " " | awk '{print [$]5}'`
AC_SUBST([jemalloc_version])
AC_SUBST([jemalloc_version_major])
AC_SUBST([jemalloc_version_minor])
AC_SUBST([jemalloc_version_bugfix])
AC_SUBST([jemalloc_version_nrev])
AC_SUBST([jemalloc_version_gid])

dnl Platform-specific settings.  abi and RPATH can probably be determined
dnl programmatically, but doing so is error-prone, which makes it generally
dnl not worth the trouble.
dnl
dnl Define cpp macros in CPPFLAGS, rather than doing AC_DEFINE(macro), since the
dnl definitions need to be seen before any headers are included, which is a pain
dnl to make happen otherwise.
default_retain="0"
zero_realloc_default_free="0"
maps_coalesce="1"
DUMP_SYMS="${NM} -a"
SYM_PREFIX=""
case "${host}" in
  *-*-darwin* | *-*-ios*)
	abi="macho"
	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"
	SYM_PREFIX="_"
	if test "${LG_SIZEOF_PTR}" = "3"; then
	  default_retain="1"
	fi
	;;
  *-*-freebsd*)
	JE_APPEND_VS(CPPFLAGS, -D_BSD_SOURCE)
	abi="elf"
	AC_DEFINE([JEMALLOC_SYSCTL_VM_OVERCOMMIT], [ ], [ ])
	force_lazy_lock="1"
	;;
  *-*-dragonfly*)
	abi="elf"
	;;
  *-*-openbsd*)
	abi="elf"
	force_tls="0"
	;;
  *-*-bitrig*)
	abi="elf"
	;;
  *-*-linux-android*)
	dnl syscall(2) and secure_getenv(3) are exposed by _GNU_SOURCE.
	JE_APPEND_VS(CPPFLAGS, -D_GNU_SOURCE)
	abi="elf"
	glibc="0"
	AC_DEFINE([JEMALLOC_PURGE_MADVISE_DONTNEED_ZEROS], [ ], [ ])
	AC_DEFINE([JEMALLOC_HAS_ALLOCA_H], [ ], [ ])
	AC_DEFINE([JEMALLOC_PROC_SYS_VM_OVERCOMMIT_MEMORY], [ ], [ ])
	AC_DEFINE([JEMALLOC_THREADED_INIT], [ ], [ ])
	AC_DEFINE([JEMALLOC_C11_ATOMICS], [ ], [ ])
	force_tls="0"
	if test "${LG_SIZEOF_PTR}" = "3"; then
	  default_retain="1"
	fi
	zero_realloc_default_free="1"
	;;
  *-*-linux-musl*)
	dnl syscall(2) and secure_getenv(3) are exposed by _GNU_SOURCE.
	JE_APPEND_VS(CPPFLAGS, -D_GNU_SOURCE)
	abi="elf"
	AC_DEFINE([JEMALLOC_PURGE_MADVISE_DONTNEED_ZEROS], [ ], [ ])
	AC_DEFINE([JEMALLOC_HAS_ALLOCA_H], [ ], [ ])
	AC_DEFINE([JEMALLOC_PROC_SYS_VM_OVERCOMMIT_MEMORY], [ ], [ ])
	AC_DEFINE([JEMALLOC_THREADED_INIT], [ ], [ ])
	if test "${LG_SIZEOF_PTR}" = "3"; then
	  default_retain="1"
	fi
	zero_realloc_default_free="1"
	;;
  *-*-linux*)
	dnl syscall(2) and secure_getenv(3) are exposed by _GNU_SOURCE.
	JE_APPEND_VS(CPPFLAGS, -D_GNU_SOURCE)
	abi="elf"
	glibc="1"
	AC_DEFINE([JEMALLOC_PURGE_MADVISE_DONTNEED_ZEROS], [ ], [ ])
	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], [ ], [ ])
	if test "${LG_SIZEOF_PTR}" = "3"; then
	  default_retain="1"
	fi
	zero_realloc_default_free="1"
	;;
  *-*-kfreebsd*)
	dnl syscall(2) and secure_getenv(3) are exposed by _GNU_SOURCE.
	JE_APPEND_VS(CPPFLAGS, -D_GNU_SOURCE)
	abi="elf"
	AC_DEFINE([JEMALLOC_HAS_ALLOCA_H], [ ], [ ])
	AC_DEFINE([JEMALLOC_SYSCTL_VM_OVERCOMMIT], [ ], [ ])
	AC_DEFINE([JEMALLOC_THREADED_INIT], [ ], [ ])
	AC_DEFINE([JEMALLOC_USE_CXX_THROW], [ ], [ ])
	;;
  *-*-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])
	;;
  *-*-solaris2*)
	abi="elf"
	RPATH='-Wl,-R,$(1)'
	dnl Solaris needs this for sigwait().
	JE_APPEND_VS(CPPFLAGS, -D_POSIX_PTHREAD_SEMANTICS)
	JE_APPEND_VS(LIBS, -lposix4 -lsocket -lnsl)
	;;
  *-ibm-aix*)
	if test "${LG_SIZEOF_PTR}" = "3"; then
	  dnl 64bit AIX
	  LD_PRELOAD_VAR="LDR_PRELOAD64"
	else
	  dnl 32bit AIX
	  LD_PRELOAD_VAR="LDR_PRELOAD"
	fi
	abi="xcoff"
	;;
  *-*-mingw* | *-*-cygwin*)
	abi="pecoff"
	force_tls="0"
	maps_coalesce="0"
	RPATH=""
	so="dll"
	if test "x$je_cv_msvc" = "xyes" ; then
	  importlib="lib"
	  DSO_LDFLAGS="-LD"
	  EXTRA_LDFLAGS="-link -DEBUG"
	  CTARGET='-Fo$@'
	  LDTARGET='-Fe$@'
	  AR='lib'
	  ARFLAGS='-nologo -out:'
	  AROUT='$@'
	  CC_MM=
        else
	  importlib="${so}"
	  DSO_LDFLAGS="-shared"
	  link_whole_archive="1"
	fi
	case "${host}" in
	  *-*-cygwin*)
	    DUMP_SYMS="dumpbin /SYMBOLS"
	    ;;
	  *)
	    ;;
	esac
	a="lib"
	libprefix=""
	SOREV="${so}"
	PIC_CFLAGS=""
	if test "${LG_SIZEOF_PTR}" = "3"; then
	  default_retain="1"
	fi
	zero_realloc_default_free="1"
	;;
  *-*-nto-qnx)
	abi="elf"
  force_tls="0"
  AC_DEFINE([JEMALLOC_HAS_ALLOCA_H], [ ], [ ])
	;;
  *)
	AC_MSG_RESULT([Unsupported operating system: ${host}])
	abi="elf"
	;;
esac

JEMALLOC_USABLE_SIZE_CONST=const
AC_CHECK_HEADERS([malloc.h], [
  AC_MSG_CHECKING([whether malloc_usable_size definition can use const argument])
  AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
    [#include <malloc.h>
     #include <stddef.h>
    size_t malloc_usable_size(const void *ptr);
    ],
    [])],[
                AC_MSG_RESULT([yes])
         ],[
                JEMALLOC_USABLE_SIZE_CONST=
                AC_MSG_RESULT([no])
         ])
])
AC_DEFINE_UNQUOTED([JEMALLOC_USABLE_SIZE_CONST], [$JEMALLOC_USABLE_SIZE_CONST], [ ])
AC_SUBST([abi])
AC_SUBST([RPATH])
AC_SUBST([LD_PRELOAD_VAR])
AC_SUBST([so])
AC_SUBST([importlib])
AC_SUBST([o])
AC_SUBST([a])
AC_SUBST([exe])
AC_SUBST([libprefix])
AC_SUBST([link_whole_archive])
AC_SUBST([DSO_LDFLAGS])
AC_SUBST([EXTRA_LDFLAGS])
AC_SUBST([SOREV])
AC_SUBST([PIC_CFLAGS])
AC_SUBST([CTARGET])
AC_SUBST([LDTARGET])
AC_SUBST([TEST_LD_MODE])
AC_SUBST([MKLIB])
AC_SUBST([ARFLAGS])
AC_SUBST([AROUT])
AC_SUBST([DUMP_SYMS])
AC_SUBST([CC_MM])

dnl Determine whether libm must be linked to use e.g. log(3).

# On MSVC, log is an intrinsic that doesn't require libm. However,
# AC_SEARCH_LIBS does not successfully detect this, as it will try to compile
# a program using the wrong signature for log. Newer versions of MSVC CL detects
# this and rejects the program with the following messages.
#
# conftest.c(40): warning C4391: 'char log()': incorrect return type for intrinsic function, expected 'double'
# conftest.c(44): error C2168: 'log': too few actual parameters for intrinsic function
#
# Since log is always available on MSVC (it's been around since the dawn of
# time), we simply always assume it's there if MSVC is detected.
if test "x$je_cv_msvc" = "xyes" ; then
  LM=
else
  AC_SEARCH_LIBS([log], [m], , [AC_MSG_ERROR([Missing math functions])])
    if test "x$ac_cv_search_log" != "xnone required" ; then
      LM="$ac_cv_search_log"
    else
      LM=
    fi
fi
AC_SUBST(LM)

JE_COMPILABLE([__attribute__ syntax],
              [static __attribute__((unused)) void foo(void){}],
              [],
              [je_cv_attribute])
if test "x${je_cv_attribute}" = "xyes" ; then
  AC_DEFINE([JEMALLOC_HAVE_ATTR], [ ], [ ])
  if test "x${GCC}" = "xyes" -a "x${abi}" = "xelf"; then
    JE_CFLAGS_ADD([-fvisibility=hidden])
    JE_CXXFLAGS_ADD([-fvisibility=hidden])
  fi
fi
dnl Check for tls_model attribute support (clang 3.0 still lacks support).
JE_CFLAGS_SAVE()
JE_CFLAGS_ADD([-Werror])
JE_CFLAGS_ADD([-herror_on_warning])
JE_COMPILABLE([tls_model attribute], [],
              [static __thread int
               __attribute__((tls_model("initial-exec"), unused)) foo;
               foo = 0;],
              [je_cv_tls_model])
JE_CFLAGS_RESTORE()
dnl (Setting of JEMALLOC_TLS_MODEL is done later, after we've checked for
dnl --disable-initial-exec-tls)

dnl Check for alloc_size attribute support.
JE_CFLAGS_SAVE()
JE_CFLAGS_ADD([-Werror])
JE_CFLAGS_ADD([-herror_on_warning])
JE_COMPILABLE([alloc_size attribute], [#include <stdlib.h>],
              [void *foo(size_t size) __attribute__((alloc_size(1)));],
              [je_cv_alloc_size])
JE_CFLAGS_RESTORE()
if test "x${je_cv_alloc_size}" = "xyes" ; then
  AC_DEFINE([JEMALLOC_HAVE_ATTR_ALLOC_SIZE], [ ], [ ])
fi
dnl Check for format(gnu_printf, ...) attribute support.
JE_CFLAGS_SAVE()
JE_CFLAGS_ADD([-Werror])
JE_CFLAGS_ADD([-herror_on_warning])
JE_COMPILABLE([format(gnu_printf, ...) attribute], [#include <stdlib.h>],
              [void *foo(const char *format, ...) __attribute__((format(gnu_printf, 1, 2)));],
              [je_cv_format_gnu_printf])
JE_CFLAGS_RESTORE()
if test "x${je_cv_format_gnu_printf}" = "xyes" ; then
  AC_DEFINE([JEMALLOC_HAVE_ATTR_FORMAT_GNU_PRINTF], [ ], [ ])
fi
dnl Check for format(printf, ...) attribute support.
JE_CFLAGS_SAVE()
JE_CFLAGS_ADD([-Werror])
JE_CFLAGS_ADD([-herror_on_warning])
JE_COMPILABLE([format(printf, ...) attribute], [#include <stdlib.h>],
              [void *foo(const char *format, ...) __attribute__((format(printf, 1, 2)));],
              [je_cv_format_printf])
JE_CFLAGS_RESTORE()
if test "x${je_cv_format_printf}" = "xyes" ; then
  AC_DEFINE([JEMALLOC_HAVE_ATTR_FORMAT_PRINTF], [ ], [ ])
fi

dnl Check for format_arg(...) attribute support.
JE_CFLAGS_SAVE()
JE_CFLAGS_ADD([-Werror])
JE_CFLAGS_ADD([-herror_on_warning])
JE_COMPILABLE([format(printf, ...) attribute], [#include <stdlib.h>],
              [const char * __attribute__((__format_arg__(1))) foo(const char *format);],
              [je_cv_format_arg])
JE_CFLAGS_RESTORE()
if test "x${je_cv_format_arg}" = "xyes" ; then
  AC_DEFINE([JEMALLOC_HAVE_ATTR_FORMAT_ARG], [ ], [ ])
fi

dnl Check for fallthrough attribute support.
JE_CFLAGS_SAVE()
JE_CFLAGS_ADD([-Wimplicit-fallthrough])
JE_COMPILABLE([fallthrough attribute],
              [#if !__has_attribute(fallthrough)
               #error "foo"
               #endif],
              [int x = 0;
               switch (x) {
               case 0: __attribute__((__fallthrough__));
               case 1: return 1;
               }],
              [je_cv_fallthrough])
JE_CFLAGS_RESTORE()
if test "x${je_cv_fallthrough}" = "xyes" ; then
  AC_DEFINE([JEMALLOC_HAVE_ATTR_FALLTHROUGH], [ ], [ ])
  JE_CFLAGS_ADD([-Wimplicit-fallthrough])
  JE_CXXFLAGS_ADD([-Wimplicit-fallthrough])
fi

dnl Check for cold attribute support.
JE_CFLAGS_SAVE()
JE_CFLAGS_ADD([-Werror])
JE_CFLAGS_ADD([-herror_on_warning])
JE_COMPILABLE([cold attribute], [],
              [__attribute__((__cold__)) void foo();],
              [je_cv_cold])
JE_CFLAGS_RESTORE()
if test "x${je_cv_cold}" = "xyes" ; then
  AC_DEFINE([JEMALLOC_HAVE_ATTR_COLD], [ ], [ ])
fi

dnl Check for deprecated attribute support.
JE_CFLAGS_SAVE()
JE_CFLAGS_ADD([-Wdeprecated-declarations])
JE_COMPILABLE([deprecated attribute],
              [#if !__has_attribute(deprecated)
               #error "deprecated attribute not supported"
               #endif
               struct has_deprecated_field {
                   int good;
                   int __attribute__((deprecated("Do not use"))) bad;
               };
              ],
              [struct has_deprecated_field instance;
               instance.good = 0;
               instance.bad = 1;
              ],
              [je_cv_deprecated])
JE_CFLAGS_RESTORE()
if test "x${je_cv_deprecated}" = "xyes" ; then
  AC_DEFINE([JEMALLOC_HAVE_ATTR_DEPRECATED], [ ], [ ])
  JE_CFLAGS_ADD([-Wdeprecated-declarations])
  JE_CXXFLAGS_ADD([-Wdeprecated-declarations])
fi

dnl Check for VM_MAKE_TAG for mmap support.
JE_COMPILABLE([vm_make_tag],
	      [#include <sys/mman.h>
	       #include <mach/vm_statistics.h>],
	      [void *p;
	       p = mmap(0, 16, PROT_READ, MAP_ANON|MAP_PRIVATE, VM_MAKE_TAG(1), 0);
	       munmap(p, 16);],
	      [je_cv_vm_make_tag])
if test "x${je_cv_vm_make_tag}" = "xyes" ; then
  AC_DEFINE([JEMALLOC_HAVE_VM_MAKE_TAG], [ ], [ ])
fi

dnl Support optional additions to rpath.
AC_ARG_WITH([rpath],
  [AS_HELP_STRING([--with-rpath=<rpath>], [Colon-separated rpath (ELF systems only)])],
if test "x$with_rpath" = "xno" ; then
  RPATH_EXTRA=
else
  RPATH_EXTRA="`echo $with_rpath | tr \":\" \" \"`"
fi,
  RPATH_EXTRA=
)
AC_SUBST([RPATH_EXTRA])

dnl Disable rules that do automatic regeneration of configure output by default.
AC_ARG_ENABLE([autogen],
  [AS_HELP_STRING([--enable-autogen], [Automatically regenerate configure output])],
if test "x$enable_autogen" = "xno" ; then
  enable_autogen="0"
else
  enable_autogen="1"
fi
,
enable_autogen="0"
)
AC_SUBST([enable_autogen])

AC_PROG_INSTALL
AC_PROG_RANLIB
AC_PATH_PROG([LD], [ld], [false], [$PATH])
AC_PATH_PROG([AUTOCONF], [autoconf], [false], [$PATH])

dnl Enable documentation
AC_ARG_ENABLE([doc],
	      [AS_HELP_STRING([--enable-doc], [Build documentation])],
if test "x$enable_doc" = "xno" ; then
  enable_doc="0"
else
  enable_doc="1"
fi
,
enable_doc="1"
)
AC_SUBST([enable_doc])

dnl Enable shared libs
AC_ARG_ENABLE([shared],
  [AS_HELP_STRING([--enable-shared], [Build shared libaries])],
if test "x$enable_shared" = "xno" ; then
  enable_shared="0"
else
  enable_shared="1"
fi
,
enable_shared="1"
)
AC_SUBST([enable_shared])

dnl Enable static libs
AC_ARG_ENABLE([static],
  [AS_HELP_STRING([--enable-static], [Build static libaries])],
if test "x$enable_static" = "xno" ; then
  enable_static="0"
else
  enable_static="1"
fi
,
enable_static="1"
)
AC_SUBST([enable_static])

if test "$enable_shared$enable_static" = "00" ; then
  AC_MSG_ERROR([Please enable one of shared or static builds])
fi

dnl Perform no name mangling by default.
AC_ARG_WITH([mangling],
  [AS_HELP_STRING([--with-mangling=<map>], [Mangle symbols in <map>])],
  [mangling_map="$with_mangling"], [mangling_map=""])

dnl Do not prefix public APIs by default.
AC_ARG_WITH([jemalloc_prefix],
  [AS_HELP_STRING([--with-jemalloc-prefix=<prefix>], [Prefix to prepend to all public APIs])],
  [JEMALLOC_PREFIX="$with_jemalloc_prefix"],
  [if test "x$abi" != "xmacho" -a "x$abi" != "xpecoff"; then
  JEMALLOC_PREFIX=""
else
  JEMALLOC_PREFIX="je_"
fi]
)
if test "x$JEMALLOC_PREFIX" = "x" ; then
  AC_DEFINE([JEMALLOC_IS_MALLOC], [ ], [ ])
else
  JEMALLOC_CPREFIX=`echo ${JEMALLOC_PREFIX} | tr "a-z" "A-Z"`
  AC_DEFINE_UNQUOTED([JEMALLOC_PREFIX], ["$JEMALLOC_PREFIX"], [ ])
  AC_DEFINE_UNQUOTED([JEMALLOC_CPREFIX], ["$JEMALLOC_CPREFIX"], [ ])
fi
AC_SUBST([JEMALLOC_PREFIX])
AC_SUBST([JEMALLOC_CPREFIX])

AC_ARG_WITH([export],
  [AS_HELP_STRING([--without-export], [disable exporting jemalloc public APIs])],
  [if test "x$with_export" = "xno"; then
  AC_DEFINE([JEMALLOC_EXPORT], [ ], [ ])
fi]
)

public_syms="aligned_alloc calloc dallocx free free_sized free_aligned_sized mallctl mallctlbymib mallctlnametomib malloc malloc_conf malloc_conf_2_conf_harder malloc_message malloc_stats_print malloc_usable_size mallocx smallocx_${jemalloc_version_gid} nallocx posix_memalign rallocx realloc sallocx sdallocx xallocx"
dnl Check for additional platform-specific public API functions.
AC_CHECK_FUNC([memalign],
	      [AC_DEFINE([JEMALLOC_OVERRIDE_MEMALIGN], [ ], [ ])
	       public_syms="${public_syms} memalign"])
AC_CHECK_FUNC([valloc],
	      [AC_DEFINE([JEMALLOC_OVERRIDE_VALLOC], [ ], [ ])
	       public_syms="${public_syms} valloc"])
AC_CHECK_FUNC([pvalloc],
	      [AC_DEFINE([JEMALLOC_OVERRIDE_PVALLOC], [ ], [ ])
	       public_syms="${public_syms} pvalloc"])
AC_CHECK_FUNC([malloc_size],
	      [AC_DEFINE([JEMALLOC_HAVE_MALLOC_SIZE], [ ], [ ])
	       public_syms="${public_syms} malloc_size"])

dnl Check for allocator-related functions that should be wrapped.
wrap_syms=
if test "x${JEMALLOC_PREFIX}" = "x" ; then
  AC_CHECK_FUNC([__libc_calloc],
		[AC_DEFINE([JEMALLOC_OVERRIDE___LIBC_CALLOC], [ ], [ ])
		 wrap_syms="${wrap_syms} __libc_calloc"])
  AC_CHECK_FUNC([__libc_free],
		[AC_DEFINE([JEMALLOC_OVERRIDE___LIBC_FREE], [ ], [ ])
		 wrap_syms="${wrap_syms} __libc_free"])
  dnl __libc_free_sized and __libc_free_aligned_sized are here speculatively
  dnl under the assumption that glibc will eventually define symbols with these
  dnl names. In the event glibc chooses different names for these symbols,
  dnl these will need to be amended to match.
  AC_CHECK_FUNC([__libc_free_sized],
		[AC_DEFINE([JEMALLOC_OVERRIDE___LIBC_FREE_SIZED], [ ], [ ])
		 wrap_syms="${wrap_syms} __libc_free_sized"])
  AC_CHECK_FUNC([__libc_free_aligned_sized],
		[AC_DEFINE([JEMALLOC_OVERRIDE___LIBC_FREE_ALIGNED_SIZED], [ ], [ ])
		 wrap_syms="${wrap_syms} __libc_free_aligned_sized"])
  AC_CHECK_FUNC([__libc_malloc],
		[AC_DEFINE([JEMALLOC_OVERRIDE___LIBC_MALLOC], [ ], [ ])
		 wrap_syms="${wrap_syms} __libc_malloc"])
  AC_CHECK_FUNC([__libc_memalign],
		[AC_DEFINE([JEMALLOC_OVERRIDE___LIBC_MEMALIGN], [ ], [ ])
		 wrap_syms="${wrap_syms} __libc_memalign"])
  AC_CHECK_FUNC([__libc_realloc],
		[AC_DEFINE([JEMALLOC_OVERRIDE___LIBC_REALLOC], [ ], [ ])
		 wrap_syms="${wrap_syms} __libc_realloc"])
  AC_CHECK_FUNC([__libc_valloc],
		[AC_DEFINE([JEMALLOC_OVERRIDE___LIBC_VALLOC], [ ], [ ])
		 wrap_syms="${wrap_syms} __libc_valloc"])
  AC_CHECK_FUNC([__libc_pvalloc],
		[AC_DEFINE([JEMALLOC_OVERRIDE___LIBC_PVALLOC], [ ], [ ])
		 wrap_syms="${wrap_syms} __libc_pvalloc"])
  AC_CHECK_FUNC([__posix_memalign],
		[AC_DEFINE([JEMALLOC_OVERRIDE___POSIX_MEMALIGN], [ ], [ ])
		 wrap_syms="${wrap_syms} __posix_memalign"])
fi

case "${host}" in
  *-*-mingw* | *-*-cygwin*)
    wrap_syms="${wrap_syms} tls_callback"
    ;;
  *)
    ;;
esac

dnl Mangle library-private APIs.
AC_ARG_WITH([private_namespace],
  [AS_HELP_STRING([--with-private-namespace=<prefix>], [Prefix to prepend to all library-private APIs])],
  [JEMALLOC_PRIVATE_NAMESPACE="${with_private_namespace}je_"],
  [JEMALLOC_PRIVATE_NAMESPACE="je_"]
)
AC_DEFINE_UNQUOTED([JEMALLOC_PRIVATE_NAMESPACE], [$JEMALLOC_PRIVATE_NAMESPACE], [ ])
private_namespace="$JEMALLOC_PRIVATE_NAMESPACE"
AC_SUBST([private_namespace])

dnl Do not add suffix to installed files by default.
AC_ARG_WITH([install_suffix],
  [AS_HELP_STRING([--with-install-suffix=<suffix>], [Suffix to append to all installed files])],
  [case "$with_install_suffix" in
   *\ * ) AC_MSG_ERROR([Install suffix should not contain spaces]) ;;
   * ) INSTALL_SUFFIX="$with_install_suffix" ;;
esac],
  [INSTALL_SUFFIX=]
)
install_suffix="$INSTALL_SUFFIX"
AC_SUBST([install_suffix])

dnl Specify default malloc_conf.
AC_ARG_WITH([malloc_conf],
  [AS_HELP_STRING([--with-malloc-conf=<malloc_conf>], [config.malloc_conf options string])],
  [JEMALLOC_CONFIG_MALLOC_CONF="$with_malloc_conf"],
  [JEMALLOC_CONFIG_MALLOC_CONF=""]
)
config_malloc_conf="$JEMALLOC_CONFIG_MALLOC_CONF"
AC_DEFINE_UNQUOTED([JEMALLOC_CONFIG_MALLOC_CONF], ["$config_malloc_conf"], [ ])

dnl Substitute @je_@ in jemalloc_protos.h.in, primarily to make generation of
dnl jemalloc_protos_jet.h easy.
je_="je_"
AC_SUBST([je_])

cfgoutputs_in="Makefile.in"
cfgoutputs_in="${cfgoutputs_in} jemalloc.pc.in"
cfgoutputs_in="${cfgoutputs_in} doc/html.xsl.in"
cfgoutputs_in="${cfgoutputs_in} doc/manpages.xsl.in"
cfgoutputs_in="${cfgoutputs_in} doc/jemalloc.xml.in"
cfgoutputs_in="${cfgoutputs_in} include/jemalloc/jemalloc_macros.h.in"
cfgoutputs_in="${cfgoutputs_in} include/jemalloc/jemalloc_protos.h.in"
cfgoutputs_in="${cfgoutputs_in} include/jemalloc/jemalloc_typedefs.h.in"
cfgoutputs_in="${cfgoutputs_in} include/jemalloc/internal/jemalloc_preamble.h.in"
cfgoutputs_in="${cfgoutputs_in} test/test.sh.in"
cfgoutputs_in="${cfgoutputs_in} test/include/test/jemalloc_test.h.in"

cfgoutputs_out="Makefile"
cfgoutputs_out="${cfgoutputs_out} jemalloc.pc"
cfgoutputs_out="${cfgoutputs_out} doc/html.xsl"
cfgoutputs_out="${cfgoutputs_out} doc/manpages.xsl"
cfgoutputs_out="${cfgoutputs_out} doc/jemalloc.xml"
cfgoutputs_out="${cfgoutputs_out} include/jemalloc/jemalloc_macros.h"
cfgoutputs_out="${cfgoutputs_out} include/jemalloc/jemalloc_protos.h"
cfgoutputs_out="${cfgoutputs_out} include/jemalloc/jemalloc_typedefs.h"
cfgoutputs_out="${cfgoutputs_out} include/jemalloc/internal/jemalloc_preamble.h"
cfgoutputs_out="${cfgoutputs_out} test/test.sh"
cfgoutputs_out="${cfgoutputs_out} test/include/test/jemalloc_test.h"

cfgoutputs_tup="Makefile"
cfgoutputs_tup="${cfgoutputs_tup} jemalloc.pc:jemalloc.pc.in"
cfgoutputs_tup="${cfgoutputs_tup} doc/html.xsl:doc/html.xsl.in"
cfgoutputs_tup="${cfgoutputs_tup} doc/manpages.xsl:doc/manpages.xsl.in"
cfgoutputs_tup="${cfgoutputs_tup} doc/jemalloc.xml:doc/jemalloc.xml.in"
cfgoutputs_tup="${cfgoutputs_tup} include/jemalloc/jemalloc_macros.h:include/jemalloc/jemalloc_macros.h.in"
cfgoutputs_tup="${cfgoutputs_tup} include/jemalloc/jemalloc_protos.h:include/jemalloc/jemalloc_protos.h.in"
cfgoutputs_tup="${cfgoutputs_tup} include/jemalloc/jemalloc_typedefs.h:include/jemalloc/jemalloc_typedefs.h.in"
cfgoutputs_tup="${cfgoutputs_tup} include/jemalloc/internal/jemalloc_preamble.h"
cfgoutputs_tup="${cfgoutputs_tup} test/test.sh:test/test.sh.in"
cfgoutputs_tup="${cfgoutputs_tup} test/include/test/jemalloc_test.h:test/include/test/jemalloc_test.h.in"

cfghdrs_in="include/jemalloc/jemalloc_defs.h.in"
cfghdrs_in="${cfghdrs_in} include/jemalloc/internal/jemalloc_internal_defs.h.in"
cfghdrs_in="${cfghdrs_in} include/jemalloc/internal/private_symbols.sh"
cfghdrs_in="${cfghdrs_in} include/jemalloc/internal/private_namespace.sh"
cfghdrs_in="${cfghdrs_in} include/jemalloc/internal/public_namespace.sh"
cfghdrs_in="${cfghdrs_in} include/jemalloc/internal/public_unnamespace.sh"
cfghdrs_in="${cfghdrs_in} include/jemalloc/jemalloc_rename.sh"
cfghdrs_in="${cfghdrs_in} include/jemalloc/jemalloc_mangle.sh"
cfghdrs_in="${cfghdrs_in} include/jemalloc/jemalloc.sh"
cfghdrs_in="${cfghdrs_in} test/include/test/jemalloc_test_defs.h.in"

cfghdrs_out="include/jemalloc/jemalloc_defs.h"
cfghdrs_out="${cfghdrs_out} include/jemalloc/jemalloc${install_suffix}.h"
cfghdrs_out="${cfghdrs_out} include/jemalloc/internal/private_symbols.awk"
cfghdrs_out="${cfghdrs_out} include/jemalloc/internal/private_symbols_jet.awk"
cfghdrs_out="${cfghdrs_out} include/jemalloc/internal/public_symbols.txt"
cfghdrs_out="${cfghdrs_out} include/jemalloc/internal/public_namespace.h"
cfghdrs_out="${cfghdrs_out} include/jemalloc/internal/public_unnamespace.h"
cfghdrs_out="${cfghdrs_out} include/jemalloc/jemalloc_protos_jet.h"
cfghdrs_out="${cfghdrs_out} include/jemalloc/jemalloc_rename.h"
cfghdrs_out="${cfghdrs_out} include/jemalloc/jemalloc_mangle.h"
cfghdrs_out="${cfghdrs_out} include/jemalloc/jemalloc_mangle_jet.h"
cfghdrs_out="${cfghdrs_out} include/jemalloc/internal/jemalloc_internal_defs.h"
cfghdrs_out="${cfghdrs_out} test/include/test/jemalloc_test_defs.h"

cfghdrs_tup="include/jemalloc/jemalloc_defs.h:include/jemalloc/jemalloc_defs.h.in"
cfghdrs_tup="${cfghdrs_tup} include/jemalloc/internal/jemalloc_internal_defs.h:include/jemalloc/internal/jemalloc_internal_defs.h.in"
cfghdrs_tup="${cfghdrs_tup} test/include/test/jemalloc_test_defs.h:test/include/test/jemalloc_test_defs.h.in"

dnl ============================================================================
dnl jemalloc build options.
dnl

dnl Do not compile with debugging by default.
AC_ARG_ENABLE([debug],
  [AS_HELP_STRING([--enable-debug],
                  [Build debugging code])],
[if test "x$enable_debug" = "xno" ; then
  enable_debug="0"
else
  enable_debug="1"
fi
],
[enable_debug="0"]
)
if test "x$enable_debug" = "x1" ; then
  AC_DEFINE([JEMALLOC_DEBUG], [ ], [ ])
fi
AC_SUBST([enable_debug])

dnl Only optimize if not debugging.
if test "x$enable_debug" = "x0" ; then
  if test "x$GCC" = "xyes" ; then
    JE_CFLAGS_ADD([-O3])
    JE_CXXFLAGS_ADD([-O3])
    JE_CFLAGS_ADD([-funroll-loops])
  elif test "x$je_cv_msvc" = "xyes" ; then
    JE_CFLAGS_ADD([-O2])
    JE_CXXFLAGS_ADD([-O2])
  else
    JE_CFLAGS_ADD([-O])
    JE_CXXFLAGS_ADD([-O])
  fi
fi

dnl Enable statistics calculation by default.
AC_ARG_ENABLE([stats],
  [AS_HELP_STRING([--disable-stats],
                  [Disable statistics calculation/reporting])],
[if test "x$enable_stats" = "xno" ; then
  enable_stats="0"
else
  enable_stats="1"
fi
],
[enable_stats="1"]
)
if test "x$enable_stats" = "x1" ; then
  AC_DEFINE([JEMALLOC_STATS], [ ], [ ])
fi
AC_SUBST([enable_stats])

dnl Disable reading configuration from file and environment variable
AC_ARG_ENABLE([user_config],
  [AS_HELP_STRING([--disable-user-config],
  [Do not read malloc config from /etc/malloc.conf or MALLOC_CONF])],
[if test "x$enable_user_config" = "xno" ; then
  enable_user_config="0"
else
  enable_user_config="1"
fi
],
[enable_user_config="1"]
)
if test "x$enable_user_config" = "x1" ; then
  AC_DEFINE([JEMALLOC_CONFIG_ENV], [ ], [ ])
  AC_DEFINE([JEMALLOC_CONFIG_FILE], [ ], [ ])
fi

dnl Do not enable smallocx by default.
AC_ARG_ENABLE([experimental_smallocx],
  [AS_HELP_STRING([--enable-experimental-smallocx], [Enable experimental smallocx API])],
[if test "x$enable_experimental_smallocx" = "xno" ; then
enable_experimental_smallocx="0"
else
enable_experimental_smallocx="1"
fi
],
[enable_experimental_smallocx="0"]
)
if test "x$enable_experimental_smallocx" = "x1" ; then
  AC_DEFINE([JEMALLOC_EXPERIMENTAL_SMALLOCX_API], [ ], [ ])
fi
AC_SUBST([enable_experimental_smallocx])

dnl Do not enable profiling by default.
AC_ARG_ENABLE([prof],
  [AS_HELP_STRING([--enable-prof], [Enable allocation profiling])],
[if test "x$enable_prof" = "xno" ; then
  enable_prof="0"
else
  enable_prof="1"
fi
],
[enable_prof="0"]
)
if test "x$enable_prof" = "x1" ; then
  backtrace_method=""
else
  backtrace_method="N/A"
fi

AC_ARG_ENABLE([prof-libunwind],
  [AS_HELP_STRING([--enable-prof-libunwind], [Use libunwind for backtracing])],
[if test "x$enable_prof_libunwind" = "xno" ; then
  enable_prof_libunwind="0"
else
  enable_prof_libunwind="1"
  if test "x$enable_prof" = "x0" ; then
    AC_MSG_ERROR([--enable-prof-libunwind should only be used with --enable-prof])
  fi
fi
],
[enable_prof_libunwind="0"]
)
AC_ARG_WITH([static_libunwind],
  [AS_HELP_STRING([--with-static-libunwind=<libunwind.a>],
  [Path to static libunwind library; use rather than dynamically linking])],
if test "x$with_static_libunwind" = "xno" ; then
  LUNWIND="-lunwind"
else
  if test ! -f "$with_static_libunwind" ; then
    AC_MSG_ERROR([Static libunwind not found: $with_static_libunwind])
  fi
  LUNWIND="$with_static_libunwind"
fi,
  LUNWIND="-lunwind"
)
if test "x$backtrace_method" = "x" -a "x$enable_prof_libunwind" = "x1" ; then
  AC_CHECK_HEADERS([libunwind.h], , [enable_prof_libunwind="0"])
  if test "x$LUNWIND" = "x-lunwind" ; then
    AC_CHECK_LIB([unwind], [unw_backtrace], [JE_APPEND_VS(LIBS, $LUNWIND)],
                 [enable_prof_libunwind="0"])
  else
    JE_APPEND_VS(LIBS, $LUNWIND)
  fi
  if test "x${enable_prof_libunwind}" = "x1" ; then
    backtrace_method="libunwind"
    AC_DEFINE([JEMALLOC_PROF_LIBUNWIND], [ ], [ ])
  fi
fi

AC_ARG_ENABLE([prof-libgcc],
  [AS_HELP_STRING([--disable-prof-libgcc],
  [Do not use libgcc for backtracing])],
[if test "x$enable_prof_libgcc" = "xno" ; then
  enable_prof_libgcc="0"
else
  enable_prof_libgcc="1"
fi
],
[enable_prof_libgcc="1"]
)
if test "x$backtrace_method" = "x" -a "x$enable_prof_libgcc" = "x1" \
     -a "x$GCC" = "xyes" ; then
  AC_CHECK_HEADERS([unwind.h], , [enable_prof_libgcc="0"])
  if test "x${enable_prof_libgcc}" = "x1" ; then
    AC_CHECK_LIB([gcc], [_Unwind_Backtrace], [JE_APPEND_VS(LIBS, -lgcc)], [enable_prof_libgcc="0"])
  fi
  if test "x${enable_prof_libgcc}" = "x1" ; then
    backtrace_method="libgcc"
    AC_DEFINE([JEMALLOC_PROF_LIBGCC], [ ], [ ])
  fi
else
  enable_prof_libgcc="0"
fi

AC_ARG_ENABLE([prof-gcc],
  [AS_HELP_STRING([--disable-prof-gcc],
  [Do not use gcc intrinsics for backtracing])],
[if test "x$enable_prof_gcc" = "xno" ; then
  enable_prof_gcc="0"
else
  enable_prof_gcc="1"
fi
],
[enable_prof_gcc="1"]
)
if test "x$backtrace_method" = "x" -a "x$enable_prof_gcc" = "x1" \
     -a "x$GCC" = "xyes" ; then
  JE_CFLAGS_ADD([-fno-omit-frame-pointer])
  backtrace_method="gcc intrinsics"
  AC_DEFINE([JEMALLOC_PROF_GCC], [ ], [ ])
else
  enable_prof_gcc="0"
fi

if test "x$backtrace_method" = "x" ; then
  backtrace_method="none (disabling profiling)"
  enable_prof="0"
fi
AC_MSG_CHECKING([configured backtracing method])
AC_MSG_RESULT([$backtrace_method])
if test "x$enable_prof" = "x1" ; then
  dnl Heap profiling uses the log(3) function.
  JE_APPEND_VS(LIBS, $LM)

  AC_DEFINE([JEMALLOC_PROF], [ ], [ ])
fi
AC_SUBST([enable_prof])

dnl Indicate whether adjacent virtual memory mappings automatically coalesce
dnl (and fragment on demand).
if test "x${maps_coalesce}" = "x1" ; then
  AC_DEFINE([JEMALLOC_MAPS_COALESCE], [ ], [ ])
fi

dnl Indicate whether to retain memory (rather than using munmap()) by default.
if test "x$default_retain" = "x1" ; then
  AC_DEFINE([JEMALLOC_RETAIN], [ ], [ ])
fi

dnl Indicate whether realloc(ptr, 0) defaults to the "alloc" behavior.
if test "x$zero_realloc_default_free" = "x1" ; then
  AC_DEFINE([JEMALLOC_ZERO_REALLOC_DEFAULT_FREE], [ ], [ ])
fi

dnl Support allocation from DSS by default
AC_ARG_ENABLE([dss],
  [AS_HELP_STRING([--disable-dss], [Disable usage of sbrk(2)])],
[if test "x$enable_dss" = "xno" ; then
  enable_dss="0"
else
  enable_dss="1"
fi
],
[enable_dss="1"]
)

dnl Enable allocation from DSS if supported by the OS.
have_dss="1"
dnl Check whether the BSD/SUSv1 sbrk() exists.  If not, disable DSS support.
AC_CHECK_FUNC([sbrk], [have_sbrk="1"], [have_sbrk="0"])
if test "x$have_sbrk" = "x1" ; then
  if test "x$sbrk_deprecated" = "x1" ; then
    AC_MSG_RESULT([Disabling dss allocation because sbrk is deprecated])
    have_dss="0"
  fi
else
  have_dss="0"
fi

if test "x$have_dss" = "x1" -a "x$enable_dss" = "x1" ; then
  AC_DEFINE([JEMALLOC_DSS], [ ], [ ])
fi

dnl Support the junk/zero filling option by default.
AC_ARG_ENABLE([fill],
  [AS_HELP_STRING([--disable-fill], [Disable support for junk/zero filling])],
[if test "x$enable_fill" = "xno" ; then
  enable_fill="0"
else
  enable_fill="1"
fi
],
[enable_fill="1"]
)
if test "x$enable_fill" = "x1" ; then
  AC_DEFINE([JEMALLOC_FILL], [ ], [ ])
fi
AC_SUBST([enable_fill])

dnl Disable utrace(2)-based tracing by default.
AC_ARG_ENABLE([utrace],
  [AS_HELP_STRING([--enable-utrace], [Enable utrace(2)-based tracing])],
[if test "x$enable_utrace" = "xno" ; then
  enable_utrace="0"
else
  enable_utrace="1"
fi
],
[enable_utrace="0"]
)
JE_COMPILABLE([utrace(2)], [
#include <sys/types.h>
#include <sys/param.h>
#include <sys/time.h>
#include <sys/uio.h>
#include <sys/ktrace.h>
], [
	utrace((void *)0, 0);
], [je_cv_utrace])
if test "x${je_cv_utrace}" = "xno" ; then
  JE_COMPILABLE([utrace(2) with label], [
  #include <sys/types.h>
  #include <sys/param.h>
  #include <sys/time.h>
  #include <sys/uio.h>
  #include <sys/ktrace.h>
  ], [
	  utrace((void *)0, (void *)0, 0);
  ], [je_cv_utrace_label])
  if test "x${je_cv_utrace_label}" = "xno"; then
    enable_utrace="0"
  fi
  if test "x$enable_utrace" = "x1" ; then
    AC_DEFINE([JEMALLOC_UTRACE_LABEL], [ ], [ ])
  fi
else
  if test "x$enable_utrace" = "x1" ; then
    AC_DEFINE([JEMALLOC_UTRACE], [ ], [ ])
  fi
fi
AC_SUBST([enable_utrace])

dnl Disable experimental sdt tracing by default.
AC_ARG_ENABLE([experimental-sdt],
  [AS_HELP_STRING([--enable-experimental-sdt], [Enable systemtap USDT probes])],
[if test "x$enable_experimental_sdt" = "xno" ; then
  enable_experimental_sdt="0"
else
	JE_COMPILABLE([systemtap sdt], [
#include <sys/sdt.h>
	], [
void foo(int i, void *p) { STAP_PROBE2(jemalloc, test, i, p); }
  	],
	[je_cv_stap_sdt])

	if test "x${je_cv_stap_sdt}" = "xyes" ; then
	   enable_experimental_sdt="1"
	elif test "x${abi}" = "xelf" ; then
	     case "${host}" in
	     	  *-*-linux-android*)
			case "${host_cpu}" in aarch64|x86_64)
			     enable_experimental_sdt="2"
			     ;;
			esac
			;;
		  *-*-linux*)
			case "${host_cpu}" in x86_64|aarch64|arm*)
			      enable_experimental_sdt="2"
			      ;;
			esac
		        ;;
		  *)
			enable_experimental_sdt="0"
			AC_MSG_ERROR([Unsupported sdt on this platform])
			;;
	     esac
	else
	   AC_MSG_ERROR([Unsupported sdt on this platform])
   	fi
fi
],
[enable_experimental_sdt="0"]
)

if test "x$enable_experimental_sdt" = "x1" ; then
    AC_DEFINE([JEMALLOC_EXPERIMENTAL_USDT_STAP], [ ], [ ])
elif test "x$enable_experimental_sdt" = "x2"; then
    AC_DEFINE([JEMALLOC_EXPERIMENTAL_USDT_CUSTOM], [ ], [ ])
fi
AC_SUBST([enable_experimental_sdt])

dnl Do not support the xmalloc option by default.
AC_ARG_ENABLE([xmalloc],
  [AS_HELP_STRING([--enable-xmalloc], [Support xmalloc option])],
[if test "x$enable_xmalloc" = "xno" ; then
  enable_xmalloc="0"
else
  enable_xmalloc="1"
fi
],
[enable_xmalloc="0"]
)
if test "x$enable_xmalloc" = "x1" ; then
  AC_DEFINE([JEMALLOC_XMALLOC], [ ], [ ])
fi
AC_SUBST([enable_xmalloc])

dnl Support cache-oblivious allocation alignment by default.
AC_ARG_ENABLE([cache-oblivious],
  [AS_HELP_STRING([--disable-cache-oblivious],
                  [Disable support for cache-oblivious allocation alignment])],
[if test "x$enable_cache_oblivious" = "xno" ; then
  enable_cache_oblivious="0"
else
  enable_cache_oblivious="1"
fi
],
[enable_cache_oblivious="1"]
)
if test "x$enable_cache_oblivious" = "x1" ; then
  AC_DEFINE([JEMALLOC_CACHE_OBLIVIOUS], [ ], [ ])
fi
AC_SUBST([enable_cache_oblivious])

dnl Do not log by default.
AC_ARG_ENABLE([log],
  [AS_HELP_STRING([--enable-log], [Support debug logging])],
[if test "x$enable_log" = "xno" ; then
  enable_log="0"
else
  enable_log="1"
fi
],
[enable_log="0"]
)
if test "x$enable_log" = "x1" ; then
  AC_DEFINE([JEMALLOC_LOG], [ ], [ ])
fi
AC_SUBST([enable_log])

dnl Do not use readlinkat by default
AC_ARG_ENABLE([readlinkat],
  [AS_HELP_STRING([--enable-readlinkat], [Use readlinkat over readlink])],
[if test "x$enable_readlinkat" = "xno" ; then
  enable_readlinkat="0"
else
  enable_readlinkat="1"
fi
],
[enable_readlinkat="0"]
)
if test "x$enable_readlinkat" = "x1" ; then
  AC_DEFINE([JEMALLOC_READLINKAT], [ ], [ ])
fi
AC_SUBST([enable_readlinkat])

dnl Do not force getenv by default
AC_ARG_ENABLE([force-getenv],
  [AS_HELP_STRING([--enable-force-getenv], [Use getenv over secure_getenv])],
[if test "x$enable_force_getenv" = "xno" ; then
  enable_force_getenv="0"
else
  enable_force_getenv="1"
fi
],
[enable_force_getenv="0"]
)
if test "x$enable_force_getenv" = "x1" ; then
  AC_DEFINE([JEMALLOC_FORCE_GETENV], [ ], [ ])
fi
AC_SUBST([force_getenv])

dnl Avoid extra safety checks by default
AC_ARG_ENABLE([opt-safety-checks],
  [AS_HELP_STRING([--enable-opt-safety-checks],
  [Perform certain low-overhead checks, even in opt mode])],
[if test "x$enable_opt_safety_checks" = "xno" ; then
  enable_opt_safety_checks="0"
else
  enable_opt_safety_checks="1"
fi
],
[enable_opt_safety_checks="0"]
)
if test "x$enable_opt_safety_checks" = "x1" ; then
  AC_DEFINE([JEMALLOC_OPT_SAFETY_CHECKS], [ ], [ ])
fi
AC_SUBST([enable_opt_safety_checks])

dnl Look for sized-deallocation bugs while otherwise being in opt mode.
AC_ARG_ENABLE([opt-size-checks],
  [AS_HELP_STRING([--enable-opt-size-checks],
  [Perform sized-deallocation argument checks, even in opt mode])],
[if test "x$enable_opt_size_checks" = "xno" ; then
  enable_opt_size_checks="0"
else
  enable_opt_size_checks="1"
fi
],
[enable_opt_size_checks="0"]
)
if test "x$enable_opt_size_checks" = "x1" ; then
  AC_DEFINE([JEMALLOC_OPT_SIZE_CHECKS], [ ], [ ])
fi
AC_SUBST([enable_opt_size_checks])

dnl Do not check for use-after-free by default.
AC_ARG_ENABLE([uaf-detection],
  [AS_HELP_STRING([--enable-uaf-detection],
  [Allow sampled junk-filling on deallocation to detect use-after-free])],
[if test "x$enable_uaf_detection" = "xno" ; then
  enable_uaf_detection="0"
else
  enable_uaf_detection="1"
fi
],
[enable_uaf_detection="0"]
)
if test "x$enable_uaf_detection" = "x1" ; then
  AC_DEFINE([JEMALLOC_UAF_DETECTION], [ ], [ ])
fi
AC_SUBST([enable_uaf_detection])

JE_COMPILABLE([a program using __builtin_unreachable], [
void foo (void) {
  __builtin_unreachable();
}
], [
	{
		foo();
	}
], [je_cv_gcc_builtin_unreachable])
if test "x${je_cv_gcc_builtin_unreachable}" = "xyes" ; then
  AC_DEFINE([JEMALLOC_INTERNAL_UNREACHABLE], [__builtin_unreachable], [ ])
else
  AC_DEFINE([JEMALLOC_INTERNAL_UNREACHABLE], [abort], [ ])
fi

dnl ============================================================================
dnl Check for  __builtin_ffsl(), then ffsl(3), and fail if neither are found.
dnl One of those two functions should (theoretically) exist on all platforms
dnl that jemalloc currently has a chance of functioning on without modification.
dnl We additionally assume ffs[ll]() or __builtin_ffs[ll]() are defined if
dnl ffsl() or __builtin_ffsl() are defined, respectively.
JE_COMPILABLE([a program using __builtin_ffsl], [
#include <stdio.h>
#include <strings.h>
#include <string.h>
], [
	{
		int rv = __builtin_ffsl(0x08);
		printf("%d\n", rv);
	}
], [je_cv_gcc_builtin_ffsl])
if test "x${je_cv_gcc_builtin_ffsl}" = "xyes" ; then
  AC_DEFINE([JEMALLOC_INTERNAL_FFSLL], [__builtin_ffsll], [ ])
  AC_DEFINE([JEMALLOC_INTERNAL_FFSL], [__builtin_ffsl], [ ])
  AC_DEFINE([JEMALLOC_INTERNAL_FFS], [__builtin_ffs], [ ])
else
  JE_COMPILABLE([a program using ffsl], [
  #include <stdio.h>
  #include <strings.h>
  #include <string.h>
  ], [
	{
		int rv = ffsl(0x08);
		printf("%d\n", rv);
	}
  ], [je_cv_function_ffsl])
  if test "x${je_cv_function_ffsl}" = "xyes" ; then
    AC_DEFINE([JEMALLOC_INTERNAL_FFSLL], [ffsll], [ ])
    AC_DEFINE([JEMALLOC_INTERNAL_FFSL], [ffsl], [ ])
    AC_DEFINE([JEMALLOC_INTERNAL_FFS], [ffs], [ ])
  else
    AC_MSG_ERROR([Cannot build without ffsl(3) or __builtin_ffsl()])
  fi
fi

JE_COMPILABLE([a program using __builtin_popcountl], [
#include <stdio.h>
#include <strings.h>
#include <string.h>
], [
	{
		int rv = __builtin_popcountl(0x08);
		printf("%d\n", rv);
	}
], [je_cv_gcc_builtin_popcountl])
if test "x${je_cv_gcc_builtin_popcountl}" = "xyes" ; then
  AC_DEFINE([JEMALLOC_INTERNAL_POPCOUNT], [__builtin_popcount], [ ])
  AC_DEFINE([JEMALLOC_INTERNAL_POPCOUNTL], [__builtin_popcountl], [ ])
  AC_DEFINE([JEMALLOC_INTERNAL_POPCOUNTLL], [__builtin_popcountll], [ ])
fi

AC_ARG_WITH([lg_quantum],
  [AS_HELP_STRING([--with-lg-quantum=<lg-quantum>],
   [Base 2 log of minimum allocation alignment])])
if test "x$with_lg_quantum" != "x" ; then
  AC_DEFINE_UNQUOTED([LG_QUANTUM], [$with_lg_quantum], [ ])
fi

AC_ARG_WITH([lg_slab_maxregs],
  [AS_HELP_STRING([--with-lg-slab-maxregs=<lg-slab-maxregs>],
   [Base 2 log of maximum number of regions in a slab (used with malloc_conf slab_sizes)])],
  [CONFIG_LG_SLAB_MAXREGS="with_lg_slab_maxregs"],
  [CONFIG_LG_SLAB_MAXREGS=""])
if test "x$with_lg_slab_maxregs" != "x" ; then
  AC_DEFINE_UNQUOTED([CONFIG_LG_SLAB_MAXREGS], [$with_lg_slab_maxregs], [ ])
fi

AC_ARG_WITH([lg_page],
  [AS_HELP_STRING([--with-lg-page=<lg-page>], [Base 2 log of system page size])],
  [LG_PAGE="$with_lg_page"], [LG_PAGE="detect"])
case "${host}" in
  aarch64-apple-darwin*)
      dnl When cross-compile for Apple M1 and no page size specified, use the
      dnl default and skip detecting the page size (which is likely incorrect).
      if test "x${host}" != "x${build}" -a "x$LG_PAGE" = "xdetect"; then
        LG_PAGE=14
      fi
      ;;
  *-*-linux-android)
      if test "x$LG_PAGE" = "xdetect"; then
	AC_CHECK_DECLS([PAGE_SIZE], [LG_PAGE=12], [LG_PAGE=14], [#include <sys/user.h>])
      fi
      ;;
  aarch64-unknown-linux-*)
      if test "x$LG_PAGE" = "xdetect"; then
        LG_PAGE=16
      fi
      ;;
esac
if test "x$LG_PAGE" = "xdetect"; then
  AC_CACHE_CHECK([LG_PAGE],
               [je_cv_lg_page],
               AC_RUN_IFELSE([AC_LANG_PROGRAM(
[[
#include <strings.h>
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
#include <stdio.h>
]],
[[
    int result;
    FILE *f;

#ifdef _WIN32
    SYSTEM_INFO si;
    GetSystemInfo(&si);
    result = si.dwPageSize;
#else
    result = sysconf(_SC_PAGESIZE);
#endif
    if (result == -1) {
	return 1;
    }
    result = JEMALLOC_INTERNAL_FFSL(result) - 1;

    f = fopen("conftest.out", "w");
    if (f == NULL) {
	return 1;
    }
    fprintf(f, "%d", result);
    fclose(f);

    return 0;
]])],
                             [je_cv_lg_page=`cat conftest.out`],
                             [je_cv_lg_page=undefined],
                             [je_cv_lg_page=12]))
fi
if test "x${je_cv_lg_page}" != "x" ; then
  LG_PAGE="${je_cv_lg_page}"
fi
if test "x${LG_PAGE}" != "xundefined" ; then
   AC_DEFINE_UNQUOTED([LG_PAGE], [$LG_PAGE], [ ])
else
   AC_MSG_ERROR([cannot determine value for LG_PAGE])
fi
if test "${LG_PAGE}" -lt 8 ; then
   AC_MSG_ERROR([LG_PAGE must be at least 8 (PAGE >= 256)])
fi

AC_ARG_WITH([lg_hugepage],
  [AS_HELP_STRING([--with-lg-hugepage=<lg-hugepage>],
   [Base 2 log of system huge page size])],
  [je_cv_lg_hugepage="${with_lg_hugepage}"],
  [je_cv_lg_hugepage=""])
if test "x${je_cv_lg_hugepage}" = "x" ; then
  dnl Look in /proc/meminfo (Linux-specific) for information on the default huge
  dnl page size, if any.  The relevant line looks like:
  dnl
  dnl   Hugepagesize:       2048 kB
  if test -e "/proc/meminfo" ; then
    hpsk=[`cat /proc/meminfo 2>/dev/null | \
          grep '^Hugepagesize:[[:space:]]\{1,\}[0-9]\{1,\}[[:space:]]kB$' | \
          awk '{print $2}'`]
    if test "x${hpsk}" != "x" ; then
      je_cv_lg_hugepage=10
      while test "${hpsk}" -gt 1 ; do
        hpsk="$((hpsk / 2))"
        je_cv_lg_hugepage="$((je_cv_lg_hugepage + 1))"
      done
    fi
  fi

  dnl Set default if unable to automatically configure.
  if test "x${je_cv_lg_hugepage}" = "x" ; then
    je_cv_lg_hugepage=21
  fi
fi
if test "x${LG_PAGE}" != "xundefined" -a \
        "${je_cv_lg_hugepage}" -lt "${LG_PAGE}" ; then
  AC_MSG_ERROR([Huge page size (2^${je_cv_lg_hugepage}) must be at least page size (2^${LG_PAGE})])
fi
AC_DEFINE_UNQUOTED([LG_HUGEPAGE], [${je_cv_lg_hugepage}], [ ])

dnl ============================================================================
dnl Enable libdl by default.
AC_ARG_ENABLE([libdl],
  [AS_HELP_STRING([--disable-libdl],
  [Do not use libdl])],
[if test "x$enable_libdl" = "xno" ; then
  enable_libdl="0"
else
  enable_libdl="1"
fi
],
[enable_libdl="1"]
)
AC_SUBST([libdl])

dnl ============================================================================
dnl Configure pthreads.

if test "x$abi" != "xpecoff" ; then
  AC_DEFINE([JEMALLOC_HAVE_PTHREAD], [ ], [ ])
  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], [JE_APPEND_VS(LIBS, -pthread)],
               [AC_SEARCH_LIBS([pthread_create], , ,
                               AC_MSG_ERROR([libpthread is missing]))])
  wrap_syms="${wrap_syms} pthread_create"
  have_pthread="1"

dnl Check if we have dlsym support.
  if test "x$enable_libdl" = "x1" ; then
    have_dlsym="1"
    AC_CHECK_HEADERS([dlfcn.h],
      AC_CHECK_FUNC([dlsym], [],
        [AC_CHECK_LIB([dl], [dlsym], [LIBS="$LIBS -ldl"], [have_dlsym="0"])]),
      [have_dlsym="0"])
    if test "x$have_dlsym" = "x1" ; then
      AC_DEFINE([JEMALLOC_HAVE_DLSYM], [ ], [ ])
    fi
  else
    have_dlsym="0"
  fi

  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
  dnl Check if pthread_setname_np is available with the expected API.
  JE_COMPILABLE([pthread_setname_np(3)], [
#include <pthread.h>
], [
  pthread_setname_np(pthread_self(), "setname_test");
], [je_cv_pthread_setname_np])
  if test "x${je_cv_pthread_setname_np}" = "xyes" ; then
    AC_DEFINE([JEMALLOC_HAVE_PTHREAD_SETNAME_NP], [ ], [ ])
  fi
  dnl Check if pthread_getname_np is not necessarily present despite
  dnl the pthread_setname_np counterpart
  JE_COMPILABLE([pthread_getname_np(3)], [
#include <pthread.h>
#include <stdlib.h>
], [
  {
  	char *name = malloc(16);
  	pthread_getname_np(pthread_self(), name, 16);
	free(name);
  }
], [je_cv_pthread_getname_np])
  if test "x${je_cv_pthread_getname_np}" = "xyes" ; then
    AC_DEFINE([JEMALLOC_HAVE_PTHREAD_GETNAME_NP], [ ], [ ])
  fi
  dnl Check if pthread_set_name_np is available with the expected API.
  JE_COMPILABLE([pthread_set_name_np(3)], [
#include <pthread.h>
#include <pthread_np.h>
], [
  pthread_set_name_np(pthread_self(), "set_name_test");
], [je_cv_pthread_set_name_np])
  if test "x${je_cv_pthread_set_name_np}" = "xyes" ; then
    AC_DEFINE([JEMALLOC_HAVE_PTHREAD_SET_NAME_NP], [ ], [ ])
  fi
  dnl Check if pthread_get_name_np is not necessarily present despite
  dnl the pthread_set_name_np counterpart
  JE_COMPILABLE([pthread_get_name_np(3)], [
#include <pthread.h>
#include <pthread_np.h>
#include <stdlib.h>
], [
  {
  	char *name = malloc(16);
  	pthread_get_name_np(pthread_self(), name, 16);
	free(name);
  }
], [je_cv_pthread_get_name_np])
  if test "x${je_cv_pthread_get_name_np}" = "xyes" ; then
    AC_DEFINE([JEMALLOC_HAVE_PTHREAD_GET_NAME_NP], [ ], [ ])
  fi
  dnl Runtime-check pthread_condattr_setclock and clock_gettime with
  dnl CLOCK_MONOTONIC to confirm the kernel actually supports the
  dnl monotonic clock.
  AC_CACHE_CHECK([whether pthread_condattr_setclock with CLOCK_MONOTONIC is usable],
                 [je_cv_pthread_cond_timedwait_monotonic],
                 AC_RUN_IFELSE([AC_LANG_PROGRAM(
[[
#include <pthread.h>
#include <time.h>
]], [[
  pthread_condattr_t attr;
  pthread_cond_t cond;
  struct timespec ts;
  int ret = pthread_condattr_init(&attr);
  if (ret != 0) {
    return 1;
  }
  ret = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
  if (ret != 0) {
    pthread_condattr_destroy(&attr);
    return 1;
  }
  ret = pthread_cond_init(&cond, &attr);
  pthread_condattr_destroy(&attr);
  if (ret != 0) {
    return 1;
  }
  ret = clock_gettime(CLOCK_MONOTONIC, &ts);
  pthread_cond_destroy(&cond);
  return ret != 0;
]])],
                 [je_cv_pthread_cond_timedwait_monotonic=yes],
                 [je_cv_pthread_cond_timedwait_monotonic=no],
                 [je_cv_pthread_cond_timedwait_monotonic=no]))
  if test "x${je_cv_pthread_cond_timedwait_monotonic}" = "xyes" ; then
    AC_DEFINE([JEMALLOC_HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC], [ ], [ ])
  fi
fi

JE_APPEND_VS(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
dnl `-dynamic` as well in case a user tries to dynamically link in jemalloc
if test "x$je_cv_cray_prgenv_wrapper" = "xyes" ; then
  if test "$ac_cv_search_clock_gettime" != "-lrt"; then
    JE_CFLAGS_SAVE()

    unset ac_cv_search_clock_gettime
    JE_CFLAGS_ADD([-dynamic])
    AC_SEARCH_LIBS([clock_gettime], [rt])

    JE_CFLAGS_RESTORE()
  fi
fi

dnl check for CLOCK_MONOTONIC_COARSE (Linux-specific).
JE_COMPILABLE([clock_gettime(CLOCK_MONOTONIC_COARSE, ...)], [
#include <time.h>
], [
	struct timespec ts;

	clock_gettime(CLOCK_MONOTONIC_COARSE, &ts);
], [je_cv_clock_monotonic_coarse])
if test "x${je_cv_clock_monotonic_coarse}" = "xyes" ; then
  AC_DEFINE([JEMALLOC_HAVE_CLOCK_MONOTONIC_COARSE], [ ], [ ])
fi

dnl check for CLOCK_MONOTONIC.
JE_COMPILABLE([clock_gettime(CLOCK_MONOTONIC, ...)], [
#include <unistd.h>
#include <time.h>
], [
	struct timespec ts;

	clock_gettime(CLOCK_MONOTONIC, &ts);
#if !defined(_POSIX_MONOTONIC_CLOCK) || _POSIX_MONOTONIC_CLOCK < 0
#  error _POSIX_MONOTONIC_CLOCK missing/invalid
#endif
], [je_cv_clock_monotonic])
if test "x${je_cv_clock_monotonic}" = "xyes" ; then
  AC_DEFINE([JEMALLOC_HAVE_CLOCK_MONOTONIC], [ ], [ ])
fi

dnl Check for mach_absolute_time().
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 for CLOCK_REALTIME (always should be available on Linux)
JE_COMPILABLE([clock_gettime(CLOCK_REALTIME, ...)], [
#include <time.h>
], [
	struct timespec ts;

	clock_gettime(CLOCK_REALTIME, &ts);
], [je_cv_clock_realtime])
if test "x${je_cv_clock_realtime}" = "xyes" ; then
  AC_DEFINE([JEMALLOC_HAVE_CLOCK_REALTIME], [ ], [ ])
fi

dnl Check for clock_gettime_nsec_np().
JE_COMPILABLE([clock_gettime_nsec_np()], [
#include <time.h>
], [
	clock_gettime_nsec_np(CLOCK_UPTIME_RAW);
], [je_cv_clock_gettime_nsec_np])
if test "x${je_cv_clock_gettime_nsec_np}" = "xyes" ; then
  AC_DEFINE([JEMALLOC_HAVE_CLOCK_GETTIME_NSEC_NP], [ ], [ ])
fi

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.
  JE_CFLAGS_SAVE()
  JE_CFLAGS_ADD([-Werror])
  JE_COMPILABLE([syscall(2)], [
#include <sys/syscall.h>
#include <unistd.h>
], [
	syscall(SYS_write, 2, "hello", 5);
],
                [je_cv_syscall])
  JE_CFLAGS_RESTORE()
  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
  AC_DEFINE([JEMALLOC_HAVE_SECURE_GETENV], [ ], [ ])
fi

dnl Check if the GNU-specific sched_getcpu function exists.
AC_CHECK_FUNC([sched_getcpu],
              [have_sched_getcpu="1"],
              [have_sched_getcpu="0"]
             )
if test "x$have_sched_getcpu" = "x1" ; then
  AC_DEFINE([JEMALLOC_HAVE_SCHED_GETCPU], [ ], [ ])
fi

dnl Check if the GNU-specific sched_setaffinity function exists.
AC_CHECK_FUNC([sched_setaffinity],
              [have_sched_setaffinity="1"],
              [have_sched_setaffinity="0"]
             )
if test "x$have_sched_setaffinity" = "x1" ; then
  AC_DEFINE([JEMALLOC_HAVE_SCHED_SETAFFINITY], [ ], [ ])
fi

dnl Check if the pthread_setaffinity_np function exists.
AC_CHECK_FUNC([pthread_setaffinity_np],
              [have_pthread_setaffinity_np="1"],
              [have_pthread_setaffinity_np="0"]
             )
if test "x$have_pthread_setaffinity_np" = "x1" ; then
  AC_DEFINE([JEMALLOC_HAVE_PTHREAD_SETAFFINITY_NP], [ ], [ ])
fi

dnl Check if the Solaris/BSD issetugid function exists.
AC_CHECK_FUNC([issetugid],
              [have_issetugid="1"],
              [have_issetugid="0"]
             )
if test "x$have_issetugid" = "x1" ; then
  AC_DEFINE([JEMALLOC_HAVE_ISSETUGID], [ ], [ ])
fi

dnl Check whether the BSD-specific _malloc_thread_cleanup() exists.  If so, use
dnl it rather than pthreads TSD cleanup functions to support cleanup during
dnl thread exit, in order to avoid pthreads library recursion during
dnl bootstrapping.
AC_CHECK_FUNC([_malloc_thread_cleanup],
              [have__malloc_thread_cleanup="1"],
              [have__malloc_thread_cleanup="0"]
             )
if test "x$have__malloc_thread_cleanup" = "x1" ; then
  AC_DEFINE([JEMALLOC_MALLOC_THREAD_CLEANUP], [ ], [ ])
  wrap_syms="${wrap_syms} _malloc_thread_cleanup _malloc_tsd_cleanup_register"
  force_tls="1"
fi

dnl Check whether the BSD-specific _pthread_mutex_init_calloc_cb() exists.  If
dnl so, mutex initialization causes allocation, and we need to implement this
dnl callback function in order to prevent recursive allocation.
AC_CHECK_FUNC([_pthread_mutex_init_calloc_cb],
              [have__pthread_mutex_init_calloc_cb="1"],
              [have__pthread_mutex_init_calloc_cb="0"]
             )
if test "x$have__pthread_mutex_init_calloc_cb" = "x1" ; then
  AC_DEFINE([JEMALLOC_MUTEX_INIT_CB], [ ], [ ])
  wrap_syms="${wrap_syms} _malloc_prefork _malloc_postfork"
fi

AC_CHECK_FUNC([memcntl],
	      [have_memcntl="1"],
	      [have_memcntl="0"],
	      )
if test "x$have_memcntl" = "x1" ; then
  AC_DEFINE([JEMALLOC_HAVE_MEMCNTL], [ ], [ ])
fi

AC_CHECK_FUNC([prctl],
	      [have_prctl="1"],
	      [have_prctl="0"],
	      )
if test "x$have_prctl" = "x1" ; then
  AC_DEFINE([JEMALLOC_HAVE_PRCTL], [ ], [ ])
fi

dnl Disable lazy locking by default.
AC_ARG_ENABLE([lazy_lock],
  [AS_HELP_STRING([--enable-lazy-lock],
  [Enable lazy locking (only lock when multi-threaded)])],
[if test "x$enable_lazy_lock" = "xno" ; then
  enable_lazy_lock="0"
else
  enable_lazy_lock="1"
fi
],
[enable_lazy_lock=""]
)
if test "x${enable_lazy_lock}" = "x" ; then
  if test "x${force_lazy_lock}" = "x1" ; then
    AC_MSG_RESULT([Forcing lazy-lock to avoid allocator/threading bootstrap issues])
    enable_lazy_lock="1"
  else
    enable_lazy_lock="0"
  fi
fi
if test "x${enable_lazy_lock}" = "x1" -a "x${abi}" = "xpecoff" ; then
  AC_MSG_RESULT([Forcing no lazy-lock because thread creation monitoring is unimplemented])
  enable_lazy_lock="0"
fi
if test "x$enable_lazy_lock" = "x1" ; then
  if test "x$have_dlsym" = "x1" ; then
    AC_DEFINE([JEMALLOC_LAZY_LOCK], [ ], [ ])
  else
    AC_MSG_ERROR([Missing dlsym support: lazy-lock cannot be enabled.])
  fi
fi
AC_SUBST([enable_lazy_lock])

dnl Automatically configure TLS.
if test "x${force_tls}" = "x1" ; then
  enable_tls="1"
elif test "x${force_tls}" = "x0" ; then
  enable_tls="0"
else
  enable_tls="1"
fi
if test "x${enable_tls}" = "x1" ; then
AC_MSG_CHECKING([for TLS])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
[[
    __thread int x;
]], [[
    x = 42;

    return 0;
]])],
              AC_MSG_RESULT([yes]),
              AC_MSG_RESULT([no])
              enable_tls="0")
else
  enable_tls="0"
fi
AC_SUBST([enable_tls])
if test "x${enable_tls}" = "x1" ; then
  AC_DEFINE_UNQUOTED([JEMALLOC_TLS], [ ], [ ])
fi

dnl ============================================================================
dnl Check for C11 atomics.

JE_COMPILABLE([C11 atomics], [
#include <stdint.h>
#if (__STDC_VERSION__ >= 201112L) && !defined(__STDC_NO_ATOMICS__)
#include <stdatomic.h>
#else
#error Atomics not available
#endif
], [
    uint64_t *p = (uint64_t *)0;
    uint64_t x = 1;
    volatile atomic_uint_least64_t *a = (volatile atomic_uint_least64_t *)p;
    uint64_t r = atomic_fetch_add(a, x) + x;
    return r == 0;
], [je_cv_c11_atomics])
if test "x${je_cv_c11_atomics}" = "xyes" ; then
  AC_DEFINE([JEMALLOC_C11_ATOMICS], [ ], [ ])
fi

dnl ============================================================================
dnl Check for GCC-style __atomic atomics.

JE_COMPILABLE([GCC __atomic atomics], [
], [
    int x = 0;
    int val = 1;
    int y = __atomic_fetch_add(&x, val, __ATOMIC_RELAXED);
    int after_add = x;
    return after_add == 1;
], [je_cv_gcc_atomic_atomics])
if test "x${je_cv_gcc_atomic_atomics}" = "xyes" ; then
  AC_DEFINE([JEMALLOC_GCC_ATOMIC_ATOMICS], [ ], [ ])

  dnl check for 8-bit atomic support
  JE_COMPILABLE([GCC 8-bit __atomic atomics], [
  ], [
      unsigned char x = 0;
      int val = 1;
      int y = __atomic_fetch_add(&x, val, __ATOMIC_RELAXED);
      int after_add = (int)x;
      return after_add == 1;
  ], [je_cv_gcc_u8_atomic_atomics])
  if test "x${je_cv_gcc_u8_atomic_atomics}" = "xyes" ; then
    AC_DEFINE([JEMALLOC_GCC_U8_ATOMIC_ATOMICS], [ ], [ ])
  fi
fi

dnl ============================================================================
dnl Check for GCC-style __sync atomics.

JE_COMPILABLE([GCC __sync atomics], [
], [
    int x = 0;
    int before_add = __sync_fetch_and_add(&x, 1);
    int after_add = x;
    return (before_add == 0) && (after_add == 1);
], [je_cv_gcc_sync_atomics])
if test "x${je_cv_gcc_sync_atomics}" = "xyes" ; then
  AC_DEFINE([JEMALLOC_GCC_SYNC_ATOMICS], [ ], [ ])

  dnl check for 8-bit atomic support
  JE_COMPILABLE([GCC 8-bit __sync atomics], [
  ], [
      unsigned char x = 0;
      int before_add = __sync_fetch_and_add(&x, 1);
      int after_add = (int)x;
      return (before_add == 0) && (after_add == 1);
  ], [je_cv_gcc_u8_sync_atomics])
  if test "x${je_cv_gcc_u8_sync_atomics}" = "xyes" ; then
    AC_DEFINE([JEMALLOC_GCC_U8_SYNC_ATOMICS], [ ], [ ])
  fi
fi

dnl ============================================================================
dnl Check for atomic(3) operations as provided on Darwin.
dnl We need this not for the atomic operations (which are provided above), but
dnl rather for the OS_unfair_lock type it exposes.

JE_COMPILABLE([Darwin OSAtomic*()], [
#include <libkern/OSAtomic.h>
#include <inttypes.h>
], [
	{
		int32_t x32 = 0;
		volatile int32_t *x32p = &x32;
		OSAtomicAdd32(1, x32p);
	}
	{
		int64_t x64 = 0;
		volatile int64_t *x64p = &x64;
		OSAtomicAdd64(1, x64p);
	}
], [je_cv_osatomic])
if test "x${je_cv_osatomic}" = "xyes" ; then
  AC_DEFINE([JEMALLOC_OSATOMIC], [ ], [ ])
fi

dnl ============================================================================

AC_ARG_WITH([experimental_sys_process_madvise],
  [AS_HELP_STRING([--with-experimental-sys-process-madvise=<experimental-sys-process-madvise>],
   [Force process_madvise and use experimental-sys-process-madvise number when making syscall])],
  [je_cv_sys_pmadv_nr="${with_experimental_sys_process_madvise}"],
  [je_cv_sys_pmadv_nr=""])

dnl Check for madvise(2).

JE_COMPILABLE([madvise(2)], [
#include <sys/mman.h>
], [
	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], [ ], [ ])
  elif test "x${je_cv_madvise}" = "xyes" ; then
    case "${host_cpu}" in i686|x86_64)
        case "${host}" in *-*-linux*)
            AC_DEFINE([JEMALLOC_PURGE_MADVISE_FREE], [ ], [ ])
            AC_DEFINE([JEMALLOC_DEFINE_MADVISE_FREE], [ ], [ ])
	    ;;
        esac
        ;;
    esac
  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_DO[NT]DUMP).
  JE_COMPILABLE([madvise(..., MADV_DO[[NT]]DUMP)], [
#include <sys/mman.h>
], [
	madvise((void *)0, 0, MADV_DONTDUMP);
	madvise((void *)0, 0, MADV_DODUMP);
], [je_cv_madv_dontdump])
  if test "x${je_cv_madv_dontdump}" = "xyes" ; then
    AC_DEFINE([JEMALLOC_MADVISE_DONTDUMP], [ ], [ ])
  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])
  case "${host_cpu}" in
    arm*)
      ;;
    *)
    if test "x${je_cv_thp}" = "xyes" ; then
      AC_DEFINE([JEMALLOC_HAVE_MADVISE_HUGE], [ ], [ ])
    fi
    ;;
  esac

  dnl Check for madvise(..., MADV_[NO]CORE).
  JE_COMPILABLE([madvise(..., MADV_[[NO]]CORE)], [
#include <sys/mman.h>
], [
	madvise((void *)0, 0, MADV_NOCORE);
	madvise((void *)0, 0, MADV_CORE);
], [je_cv_madv_nocore])
  if test "x${je_cv_madv_nocore}" = "xyes" ; then
    AC_DEFINE([JEMALLOC_MADVISE_NOCORE], [ ], [ ])
  fi

  dnl Check for madvise(..., MADV_COLLAPSE).
  JE_COMPILABLE([madvise(..., MADV_COLLAPSE)], [
#include <sys/mman.h>
], [
	madvise((void *)0, 0, MADV_COLLAPSE);
], [je_cv_madv_collapse])
  if test "x${je_cv_madv_collapse}" = "xyes" ; then
    AC_DEFINE([JEMALLOC_HAVE_MADVISE_COLLAPSE], [ ], [ ])
  fi

  dnl Check for process_madvise
  JE_COMPILABLE([process_madvise(2)], [
#include <sys/pidfd.h>
#include <sys/syscall.h>
#include <unistd.h>
], [
	syscall(SYS_process_madvise, PIDFD_SELF, (void *)0, 0, 0, 0);
], [je_cv_process_madvise])
  if test "x${je_cv_process_madvise}" = "xyes" ; then
    AC_DEFINE([JEMALLOC_HAVE_PROCESS_MADVISE], [ ], [ ])
  else
    if test "x${je_cv_sys_pmadv_nr}" != "x" ; then
      dnl Forcing experimental usage of process_madvise
      AC_MSG_RESULT([Forcing usage of process_madvise with syscall nr=${je_cv_sys_pmadv_nr}])
      AC_DEFINE([JEMALLOC_HAVE_PROCESS_MADVISE], [ ], [ ])
      AC_DEFINE_UNQUOTED([EXPERIMENTAL_SYS_PROCESS_MADVISE_NR], [${je_cv_sys_pmadv_nr}], [ ])
    fi
  fi
else
  dnl Check for posix_madvise.
  JE_COMPILABLE([posix_madvise], [
  #include <sys/mman.h>
  ], [
    posix_madvise((void *)0, 0, 0);
  ], [je_cv_posix_madvise])
  if test "x${je_cv_posix_madvise}" = "xyes" ; then
    AC_DEFINE([JEMALLOC_HAVE_POSIX_MADVISE], [ ], [ ])

    dnl Check for posix_madvise(..., POSIX_MADV_DONTNEED).
    JE_COMPILABLE([posix_madvise(..., POSIX_MADV_DONTNEED)], [
  #include <sys/mman.h>
  ], [
    posix_madvise((void *)0, 0, POSIX_MADV_DONTNEED);
  ], [je_cv_posix_madv_dontneed])
    if test "x${je_cv_posix_madv_dontneed}" = "xyes" ; then
      AC_DEFINE([JEMALLOC_PURGE_POSIX_MADVISE_DONTNEED], [ ], [ ])
    fi
  fi
fi

dnl ============================================================================
dnl Check for mprotect(2).

JE_COMPILABLE([mprotect(2)], [
#include <sys/mman.h>
], [
	mprotect((void *)0, 0, PROT_NONE);
], [je_cv_mprotect])
if test "x${je_cv_mprotect}" = "xyes" ; then
  AC_DEFINE([JEMALLOC_HAVE_MPROTECT], [ ], [ ])
fi

dnl ============================================================================
dnl Check for __builtin_clz(), __builtin_clzl(), and __builtin_clzll().

AC_CACHE_CHECK([for __builtin_clz],
               [je_cv_builtin_clz],
               [AC_LINK_IFELSE([AC_LANG_PROGRAM([],
                                                [
                                                {
                                                        unsigned x = 0;
                                                        int y = __builtin_clz(x);
                                                }
                                                {
                                                        unsigned long x = 0;
                                                        int y = __builtin_clzl(x);
                                                }
                                                {
                                                        unsigned long long x = 0;
                                                        int y = __builtin_clzll(x);
                                                }
                                                ])],
                               [je_cv_builtin_clz=yes],
                               [je_cv_builtin_clz=no])])

if test "x${je_cv_builtin_clz}" = "xyes" ; then
  AC_DEFINE([JEMALLOC_HAVE_BUILTIN_CLZ], [ ], [ ])
fi

dnl ============================================================================
dnl Check for 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 Darwin-related configuration.

AC_ARG_ENABLE([zone-allocator],
  [AS_HELP_STRING([--disable-zone-allocator],
                  [Disable zone allocator for Darwin])],
[if test "x$enable_zone_allocator" = "xno" ; then
  enable_zone_allocator="0"
else
  enable_zone_allocator="1"
fi
],
[if test "x${abi}" = "xmacho"; then
  enable_zone_allocator="1"
fi
]
)
AC_SUBST([enable_zone_allocator])

if test "x${enable_zone_allocator}" = "x1" ; then
  if test "x${abi}" != "xmacho"; then
    AC_MSG_ERROR([--enable-zone-allocator is only supported on Darwin])
  fi
  AC_DEFINE([JEMALLOC_ZONE], [ ], [ ])
fi

dnl ============================================================================
dnl Use initial-exec TLS by default.
AC_ARG_ENABLE([initial-exec-tls],
  [AS_HELP_STRING([--disable-initial-exec-tls],
                  [Disable the initial-exec tls model])],
[if test "x$enable_initial_exec_tls" = "xno" ; then
  enable_initial_exec_tls="0"
else
  enable_initial_exec_tls="1"
fi
],
[enable_initial_exec_tls="1"]
)
AC_SUBST([enable_initial_exec_tls])

if test "x${je_cv_tls_model}" = "xyes" -a \
       "x${enable_initial_exec_tls}" = "x1" ; then
  AC_DEFINE([JEMALLOC_TLS_MODEL],
            [__attribute__((tls_model("initial-exec")))],
            [ ])
else
  AC_DEFINE([JEMALLOC_TLS_MODEL], [ ], [ ])
fi

dnl Do not compile with debugging by default.
AC_ARG_ENABLE([pageid],
  [AS_HELP_STRING([--enable-pageid],
                  [Enable named pages])],
[if test "x$enable_pageid" = "xno" ; then
  enable_pageid="0"
else
  enable_pageid="1"
fi
],
[enable_pageid="0"]
)
if test "x$enable_pageid" = "x1" ; then
  AC_DEFINE([JEMALLOC_PAGEID], [ ], [ ])
fi

AC_ARG_ENABLE([tsan],
  [AS_HELP_STRING([--enable-tsan],
                  [Enable thread sanitizer])],
[if test "x$enable_tsan" = "xno" ; then
  enable_tsan="0"
else
  enable_tsan="1"
fi
],
[enable_tsan="0"]
)
if test "x$enable_tsan" = "x1" ; then
  JE_CFLAGS_ADD([-fsanitize=thread])
  JE_CXXFLAGS_ADD([-fsanitize=thread])
  JE_LDFLAGS_ADD([-fsanitize=thread])
fi

AC_ARG_ENABLE([ubsan],
  [AS_HELP_STRING([--enable-ubsan],
                  [Enable undefined behavior sanitizer])],
[if test "x$enable_ubsan" = "xno" ; then
  enable_ubsan="0"
else
  enable_ubsan="1"
fi
],
[enable_ubsan="0"]
)
if test "x$enable_ubsan" = "x1" ; then
  JE_CFLAGS_ADD([-fsanitize=undefined])
  JE_CXXFLAGS_ADD([-fsanitize=undefined])
  JE_LDFLAGS_ADD([-fsanitize=undefined])
fi

dnl ============================================================================
dnl Enable background threads if possible.

if test "x${have_pthread}" = "x1" -a "x${je_cv_os_unfair_lock}" != "xyes" -a \
       "x${abi}" != "xmacho" ; then
  AC_DEFINE([JEMALLOC_BACKGROUND_THREAD], [ ], [ ])
fi

dnl ============================================================================
dnl Check for glibc malloc hooks

if test "x$glibc" = "x1" ; then
  JE_COMPILABLE([glibc malloc hook], [
  #include <stddef.h>

  extern void (* __free_hook)(void *ptr);
  extern void *(* __malloc_hook)(size_t size);
  extern void *(* __realloc_hook)(void *ptr, size_t size);
], [
    void *ptr = 0L;
    if (__malloc_hook) ptr = __malloc_hook(1);
    if (__realloc_hook) ptr = __realloc_hook(ptr, 2);
    if (__free_hook && ptr) __free_hook(ptr);
], [je_cv_glibc_malloc_hook])
  if test "x${je_cv_glibc_malloc_hook}" = "xyes" ; then
    if test "x${JEMALLOC_PREFIX}" = "x" ; then
      AC_DEFINE([JEMALLOC_GLIBC_MALLOC_HOOK], [ ], [ ])
      wrap_syms="${wrap_syms} __free_hook __malloc_hook __realloc_hook"
    fi
  fi

  JE_COMPILABLE([glibc memalign hook], [
  #include <stddef.h>

  extern void *(* __memalign_hook)(size_t alignment, size_t size);
], [
    void *ptr = 0L;
    if (__memalign_hook) ptr = __memalign_hook(16, 7);
], [je_cv_glibc_memalign_hook])
  if test "x${je_cv_glibc_memalign_hook}" = "xyes" ; then
    if test "x${JEMALLOC_PREFIX}" = "x" ; then
      AC_DEFINE([JEMALLOC_GLIBC_MEMALIGN_HOOK], [ ], [ ])
      wrap_syms="${wrap_syms} __memalign_hook"
    fi
  fi
fi

JE_COMPILABLE([pthreads adaptive mutexes], [
#include <pthread.h>
], [
  pthread_mutexattr_t attr;
  pthread_mutexattr_init(&attr);
  pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP);
  pthread_mutexattr_destroy(&attr);
], [je_cv_pthread_mutex_adaptive_np])
if test "x${je_cv_pthread_mutex_adaptive_np}" = "xyes" ; then
  AC_DEFINE([JEMALLOC_HAVE_PTHREAD_MUTEX_ADAPTIVE_NP], [ ], [ ])
fi

JE_COMPILABLE([gettid], [
#include <unistd.h>
], [
  int tid = gettid();
], [je_cv_gettid])
if test "x${je_cv_gettid}" = "xyes" ; then
  AC_DEFINE([JEMALLOC_HAVE_GETTID], [ ], [ ])
fi

JE_CFLAGS_SAVE()
JE_CFLAGS_ADD([-D_GNU_SOURCE])
JE_CFLAGS_ADD([-Werror])
JE_CFLAGS_ADD([-herror_on_warning])
JE_COMPILABLE([strerror_r returns char with gnu source], [
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
], [
  char *buffer = (char *) malloc(100);
  char *error = strerror_r(EINVAL, buffer, 100);
  printf("%s\n", error);
], [je_cv_strerror_r_returns_char_with_gnu_source])
if test "x${je_cv_strerror_r_returns_char_with_gnu_source}" = "xno" ; then
  JE_COMPILABLE([strerror_r header only], [
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
], [], [je_cv_strerror_r_header_pass])
fi
JE_CFLAGS_RESTORE()
if test "x${je_cv_strerror_r_returns_char_with_gnu_source}" = "xyes" ; then
  AC_DEFINE([JEMALLOC_STRERROR_R_RETURNS_CHAR_WITH_GNU_SOURCE], [ ], [ ])
elif test "x${je_cv_strerror_r_header_pass}" = "xno" ; then
  AC_MSG_ERROR([cannot determine return type of strerror_r])
fi

dnl ============================================================================
dnl Check for typedefs, structures, and compiler characteristics.
AC_HEADER_STDBOOL

dnl ============================================================================
dnl Define commands that generate output files.

AC_CONFIG_COMMANDS([include/jemalloc/internal/public_symbols.txt], [
  f="${objroot}include/jemalloc/internal/public_symbols.txt"
  mkdir -p "${objroot}include/jemalloc/internal"
  cp /dev/null "${f}"
  for nm in `echo ${mangling_map} |tr ',' ' '` ; do
    n=`echo ${nm} |tr ':' ' ' |awk '{print $[]1}'`
    m=`echo ${nm} |tr ':' ' ' |awk '{print $[]2}'`
    echo "${n}:${m}" >> "${f}"
    dnl Remove name from public_syms so that it isn't redefined later.
    public_syms=`for sym in ${public_syms}; do echo "${sym}"; done |grep -v "^${n}\$" |tr '\n' ' '`
  done
  for sym in ${public_syms} ; do
    n="${sym}"
    m="${JEMALLOC_PREFIX}${sym}"
    echo "${n}:${m}" >> "${f}"
  done
], [
  srcdir="${srcdir}"
  objroot="${objroot}"
  mangling_map="${mangling_map}"
  public_syms="${public_syms}"
  JEMALLOC_PREFIX="${JEMALLOC_PREFIX}"
])
AC_CONFIG_COMMANDS([include/jemalloc/internal/private_symbols.awk], [
  f="${objroot}include/jemalloc/internal/private_symbols.awk"
  mkdir -p "${objroot}include/jemalloc/internal"
  export_syms=`for sym in ${public_syms}; do echo "${JEMALLOC_PREFIX}${sym}"; done; for sym in ${wrap_syms}; do echo "${sym}"; done;`
  "${srcdir}/include/jemalloc/internal/private_symbols.sh" "${SYM_PREFIX}" ${export_syms} > "${objroot}include/jemalloc/internal/private_symbols.awk"
], [
  srcdir="${srcdir}"
  objroot="${objroot}"
  public_syms="${public_syms}"
  wrap_syms="${wrap_syms}"
  SYM_PREFIX="${SYM_PREFIX}"
  JEMALLOC_PREFIX="${JEMALLOC_PREFIX}"
])
AC_CONFIG_COMMANDS([include/jemalloc/internal/private_symbols_jet.awk], [
  f="${objroot}include/jemalloc/internal/private_symbols_jet.awk"
  mkdir -p "${objroot}include/jemalloc/internal"
  export_syms=`for sym in ${public_syms}; do echo "jet_${sym}"; done; for sym in ${wrap_syms}; do echo "${sym}"; done;`
  "${srcdir}/include/jemalloc/internal/private_symbols.sh" "${SYM_PREFIX}" ${export_syms} > "${objroot}include/jemalloc/internal/private_symbols_jet.awk"
], [
  srcdir="${srcdir}"
  objroot="${objroot}"
  public_syms="${public_syms}"
  wrap_syms="${wrap_syms}"
  SYM_PREFIX="${SYM_PREFIX}"
])
AC_CONFIG_COMMANDS([include/jemalloc/internal/public_namespace.h], [
  mkdir -p "${objroot}include/jemalloc/internal"
  "${srcdir}/include/jemalloc/internal/public_namespace.sh" "${objroot}include/jemalloc/internal/public_symbols.txt" > "${objroot}include/jemalloc/internal/public_namespace.h"
], [
  srcdir="${srcdir}"
  objroot="${objroot}"
])
AC_CONFIG_COMMANDS([include/jemalloc/internal/public_unnamespace.h], [
  mkdir -p "${objroot}include/jemalloc/internal"
  "${srcdir}/include/jemalloc/internal/public_unnamespace.sh" "${objroot}include/jemalloc/internal/public_symbols.txt" > "${objroot}include/jemalloc/internal/public_unnamespace.h"
], [
  srcdir="${srcdir}"
  objroot="${objroot}"
])
AC_CONFIG_COMMANDS([include/jemalloc/jemalloc_protos_jet.h], [
  mkdir -p "${objroot}include/jemalloc"
  cat "${srcdir}/include/jemalloc/jemalloc_protos.h.in" | sed -e 's/@je_@/jet_/g' > "${objroot}include/jemalloc/jemalloc_protos_jet.h"
], [
  srcdir="${srcdir}"
  objroot="${objroot}"
])
AC_CONFIG_COMMANDS([include/jemalloc/jemalloc_rename.h], [
  mkdir -p "${objroot}include/jemalloc"
  "${srcdir}/include/jemalloc/jemalloc_rename.sh" "${objroot}include/jemalloc/internal/public_symbols.txt" > "${objroot}include/jemalloc/jemalloc_rename.h"
], [
  srcdir="${srcdir}"
  objroot="${objroot}"
])
AC_CONFIG_COMMANDS([include/jemalloc/jemalloc_mangle.h], [
  mkdir -p "${objroot}include/jemalloc"
  "${srcdir}/include/jemalloc/jemalloc_mangle.sh" "${objroot}include/jemalloc/internal/public_symbols.txt" je_ > "${objroot}include/jemalloc/jemalloc_mangle.h"
], [
  srcdir="${srcdir}"
  objroot="${objroot}"
])
AC_CONFIG_COMMANDS([include/jemalloc/jemalloc_mangle_jet.h], [
  mkdir -p "${objroot}include/jemalloc"
  "${srcdir}/include/jemalloc/jemalloc_mangle.sh" "${objroot}include/jemalloc/internal/public_symbols.txt" jet_ > "${objroot}include/jemalloc/jemalloc_mangle_jet.h"
], [
  srcdir="${srcdir}"
  objroot="${objroot}"
])
AC_CONFIG_COMMANDS([include/jemalloc/jemalloc.h], [
  mkdir -p "${objroot}include/jemalloc"
  "${srcdir}/include/jemalloc/jemalloc.sh" "${objroot}" > "${objroot}include/jemalloc/jemalloc${install_suffix}.h"
], [
  srcdir="${srcdir}"
  objroot="${objroot}"
  install_suffix="${install_suffix}"
])

dnl Process .in files.
AC_SUBST([cfghdrs_in])
AC_SUBST([cfghdrs_out])
AC_CONFIG_HEADERS([$cfghdrs_tup])

dnl ============================================================================
dnl Generate outputs.

AC_CONFIG_FILES([$cfgoutputs_tup config.stamp bin/jemalloc-config bin/jemalloc.sh bin/jeprof])
AC_SUBST([cfgoutputs_in])
AC_SUBST([cfgoutputs_out])
AC_OUTPUT

dnl ============================================================================
dnl Print out the results of configuration.
AC_MSG_RESULT([===============================================================================])
AC_MSG_RESULT([jemalloc version   : ${jemalloc_version}])
AC_MSG_RESULT([library revision   : ${rev}])
AC_MSG_RESULT([])
AC_MSG_RESULT([CONFIG             : ${CONFIG}])
AC_MSG_RESULT([CC                 : ${CC}])
AC_MSG_RESULT([CONFIGURE_CFLAGS   : ${CONFIGURE_CFLAGS}])
AC_MSG_RESULT([SPECIFIED_CFLAGS   : ${SPECIFIED_CFLAGS}])
AC_MSG_RESULT([EXTRA_CFLAGS       : ${EXTRA_CFLAGS}])
AC_MSG_RESULT([CPPFLAGS           : ${CPPFLAGS}])
AC_MSG_RESULT([CXX                : ${CXX}])
AC_MSG_RESULT([CONFIGURE_CXXFLAGS : ${CONFIGURE_CXXFLAGS}])
AC_MSG_RESULT([SPECIFIED_CXXFLAGS : ${SPECIFIED_CXXFLAGS}])
AC_MSG_RESULT([EXTRA_CXXFLAGS     : ${EXTRA_CXXFLAGS}])
AC_MSG_RESULT([CONFIGURE_LDFLAGS  : ${CONFIGURE_LDFLAGS}])
AC_MSG_RESULT([SPECIFIED_LDFLAGS  : ${SPECIFIED_LDFLAGS}])
AC_MSG_RESULT([EXTRA_LDFLAGS      : ${EXTRA_LDFLAGS}])
AC_MSG_RESULT([DSO_LDFLAGS        : ${DSO_LDFLAGS}])
AC_MSG_RESULT([LIBS               : ${LIBS}])
AC_MSG_RESULT([RPATH_EXTRA        : ${RPATH_EXTRA}])
AC_MSG_RESULT([])
AC_MSG_RESULT([XSLTPROC           : ${XSLTPROC}])
AC_MSG_RESULT([XSLROOT            : ${XSLROOT}])
AC_MSG_RESULT([])
AC_MSG_RESULT([PREFIX             : ${PREFIX}])
AC_MSG_RESULT([BINDIR             : ${BINDIR}])
AC_MSG_RESULT([DATADIR            : ${DATADIR}])
AC_MSG_RESULT([INCLUDEDIR         : ${INCLUDEDIR}])
AC_MSG_RESULT([LIBDIR             : ${LIBDIR}])
AC_MSG_RESULT([MANDIR             : ${MANDIR}])
AC_MSG_RESULT([])
AC_MSG_RESULT([LG_PAGE            : ${LG_PAGE}])
AC_MSG_RESULT([])
AC_MSG_RESULT([srcroot            : ${srcroot}])
AC_MSG_RESULT([abs_srcroot        : ${abs_srcroot}])
AC_MSG_RESULT([objroot            : ${objroot}])
AC_MSG_RESULT([abs_objroot        : ${abs_objroot}])
AC_MSG_RESULT([])
AC_MSG_RESULT([JEMALLOC_PREFIX    : ${JEMALLOC_PREFIX}])
AC_MSG_RESULT([JEMALLOC_PRIVATE_NAMESPACE])
AC_MSG_RESULT([                   : ${JEMALLOC_PRIVATE_NAMESPACE}])
AC_MSG_RESULT([install_suffix     : ${install_suffix}])
AC_MSG_RESULT([malloc_conf        : ${config_malloc_conf}])
AC_MSG_RESULT([documentation      : ${enable_doc}])
AC_MSG_RESULT([shared libs        : ${enable_shared}])
AC_MSG_RESULT([static libs        : ${enable_static}])
AC_MSG_RESULT([autogen            : ${enable_autogen}])
AC_MSG_RESULT([debug              : ${enable_debug}])
AC_MSG_RESULT([stats              : ${enable_stats}])
AC_MSG_RESULT([user_config        : ${enable_user_config}])
AC_MSG_RESULT([experimental_smallocx : ${enable_experimental_smallocx}])
AC_MSG_RESULT([prof               : ${enable_prof}])
AC_MSG_RESULT([prof-libunwind     : ${enable_prof_libunwind}])
AC_MSG_RESULT([prof-libgcc        : ${enable_prof_libgcc}])
AC_MSG_RESULT([prof-gcc           : ${enable_prof_gcc}])
AC_MSG_RESULT([fill               : ${enable_fill}])
AC_MSG_RESULT([utrace             : ${enable_utrace}])
AC_MSG_RESULT([xmalloc            : ${enable_xmalloc}])
AC_MSG_RESULT([log                : ${enable_log}])
AC_MSG_RESULT([lazy_lock          : ${enable_lazy_lock}])
AC_MSG_RESULT([cache-oblivious    : ${enable_cache_oblivious}])
AC_MSG_RESULT([pageid             : ${enable_pageid}])
AC_MSG_RESULT([cxx                : ${enable_cxx}])
AC_MSG_RESULT([dss                : ${enable_dss}])
AC_MSG_RESULT([tsan               : ${enable_tsan}])
AC_MSG_RESULT([ubsan              : ${enable_ubsan}])
AC_MSG_RESULT([===============================================================================])
