dnl Process this file with autoconf to produce a configure script.
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-emty.
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_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}"]
)
JE_CONCAT_VVV(CXXFLAGS, CONFIGURE_CXXFLAGS, SPECIFIED_CXXFLAGS)
])

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

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

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

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

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

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

dnl Munge install path variables.
if test "x$prefix" = "xNONE" ; then
  prefix="/usr/local"
fi
if test "x$exec_prefix" = "xNONE" ; then
  exec_prefix=$prefix
fi
PREFIX=$prefix
AC_SUBST([PREFIX])
BINDIR=`eval echo $bindir`
BINDIR=`eval echo $BINDIR`
AC_SUBST([BINDIR])
INCLUDEDIR=`eval echo $includedir`
INCLUDEDIR=`eval echo $INCLUDEDIR`
AC_SUBST([INCLUDEDIR])
LIBDIR=`eval echo $libdir`
LIBDIR=`eval echo $LIBDIR`
AC_SUBST([LIBDIR])
DATADIR=`eval echo $datadir`
DATADIR=`eval echo $DATADIR`
AC_SUBST([DATADIR])
MANDIR=`eval echo $mandir`
MANDIR=`eval echo $MANDIR`
AC_SUBST([MANDIR])

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

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

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

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([-Wall])
  JE_CFLAGS_ADD([-Wshorten-64-to-32])
  JE_CFLAGS_ADD([-Wsign-compare])
  JE_CFLAGS_ADD([-Wundef])
  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"
)
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([14], [noext], [optional])
  if test "x${HAVE_CXX14}" = "x1" ; then
    JE_CXXFLAGS_ADD([-Wall])
    JE_CXXFLAGS_ADD([-g3])

    SAVED_LIBS="${LIBS}"
    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
  else
    enable_cxx="0"
  fi
fi
AC_SUBST([enable_cxx])
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)
	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
	;;
  powerpc*)
	AC_DEFINE_UNQUOTED([HAVE_ALTIVEC], [ ])
	CPU_SPINWAIT='__asm__ volatile("or 31,31,31")'
	;;
  *)
	;;
esac
AC_DEFINE_UNQUOTED([CPU_SPINWAIT], [$CPU_SPINWAIT])

case "${host_cpu}" in
  aarch64)
    AC_MSG_CHECKING([number of significant virtual address bits])
    LG_VADDR=48
    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}" != "x" ; then
      LG_VADDR="${je_cv_lg_vaddr}"
    fi
    if test "x${LG_VADDR}" != "xerror" ; then
      AC_DEFINE_UNQUOTED([LG_VADDR], [$LG_VADDR])
    else
      AC_MSG_ERROR([cannot determine number of significant virtual address bits])
    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
AC_DEFINE_UNQUOTED([LG_VADDR], [$LG_VADDR])

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

AC_PROG_AWK

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"
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="_"
	;;
  *-*-freebsd*)
	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"
	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
	;;
  *-*-linux* | *-*-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_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
	;;
  *-*-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
	DUMP_SYMS="dumpbin /SYMBOLS"
	a="lib"
	libprefix=""
	SOREV="${so}"
	PIC_CFLAGS=""
	;;
  *)
	AC_MSG_RESULT([Unsupported operating system: ${host}])
	abi="elf"
	;;
esac

