acinclude.m4 (GLIBCXX_ENABLE_ATOMIC_BUILTINS): Check for set of all used __sync builtins, in two sizes.

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.

From-SVN: r134629
This commit is contained in:
Benjamin Kosnik 2008-04-24 14:40:29 +00:00 committed by Benjamin Kosnik
parent 2aa43509ae
commit 35648b4572
8 changed files with 171 additions and 60 deletions

View File

@ -1,3 +1,14 @@
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> 2008-04-23 Benjamin Kosnik <bkoz@redhat.com>
* config/os/hpux/os_defines.h: Use _GLIBCXX_BEGIN_NAMESPACE, * config/os/hpux/os_defines.h: Use _GLIBCXX_BEGIN_NAMESPACE,

View File

@ -2129,23 +2129,29 @@ dnl See:
dnl http://gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html#Atomic-Builtins dnl http://gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html#Atomic-Builtins
dnl dnl
dnl This checks to see if the host supports the compiler-generated 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 builtins for atomic operations for various integral sizes. Note, this
dnl all-or-nothing switch, so all the atomic operations that are used dnl is intended to be an all-or-nothing switch, so all the atomic operations
dnl should be checked. dnl that are used should be checked.
dnl dnl
dnl Note: dnl Note:
dnl libgomp and libgfortran do this with a link test, instead of an asm test. dnl libgomp and libgfortran do this with a link test, instead of an asm test.
dnl see: CHECK_SYNC_FETCH_AND_ADD dnl see: CHECK_SYNC_FETCH_AND_ADD
dnl dnl
dnl Defines: 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 dnl
AC_DEFUN([GLIBCXX_ENABLE_ATOMIC_BUILTINS], [ AC_DEFUN([GLIBCXX_ENABLE_ATOMIC_BUILTINS], [
AC_MSG_CHECKING([for atomic builtins])
AC_LANG_SAVE AC_LANG_SAVE
AC_LANG_CPLUSPLUS 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 cat > conftest.$ac_ext << EOF
[#]line __oline__ "configure" [#]line __oline__ "configure"
int main() int main()
@ -2155,34 +2161,71 @@ int main()
atomic_type c1; atomic_type c1;
atomic_type c2; atomic_type c2;
const atomic_type c3(0); const atomic_type c3(0);
if (__sync_fetch_and_add(&c1, c2) == c3) __sync_fetch_and_add(&c1, c2);
{ __sync_val_compare_and_swap(&c1, c3, c2);
// Do something. __sync_lock_test_and_set(&c1, c3);
} __sync_lock_release(&c1);
return 0; __sync_synchronize();
return 0;
} }
EOF EOF
old_CXXFLAGS="$CXXFLAGS"
CXXFLAGS='-O0 -S' AC_MSG_CHECKING([for atomic builtins for int])
if AC_TRY_EVAL(ac_compile); then if AC_TRY_EVAL(ac_compile); then
if grep __sync_fetch_and_add conftest.s >/dev/null 2>&1 ; then if grep __sync_ conftest.s >/dev/null 2>&1 ; then
enable_atomic_builtins=no enable_atomic_builtinsi=no
else else
AC_DEFINE(_GLIBCXX_ATOMIC_BUILTINS, 1, AC_DEFINE(_GLIBCXX_ATOMIC_BUILTINS_4, 1,
[Define if builtin atomic operations are supported on this host.]) [Define if builtin atomic operations for int are supported on this host.])
enable_atomic_builtins=yes enable_atomic_builtinsi=yes
atomicity_dir=cpu/generic/atomicity_builtins
fi fi
fi fi
AC_MSG_RESULT($enable_atomic_builtins) AC_MSG_RESULT($enable_atomic_builtinsi)
CXXFLAGS="$old_CXXFLAGS"
rm -f conftest* rm -f conftest*
# Now, if still generic, set to mutex. cat > conftest.$ac_ext << EOF
if test $atomicity_dir = "cpu/generic" ; then [#]line __oline__ "configure"
atomicity_dir=cpu/generic/atomicity_mutex 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 fi
AC_LANG_RESTORE
# If still generic, set to mutex.
if test $atomicity_dir = "cpu/generic" ; then
atomicity_dir=cpu/generic/atomicity_mutex
fi
]) ])

View File

@ -740,8 +740,11 @@
/* Version number of package */ /* Version number of package */
#undef VERSION #undef VERSION
/* Define if builtin atomic operations are supported on this host. */ /* Define if builtin atomic operations for bool are supported on this host. */
#undef _GLIBCXX_ATOMIC_BUILTINS #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. */ /* Define to use concept checking code from the boost libraries. */
#undef _GLIBCXX_CONCEPT_CHECKS #undef _GLIBCXX_CONCEPT_CHECKS

View File

