On 11/21/2011 11:02 PM, Andrew MacLeod wrote:
Anyway, it looks like __atomic_always_lock_free doesn't fold early
enough to be usable by the preprocessor like that even with my earlier
version. ugg. I think I can get something defined in cpp-builtins
that we can use. We're going to need it for C1x next release
anyway. Should be ready to try tomorrow sometime.
Ok, try this. I've changed CPP to define a set of macros
__GCC_ATOMIC_{TYPE}_IS_LOCK_FREE
which we can use directly in the c++ header. We're going to need
something like this for C1x next release when stdatomic.h defines the
same macros.
C currently doesn't have a char16_t and char32_t, so they aren't defined
there. I defined them in the C++ header with the appropriate
HAVE_COMPARE_AND_SWAP.
this should make things work the way you were looking for, ie
#if (ATOMIC_INT_LOCK_FREE> 1)
// yes, cool, yeah!
#endif
should work just fine.
Give it a shot and see if you get what you are looking for. Ive
bootstrapped this on x86_64-unknown-linux-gnu, and didn't see any
regressions in libstdc++-v3... Im running a full bootstrap and
testsuite run overnight
Andrew
* c-cppbuiltin.c (cpp_atomic_builtins): New. Emit all atomic
predefines in one place. Add LOCK_FREE predefines.
(c_cpp_builtins): Move Legacy HAVE_SYNC predefines to new func.
* include/bits/atomic_base.h (ATOMIC_TYPE_LOCK_FREE): Use new cpp
predefined macros.
Index: gcc/c-family/c-cppbuiltin.c
===================================================================
*** gcc/c-family/c-cppbuiltin.c (revision 181584)
--- gcc/c-family/c-cppbuiltin.c (working copy)
*************** c_cpp_builtins_optimize_pragma (cpp_read
*** 568,573 ****
--- 568,672 ----
}
+ /* This function will emit cpp macros to indicate the presence of various lock
+ free atomic operations. */
+
+ static void
+ cpp_atomic_builtins (cpp_reader *pfile)
+ {
+ /* Set a flag for each size of object that compare and swap exists for up to
+ a 16 byte object. */
+ #define SWAP_LIMIT 17
+ bool have_swap[SWAP_LIMIT];
+
+ /* Clear the map of sizes compare_and swap exists for. */
+ memset (have_swap, 0, sizeof (have_swap));
+
+ /* Tell source code if the compiler makes sync_compare_and_swap
+ builtins available. */
+ #ifndef HAVE_sync_compare_and_swapqi
+ #define HAVE_sync_compare_and_swapqi 0
+ #endif
+ #ifndef HAVE_atomic_compare_and_swapqi
+ #define HAVE_atomic_compare_and_swapqi 0
+ #endif
+
+ if (HAVE_sync_compare_and_swapqi || HAVE_atomic_compare_and_swapqi)
+ {
+ cpp_define (pfile, "__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
+ have_swap[1] = true;
+ }
+
+ #ifndef HAVE_sync_compare_and_swaphi
+ #define HAVE_sync_compare_and_swaphi 0
+ #endif
+ #ifndef HAVE_atomic_compare_and_swaphi
+ #define HAVE_atomic_compare_and_swaphi 0
+ #endif
+ if (HAVE_sync_compare_and_swaphi || HAVE_atomic_compare_and_swaphi)
+ {
+ cpp_define (pfile, "__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
+ have_swap[2] = true;
+ }
+
+ #ifndef HAVE_sync_compare_and_swapsi
+ #define HAVE_sync_compare_and_swapsi 0
+ #endif
+ #ifndef HAVE_atomic_compare_and_swapsi
+ #define HAVE_atomic_compare_and_swapsi 0
+ #endif
+ if (HAVE_sync_compare_and_swapsi || HAVE_atomic_compare_and_swapsi)
+ {
+ cpp_define (pfile, "__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
+ have_swap[4] = true;
+ }
+
+ #ifndef HAVE_sync_compare_and_swapdi
+ #define HAVE_sync_compare_and_swapdi 0
+ #endif
+ #ifndef HAVE_atomic_compare_and_swapdi
+ #define HAVE_atomic_compare_and_swapdi 0
+ #endif
+ if (HAVE_sync_compare_and_swapdi || HAVE_atomic_compare_and_swapdi)
+ {
+ cpp_define (pfile, "__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
+ have_swap[8] = true;
+ }
+
+ #ifndef HAVE_sync_compare_and_swapti
+ #define HAVE_sync_compare_and_swapti 0
+ #endif
+ #ifndef HAVE_atomic_compare_and_swapti
+ #define HAVE_atomic_compare_and_swapti 0
+ #endif
+ if (HAVE_sync_compare_and_swapti || HAVE_atomic_compare_and_swapti)
+ {
+ cpp_define (pfile, "__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16");
+ have_swap[16] = true;
+ }
+
+ /* Tell the source code about various types. These map to the C++11 and C1x
+ macros where 2 indicates lock-free always, and 1 indicates sometimes
+ lock free. */
+ #define SWAP_INDEX(I) ( ((I) < SWAP_LIMIT) ? I : 0)
+ builtin_define_with_int_value ("__GCC_ATOMIC_BOOL_LOCK_FREE",
+ (have_swap[SWAP_INDEX (sizeof(bool))]? 2 : 1));
+ builtin_define_with_int_value ("__GCC_ATOMIC_CHAR_LOCK_FREE",
+ (have_swap[SWAP_INDEX (sizeof(char))]? 2 : 1));
+ builtin_define_with_int_value ("__GCC_ATOMIC_WCHAR_T_LOCK_FREE",
+ (have_swap[SWAP_INDEX (sizeof(wchar_t))]? 2 : 1));
+ builtin_define_with_int_value ("__GCC_ATOMIC_SHORT_LOCK_FREE",
+ (have_swap[SWAP_INDEX (sizeof(short))]? 2 : 1));
+ builtin_define_with_int_value ("__GCC_ATOMIC_INT_LOCK_FREE",
+ (have_swap[SWAP_INDEX (sizeof(int))]? 2 : 1));
+ builtin_define_with_int_value ("__GCC_ATOMIC_LONG_LOCK_FREE",
+ (have_swap[SWAP_INDEX (sizeof(long))]? 2 : 1));
+ builtin_define_with_int_value ("__GCC_ATOMIC_LLONG_LOCK_FREE",
+ (have_swap[SWAP_INDEX (sizeof(long long))]? 2 : 1));
+ builtin_define_with_int_value ("__GCC_ATOMIC_ADDRESS_LOCK_FREE",
+ (have_swap[SWAP_INDEX (sizeof(void *))]? 2 : 1));
+ }
+
/* Hook that registers front end and target-specific built-ins. */
void
c_cpp_builtins (cpp_reader *pfile)
*************** c_cpp_builtins (cpp_reader *pfile)
*** 756,808 ****
if (c_dialect_cxx () && TYPE_UNSIGNED (wchar_type_node))
cpp_define (pfile, "__WCHAR_UNSIGNED__");
! /* Tell source code if the compiler makes sync_compare_and_swap
! builtins available. */
! #ifndef HAVE_sync_compare_and_swapqi
! #define HAVE_sync_compare_and_swapqi 0
! #endif
! #ifndef HAVE_atomic_compare_and_swapqi
! #define HAVE_atomic_compare_and_swapqi 0
! #endif
! if (HAVE_sync_compare_and_swapqi || HAVE_atomic_compare_and_swapqi)
! cpp_define (pfile, "__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
!
! #ifndef HAVE_sync_compare_and_swaphi
! #define HAVE_sync_compare_and_swaphi 0
! #endif
! #ifndef HAVE_atomic_compare_and_swaphi
! #define HAVE_atomic_compare_and_swaphi 0
! #endif
! if (HAVE_sync_compare_and_swaphi || HAVE_atomic_compare_and_swaphi)
! cpp_define (pfile, "__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
!
! #ifndef HAVE_sync_compare_and_swapsi
! #define HAVE_sync_compare_and_swapsi 0
! #endif
! #ifndef HAVE_atomic_compare_and_swapsi
! #define HAVE_atomic_compare_and_swapsi 0
! #endif
! if (HAVE_sync_compare_and_swapsi || HAVE_atomic_compare_and_swapsi)
! cpp_define (pfile, "__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
!
! #ifndef HAVE_sync_compare_and_swapdi
! #define HAVE_sync_compare_and_swapdi 0
! #endif
! #ifndef HAVE_atomic_compare_and_swapdi
! #define HAVE_atomic_compare_and_swapdi 0
! #endif
! if (HAVE_sync_compare_and_swapdi || HAVE_atomic_compare_and_swapdi)
! cpp_define (pfile, "__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
!
! #ifndef HAVE_sync_compare_and_swapti
! #define HAVE_sync_compare_and_swapti 0
! #endif
! #ifndef HAVE_atomic_compare_and_swapti
! #define HAVE_atomic_compare_and_swapti 0
! #endif
! if (HAVE_sync_compare_and_swapti || HAVE_atomic_compare_and_swapti)
! cpp_define (pfile, "__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16");
!
#ifdef DWARF2_UNWIND_INFO
if (dwarf2out_do_cfi_asm ())
cpp_define (pfile, "__GCC_HAVE_DWARF2_CFI_ASM");
--- 855,862 ----
if (c_dialect_cxx () && TYPE_UNSIGNED (wchar_type_node))
cpp_define (pfile, "__WCHAR_UNSIGNED__");
! cpp_atomic_builtins (pfile);
!
#ifdef DWARF2_UNWIND_INFO
if (dwarf2out_do_cfi_asm ())
cpp_define (pfile, "__GCC_HAVE_DWARF2_CFI_ASM");
Index: libstdc++-v3/include/bits/atomic_base.h
===================================================================
*** libstdc++-v3/include/bits/atomic_base.h (revision 181584)
--- libstdc++-v3/include/bits/atomic_base.h (working copy)
*************** _GLIBCXX_BEGIN_NAMESPACE_VERSION
*** 91,108 ****
/// Lock-free Property
- #define LOCKFREE_PROP(T) (__atomic_always_lock_free (sizeof (T), 0) ? 2 : 1)
! #define ATOMIC_BOOL_LOCK_FREE LOCKFREE_PROP (bool)
! #define ATOMIC_CHAR_LOCK_FREE LOCKFREE_PROP (char)
! #define ATOMIC_CHAR16_T_LOCK_FREE LOCKFREE_PROP (char16_t)
! #define ATOMIC_CHAR32_T_LOCK_FREE LOCKFREE_PROP (char32_t)
! #define ATOMIC_WCHAR_T_LOCK_FREE LOCKFREE_PROP (wchar_t)
! #define ATOMIC_SHORT_LOCK_FREE LOCKFREE_PROP (short)
! #define ATOMIC_INT_LOCK_FREE LOCKFREE_PROP (int)
! #define ATOMIC_LONG_LOCK_FREE LOCKFREE_PROP (long)
! #define ATOMIC_LLONG_LOCK_FREE LOCKFREE_PROP (long long)
! #define ATOMIC_POINTER_LOCK_FREE LOCKFREE_PROP (void *)
// Base types for atomics.
template<typename _IntTp>
--- 91,117 ----
/// Lock-free Property
! #ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2
! #define ATOMIC_CHAR16_T_LOCK_FREE 2
! #else
! #define ATOMIC_CHAR16_T_LOCK_FREE 1
! #endif
!
! #ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
! #define ATOMIC_CHAR32_T_LOCK_FREE 2
! #else
! #define ATOMIC_CHAR32_T_LOCK_FREE 1
! #endif
!
! #define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE
! #define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE
! #define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE
! #define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE
! #define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE
! #define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE
! #define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE
! #define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE
// Base types for atomics.
template<typename _IntTp>