1 dnl Process this file with autoconf to produce a configure script.
3 AC_INIT([masstree-beta], [0.1])
5 AC_CONFIG_HEADERS([config.h])
6 AC_CONFIG_FILES([GNUmakefile])
7 AC_SUBST(ac_configure_args)
15 AC_DEFINE([WORDS_BIGENDIAN_SET], [1], [Define if WORDS_BIGENDIAN has been set.])
18 AC_CHECK_HEADERS([sys/epoll.h numa.h])
20 AC_SEARCH_LIBS([numa_available], [numa], [AC_DEFINE([HAVE_LIBNUMA], [1], [Define if you have libnuma.])])
25 AC_DEFUN([KVDB_CHECK_BUILTIN], [
26 AC_CACHE_CHECK([for $1 builtin], [ac_cv_have_$1],
27 [AC_LINK_IFELSE([AC_LANG_PROGRAM([$2], [])],
28 [ac_cv_have_$1=yes], [ac_cv_have_$1=no])])
29 if test $ac_cv_have_$1 = yes; then
30 AC_DEFINE(AS_TR_CPP([HAVE_$1]), [1], [Define if you have the $1 builtin.])
34 KVDB_CHECK_BUILTIN([__builtin_clz],
35 [[unsigned f(unsigned x) { return __builtin_clz(x); }]])
37 KVDB_CHECK_BUILTIN([__builtin_clzl],
38 [[unsigned long f(unsigned long x) { return __builtin_clzl(x); }]])
40 KVDB_CHECK_BUILTIN([__builtin_clzll],
41 [[unsigned long long f(unsigned long long x) { return __builtin_clzll(x); }]])
43 KVDB_CHECK_BUILTIN([__builtin_ctz],
44 [[unsigned f(unsigned x) { return __builtin_ctz(x); }]])
46 KVDB_CHECK_BUILTIN([__builtin_ctzl],
47 [[unsigned long f(unsigned long x) { return __builtin_ctzl(x); }]])
49 KVDB_CHECK_BUILTIN([__builtin_ctzll],
50 [[unsigned long long f(unsigned long long x) { return __builtin_ctzll(x); }]])
52 KVDB_CHECK_BUILTIN([__sync_synchronize], [[long x = 11;
53 void f(long i) { long* y = &x; __sync_synchronize(); *y = i; }]])
55 KVDB_CHECK_BUILTIN([__sync_fetch_and_add],
56 [[long f(long* x) { return __sync_fetch_and_add(x, 2L); }]])
58 KVDB_CHECK_BUILTIN([__sync_add_and_fetch],
59 [[long f(long* x) { return __sync_add_and_fetch(x, 2L); }]])
61 KVDB_CHECK_BUILTIN([__sync_fetch_and_add_8],
63 int64_t f(int64_t* x) { return __sync_fetch_and_add(x, (int64_t) 2); }]])
65 KVDB_CHECK_BUILTIN([__sync_add_and_fetch_8],
67 int64_t f(int64_t* x) { return __sync_add_and_fetch(x, (int64_t) 2); }]])
69 KVDB_CHECK_BUILTIN([__sync_fetch_and_or],
70 [[long f(long* x) { return __sync_fetch_and_or(x, 2L); }]])
72 KVDB_CHECK_BUILTIN([__sync_or_and_fetch],
73 [[long f(long* x) { return __sync_or_and_fetch(x, 2L); }]])
75 KVDB_CHECK_BUILTIN([__sync_fetch_and_or_8],
77 int64_t f(int64_t* x) { return __sync_fetch_and_or(x, (int64_t) 2); }]])
79 KVDB_CHECK_BUILTIN([__sync_or_and_fetch_8],
81 int64_t f(int64_t* x) { return __sync_or_and_fetch(x, (int64_t) 2); }]])
83 KVDB_CHECK_BUILTIN([__sync_bool_compare_and_swap],
84 [[bool f(long* x, long y, long z) { return __sync_bool_compare_and_swap(x, y, z); }]])
86 KVDB_CHECK_BUILTIN([__sync_bool_compare_and_swap_8],
88 bool f(int64_t* x, int64_t y, int64_t z) { return __sync_bool_compare_and_swap(x, y, z); }]])
90 KVDB_CHECK_BUILTIN([__sync_val_compare_and_swap],
91 [[long f(long* x, long y, long z) { return __sync_val_compare_and_swap(x, y, z); }]])
93 KVDB_CHECK_BUILTIN([__sync_val_compare_and_swap_8],
95 int64_t f(int64_t* x, int64_t y, int64_t z) { return __sync_val_compare_and_swap(x, y, z); }]])
97 KVDB_CHECK_BUILTIN([__sync_lock_test_and_set],
98 [[long f(long* x) { return __sync_lock_test_and_set(x, 1); }]])
100 KVDB_CHECK_BUILTIN([__sync_lock_test_and_set_val],
101 [[long f(long* x, long y) { return __sync_lock_test_and_set(x, y); }]])
103 KVDB_CHECK_BUILTIN([__sync_lock_release_set],
104 [[void f(long* x) { __sync_lock_release(x); }]])
109 AC_CACHE_CHECK([whether the C++ compiler understands 'auto'], [ac_cv_cxx_auto], [
110 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[struct s { int a; }; int f(s x) { auto &y = x; return y.a; }]], [[]])],
111 [ac_cv_cxx_auto=yes], [ac_cv_cxx_auto=no])])
112 if test "$ac_cv_cxx_auto" != yes -a -z "$ac_user_cxx"; then
113 CXX="${CXX} -std=gnu++0x"
114 AC_MSG_CHECKING([whether the C++ compiler with -std=gnu++0x understands 'auto'])
115 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[struct s { int a; }; int f(s x) { auto &y = x; return y.a; }]], [[]])],
116 [ac_cv_cxx_auto=yes], [ac_cv_cxx_auto=no])
117 AC_MSG_RESULT([$ac_cv_cxx_auto])
120 if test "$ac_cv_cxx_auto" = yes; then
121 AC_DEFINE([HAVE_CXX_AUTO], [1], [Define if the C++ compiler understands 'auto'.])
125 The C++ compiler does not appear to understand C++11.
126 To fix this problem, try supplying a "CXX" argument to ./configure,
127 such as "./configure CXX='c++ -std=gnu++0x'".
129 ========================================================])
132 AC_CACHE_CHECK([whether the C++ compiler understands constexpr], [ac_cv_cxx_constexpr], [
133 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[constexpr int f(int x) { return x + 1; }]], [[]])],
134 [ac_cv_cxx_constexpr=yes], [ac_cv_cxx_constexpr=no])])
135 if test "$ac_cv_cxx_constexpr" = yes; then
136 AC_DEFINE([HAVE_CXX_CONSTEXPR], [1], [Define if the C++ compiler understands constexpr.])
139 AC_CACHE_CHECK([whether the C++ compiler understands static_assert], [ac_cv_cxx_static_assert], [
140 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[const int f = 2;]], [[static_assert(f == 2, "f should be 2");]])],
141 [ac_cv_cxx_static_assert=yes], [ac_cv_cxx_static_assert=no])])
142 if test "$ac_cv_cxx_static_assert" = yes; then
143 AC_DEFINE([HAVE_CXX_STATIC_ASSERT], [1], [Define if the C++ compiler understands static_assert.])
146 AC_CACHE_CHECK([whether the C++ compiler understands rvalue references], [ac_cv_cxx_rvalue_references], [
147 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[int f(int &) { return 1; } int f(int &&) { return 0; }]], [[return f(int());]])],
148 [ac_cv_cxx_rvalue_references=yes], [ac_cv_cxx_rvalue_references=no])])
149 if test "$ac_cv_cxx_rvalue_references" = yes; then
150 AC_DEFINE([HAVE_CXX_RVALUE_REFERENCES], [1], [Define if the C++ compiler understands rvalue references.])
153 AC_CACHE_CHECK([whether the C++ compiler understands template alias], [ac_cv_cxx_template_alias], [
154 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[template <typename T> struct X { typedef T type; }; template <typename T> using Y = X<T>; int f(int x) { return x; }]], [[return f(Y<int>::type());]])],
155 [ac_cv_cxx_template_alias=yes], [ac_cv_cxx_template_alias=no])])
156 if test "$ac_cv_cxx_template_alias" = yes; then
157 AC_DEFINE([HAVE_CXX_TEMPLATE_ALIAS], [1], [Define if the C++ compiler understands template alias.])
160 AC_CHECK_HEADERS([type_traits])
162 AC_CACHE_CHECK([for std::hash], [ac_cv_have_std_hash], [
163 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <functional>
164 #include <stddef.h>],
165 [[std::hash<int> h; size_t x = h(1); return x == 0;]])],
166 [ac_cv_have_std_hash=yes], [ac_cv_have_std_hash=no])])
167 if test $ac_cv_have_std_hash = yes; then
168 AC_DEFINE([HAVE_STD_HASH], [1], [Define if you have std::hash.])
171 AC_CACHE_CHECK([for __has_trivial_copy], [ac_cv_have___has_trivial_copy], [
172 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[long x = 1; if (__has_trivial_copy(long)) x = 0;]])], [ac_cv_have___has_trivial_copy=yes], [ac_cv_have___has_trivial_copy=no])])
173 if test $ac_cv_have___has_trivial_copy = yes; then
174 AC_DEFINE([HAVE___HAS_TRIVIAL_COPY], [1], [Define if you have the __has_trivial_copy compiler intrinsic.])
177 if test "$ac_cv_cxx_rvalue_references" = yes; then
178 AC_MSG_CHECKING([for std::move])
179 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <utility>], [[long x = 0; long &&y = std::move(x);]])], [ac_cv_std_move=yes], [ac_cv_std_move=no])
180 AC_MSG_RESULT([$ac_cv_std_move])
181 if test "$ac_cv_std_move" != yes; then
184 The C++ compiler understands C++11, but does not have std::move.
185 If you are using clang on Mac, ensure the -stdlib=libc++ option.
187 ========================================================])
191 AC_CACHE_CHECK([for std::is_trivially_copyable], [ac_cv_have_std_is_trivially_copyable], [
192 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <type_traits>], [[return std::is_trivially_copyable<int>::value;]])], [ac_cv_have_std_is_trivially_copyable=yes], [ac_cv_have_std_is_trivially_copyable=no])])
193 if test $ac_cv_have_std_is_trivially_copyable = yes; then
194 AC_DEFINE([HAVE_STD_IS_TRIVIALLY_COPYABLE], [1], [Define if you have the std::is_trivially_copyable template.])
197 AC_CACHE_CHECK([for std::is_rvalue_reference], [ac_cv_have_std_is_rvalue_reference], [
198 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <type_traits>], [[return std::is_rvalue_reference<int>::value;]])], [ac_cv_have_std_is_rvalue_reference=yes], [ac_cv_have_std_is_rvalue_reference=no])])
199 if test $ac_cv_have_std_is_rvalue_reference = yes; then
200 AC_DEFINE([HAVE_STD_IS_RVALUE_REFERENCE], [1], [Define if you have the std::is_rvalue_reference template.])
206 AC_CHECK_LIB([flow], [malloc], [have_flow=true], [have_flow=])
207 AC_CHECK_LIB([jemalloc], [mallctl], [have_jemalloc=true], [have_jemalloc=])
208 AC_CHECK_LIB([tcmalloc_minimal], [tc_malloc], [have_tcmalloc_minimal=true], [have_tcmalloc_minimal=])
209 AC_CHECK_LIB([hoard], [_Z16getMainHoardHeapv], [have_hoard=true], [have_hoard=])
211 AC_ARG_WITH([malloc],
212 [AS_HELP_STRING([--with-malloc=TYPE],
213 [memory allocator (malloc|jemalloc|tcmalloc|hoard|flow)])],
214 [ac_mtd_malloc=$withval], [ac_mtd_malloc=yes])
216 if test \( "$ac_mtd_malloc" = tcmalloc -a -z "$have_tcmalloc_minimal" \) \
217 -o \( "$ac_mtd_malloc" = jemalloc -a -z "$have_jemalloc" \) \
218 -o \( "$ac_mtd_malloc" = flow -a -z "$have_flow" \) \
219 -o \( "$ac_mtd_malloc" = hoard -a -z "$have_hoard" \) ; then
220 AC_MSG_ERROR([$ac_mtd_malloc not found])
221 elif test "$ac_mtd_malloc" = tcmalloc -o "$ac_mtd_malloc" = jemalloc -o "$ac_mtd_malloc" = flow -o "$ac_mtd_malloc" = hoard; then
223 elif test "$ac_mtd_malloc" = yes -o "$ac_mtd_malloc" = default; then
224 AC_MSG_CHECKING([for malloc library])
225 if test -n "$have_flow"; then ac_mtd_malloc=flow;
226 elif test -n "$have_jemalloc"; then ac_mtd_malloc=jemalloc;
227 elif test -n "$have_tcmalloc_minimal"; then ac_mtd_malloc=tcmalloc;
228 else ac_mtd_malloc=malloc; fi
229 AC_MSG_RESULT([$ac_mtd_malloc])
230 elif test "$ac_mtd_malloc" = no -o "$ac_mtd_malloc" = malloc -o -z "$ac_mtd_malloc"; then
233 AC_MSG_ERROR([Unknown malloc type $ac_mtd_malloc])
236 AC_MSG_CHECKING([for malloc library])
237 if test "$ac_mtd_malloc" = tcmalloc; then
238 MALLOC_LIBS="-ltcmalloc_minimal"
239 AC_DEFINE([HAVE_TCMALLOC], [1], [Define if you are using libtcmalloc for malloc.])
240 AC_MSG_RESULT([-ltcmalloc_minimal])
241 elif test "$ac_mtd_malloc" = jemalloc; then
242 MALLOC_LIBS="-ljemalloc"
243 AC_DEFINE([HAVE_JEMALLOC], [1], [Define if you are using libjemalloc for malloc.])
244 AC_MSG_RESULT([-ljemalloc])
245 elif test "$ac_mtd_malloc" = flow; then
247 AC_DEFINE([HAVE_FLOW_MALLOC], [1], [Define if you are using libflow for malloc.])
248 AC_MSG_RESULT([-lflow])
249 elif test "$ac_mtd_malloc" = hoard; then
250 MALLOC_LIBS="-lhoard"
251 AC_DEFINE([HAVE_HOARD_MALLOC], [1], [Define if you are using libhoard for malloc.])
252 AC_MSG_RESULT([-lhoard])
255 AC_MSG_RESULT([default])
257 AC_SUBST(MALLOC_LIBS)
262 AC_DEFUN([KVDB_CHECK_SAME_TYPE], [
263 pushdef([KVDB_CST_VAR], [AS_TR_SH([ac_cv_have_same_type_$1_is_$2])])
264 AC_CACHE_CHECK([whether $1 and $2 are the same type], KVDB_CST_VAR,
265 [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([$3
266 int f($1) {return 0;} int f($2) {return 0;}], [])],
267 [KVDB_CST_VAR=no], [KVDB_CST_VAR=yes])])
268 if test $KVDB_CST_VAR = yes; then
269 AC_DEFINE(AS_TR_CPP([HAVE_$1_IS_$2]), [1], [Define if $1 and $2 are the same type.])
271 popdef([KVDB_CST_VAR])
274 KVDB_CHECK_SAME_TYPE([off_t], [long], [#include <stdio.h>])
275 KVDB_CHECK_SAME_TYPE([off_t], [long long], [#include <stdio.h>])
276 KVDB_CHECK_SAME_TYPE([int64_t], [long], [#include <stdint.h>])
277 KVDB_CHECK_SAME_TYPE([int64_t], [long long], [#include <stdint.h>])
278 KVDB_CHECK_SAME_TYPE([size_t], [unsigned], [#include <stdio.h>])
279 KVDB_CHECK_SAME_TYPE([size_t], [unsigned long], [#include <stdio.h>])
280 KVDB_CHECK_SAME_TYPE([size_t], [unsigned long long], [#include <stdio.h>])
282 AC_CHECK_TYPES([long long])
283 AC_CHECK_SIZEOF([short])
284 AC_CHECK_SIZEOF([int])
285 AC_CHECK_SIZEOF([long])
286 AC_CHECK_SIZEOF([long long])
287 AC_CHECK_SIZEOF([void *])
289 AC_CHECK_DECLS([getline])
291 AC_CHECK_HEADERS([time.h execinfo.h])
292 AC_CHECK_DECLS([clock_gettime], [], [], [#if HAVE_TIME_H
295 AC_SEARCH_LIBS([clock_gettime], [rt])
296 AC_CHECK_FUNCS([clock_gettime])
299 AC_ARG_ENABLE([row-type],
300 [AS_HELP_STRING([--enable-row-type=ARG],
301 [row type: bag array array_ver str, default bag])],
302 [ac_cv_row_type=$enableval], [ac_cv_row_type=bag])
303 if test "$ac_cv_row_type" = array; then
304 AC_DEFINE_UNQUOTED([MASSTREE_ROW_TYPE_ARRAY], [1], [Define if the default row type is value_timed_array.])
305 elif test "$ac_cv_row_type" = array_ver; then
306 AC_DEFINE_UNQUOTED([MASSTREE_ROW_TYPE_ARRAY_VER], [1], [Define if the default row type is value_timed_array_ver.])
307 elif test "$ac_cv_row_type" = bag; then
308 AC_DEFINE_UNQUOTED([MASSTREE_ROW_TYPE_BAG], [1], [Define if the default row type is value_timed_bag.])
309 elif test "$ac_cv_row_type" = str; then
310 AC_DEFINE_UNQUOTED([MASSTREE_ROW_TYPE_STR], [1], [Define if the default row type is value_timed_str.])
312 AC_MSG_ERROR([$ac_cv_row_type: Unknown row type])
315 AC_ARG_ENABLE([max-key-len],
316 [AS_HELP_STRING([--enable-max-key-len=ARG],
317 [maximum length of a key in bytes, default 255])],
318 [ac_cv_max_key_len=$enableval], [ac_cv_max_key_len=255])
319 AC_DEFINE_UNQUOTED([MASSTREE_MAXKEYLEN], [$ac_cv_max_key_len], [Maximum key length])
321 AC_MSG_CHECKING([whether MADV_HUGEPAGE is supported])
322 AC_PREPROC_IFELSE([AC_LANG_PROGRAM([[#include <sys/mman.h>
323 #ifndef MADV_HUGEPAGE
326 [have_madv_hugepage=yes], [have_madv_hugepage=no])
327 AC_MSG_RESULT([$have_madv_hugepage])
328 if test $have_madv_hugepage = yes; then
329 AC_DEFINE([HAVE_MADV_HUGEPAGE], [1], [Define if MADV_HUGEPAGE is supported.])
332 AC_MSG_CHECKING([whether MAP_HUGETLB is supported])
333 AC_PREPROC_IFELSE([AC_LANG_PROGRAM([[#include <sys/mman.h>
337 [have_map_hugetlb=yes], [have_map_hugetlb=no])
338 AC_MSG_RESULT([$have_map_hugetlb])
339 if test $have_map_hugetlb = yes; then
340 AC_DEFINE([HAVE_MAP_HUGETLB], [1], [Define if MAP_HUGETLB is supported.])
343 AC_ARG_ENABLE([superpage],
344 [AS_HELP_STRING([--disable-superpage],
345 [disable superpage support])],
346 [], [enable_superpage=maybe])
347 if test "$enable_superpage $have_madv_hugepage $have_map_hugetlb" = "yes no no"; then
349 Error: superpages are not supported on this machine.
350 Try again without --enable-superpage.
352 elif test "$enable_superpage $have_madv_hugepage $have_map_hugetlb" != "maybe no no" -a "$enable_superpage" != no; then
353 AC_DEFINE_UNQUOTED([HAVE_SUPERPAGE], [1], [Define if superpage support is enabled.])
356 AC_ARG_ENABLE([memdebug],
357 [AS_HELP_STRING([--enable-memdebug],
358 [enable memory debugging])])
359 if test "$enable_memdebug" = yes; then
360 AC_DEFINE_UNQUOTED([HAVE_MEMDEBUG], [1], [Define if memory debugging support is enabled.])
363 AC_ARG_ENABLE([assert],
365 [AC_MSG_WARN([Use --disable-assertions instead of --disable-assert.])])
366 AC_ARG_ENABLE([assertions],
367 [AS_HELP_STRING([--disable-assertions],
368 [disable debugging assertions])])
369 if test "$enable_assertions" != no -o "(" -z "$enable_assertions" -a "$enable_assert" != no ")"; then
370 AC_DEFINE_UNQUOTED([ENABLE_ASSERTIONS], [1], [Define to enable debugging assertions.])
373 AC_ARG_ENABLE([preconditions],
374 [AS_HELP_STRING([--disable-preconditions],
375 [disable precondition assertions])])
376 if test "$enable_preconditions" = no; then
377 AC_DEFINE_UNQUOTED([ENABLE_PRECONDITIONS], [0], [Define to enable precondition assertions.])
378 elif test -n "$enable_preconditions"; then
379 AC_DEFINE_UNQUOTED([ENABLE_PRECONDITIONS], [1], [Define to enable precondition assertions.])
382 AC_ARG_ENABLE([invariants],
383 [AS_HELP_STRING([--disable-invariants],
384 [disable invariant assertions])])
385 if test "$enable_invariants" = no; then
386 AC_DEFINE_UNQUOTED([ENABLE_INVARIANTS], [0], [Define to enable invariant assertions.])
387 elif test -n "$enable_preconditions"; then
388 AC_DEFINE_UNQUOTED([ENABLE_INVARIANTS], [1], [Define to enable invariant assertions.])
391 AC_DEFINE_UNQUOTED([CACHE_LINE_SIZE], [64], [Assumed size of a cache line.])
393 AH_TOP([#ifndef MASSTREE_CONFIG_H_INCLUDED
394 #define MASSTREE_CONFIG_H_INCLUDED 1])
396 AH_BOTTOM([#if !FORCE_ENABLE_ASSERTIONS && !ENABLE_ASSERTIONS
400 /** @brief Assert macro that always runs. */
401 extern void fail_always_assert(const char* file, int line, const char* assertion, const char* message = 0) __attribute__((noreturn));
402 #define always_assert(x, ...) do { if (!(x)) fail_always_assert(__FILE__, __LINE__, #x, ## __VA_ARGS__); } while (0)
403 #define mandatory_assert always_assert
405 /** @brief Assert macro for invariants.
407 masstree_invariant(x) is executed if --enable-invariants or
408 --enable-assertions. */
409 extern void fail_masstree_invariant(const char* file, int line, const char* assertion, const char* message = 0) __attribute__((noreturn));
410 #if FORCE_ENABLE_ASSERTIONS || (!defined(ENABLE_INVARIANTS) && ENABLE_ASSERTIONS) || ENABLE_INVARIANTS
411 #define masstree_invariant(x, ...) do { if (!(x)) fail_masstree_invariant(__FILE__, __LINE__, #x, ## __VA_ARGS__); } while (0)
413 #define masstree_invariant(x, ...) do { } while (0)
416 /** @brief Assert macro for preconditions.
418 masstree_precondition(x) is executed if --enable-preconditions or
419 --enable-assertions. */
420 extern void fail_masstree_precondition(const char* file, int line, const char* assertion, const char* message = 0) __attribute__((noreturn));
421 #if FORCE_ENABLE_ASSERTIONS || (!defined(ENABLE_PRECONDITIONS) && ENABLE_ASSERTIONS) || ENABLE_PRECONDITIONS
422 #define masstree_precondition(x, ...) do { if (!(x)) fail_masstree_precondition(__FILE__, __LINE__, #x, ## __VA_ARGS__); } while (0)
424 #define masstree_precondition(x, ...) do { } while (0)
428 #define invariant masstree_invariant
431 #define precondition masstree_precondition
436 AC_DEFINE_UNQUOTED([HAVE_UNALIGNED_ACCESS], [1], [Define if unaligned accesses are OK.])