detect __sync_bool_compare_and_swap() via `configure'

This commit is contained in:
Matthew Flatt 2011-08-12 16:29:42 -06:00
parent d374fab4ca
commit ca92376381
4 changed files with 100 additions and 3 deletions

71
src/configure vendored
View File

@ -8291,6 +8291,77 @@ _ACEOF
enable_mzrt=yes
fi
############## compare-and-swap ################
if test "${enable_mzrt}" = "yes" ; then
msg="for compare-and-swap"
{ echo "$as_me:$LINENO: checking $msg" >&5
echo $ECHO_N "checking $msg... $ECHO_C" >&6; }
if test "$cross_compiling" = yes; then
cas_available=no
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
int check1(long *addr, long old, long new_val) {
return __sync_bool_compare_and_swap(addr, old, new_val);
}
int check2(short *addr, short old, short new_val) {
return __sync_bool_compare_and_swap(addr, old, new_val);
}
int main() {
long l = 2; short s = 3;
return !check1(&l, 2, 4) || !check2(&s, 3, 6);
}
_ACEOF
rm -f conftest$ac_exeext
if { (ac_try="$ac_link"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_link") 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && { ac_try='./conftest$ac_exeext'
{ (case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_try") 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
cas_available=yes
else
echo "$as_me: program exited with status $ac_status" >&5
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
( exit $ac_status )
cas_available=no
fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
fi
{ echo "$as_me:$LINENO: result: $cas_available" >&5
echo "${ECHO_T}$cas_available" >&6; }
if test "${cas_available}" = "yes" ; then
cat >>confdefs.h <<\_ACEOF
#define MZ_CAS_AVAILABLE 1
_ACEOF
fi
fi
############### OS threads ###################
if test "${enable_mzrt}" = "yes" ; then

View File

@ -937,6 +937,29 @@ if test "${enable_futures}" = "yes" ; then
enable_mzrt=yes
fi
############## compare-and-swap ################
if test "${enable_mzrt}" = "yes" ; then
[ msg="for compare-and-swap" ]
AC_MSG_CHECKING($msg)
AC_TRY_RUN(
int check1(long *addr, long old, long new_val) {
return __sync_bool_compare_and_swap(addr, old, new_val);
}
int check2(short *addr, short old, short new_val) {
return __sync_bool_compare_and_swap(addr, old, new_val);
}
int main() {
long l = 2; short s = 3;
return !check1(&l, 2, 4) || !check2(&s, 3, 6);
}, cas_available=yes, cas_available=no, cas_available=no)
AC_MSG_RESULT($cas_available)
if test "${cas_available}" = "yes" ; then
AC_DEFINE(MZ_CAS_AVAILABLE,1,[Compare-and-swap available])
fi
fi
############### OS threads ###################
if test "${enable_mzrt}" = "yes" ; then

View File

@ -64,6 +64,9 @@ typedef unsigned long uintptr_t;
#undef MZ_USE_PLACES
#endif
/* Whether __sync_bool_compare_and_swap() works: */
#undef MZ_CAS_AVAILABLE
/* Configure use of pthreads for the user-thread timer. */
#undef USE_PTHREAD_INSTEAD_OF_ITIMER

View File

@ -1,7 +1,9 @@
XFORM_NONGCING static MZ_INLINE int mz_MZRT_CAS(volatile mz_CAS_T *addr, mz_CAS_T old, mz_CAS_T new_val)
XFORM_SKIP_PROC
{
#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && ((__GNUC__ <= 3) || (__GNUC__ == 4 && __GNUC_MINOR__ < 1))
#ifdef MZ_CAS_AVAILABLE
return __sync_bool_compare_and_swap(addr, old, new_val);
#elif defined(__GNUC__)
# if defined(__i386__) || defined(__x86_64__)
# ifdef mz_CAS_64
# define CAS_I_SIZE "q"
@ -47,8 +49,6 @@ XFORM_NONGCING static MZ_INLINE int mz_MZRT_CAS(volatile mz_CAS_T *addr, mz_CAS_
# error mzrt_cas not defined on this platform
# endif
#elif defined(__GNUC__) && !defined(__INTEL_COMPILER)
return __sync_bool_compare_and_swap(addr, old, new_val);
#elif defined(_MSC_VER)
# ifdef mz_CAS_64
return _InterlockedCompareExchange64((__int64 *)addr, (__int64)new_val, (__int64)old) == (__int64)old;