From 62bad7cd053b0f139bb46ae54976ed97d6dc0811 Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Mon, 28 Nov 2011 20:28:23 +0000 Subject: c-family * c-cpp-builtin.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. libstdc++-v3 * include/bits/atomic_base.h (ATOMIC_*_LOCK_FREE): Use new cpp predefined macros. * testsuite/29_atomics/headers/atomic/macros.cc: Add BOOL and POINTER macro checks. Check for expected compile time values. From-SVN: r181784 --- gcc/c-family/ChangeLog | 7 + gcc/c-family/c-cppbuiltin.c | 160 +++++++++++++++------ libstdc++-v3/ChangeLog | 7 + libstdc++-v3/include/bits/atomic_base.h | 23 ++- .../testsuite/29_atomics/headers/atomic/macros.cc | 48 ++++--- 5 files changed, 170 insertions(+), 75 deletions(-) diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 4463106..b53f766 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,10 @@ +2011-11-28 Andrew MacLeod + + * c-cpp-builtin.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. + 2011-11-24 Andrew MacLeod PR c/51256 diff --git a/gcc/c-family/c-cppbuiltin.c b/gcc/c-family/c-cppbuiltin.c index bf83c26..8d0d4af 100644 --- a/gcc/c-family/c-cppbuiltin.c +++ b/gcc/c-family/c-cppbuiltin.c @@ -568,6 +568,117 @@ c_cpp_builtins_optimize_pragma (cpp_reader *pfile, tree prev_tree, } +/* 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]; + unsigned int psize; + + /* 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 SIZEOF_NODE(T) (tree_low_cst (TYPE_SIZE_UNIT (T), 1)) +#define SWAP_INDEX(T) ((SIZEOF_NODE (T) < SWAP_LIMIT) ? SIZEOF_NODE (T) : 0) + builtin_define_with_int_value ("__GCC_ATOMIC_BOOL_LOCK_FREE", + (have_swap[SWAP_INDEX (boolean_type_node)]? 2 : 1)); + builtin_define_with_int_value ("__GCC_ATOMIC_CHAR_LOCK_FREE", + (have_swap[SWAP_INDEX (signed_char_type_node)]? 2 : 1)); + builtin_define_with_int_value ("__GCC_ATOMIC_CHAR16_T_LOCK_FREE", + (have_swap[SWAP_INDEX (char16_type_node)]? 2 : 1)); + builtin_define_with_int_value ("__GCC_ATOMIC_CHAR32_T_LOCK_FREE", + (have_swap[SWAP_INDEX (char32_type_node)]? 2 : 1)); + builtin_define_with_int_value ("__GCC_ATOMIC_WCHAR_T_LOCK_FREE", + (have_swap[SWAP_INDEX (wchar_type_node)]? 2 : 1)); + builtin_define_with_int_value ("__GCC_ATOMIC_SHORT_LOCK_FREE", + (have_swap[SWAP_INDEX (short_integer_type_node)]? 2 : 1)); + builtin_define_with_int_value ("__GCC_ATOMIC_INT_LOCK_FREE", + (have_swap[SWAP_INDEX (integer_type_node)]? 2 : 1)); + builtin_define_with_int_value ("__GCC_ATOMIC_LONG_LOCK_FREE", + (have_swap[SWAP_INDEX (long_integer_type_node)]? 2 : 1)); + builtin_define_with_int_value ("__GCC_ATOMIC_LLONG_LOCK_FREE", + (have_swap[SWAP_INDEX (long_long_integer_type_node)]? 2 : 1)); + + /* ptr_type_node can't be used here since ptr_mode is only set when + toplev calls backend_init which is not done with -E or pch. */ + psize = POINTER_SIZE / BITS_PER_UNIT; + if (psize >= SWAP_LIMIT) + psize = 0; + builtin_define_with_int_value ("__GCC_ATOMIC_POINTER_LOCK_FREE", + (have_swap[psize]? 2 : 1)); +} + /* Hook that registers front end and target-specific built-ins. */ void c_cpp_builtins (cpp_reader *pfile) @@ -756,53 +867,8 @@ c_cpp_builtins (cpp_reader *pfile) 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"); - + cpp_atomic_builtins (pfile); + #ifdef DWARF2_UNWIND_INFO if (dwarf2out_do_cfi_asm ()) cpp_define (pfile, "__GCC_HAVE_DWARF2_CFI_ASM"); diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 1d4dff8..48c3db2 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,10 @@ +2011-11-28 Andrew MacLeod + + * include/bits/atomic_base.h (ATOMIC_*_LOCK_FREE): Use new cpp + predefined macros. + * testsuite/29_atomics/headers/atomic/macros.cc: Add BOOL and POINTER + macro checks. Check for expected compile time values. + 2011-11-28 Paolo Carlini PR libstdc++/51288 diff --git a/libstdc++-v3/include/bits/atomic_base.h b/libstdc++-v3/include/bits/atomic_base.h index cf292a8..2711323 100644 --- a/libstdc++-v3/include/bits/atomic_base.h +++ b/libstdc++-v3/include/bits/atomic_base.h @@ -91,18 +91,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// 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 *) + +#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_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE +#define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_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 diff --git a/libstdc++-v3/testsuite/29_atomics/headers/atomic/macros.cc b/libstdc++-v3/testsuite/29_atomics/headers/atomic/macros.cc index 1bbab86..fe78cff 100644 --- a/libstdc++-v3/testsuite/29_atomics/headers/atomic/macros.cc +++ b/libstdc++-v3/testsuite/29_atomics/headers/atomic/macros.cc @@ -20,6 +20,10 @@ #include +#ifndef ATOMIC_BOOL_LOCK_FREE +# error "ATOMIC_BOOL_LOCK_FREE must be a macro" +#endif + #ifndef ATOMIC_CHAR_LOCK_FREE # error "ATOMIC_CHAR_LOCK_FREE must be a macro" #endif @@ -52,6 +56,10 @@ # error "ATOMIC_LLONG_LOCK_FREE must be a macro" #endif +#ifndef ATOMIC_POINTER_LOCK_FREE +# error "ATOMIC_POINTER_LOCK_FREE must be a macro" +#endif + #ifndef ATOMIC_FLAG_INIT #error "ATOMIC_FLAG_INIT_must_be_a_macro" #endif @@ -65,35 +73,43 @@ extern void abort(void); int main () { - if (ATOMIC_CHAR_LOCK_FREE != 0 && ATOMIC_CHAR_LOCK_FREE != 1 - && ATOMIC_CHAR_LOCK_FREE != 2) +#if (ATOMIC_BOOL_LOCK_FREE != 1 && ATOMIC_BOOL_LOCK_FREE != 2) + abort (); +#endif + +#if (ATOMIC_CHAR_LOCK_FREE != 1 && ATOMIC_CHAR_LOCK_FREE != 2) + abort (); +#endif + +#if (ATOMIC_CHAR16_T_LOCK_FREE != 1 && ATOMIC_CHAR16_T_LOCK_FREE != 2) abort (); +#endif - if (ATOMIC_CHAR16_T_LOCK_FREE != 0 && ATOMIC_CHAR16_T_LOCK_FREE != 1 - && ATOMIC_CHAR16_T_LOCK_FREE != 2) +#if (ATOMIC_CHAR32_T_LOCK_FREE != 1 && ATOMIC_CHAR32_T_LOCK_FREE != 2) abort (); +#endif - if (ATOMIC_CHAR32_T_LOCK_FREE != 0 && ATOMIC_CHAR32_T_LOCK_FREE != 1 - && ATOMIC_CHAR32_T_LOCK_FREE != 2) +#if (ATOMIC_WCHAR_T_LOCK_FREE != 1 && ATOMIC_WCHAR_T_LOCK_FREE != 2) abort (); +#endif - if (ATOMIC_WCHAR_T_LOCK_FREE != 0 && ATOMIC_WCHAR_T_LOCK_FREE != 1 - && ATOMIC_WCHAR_T_LOCK_FREE != 2) +#if (ATOMIC_SHORT_LOCK_FREE != 1 && ATOMIC_SHORT_LOCK_FREE != 2) abort (); +#endif - if (ATOMIC_SHORT_LOCK_FREE != 0 && ATOMIC_SHORT_LOCK_FREE != 1 - && ATOMIC_SHORT_LOCK_FREE != 2) +#if (ATOMIC_INT_LOCK_FREE != 1 && ATOMIC_INT_LOCK_FREE != 2) abort (); +#endif - if (ATOMIC_INT_LOCK_FREE != 0 && ATOMIC_INT_LOCK_FREE != 1 - && ATOMIC_INT_LOCK_FREE != 2) +#if (ATOMIC_LONG_LOCK_FREE != 1 && ATOMIC_LONG_LOCK_FREE != 2) abort (); +#endif - if (ATOMIC_LONG_LOCK_FREE != 0 && ATOMIC_LONG_LOCK_FREE != 1 - && ATOMIC_LONG_LOCK_FREE != 2) +#if (ATOMIC_LLONG_LOCK_FREE != 1 && ATOMIC_LLONG_LOCK_FREE != 2) abort (); +#endif - if (ATOMIC_LLONG_LOCK_FREE != 0 && ATOMIC_LLONG_LOCK_FREE != 1 - && ATOMIC_LLONG_LOCK_FREE != 2) +#if (ATOMIC_POINTER_LOCK_FREE != 1 && ATOMIC_POINTER_LOCK_FREE != 2) abort (); +#endif } -- cgit v1.1