JEMALLOC_USABLE_SIZE_CONST=const
AC_CHECK_HEADERS([malloc.h], [
  AC_MSG_CHECKING([whether malloc_usable_size definition can use const argument])
  AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
    [#include <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).
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
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-dialect support.
JE_CFLAGS_ADD([-mtls-dialect=gnu2])
if test "x$je_cv_cflags_added" = "x-mtls-dialect=gnu2" ; then
  je_cv_tls_dialect_gnu2=yes
else
  je_cv_tls_dialect_gnu2=no
fi
JE_CXXFLAGS_ADD([-mtls-dialect=gnu2])
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()
if test "x${je_cv_tls_dialect_gnu2}" = "xno" \
 -a "x${je_cv_tls_model}" = "xyes" ; then
  AC_DEFINE([JEMALLOC_TLS_MODEL],
            [__attribute__((tls_model("initial-exec")))])
else
  AC_DEFINE([JEMALLOC_TLS_MODEL], [ ])
fi
dnl Check for alloc_size attribute support.
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 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 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 mallctl mallctlbymib mallctlnametomib malloc malloc_conf malloc_message malloc_stats_print malloc_usable_size mallocx 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"])

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"])
  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([__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])],
  [INSTALL_SUFFIX="$with_install_suffix"],
  [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/internal/size_classes.sh"
cfghdrs_in="${cfghdrs_in} include/jemalloc/jemalloc_rename.sh"
cfghdrs_in="${cfghdrs_in} include/jemalloc/jemalloc_mangle.sh"
cfghdrs_in="${cfghdrs_in} include/jemalloc/jemalloc.sh"
cfghdrs_in="${cfghdrs_in} test/include/test/jemalloc_test_defs.h.in"

cfghdrs_out="include/jemalloc/jemalloc_defs.h"
cfghdrs_out="${cfghdrs_out} include/jemalloc/jemalloc${install_suffix}.h"
cfghdrs_out="${cfghdrs_out} include/jemalloc/internal/private_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/internal/size_classes.h"
cfghdrs_out="${cfghdrs_out} include/jemalloc/jemalloc_protos_jet.h"
cfghdrs_out="${cfghdrs_out} include/jemalloc/jemalloc_rename.h"
cfghdrs_out="${cfghdrs_out} include/jemalloc/jemalloc_mangle.h"
cfghdrs_out="${cfghdrs_out} include/jemalloc/jemalloc_mangle_jet.h"
cfghdrs_out="${cfghdrs_out} include/jemalloc/internal/jemalloc_internal_defs.h"
cfghdrs_out="${cfghdrs_out} test/include/test/jemalloc_test_defs.h"

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

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

AC_ARG_ENABLE([prof-libunwind],
  [AS_HELP_STRING([--enable-prof-libunwind], [Use libunwind for backtracing])],
[if test "x$enable_prof_libunwind" = "xno" ; then
  enable_prof_libunwind="0"
else
  enable_prof_libunwind="1"
fi
],
[enable_prof_libunwind="0"]
)
AC_ARG_WITH([static_libunwind],
  [AS_HELP_STRING([--with-static-libunwind=<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 Enable allocation from DSS if supported by the OS.
have_dss="1"
dnl Check whether the BSD/SUSv1 sbrk() exists.  If not, disable DSS support.
AC_CHECK_FUNC([sbrk], [have_sbrk="1"], [have_sbrk="0"])
if test "x$have_sbrk" = "x1" ; then
  if test "x$sbrk_deprecated" = "x1" ; then
    AC_MSG_RESULT([Disabling dss allocation because sbrk is deprecated])
    have_dss="0"
  fi
else
  have_dss="0"
fi

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

dnl Support the junk/zero filling option by default.
AC_ARG_ENABLE([fill],
  [AS_HELP_STRING([--disable-fill], [Disable support for junk/zero filling])],
[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
  enable_utrace="0"
fi
if test "x$enable_utrace" = "x1" ; then
  AC_DEFINE([JEMALLOC_UTRACE], [ ])
fi
AC_SUBST([enable_utrace])

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])



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

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

AC_ARG_WITH([lg_page],
  [AS_HELP_STRING([--with-lg-page=<lg-page>], [Base 2 log of system page size])],
  [LG_PAGE="$with_lg_page"], [LG_PAGE="detect"])
if test "x$LG_PAGE" = "xdetect"; then
  AC_CACHE_CHECK([LG_PAGE],
               [je_cv_lg_page],
               AC_RUN_IFELSE([AC_LANG_PROGRAM(
[[
#include <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

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 -e '^Hugepagesize:[[:space:]]\+[0-9]\+[[: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
AC_DEFINE_UNQUOTED([LG_HUGEPAGE], [${je_cv_lg_hugepage}])

AC_ARG_WITH([lg_page_sizes],
  [AS_HELP_STRING([--with-lg-page-sizes=<lg-page-sizes>],
   [Base 2 logs of system page sizes to support])],
  [LG_PAGE_SIZES="$with_lg_page_sizes"], [LG_PAGE_SIZES="$LG_PAGE"])

dnl ============================================================================
dnl jemalloc configuration.
dnl 

AC_ARG_WITH([version],
  [AS_HELP_STRING([--with-version=<major>.<minor>.<bugfix>-<nrev>-g<gid>],
   [Version string])],
  [
    echo "${with_version}" | grep ['^[0-9]\+\.[0-9]\+\.[0-9]\+-[0-9]\+-g[0-9a-f]\+$'] 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-g0000000000000000000000000000000000000000" > "${objroot}VERSION"
  else
    cp ${srcroot}VERSION ${objroot}VERSION
  fi
fi
jemalloc_version=`cat "${objroot}VERSION"`
jemalloc_version_major=`echo ${jemalloc_version} | tr ".g-" " " | awk '{print [$]1}'`
jemalloc_version_minor=`echo ${jemalloc_version} | tr ".g-" " " | awk '{print [$]2}'`
jemalloc_version_bugfix=`echo ${jemalloc_version} | tr ".g-" " " | awk '{print [$]3}'`
jemalloc_version_nrev=`echo ${jemalloc_version} | tr ".g-" " " | awk '{print [$]4}'`
jemalloc_version_gid=`echo ${jemalloc_version} | tr ".g-" " " | awk '{print [$]5}'`
AC_SUBST([jemalloc_version])
AC_SUBST([jemalloc_version_major])
AC_SUBST([jemalloc_version_minor])
AC_SUBST([jemalloc_version_bugfix])
AC_SUBST([jemalloc_version_nrev])
AC_SUBST([jemalloc_version_gid])

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

if test "x$abi" != "xpecoff" ; then
  AC_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, -lpthread)],
               [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.
  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
  JE_COMPILABLE([pthread_atfork(3)], [
#include <pthread.h>
], [
  pthread_atfork((void *)0, (void *)0, (void *)0);
], [je_cv_pthread_atfork])
  if test "x${je_cv_pthread_atfork}" = "xyes" ; then
    AC_DEFINE([JEMALLOC_HAVE_PTHREAD_ATFORK], [ ])
  fi
fi

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 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 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"
  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

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])
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])
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 OSSpinLock 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 ============================================================================
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], [ ])
  fi

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

  dnl Check for madvise(..., MADV_[NO]HUGEPAGE).
  JE_COMPILABLE([madvise(..., MADV_[[NO]]HUGEPAGE)], [
#include <sys/mman.h>
], [
	madvise((void *)0, 0, MADV_HUGEPAGE);
	madvise((void *)0, 0, MADV_NOHUGEPAGE);
], [je_cv_thp])
fi

dnl Enable transparent huge page support by default.
AC_ARG_ENABLE([thp],
  [AS_HELP_STRING([--disable-thp],
                  [Disable transparent huge page support])],
[if test "x$enable_thp" = "xno" -o "x${je_cv_thp}" != "xyes" ; then
  enable_thp="0"
else
  enable_thp="1"
fi
],
[if test "x${je_cv_thp}" = "xyes" ; then
  enable_thp="1"
else
  enable_thp="0"
fi
])
if test "x$enable_thp" = "x1" ; then
  AC_DEFINE([JEMALLOC_THP], [ ])
fi
AC_SUBST([enable_thp])

dnl ============================================================================
dnl Check whether __sync_{add,sub}_and_fetch() are available despite
dnl __GCC_HAVE_SYNC_COMPARE_AND_SWAP_n macros being undefined.

AC_DEFUN([JE_SYNC_COMPARE_AND_SWAP_CHECK],[
  AC_CACHE_CHECK([whether to force $1-bit __sync_{add,sub}_and_fetch()],
               [je_cv_sync_compare_and_swap_$2],
               [AC_LINK_IFELSE([AC_LANG_PROGRAM([
                                                 #include <stdint.h>
                                                ],
                                                [
                                                 #ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_$2
                                                 {
                                                    uint$1_t x$1 = 0;
                                                    __sync_add_and_fetch(&x$1, 42);
                                                    __sync_sub_and_fetch(&x$1, 1);
                                                 }
                                                 #else
                                                 #error __GCC_HAVE_SYNC_COMPARE_AND_SWAP_$2 is defined, no need to force
                                                 #endif
                                                ])],
                               [je_cv_sync_compare_and_swap_$2=yes],
                               [je_cv_sync_compare_and_swap_$2=no])])

  if test "x${je_cv_sync_compare_and_swap_$2}" = "xyes" ; then
    AC_DEFINE([JE_FORCE_SYNC_COMPARE_AND_SWAP_$2], [ ])
  fi
])

if test "x${je_cv_atomic9}" != "xyes" -a "x${je_cv_osatomic}" != "xyes" ; then
  JE_SYNC_COMPARE_AND_SWAP_CHECK(32, 4)
  JE_SYNC_COMPARE_AND_SWAP_CHECK(64, 8)
fi

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

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

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

dnl ============================================================================
dnl Check for os_unfair_lock operations as provided on Darwin.

JE_COMPILABLE([Darwin os_unfair_lock_*()], [
#include <os/lock.h>
#include <AvailabilityMacros.h>
], [
	#if MAC_OS_X_VERSION_MIN_REQUIRED < 101200
	#error "os_unfair_lock is not supported"
	#else
	os_unfair_lock lock = OS_UNFAIR_LOCK_INIT;
	os_unfair_lock_lock(&lock);
	os_unfair_lock_unlock(&lock);
	#endif
], [je_cv_os_unfair_lock])
if test "x${je_cv_os_unfair_lock}" = "xyes" ; then
  AC_DEFINE([JEMALLOC_OS_UNFAIR_LOCK], [ ])
fi

dnl ============================================================================
dnl Check for spinlock(3) operations as provided on Darwin.

JE_COMPILABLE([Darwin OSSpin*()], [
#include <libkern/OSAtomic.h>
#include <inttypes.h>
], [
	OSSpinLock lock = 0;
	OSSpinLockLock(&lock);
	OSSpinLockUnlock(&lock);
], [je_cv_osspin])
if test "x${je_cv_osspin}" = "xyes" ; then
  AC_DEFINE([JEMALLOC_OSSPIN], [ ])
fi

dnl ============================================================================
dnl Darwin-related configuration.

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

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

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

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

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

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

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

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/internal/size_classes.h], [
  mkdir -p "${objroot}include/jemalloc/internal"
  "${SHELL}" "${srcdir}/include/jemalloc/internal/size_classes.sh" "${LG_QUANTA}" 3 "${LG_PAGE_SIZES}" 2 > "${objroot}include/jemalloc/internal/size_classes.h"
], [
  SHELL="${SHELL}"
  srcdir="${srcdir}"
  objroot="${objroot}"
  LG_QUANTA="${LG_QUANTA}"
  LG_PAGE_SIZES="${LG_PAGE_SIZES}"
])
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([LDFLAGS            : ${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([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([autogen            : ${enable_autogen}])
AC_MSG_RESULT([debug              : ${enable_debug}])
AC_MSG_RESULT([stats              : ${enable_stats}])
AC_MSG_RESULT([prof               : ${enable_prof}])
AC_MSG_RESULT([prof-libunwind     : ${enable_prof_libunwind}])
AC_MSG_RESULT([prof-libgcc        : ${enable_prof_libgcc}])
AC_MSG_RESULT([prof-gcc           : ${enable_prof_gcc}])
AC_MSG_RESULT([thp                : ${enable_thp}])
AC_MSG_RESULT([fill               : ${enable_fill}])
AC_MSG_RESULT([utrace             : ${enable_utrace}])
AC_MSG_RESULT([xmalloc            : ${enable_xmalloc}])
AC_MSG_RESULT([lazy_lock          : ${enable_lazy_lock}])
AC_MSG_RESULT([cache-oblivious    : ${enable_cache_oblivious}])
AC_MSG_RESULT([cxx                : ${enable_cxx}])
AC_MSG_RESULT([===============================================================================])
