diff --git a/PLATFORMS.md b/PLATFORMS.md index 37bcd1dac1..724744d8ee 100644 --- a/PLATFORMS.md +++ b/PLATFORMS.md @@ -17,11 +17,11 @@ the OpenSSL cryptography library, and the `nghttp2` HTTP/2 library. The following C11 features are used in BIND 9: -* Atomic operations support from the compiler is needed, either in the form of - builtin operations. +* Atomic operations support, either in the form of C11 atomics or + `__atomic` builtin operations. -* Thread Local Storage support from the compiler is needed, either in the form - of C11 `_Thread_local`/`thread_local`, or the `__thread` GCC extension. +* Thread Local Storage support, either in the form of C11 + `_Thread_local`/`thread_local`, or the `__thread` GCC extension. The C11 variants are preferred. diff --git a/configure.ac b/configure.ac index 834572170f..4f05966753 100644 --- a/configure.ac +++ b/configure.ac @@ -1176,7 +1176,7 @@ AC_CHECK_HEADERS( AX_RESTORE_FLAGS([atomic]) ]) ], - [AC_MSG_RESULT([__sync builtins]) + [AC_MSG_FAILURE([not found]) ]) ]) LIBS="$LIBS $ISC_ATOMIC_LIBS" diff --git a/lib/isc/include/isc/atomic.h b/lib/isc/include/isc/atomic.h index 16b6a6ab44..56f5d6b1cc 100644 --- a/lib/isc/include/isc/atomic.h +++ b/lib/isc/include/isc/atomic.h @@ -11,11 +11,11 @@ #pragma once -#if HAVE_STDATOMIC_H +#if __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_ATOMICS__) #include -#else /* if HAVE_STDATOMIC_H */ +#else #include -#endif /* if HAVE_STDATOMIC_H */ +#endif /* * We define a few additional macros to make things easier diff --git a/lib/isc/include/isc/stdatomic.h b/lib/isc/include/isc/stdatomic.h index a4465c2f73..e9194c89e2 100644 --- a/lib/isc/include/isc/stdatomic.h +++ b/lib/isc/include/isc/stdatomic.h @@ -18,64 +18,25 @@ #include #endif /* HAVE_UCHAR_H */ -#if !defined(__has_feature) -#define __has_feature(x) 0 -#endif /* if !defined(__has_feature) */ - -#if !defined(__has_extension) -#define __has_extension(x) __has_feature(x) -#endif /* if !defined(__has_extension) */ - -#if !defined(__GNUC_PREREQ__) -#if defined(__GNUC__) && defined(__GNUC_MINOR__) -#define __GNUC_PREREQ__(maj, min) \ - ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) -#else /* if defined(__GNUC__) && defined(__GNUC_MINOR__) */ -#define __GNUC_PREREQ__(maj, min) 0 -#endif /* if defined(__GNUC__) && defined(__GNUC_MINOR__) */ -#endif /* if !defined(__GNUC_PREREQ__) */ - -#if !defined(__CLANG_ATOMICS) && !defined(__GNUC_ATOMICS) -#if __has_extension(c_atomic) || __has_extension(cxx_atomic) -#define __CLANG_ATOMICS -#elif __GNUC_PREREQ__(4, 7) +/* GCC 4.7.0 introduced __atomic builtins, but not the __GNUC_ATOMICS define */ +#if !defined(__GNUC_ATOMICS) && __GNUC__ == 4 && __GNUC_MINOR__ >= 7 #define __GNUC_ATOMICS -#elif !defined(__GNUC__) +#endif + +#if !defined(__GNUC_ATOMICS) #error "isc/stdatomic.h does not support your compiler" -#endif /* if __has_extension(c_atomic) || __has_extension(cxx_atomic) */ -#endif /* if !defined(__CLANG_ATOMICS) && !defined(__GNUC_ATOMICS) */ +#endif /* if !defined(__GNUC_ATOMICS) */ #define ATOMIC_VAR_INIT(x) x -#ifndef __ATOMIC_RELAXED -#define __ATOMIC_RELAXED 0 -#endif /* ifndef __ATOMIC_RELAXED */ -#ifndef __ATOMIC_CONSUME -#define __ATOMIC_CONSUME 1 -#endif /* ifndef __ATOMIC_CONSUME */ -#ifndef __ATOMIC_ACQUIRE -#define __ATOMIC_ACQUIRE 2 -#endif /* ifndef __ATOMIC_ACQUIRE */ -#ifndef __ATOMIC_RELEASE -#define __ATOMIC_RELEASE 3 -#endif /* ifndef __ATOMIC_RELEASE */ -#ifndef __ATOMIC_ACQ_REL -#define __ATOMIC_ACQ_REL 4 -#endif /* ifndef __ATOMIC_ACQ_REL */ -#ifndef __ATOMIC_SEQ_CST -#define __ATOMIC_SEQ_CST 5 -#endif /* ifndef __ATOMIC_SEQ_CST */ - -enum memory_order { +typedef enum memory_order { memory_order_relaxed = __ATOMIC_RELAXED, memory_order_consume = __ATOMIC_CONSUME, memory_order_acquire = __ATOMIC_ACQUIRE, memory_order_release = __ATOMIC_RELEASE, memory_order_acq_rel = __ATOMIC_ACQ_REL, memory_order_seq_cst = __ATOMIC_SEQ_CST -}; - -typedef enum memory_order memory_order; +} memory_order; #ifndef HAVE_UCHAR_H typedef uint_least16_t char16_t; @@ -120,30 +81,6 @@ typedef ptrdiff_t atomic_ptrdiff_t; typedef intmax_t atomic_intmax_t; typedef uintmax_t atomic_uintmax_t; -#if defined(__CLANG_ATOMICS) /* __c11_atomic builtins */ -#define atomic_init(obj, desired) __c11_atomic_init(obj, desired) -#define atomic_load_explicit(obj, order) __c11_atomic_load(obj, order) -#define atomic_store_explicit(obj, desired, order) \ - __c11_atomic_store(obj, desired, order) -#define atomic_fetch_add_explicit(obj, arg, order) \ - __c11_atomic_fetch_add(obj, arg, order) -#define atomic_fetch_sub_explicit(obj, arg, order) \ - __c11_atomic_fetch_sub(obj, arg, order) -#define atomic_fetch_and_explicit(obj, arg, order) \ - __c11_atomic_fetch_and(obj, arg, order) -#define atomic_fetch_or_explicit(obj, arg, order) \ - __c11_atomic_fetch_or(obj, arg, order) -#define atomic_compare_exchange_strong_explicit(obj, expected, desired, succ, \ - fail) \ - __c11_atomic_compare_exchange_strong_explicit(obj, expected, desired, \ - succ, fail) -#define atomic_compare_exchange_weak_explicit(obj, expected, desired, succ, \ - fail) \ - __c11_atomic_compare_exchange_weak_explicit(obj, expected, desired, \ - succ, fail) -#define atomic_exchange_explicit(obj, desired, order) \ - __c11_atomic_exchange_explicit(obj, expected, order) -#elif defined(__GNUC_ATOMICS) /* __atomic builtins */ #define atomic_init(obj, desired) (*obj = desired) #define atomic_load_explicit(obj, order) __atomic_load_n(obj, order) #define atomic_store_explicit(obj, desired, order) \ @@ -164,42 +101,6 @@ typedef uintmax_t atomic_uintmax_t; __atomic_compare_exchange_n(obj, expected, desired, 1, succ, fail) #define atomic_exchange_explicit(obj, desired, order) \ __atomic_exchange_n(obj, desired, order) -#else /* __sync builtins */ -#define atomic_init(obj, desired) (*obj = desired) -#define atomic_load_explicit(obj, order) __sync_fetch_and_add(obj, 0) -#define atomic_store_explicit(obj, desired, order) \ - do { \ - __sync_synchronize(); \ - *obj = desired; \ - __sync_synchronize(); \ - } while (0); -#define atomic_fetch_add_explicit(obj, arg, order) \ - __sync_fetch_and_add(obj, arg) -#define atomic_fetch_sub_explicit(obj, arg, order) \ - __sync_fetch_and_sub(obj, arg, order) -#define atomic_fetch_and_explicit(obj, arg, order) \ - __sync_fetch_and_and(obj, arg, order) -#define atomic_fetch_or_explicit(obj, arg, order) \ - __sync_fetch_and_or(obj, arg, order) -#define atomic_compare_exchange_strong_explicit(obj, expected, desired, succ, \ - fail) \ - ({ \ - __typeof__(obj) __v; \ - _Bool __r; \ - __v = (__typeof__(obj))__sync_val_compare_and_swap( \ - obj, *(expected), desired); \ - __r = ((__typeof__(obj))*(expected) == __v); \ - *(expected) = __v; \ - __r; \ - }) -#define atomic_compare_exchange_weak_explicit(obj, expected, desired, succ, \ - fail) \ - atomic_compare_exchange_strong_explicit(obj, expected, desired, succ, \ - fail) -#define atomic_exchange_explicit(obj, desired, order) \ - __sync_lock_test_and_set(obj, desired) - -#endif /* if defined(__CLANG_ATOMICS) */ #define atomic_load(obj) atomic_load_explicit(obj, memory_order_seq_cst) #define atomic_store(obj, arg) \