@ -18071,8 +18071,6 @@ _ACEOF
echo "$as_me:$LINENO: checking for atomic builtins" >&5
echo $ECHO_N "checking for atomic builtins... $ECHO_C" >&6
ac_ext=cc ac_ext=cc
@ -18081,10 +18079,16 @@ ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu 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 cat > conftest.$ac_ext << EOF
#line 18087 "configure" #line 18091 "configure"
int main() int main()
{ {
// NB: _Atomic_word not necessarily int. // NB: _Atomic_word not necessarily int.
@ -18092,48 +18096,95 @@ int main()
atomic_type c1; atomic_type c1;
atomic_type c2; atomic_type c2;
const atomic_type c3(0); const atomic_type c3(0);
if (__sync_fetch_and_add(&c1, c2) == c3) __sync_fetch_and_add(&c1, c2);
{ __sync_val_compare_and_swap(&c1, c3, c2);
// Do something. __sync_lock_test_and_set(&c1, c3);
} __sync_lock_release(&c1);
return 0; __sync_synchronize();
return 0;
} }
EOF 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 if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5 (eval $ac_compile) 2>&5
ac_status=$? ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; then (exit $ac_status); }; then
if grep __sync_fetch_and_add conftest.s >/dev/null 2>&1 ; then if grep __sync_ conftest.s >/dev/null 2>&1 ; then
enable_atomic_builtins=no enable_atomic_builtinsi=no
else else
cat >>confdefs.h <<\_ACEOF cat >>confdefs.h <<\_ACEOF
#define _GLIBCXX_ATOMIC_BUILTINS 1 #define _GLIBCXX_ATOMIC_BUILTINS_4 1
_ACEOF _ACEOF
enable_atomic_builtins=yes enable_atomic_builtinsi=yes
atomicity_dir=cpu/generic/atomicity_builtins
fi fi
fi fi
echo "$as_me:$LINENO: result: $enable_atomic_builtins" >&5 echo "$as_me:$LINENO: result: $enable_atomic_builtinsi" >&5
echo "${ECHO_T}$enable_atomic_builtins" >&6 echo "${ECHO_T}$enable_atomic_builtinsi" >&6
CXXFLAGS="$old_CXXFLAGS"
rm -f conftest* rm -f conftest*
# Now, if still generic, set to mutex. cat > conftest.$ac_ext << EOF
if test $atomicity_dir = "cpu/generic" ; then #line 18131 "configure"
atomicity_dir=cpu/generic/atomicity_mutex int main()
fi {
ac_ext=c 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_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' 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_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu 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 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:$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;} echo "$as_me: WARNING: No native atomic operations are provided for this platform." >&2;}

View File

@ -214,8 +214,11 @@ usage vary depending on the target hardware and the flags used during
compile. compile.
</para> </para>
<para> If builtins are possible, <code>_GLIBCXX_ATOMIC_BUILTINS</code> <para>
will be defined. 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> </para>

View File

@ -1,6 +1,6 @@
// Support for atomic operations -*- C++ -*- // 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 // 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 // software; you can redistribute it and/or modify it under the
@ -45,7 +45,7 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
// To abstract locking primitives across all thread policies, use: // To abstract locking primitives across all thread policies, use:
// __exchange_and_add_dispatch // __exchange_and_add_dispatch
// __atomic_add_dispatch // __atomic_add_dispatch
#ifdef _GLIBCXX_ATOMIC_BUILTINS #ifdef _GLIBCXX_ATOMIC_BUILTINS_4
static inline _Atomic_word static inline _Atomic_word
__exchange_and_add(volatile _Atomic_word* __mem, int __val) __exchange_and_add(volatile _Atomic_word* __mem, int __val)
{ return __sync_fetch_and_add(__mem, __val); } { return __sync_fetch_and_add(__mem, __val); }

View File

@ -1,4 +1,4 @@
// 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. // This file is part of GCC.
// //
@ -36,7 +36,7 @@
#include <ext/atomicity.h> #include <ext/atomicity.h>
#include <ext/concurrence.h> #include <ext/concurrence.h>
#if defined(__GTHREADS) && defined(__GTHREAD_HAS_COND) \ #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 <climits>
# include <syscall.h> # include <syscall.h>
# define _GLIBCXX_USE_FUTEX # define _GLIBCXX_USE_FUTEX

View File

@ -54,7 +54,7 @@ namespace std
atomic_flag_test_and_set_explicit(volatile atomic_flag* __a, atomic_flag_test_and_set_explicit(volatile atomic_flag* __a,
memory_order __x) memory_order __x)
{ {
#ifdef _GLIBCXX_ATOMIC_BUILTINS #ifdef _GLIBCXX_ATOMIC_BUILTINS_1
if (__x >= memory_order_acq_rel) if (__x >= memory_order_acq_rel)
__sync_synchronize(); __sync_synchronize();
return __sync_lock_test_and_set(&(__a->_M_base._M_b), 1); return __sync_lock_test_and_set(&(__a->_M_base._M_b), 1);
@ -72,7 +72,7 @@ namespace std
void void
atomic_flag_clear_explicit(volatile atomic_flag* __a, memory_order __x) 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)); __sync_lock_release(&(__a->_M_base._M_b));
if (__x >= memory_order_acq_rel) if (__x >= memory_order_acq_rel)
__sync_synchronize(); __sync_synchronize();
@ -88,7 +88,7 @@ namespace std
void void
atomic_flag_fence(const volatile atomic_flag*, memory_order) atomic_flag_fence(const volatile atomic_flag*, memory_order)
{ {
#ifdef _GLIBCXX_ATOMIC_BUILTINS #ifdef _GLIBCXX_ATOMIC_BUILTINS_1
__sync_synchronize(); __sync_synchronize();
#endif #endif
} }