+2008-04-24 Benjamin Kosnik <bkoz@redhat.com>
+
+ * acinclude.m4 (GLIBCXX_ENABLE_ATOMIC_BUILTINS): Check for set of
+ all used __sync builtins, in two sizes.
+ * config.h.in: Regenerate.
+ * configure: Regenerate.
+ * src/atomic.cc: Use _GLIBCXX_ATOMIC_BUILTINS_1.
+ * include/ext/atomicity.h: Use _GLIBCXX_ATOMIC_BUILTINS_4.
+ * libsupc++/guard.cc: Use _GLIBCXX_ATOMIC_BUILTINS_4.
+ * doc/xml/manual/concurrency.xm: Update docs.
+
2008-04-23 Benjamin Kosnik <bkoz@redhat.com>
* config/os/hpux/os_defines.h: Use _GLIBCXX_BEGIN_NAMESPACE,
dnl http://gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html#Atomic-Builtins
dnl
dnl This checks to see if the host supports the compiler-generated
-dnl builtins for atomic operations. Note, this is intended to be an
-dnl all-or-nothing switch, so all the atomic operations that are used
-dnl should be checked.
+dnl builtins for atomic operations for various integral sizes. Note, this
+dnl is intended to be an all-or-nothing switch, so all the atomic operations
+dnl that are used should be checked.
dnl
dnl Note:
dnl libgomp and libgfortran do this with a link test, instead of an asm test.
dnl see: CHECK_SYNC_FETCH_AND_ADD
dnl
dnl Defines:
-dnl _GLIBCXX_ATOMIC_BUILTINS if the compiler on this target supports atomics.
+dnl _GLIBCXX_ATOMIC_BUILTINS_1
+dnl _GLIBCXX_ATOMIC_BUILTINS_4
dnl
AC_DEFUN([GLIBCXX_ENABLE_ATOMIC_BUILTINS], [
- AC_MSG_CHECKING([for atomic builtins])
AC_LANG_SAVE
AC_LANG_CPLUSPLUS
+ old_CXXFLAGS="$CXXFLAGS"
+
+ # Compile unoptimized.
+ CXXFLAGS='-O0 -S'
+
+ # Fake what AC_TRY_COMPILE does, without linking as this is
+ # unnecessary for a builtins test.
- # Fake what AC_TRY_COMPILE does. XXX Look at redoing this new-style.
cat > conftest.$ac_ext << EOF
[#]line __oline__ "configure"
int main()
atomic_type c1;
atomic_type c2;
const atomic_type c3(0);
- if (__sync_fetch_and_add(&c1, c2) == c3)
- {
- // Do something.
- }
- return 0;
+ __sync_fetch_and_add(&c1, c2);
+ __sync_val_compare_and_swap(&c1, c3, c2);
+ __sync_lock_test_and_set(&c1, c3);
+ __sync_lock_release(&c1);
+ __sync_synchronize();
+ return 0;
}
EOF
- old_CXXFLAGS="$CXXFLAGS"
- CXXFLAGS='-O0 -S'
+
+ AC_MSG_CHECKING([for atomic builtins for int])
if AC_TRY_EVAL(ac_compile); then
- if grep __sync_fetch_and_add conftest.s >/dev/null 2>&1 ; then
- enable_atomic_builtins=no
+ if grep __sync_ conftest.s >/dev/null 2>&1 ; then
+ enable_atomic_builtinsi=no
else
- AC_DEFINE(_GLIBCXX_ATOMIC_BUILTINS, 1,
- [Define if builtin atomic operations are supported on this host.])
- enable_atomic_builtins=yes
- atomicity_dir=cpu/generic/atomicity_builtins
+ AC_DEFINE(_GLIBCXX_ATOMIC_BUILTINS_4, 1,
+ [Define if builtin atomic operations for int are supported on this host.])
+ enable_atomic_builtinsi=yes
fi
fi
- AC_MSG_RESULT($enable_atomic_builtins)
- CXXFLAGS="$old_CXXFLAGS"
+ AC_MSG_RESULT($enable_atomic_builtinsi)
rm -f conftest*
- # Now, if still generic, set to mutex.
+ cat > conftest.$ac_ext << EOF
+[#]line __oline__ "configure"
+int main()
+{
+ typedef bool atomic_type;
+ atomic_type c1;
+ atomic_type c2;
+ const atomic_type c3(0);
+ __sync_fetch_and_add(&c1, c2);
+ __sync_val_compare_and_swap(&c1, c3, c2);
+ __sync_lock_test_and_set(&c1, c3);
+ __sync_lock_release(&c1);
+ __sync_synchronize();
+ return 0;
+}
+EOF
+
+ AC_MSG_CHECKING([for atomic builtins for bool])
+ if AC_TRY_EVAL(ac_compile); then
+ if grep __sync_ conftest.s >/dev/null 2>&1 ; then
+ enable_atomic_builtinsb=no
+ else
+ AC_DEFINE(_GLIBCXX_ATOMIC_BUILTINS_1, 1,
+ [Define if builtin atomic operations for bool are supported on this host.])
+ enable_atomic_builtinsb=yes
+ fi
+ fi
+ AC_MSG_RESULT($enable_atomic_builtinsb)
+ rm -f conftest*
+
+ CXXFLAGS="$old_CXXFLAGS"
+ AC_LANG_RESTORE
+
+ # Set atomicity_dir to builtins if either of above tests pass.
+ if test $enable_atomic_builtinsi = yes || test $enable_atomic_builtinsb = yes ; then
+ atomicity_dir=cpu/generic/atomicity_builtins
+ fi
+
+ # If still generic, set to mutex.
if test $atomicity_dir = "cpu/generic" ; then
- atomicity_dir=cpu/generic/atomicity_mutex
+ atomicity_dir=cpu/generic/atomicity_mutex
fi
- AC_LANG_RESTORE
+
])
/* Version number of package */
#undef VERSION
-/* Define if builtin atomic operations are supported on this host. */
-#undef _GLIBCXX_ATOMIC_BUILTINS
+/* Define if builtin atomic operations for bool are supported on this host. */
+#undef _GLIBCXX_ATOMIC_BUILTINS_1
+
+/* Define if builtin atomic operations for int are supported on this host. */
+#undef _GLIBCXX_ATOMIC_BUILTINS_4
/* Define to use concept checking code from the boost libraries. */
#undef _GLIBCXX_CONCEPT_CHECKS
- echo "$as_me:$LINENO: checking for atomic builtins" >&5
-echo $ECHO_N "checking for atomic builtins... $ECHO_C" >&6
ac_ext=cc
ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+ old_CXXFLAGS="$CXXFLAGS"
+
+ # Compile unoptimized.
+ CXXFLAGS='-O0 -S'
+
+ # Fake what AC_TRY_COMPILE does, without linking as this is
+ # unnecessary for a builtins test.
- # Fake what AC_TRY_COMPILE does. XXX Look at redoing this new-style.
cat > conftest.$ac_ext << EOF
-#line 18087 "configure"
+#line 18091 "configure"
int main()
{
// NB: _Atomic_word not necessarily int.
atomic_type c1;
atomic_type c2;
const atomic_type c3(0);
- if (__sync_fetch_and_add(&c1, c2) == c3)
- {
- // Do something.
- }
- return 0;
+ __sync_fetch_and_add(&c1, c2);
+ __sync_val_compare_and_swap(&c1, c3, c2);
+ __sync_lock_test_and_set(&c1, c3);
+ __sync_lock_release(&c1);
+ __sync_synchronize();
+ return 0;
}
EOF
- old_CXXFLAGS="$CXXFLAGS"
- CXXFLAGS='-O0 -S'
+
+ echo "$as_me:$LINENO: checking for atomic builtins for int" >&5
+echo $ECHO_N "checking for atomic builtins for int... $ECHO_C" >&6
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; then
- if grep __sync_fetch_and_add conftest.s >/dev/null 2>&1 ; then
- enable_atomic_builtins=no
+ if grep __sync_ conftest.s >/dev/null 2>&1 ; then
+ enable_atomic_builtinsi=no
else
cat >>confdefs.h <<\_ACEOF
-#define _GLIBCXX_ATOMIC_BUILTINS 1
+#define _GLIBCXX_ATOMIC_BUILTINS_4 1
_ACEOF
- enable_atomic_builtins=yes
- atomicity_dir=cpu/generic/atomicity_builtins
+ enable_atomic_builtinsi=yes
fi
fi
- echo "$as_me:$LINENO: result: $enable_atomic_builtins" >&5
-echo "${ECHO_T}$enable_atomic_builtins" >&6
- CXXFLAGS="$old_CXXFLAGS"
+ echo "$as_me:$LINENO: result: $enable_atomic_builtinsi" >&5
+echo "${ECHO_T}$enable_atomic_builtinsi" >&6
rm -f conftest*
- # Now, if still generic, set to mutex.
- if test $atomicity_dir = "cpu/generic" ; then
- atomicity_dir=cpu/generic/atomicity_mutex
- fi
- ac_ext=c
+ cat > conftest.$ac_ext << EOF
+#line 18131 "configure"
+int main()
+{
+ typedef bool atomic_type;
+ atomic_type c1;
+ atomic_type c2;
+ const atomic_type c3(0);
+ __sync_fetch_and_add(&c1, c2);
+ __sync_val_compare_and_swap(&c1, c3, c2);
+ __sync_lock_test_and_set(&c1, c3);
+ __sync_lock_release(&c1);
+ __sync_synchronize();
+ return 0;
+}
+EOF
+
+ echo "$as_me:$LINENO: checking for atomic builtins for bool" >&5
+echo $ECHO_N "checking for atomic builtins for bool... $ECHO_C" >&6
+ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; then
+ if grep __sync_ conftest.s >/dev/null 2>&1 ; then
+ enable_atomic_builtinsb=no
+ else
+
+cat >>confdefs.h <<\_ACEOF
+#define _GLIBCXX_ATOMIC_BUILTINS_1 1
+_ACEOF
+
+ enable_atomic_builtinsb=yes
+ fi
+ fi
+ echo "$as_me:$LINENO: result: $enable_atomic_builtinsb" >&5
+echo "${ECHO_T}$enable_atomic_builtinsb" >&6
+ rm -f conftest*
+
+ CXXFLAGS="$old_CXXFLAGS"
+ ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
+ # Set atomicity_dir to builtins if either of above tests pass.
+ if test $enable_atomic_builtinsi = yes || test $enable_atomic_builtinsb = yes ; then
+ atomicity_dir=cpu/generic/atomicity_builtins
+ fi
+
+ # If still generic, set to mutex.
+ if test $atomicity_dir = "cpu/generic" ; then
+ atomicity_dir=cpu/generic/atomicity_mutex
+ fi
+
+
if test $atomicity_dir = cpu/generic/atomicity_mutex ; then
{ echo "$as_me:$LINENO: WARNING: No native atomic operations are provided for this platform." >&5
echo "$as_me: WARNING: No native atomic operations are provided for this platform." >&2;}
compile.
</para>
-<para> If builtins are possible, <code>_GLIBCXX_ATOMIC_BUILTINS</code>
-will be defined.
+<para>
+If builtins are possible for bool-sized integral types,
+<code>_GLIBCXX_ATOMIC_BUILTINS_1</code> will be defined.
+If builtins are possible for int-sized integral types,
+<code>_GLIBCXX_ATOMIC_BUILTINS_4</code> will be defined.
</para>
// Support for atomic operations -*- C++ -*-
-// Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
+// Copyright (C) 2004, 2005, 2006, 2008 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// To abstract locking primitives across all thread policies, use:
// __exchange_and_add_dispatch
// __atomic_add_dispatch
-#ifdef _GLIBCXX_ATOMIC_BUILTINS
+#ifdef _GLIBCXX_ATOMIC_BUILTINS_4
static inline _Atomic_word
__exchange_and_add(volatile _Atomic_word* __mem, int __val)
{ return __sync_fetch_and_add(__mem, __val); }
-// Copyright (C) 2002, 2004, 2006 Free Software Foundation, Inc.
+// Copyright (C) 2002, 2004, 2006, 2008 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
#include <ext/atomicity.h>
#include <ext/concurrence.h>
#if defined(__GTHREADS) && defined(__GTHREAD_HAS_COND) \
- && defined(_GLIBCXX_ATOMIC_BUILTINS) && defined(_GLIBCXX_HAVE_LINUX_FUTEX)
+ && defined(_GLIBCXX_ATOMIC_BUILTINS_4) && defined(_GLIBCXX_HAVE_LINUX_FUTEX)
# include <climits>
# include <syscall.h>
# define _GLIBCXX_USE_FUTEX
atomic_flag_test_and_set_explicit(volatile atomic_flag* __a,
memory_order __x)
{
-#ifdef _GLIBCXX_ATOMIC_BUILTINS
+#ifdef _GLIBCXX_ATOMIC_BUILTINS_1
if (__x >= memory_order_acq_rel)
__sync_synchronize();
return __sync_lock_test_and_set(&(__a->_M_base._M_b), 1);
void
atomic_flag_clear_explicit(volatile atomic_flag* __a, memory_order __x)
{
-#ifdef _GLIBCXX_ATOMIC_BUILTINS
+#ifdef _GLIBCXX_ATOMIC_BUILTINS_1
__sync_lock_release(&(__a->_M_base._M_b));
if (__x >= memory_order_acq_rel)
__sync_synchronize();
void
atomic_flag_fence(const volatile atomic_flag*, memory_order)
{
-#ifdef _GLIBCXX_ATOMIC_BUILTINS
+#ifdef _GLIBCXX_ATOMIC_BUILTINS_1
__sync_synchronize();
#endif
}