diff options
author | Hans Boehm <hboehm@google.com> | 2014-08-14 15:26:03 -0700 |
---|---|---|
committer | Hans Boehm <hboehm@google.com> | 2014-08-15 11:42:36 -0700 |
commit | f0f66c0264eb4b6ee56072af34c91a78a9184f23 (patch) | |
tree | e1817e10d001621c00c384ad5e4fbaa697437cbf /libc/include | |
parent | e2050ae1aa9d7e8e6f425bbb7a3991fe612f3913 (diff) | |
download | bionic-f0f66c0264eb4b6ee56072af34c91a78a9184f23.zip bionic-f0f66c0264eb4b6ee56072af34c91a78a9184f23.tar.gz bionic-f0f66c0264eb4b6ee56072af34c91a78a9184f23.tar.bz2 |
Have stdatomic.h punt to C++ atomic when possible
This is an alternate, somewhat simpler, fix that makes it safe to
include both <atomic> and <stdatomic.h> from C++ code in either order.
It means that C code consistently uses one implementation of atomics
and C++ another. We still have to make sure that those two
implementations interoperate correctly at runtime; in particular,
any flavor of atomic object needs to be represented exactly like the
underlying type, with the proper alignment constraint.
Bug:17007799
Change-Id: Iffcfc5220d8fa150f89dd083a121b24d23f268fc
(cherry picked from commit 019d3958118b7dc3ec8444ad2accca50c268b737)
Diffstat (limited to 'libc/include')
-rw-r--r-- | libc/include/stdatomic.h | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/libc/include/stdatomic.h b/libc/include/stdatomic.h index 669cefd..2c04221 100644 --- a/libc/include/stdatomic.h +++ b/libc/include/stdatomic.h @@ -31,9 +31,98 @@ #define _STDATOMIC_H_ #include <sys/cdefs.h> + +#if defined(__cplusplus) && defined(_USING_LIBCXX) && \ + (__has_feature(cxx_atomic) || _GNUC_VER >= 407) + +/* We have a usable C++ <atomic>; use it instead. */ + +#include <atomic> + +#define _Atomic(t) std::atomic<t> + +using std::atomic_is_lock_free; +using std::atomic_init; +using std::atomic_store; +using std::atomic_store_explicit; +using std::atomic_load; +using std::atomic_load_explicit; +using std::atomic_exchange; +using std::atomic_exchange_explicit; +using std::atomic_compare_exchange_strong; +using std::atomic_compare_exchange_strong_explicit; +using std::atomic_compare_exchange_weak; +using std::atomic_compare_exchange_weak_explicit; +using std::atomic_fetch_add; +using std::atomic_fetch_add_explicit; +using std::atomic_fetch_sub; +using std::atomic_fetch_sub_explicit; +using std::atomic_fetch_or; +using std::atomic_fetch_or_explicit; +using std::atomic_fetch_xor; +using std::atomic_fetch_xor_explicit; +using std::atomic_fetch_and; +using std::atomic_fetch_and_explicit; +using std::atomic_thread_fence; +using std::atomic_signal_fence; + +using std::memory_order; +using std::memory_order_relaxed; +using std::memory_order_consume; +using std::memory_order_release; +using std::memory_order_acq_rel; +using std::memory_order_seq_cst; + +using std::atomic_bool; +using std::atomic_char; +using std::atomic_schar; +using std::atomic_uchar; +using std::atomic_short; +using std::atomic_ushort; +using std::atomic_int; +using std::atomic_uint; +using std::atomic_long; +using std::atomic_ulong; +using std::atomic_llong; +using std::atomic_ullong; +using std::atomic_char16_t; +using std::atomic_char32_t; +using std::atomic_wchar_t; +using std::atomic_int_least8_t; +using std::atomic_uint_least8_t; +using std::atomic_int_least16_t; +using std::atomic_uint_least16_t; +using std::atomic_int_least32_t; +using std::atomic_uint_least32_t; +using std::atomic_int_least64_t; +using std::atomic_uint_least64_t; +using std::atomic_int_fast8_t; +using std::atomic_uint_fast8_t; +using std::atomic_int_fast16_t; +using std::atomic_uint_fast16_t; +using std::atomic_int_fast32_t; +using std::atomic_uint_fast32_t; +using std::atomic_int_fast64_t; +using std::atomic_uint_fast64_t; +using std::atomic_intptr_t; +using std::atomic_uintptr_t; +using std::atomic_size_t; +using std::atomic_ptrdiff_t; +using std::atomic_intmax_t; +using std::atomic_uintmax_t; + +#else /* <atomic> unavailable, possibly because this is C, not C++ */ + #include <sys/types.h> #include <stdbool.h> +/* + * C: Do it ourselves. + * Note that the runtime representation defined here should be compatible + * with the C++ one, i.e. an _Atomic(T) needs to contain the same + * bits as a T. + */ + #if __has_extension(c_atomic) || __has_extension(cxx_atomic) #define __CLANG_ATOMICS #elif __GNUC_PREREQ__(4, 7) @@ -121,6 +210,8 @@ * * The memory_order_* constants that denote the barrier behaviour of the * atomic operations. + * The enum values must be identical to those used by the + * C++ <atomic> header. */ typedef enum { @@ -419,4 +510,6 @@ atomic_flag_clear(volatile atomic_flag *__object) } #endif /* !_KERNEL */ +#endif /* <atomic> unavailable */ + #endif /* !_STDATOMIC_H_ */ |