1# -*- Mode: c-basic-offset:4 ; indent-tabs-mode:nil ; -*- 2# 3# (C) 2008 by Argonne National Laboratory. 4# See COPYRIGHT in top-level directory. 5# 6 7AC_PREREQ(2.62) 8 9AC_INIT([OpenPA], [1.0.3], [https://trac.mcs.anl.gov/projects/openpa/newticket]) 10dnl Set the directory that contains support scripts such as install-sh and 11dnl config.guess. It also contains autoconf macro files. 12AC_CONFIG_AUX_DIR(confdb) 13AC_CONFIG_MACRO_DIR([confdb]) 14 15AM_INIT_AUTOMAKE([-Wall -Werror foreign color-tests 1.12.3]) 16 17# automake 1.12 seems to require this, but automake 1.11 doesn't recognize it 18# must come before LT_INIT 19m4_ifdef([AM_PROG_AR],[AM_PROG_AR]) 20 21LT_PREREQ([2.2.6]) 22 23# Bug in libtool adds -O2 and -g by default 24save_cflags=$CFLAGS 25LT_INIT(disable-shared) 26CFLAGS=$save_cflags 27 28if test -s "$srcdir/VERSION" ; then 29 . $srcdir/VERSION 30 AC_SUBST([libopa_so_version]) 31else 32 AC_MSG_ERROR([Version information not found. Configuration aborted.]) 33fi 34 35dnl force configure to be re-run if $top_srcdir/VERSION changes 36AC_SUBST([CONFIG_STATUS_DEPENDENCIES],['$(top_srcdir)/VERSION']) 37 38# FIXME this header needs to end up in the installation include directory in some form, 39# so we probably need to change its name to something that won't collide in the 40# global namespace. [goodell@ 2009-02-19] 41AC_CONFIG_HEADER([src/config.h]) 42AH_TOP([/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */ 43/* 44 * (C) 2008 by Argonne National Laboratory. 45 * See COPYRIGHT in top-level directory. 46 */ 47]) 48AH_BOTTOM([]) 49 50dnl Preps an opa_config.h with prefixed macros from config.h for output at 51dnl AC_OUTPUT time. This way we can safely include opa_config.h in the 52dnl installation and include it in installed headers. 53AX_PREFIX_CONFIG_H([src/opa_config.h],[OPA]) 54 55# Non-verbose make 56m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) 57 58######################################################################## 59 60# check if we're cross compiling 61if test "$build_alias" = "$host_alias" ; then 62 CROSS_COMPILING="no" 63else 64 CROSS_COMPILING="yes" 65fi 66 67AC_PROG_CC 68 69AC_HEADER_ASSERT 70# do we need intrin.h in here since it's a windows file? 71AC_CHECK_HEADERS([pthread.h atomic.h intrin.h inttypes.h stdint.h stddef.h]) 72 73AC_C_RESTRICT 74AC_C_INLINE 75 76# Not strictly needed (autoconf docs: This macro is obsolescent, as current C 77# compilers support const. New programs need not use this macro. ) 78AC_C_CONST 79 80dnl Check for presence of the pthreads library. This is needed by the test 81dnl suite. 82AC_CHECK_LIB(pthread, pthread_create) 83 84dnl Check for presence of pthread_yield. If not present, check for sched_yield. 85dnl These are used by the test suite. 86AC_CHECK_FUNCS(pthread_yield, 87 , 88 [AC_CHECK_HEADER(sched.h, 89 [AC_CHECK_FUNCS(sched_yield)] 90 )] 91) 92 93if test "$ac_cv_lib_pthread_pthread_create" = yes; then 94AC_MSG_CHECKING([if 100 threads can be run at once]) 95AC_RUN_IFELSE([AC_LANG_PROGRAM([[ 96 #include <stddef.h> 97 #include <pthread.h> 98 pthread_mutex_t mutexus_maximus; 99 void *thread_func(void *udata) { 100 pthread_mutex_lock(&mutexus_maximus); 101 pthread_mutex_unlock(&mutexus_maximus); 102 return NULL; 103 } 104]], [[ 105 int i; 106 pthread_t threads[99]; 107 pthread_mutex_init(&mutexus_maximus, NULL); 108 pthread_mutex_lock(&mutexus_maximus); 109 for(i=0; i<99; i++) 110 if(pthread_create(&threads[i], NULL, thread_func, NULL)) { 111 pthread_mutex_unlock(&mutexus_maximus); 112 return 1; 113 } 114 pthread_mutex_unlock(&mutexus_maximus); 115 return 0; 116]])], 117AC_MSG_RESULT([yes]) 118AC_DEFINE(MAX_NTHREADS, 100, [define to the maximum number of simultaneous threads]), 119AC_MSG_RESULT([no]) 120dnl We cannot run 100 threads, check if we can run 10 121 AC_MSG_CHECKING([if 10 threads can be run at once]) 122 AC_RUN_IFELSE([AC_LANG_PROGRAM([[ 123 #include <stddef.h> 124 #include <pthread.h> 125 pthread_mutex_t mutexus_maximus; 126 void *thread_func(void *udata) { 127 pthread_mutex_lock(&mutexus_maximus); 128 pthread_mutex_unlock(&mutexus_maximus); 129 return NULL; 130 } 131 ]], [[[ 132 int i; 133 pthread_t threads[9]; 134 pthread_mutex_init(&mutexus_maximus, NULL); 135 pthread_mutex_lock(&mutexus_maximus); 136 for(i=0; i<9; i++) 137 if(pthread_create(&threads[i], NULL, thread_func, NULL)) { 138 pthread_mutex_unlock(&mutexus_maximus); 139 return 1; 140 } 141 pthread_mutex_unlock(&mutexus_maximus); 142 return 0; 143 ]]])], 144 AC_MSG_RESULT([yes]) 145 AC_DEFINE(MAX_NTHREADS, 10, [define to the maximum number of simultaneous threads]), 146 AC_MSG_RESULT([no]) 147 AC_DEFINE(MAX_NTHREADS, 4, [define to the maximum number of simultaneous threads]), 148 AC_MSG_RESULT([N/A])), 149AC_MSG_RESULT([N/A])) 150fi 151 152AC_CHECK_SIZEOF([void *]) 153AC_CHECK_SIZEOF([int]) 154 155dnl Check for __attribute__ support. This was originally taken from 156dnl the PAC_C_GNU_ATTRIBUTE macro in mpich2. 157dnl 158dnl We start by requiring Gcc. Some other compilers accept __attribute__ 159dnl but generate warning messages, or have different interpretations 160dnl (which seems to make __attribute__ just as bad as #pragma) 161dnl For example, the Intel icc compiler accepts __attribute__ and 162dnl __attribute__((pure)) but generates warnings for __attribute__((format...)) 163if test "$GCC" = "yes" ; then 164 AC_CACHE_CHECK([whether __attribute__ allowed], 165pac_cv_gnu_attr_pure,[ 166AC_TRY_COMPILE([int foo(int) __attribute__ ((pure));],[int a;], 167pac_cv_gnu_attr_pure=yes,pac_cv_gnu_attr_pure=no)]) 168AC_CACHE_CHECK([whether __attribute__((format)) allowed], 169pac_cv_gnu_attr_format,[ 170AC_TRY_COMPILE([int foo(char *,...) __attribute__ ((format(printf,1,2)));],[int a;], 171pac_cv_gnu_attr_format=yes,pac_cv_gnu_attr_format=no)]) 172 if test "$pac_cv_gnu_attr_pure" = "yes" -a "$pac_cv_gnu_attr_format" = "yes" ; then 173 AC_DEFINE(HAVE_GCC_ATTRIBUTE,1,[Define if GNU __attribute__ is supported]) 174 fi 175fi 176 177dnl Check to make sure that the compiler rejects bogus inline assembly 178dnl statements. If it does not, then we need to be careful below when 179dnl we're checking which primitives header file to use. 180AC_MSG_CHECKING([if compiler rejects bogus asm statements]) 181AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[ 182 __asm__ __volatile__ ("ILLEGAL_ASM_STMT"); 183 ]])], 184 compiler_rejects_bogus_asm=no 185 AC_MSG_RESULT([no]) 186 , 187 compiler_rejects_bogus_asm=yes 188 AC_MSG_RESULT([yes]) 189) 190 191AC_ARG_WITH([atomic-primitives], [AC_HELP_STRING([--with-atomic-primitives], 192 [Force OPA to use a specific atomic primitives implementation file (default 193 is auto). A value of 'no' forces the use of locks to implement atomic 194 primitives. A value of 'auto_allow_emulation' will attempt to detect 195 native primitives and will fall back to lock-based emulation if none are 196 available. Note that using locks to implement atomic primitives will have 197 a substantial impact on performance and is intended for testing only. A 198 value of 'unsafe' will use a non-atomic version of the primitives for performance 199 in single-threaded code and meta-testing.])], 200 [AS_IF([test "$with_atomic_primitives" = "yes"], [with_atomic_primitives=auto])], 201 [with_atomic_primitives=auto] 202) 203 204 205# is set to yes by the macro below if any test ever succeeds 206non_emulated_primitives_available=no 207# is set to yes in OPA_TRY_PRIMITIVE_HEADER when a primitive 208# matching $with_atomic_primitives is checked 209checked_specified_primitive=no 210 211AC_DEFUN([OPA_PRIMITIVE_TEST_PGM], [AC_LANG_PROGRAM([[ 212#define OPA_SIZEOF_INT SIZEOF_INT 213#define OPA_SIZEOF_VOID_P SIZEOF_VOID_P 214#ifndef _opa_inline 215#define _opa_inline inline 216#endif 217#ifndef _opa_restrict 218#define _opa_restrict restrict 219#endif 220#ifndef _opa_const 221#define _opa_const const 222#endif 223#ifdef HAVE_GCC_ATTRIBUTE 224#define OPA_HAVE_GCC_ATTRIBUTE 1 225#endif 226#include "opa_util.h" /* for OPA_ATTRIBUTE and friends */ 227#include "primitives/$1" 228 ]],[[ 229 OPA_int_t a, b; 230 int c; 231 232 OPA_store_int(&a, 0); 233 OPA_store_int(&b, 1); 234 c = OPA_load_int(&a); 235 236 OPA_add_int(&a, 10); 237 OPA_incr_int(&a); 238 OPA_decr_int(&a); 239 240 c = OPA_decr_and_test_int(&a); 241 c = OPA_fetch_and_add_int(&a, 10); 242 c = OPA_fetch_and_incr_int(&a); 243 c = OPA_fetch_and_decr_int(&a); 244 245 c = OPA_cas_int(&a, 10, 11); 246 c = OPA_swap_int(&a, OPA_load_int(&b)); 247 248 OPA_write_barrier(); 249 OPA_read_barrier(); 250 OPA_read_write_barrier(); 251 ]])] 252) 253 254dnl OPA_TRY_PRIMITIVE_HEADER([header file from src/ dir], [HAVE_ macro suffix], [feature description]) 255dnl Does an AC_LINK_IFELSE() to see if the header file works 256AC_DEFUN([OPA_TRY_PRIMITIVE_HEADER],[ 257if test "$with_atomic_primitives" = "auto" || \ 258 test "$with_atomic_primitives" = "auto_allow_emulation" || \ 259 test "$with_atomic_primitives" = "$1" 260then 261 checked_specified_primitive=yes 262 AC_MSG_CHECKING([for support for $3]) 263 SAVE_CFLAGS="$CFLAGS" 264 CFLAGS="$CFLAGS -I${srcdir}/src" 265 AC_LINK_IFELSE([OPA_PRIMITIVE_TEST_PGM([$1])], 266 [AC_DEFINE([HAVE_$2], [1], [define to 1 if we have support for $3]) 267 non_emulated_primitives_available=yes] 268 [AC_MSG_RESULT([yes])] 269 , 270 [AC_MSG_RESULT([no])] 271 ) 272 CFLAGS="$SAVE_CFLAGS" 273fi 274]) 275 276dnl OPA_TRY_RUN_PRIMITIVE_HEADER([header file from src/ dir], [HAVE_ macro suffix], [feature description]) 277dnl Does an AC_RUN_IFELSE() to see if the header file works, but falls back to AC_LINK_IFELSE() 278dnl if we're cross-compiling 279AC_DEFUN([OPA_TRY_RUN_PRIMITIVE_HEADER],[ 280if test "$with_atomic_primitives" = "auto" || \ 281 test "$with_atomic_primitives" = "auto_allow_emulation" || \ 282 test "$with_atomic_primitives" = "$1" 283then 284 checked_specified_primitive=yes 285 AC_MSG_CHECKING([for support for $3]) 286 SAVE_CFLAGS="$CFLAGS" 287 CFLAGS="$CFLAGS -I${srcdir}/src" 288 AC_RUN_IFELSE([OPA_PRIMITIVE_TEST_PGM([$1])],[ 289 AC_DEFINE([HAVE_$2], [1], [define to 1 if we have support for $3]) 290 non_emulated_primitives_available=yes 291 AC_MSG_RESULT([yes])] 292 , 293 [AC_MSG_RESULT([no])] 294 , 295 [AC_LINK_IFELSE([OPA_PRIMITIVE_TEST_PGM([$1])],[ 296 AC_DEFINE([HAVE_$2], [1], [define to 1 if we have support for $3]) 297 non_emulated_primitives_available=yes 298 AC_MSG_RESULT([yes])] 299 , 300 [AC_MSG_RESULT([no])] 301 )] 302 ) 303 CFLAGS="$SAVE_CFLAGS" 304fi 305]) 306 307using_emulated_primitives=no 308using_unsafe_primitives=no 309 310if test "$with_atomic_primitives" = "no" ; then 311 using_emulated_primitives=yes 312 # EXPLICIT_EMULATION becomes OPA_EXPLICIT_EMULATION in the installed opa_config.h 313 AC_DEFINE([EXPLICIT_EMULATION],[1], 314 [define if lock-based emulation was explicitly requested at 315 configure time via --with-atomic-primitives=no]) 316elif test "$with_atomic_primitives" = "unsafe" ; then 317 using_unsafe_primitives=yes 318else 319dnl We currently test for support of each platform or implementation by 320dnl attempting to compile the associated primitives header file. This doesn't 321dnl feel right, but it's actually pretty effective while being fairly easy to 322dnl implement as well. The biggest problem with this strategy is that if we are 323dnl missing some little bit of compatibility code (a missing type or header for 324dnl which we have a workaround) we could end up selecting the wrong 325dnl implementation. 326dnl 327dnl If the compiler can't tell that it's getting bad assembly, we have 328dnl no hope of being able to check what asm statements are supported 329dnl without AC_TRY_RUN(). 330 if test "$compiler_rejects_bogus_asm" = "yes" ; then 331 # if we're cross compiling, don't try the gcc_intel_32_64 332 # test, since it uses fence operations which are not supported 333 # on pre Pentium 4 machines, but it may still compile and link 334 if test "$CROSS_COMPILING" = "no" ; then 335 OPA_TRY_RUN_PRIMITIVE_HEADER([opa_gcc_intel_32_64.h], [GCC_X86_32_64], [gcc x86/x86_64 primitives]) 336 fi 337 OPA_TRY_RUN_PRIMITIVE_HEADER([opa_gcc_intel_32_64_p3.h], [GCC_X86_32_64_P3], [gcc x86 primitives for pre-Pentium 4]) 338 OPA_TRY_PRIMITIVE_HEADER([opa_gcc_ia64.h], [GCC_AND_IA64_ASM], [gcc ia64 primitives]) 339 OPA_TRY_PRIMITIVE_HEADER([opa_gcc_ppc.h], [GCC_AND_POWERPC_ASM], [gcc PowerPC atomics]) 340 OPA_TRY_PRIMITIVE_HEADER([opa_gcc_sicortex.h], [GCC_AND_SICORTEX_ASM], [gcc SiCortex atomics]) 341 fi 342 343 OPA_TRY_PRIMITIVE_HEADER([opa_gcc_intrinsics.h], [GCC_INTRINSIC_ATOMICS], [gcc atomic intrinsics]) 344 OPA_TRY_PRIMITIVE_HEADER([opa_nt_intrinsics.h], [NT_INTRINSICS], [Windows NT atomic intrinsics]) 345 OPA_TRY_PRIMITIVE_HEADER([opa_sun_atomic_ops.h], [SUN_ATOMIC_OPS], [Sun atomic operations library]) 346 347 if test "$checked_specified_primitive" = "no" ; then 348 AC_MSG_ERROR([did not find specified atomic primitives file "$with_atomic_primitives"], 1) 349 fi 350 351 if test "$non_emulated_primitives_available" = "no" ; then 352 if test "$with_atomic_primitives" = "auto_allow_emulation" ; then 353 using_emulated_primitives=yes 354 else 355 AC_MSG_ERROR([ 356======================================================= 357No native supported atomic primitives were detected. 358You can use "--with-atomic-primitives=no" to emulate 359the atomic primitives using locks, but note that doing 360this will result in a substantial performance 361penalty. 362=======================================================], 1) 363 fi 364 fi 365fi 366 367internal_pkg_config_libs= 368external_pkg_config_libs= 369if test "$using_emulated_primitives" = "yes" ; then 370 AC_MSG_WARN([ 371=================================================== 372Using locks to implement atomic primitives. This 373will result in a substantial impact on performance. 374Use this only for testing. 375===================================================]) 376 AC_DEFINE(USE_LOCK_BASED_PRIMITIVES, 1, [define to 1 to force using lock-based atomic primitives]) 377 internal_pkg_config_libs="-lpthread $internal_pkg_config_libs" 378 external_pkg_config_libs="-lopa $external_pkg_config_libs" 379fi 380 381AC_SUBST(internal_pkg_config_libs) 382AC_SUBST(external_pkg_config_libs) 383 384if test "$using_unsafe_primitives" = "yes" ; then 385 AC_MSG_WARN([ 386=================================================== 387Using *UNSAFE*, *NON-ATOMIC* primitive operations. 388Use this for only for testing or for performance 389reasons in non-concurrent code. 390 391Consider yourself warned! 392===================================================]) 393 AC_DEFINE([USE_UNSAFE_PRIMITIVES],[1],[define to 1 if unsafe (non-atomic) primitives should be used]) 394fi 395 396dnl Check to see if we should enable strict fairness checks 397AC_MSG_CHECKING([whether to enable strict fairness checks]) 398AC_ARG_ENABLE(strict-fairness-checks, 399 [AC_HELP_STRING([--enable-strict-fairness-checks], 400 [Enable stricter checks of the "fairness" of atomic operations in the 401 test suite (default is no). A value of 'yes' will remove the calls to 402 pthread_yield() from these test routines.])], 403 [strict_fairness_checks=$enableval], 404 [strict_fairness_checks=no]) 405if test "${strict_fairness_checks}" = "yes"; then 406 AC_MSG_RESULT([yes]) 407 AC_DEFINE([HAVE_STRICT_FAIRNESS_CHECKS], [1], 408 [Define if strict checking of atomic operation fairness is desired]) 409else 410 AC_MSG_RESULT([no]) 411fi 412 413## Enable creation of libtool-style versioning or no versioning 414AC_ARG_ENABLE(versioning, 415 [AC_HELP_STRING([--enable-versioning],[Enable library versioning])],, 416 [enable_versioning=yes]) 417 418if test "$enable_versioning" = "yes" ; then 419 libopa_so_versionflags="-version-info \$(libopa_so_version)" 420else 421 libopa_so_versionflags="-avoid-version" 422fi 423export libopa_so_versionflags 424AC_SUBST(libopa_so_versionflags) 425 426 427AC_CONFIG_FILES([Makefile src/Makefile test/Makefile openpa.pc]) 428AC_OUTPUT 429 430