| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 |
- // -*- C++ -*- compatibility header.
- // Copyright (C) 2008, 2009 Free Software Foundation, Inc.
- //
- // 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
- // terms of the GNU General Public License as published by the
- // Free Software Foundation; either version 3, or (at your option)
- // any later version.
- // This library is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- // Under Section 7 of GPL version 3, you are granted additional
- // permissions described in the GCC Runtime Library Exception, version
- // 3.1, as published by the Free Software Foundation.
- // You should have received a copy of the GNU General Public License and
- // a copy of the GCC Runtime Library Exception along with this program;
- // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
- // <http://www.gnu.org/licenses/>.
- /** @file stdatomic.h
- * This is a Standard C++ Library header.
- */
- #include <bits/c++config.h>
- #include <stddef.h>
- #include <stdbool.h> // XXX need to define bool w/o stdbool.h in tr1/cstdbool
- #ifndef _GLIBCXX_STDATOMIC_H
- #define _GLIBCXX_STDATOMIC_H 1
- _GLIBCXX_BEGIN_NAMESPACE(std)
- _GLIBCXX_BEGIN_EXTERN_C
- /**
- * @defgroup atomics Atomics
- *
- * Components for performing atomic operations.
- * @{
- */
- /// Enumeration for memory_order
- typedef enum memory_order
- {
- memory_order_relaxed,
- memory_order_consume,
- memory_order_acquire,
- memory_order_release,
- memory_order_acq_rel,
- memory_order_seq_cst
- } memory_order;
- // Base for atomic_flag.
- typedef struct __atomic_flag_base
- {
- bool _M_i;
- } __atomic_flag_base;
- #define ATOMIC_FLAG_INIT { false }
- /// 29.2 Lock-free Property
- #if defined(_GLIBCXX_ATOMIC_BUILTINS_1) && defined(_GLIBCXX_ATOMIC_BUILTINS_2) \
- && defined(_GLIBCXX_ATOMIC_BUILTINS_4) && defined(_GLIBCXX_ATOMIC_BUILTINS_8)
- # define _GLIBCXX_ATOMIC_PROPERTY 2
- # define _GLIBCXX_ATOMIC_NAMESPACE __atomic2
- #elif defined(_GLIBCXX_ATOMIC_BUILTINS_1)
- # define _GLIBCXX_ATOMIC_PROPERTY 1
- # define _GLIBCXX_ATOMIC_NAMESPACE __atomic1
- #else
- # define _GLIBCXX_ATOMIC_PROPERTY 0
- # define _GLIBCXX_ATOMIC_NAMESPACE __atomic0
- #endif
- #define ATOMIC_INTEGRAL_LOCK_FREE _GLIBCXX_ATOMIC_PROPERTY
- #define ATOMIC_ADDRESS_LOCK_FREE _GLIBCXX_ATOMIC_PROPERTY
- // Switch atomic integral base types based on C or C++. In
- // addition, for "C" only provide type-generic macros for atomic
- // operations. (As C++ accomplishes the same thing with sets of
- // overloaded functions.
- #ifdef __cplusplus
- inline namespace _GLIBCXX_ATOMIC_NAMESPACE { }
- # include <bits/atomicfwd_cxx.h>
- #else
- # include <bits/atomicfwd_c.h>
- #endif
-
- // Typedefs for other atomic integral types.
- typedef atomic_schar atomic_int_least8_t;
- typedef atomic_uchar atomic_uint_least8_t;
- typedef atomic_short atomic_int_least16_t;
- typedef atomic_ushort atomic_uint_least16_t;
- typedef atomic_int atomic_int_least32_t;
- typedef atomic_uint atomic_uint_least32_t;
- typedef atomic_llong atomic_int_least64_t;
- typedef atomic_ullong atomic_uint_least64_t;
- typedef atomic_schar atomic_int_fast8_t;
- typedef atomic_uchar atomic_uint_fast8_t;
- typedef atomic_short atomic_int_fast16_t;
- typedef atomic_ushort atomic_uint_fast16_t;
- typedef atomic_int atomic_int_fast32_t;
- typedef atomic_uint atomic_uint_fast32_t;
- typedef atomic_llong atomic_int_fast64_t;
- typedef atomic_ullong atomic_uint_fast64_t;
- typedef atomic_long atomic_intptr_t;
- typedef atomic_ulong atomic_uintptr_t;
- typedef atomic_long atomic_ssize_t;
- typedef atomic_ulong atomic_size_t;
- typedef atomic_llong atomic_intmax_t;
- typedef atomic_ullong atomic_uintmax_t;
- typedef atomic_long atomic_ptrdiff_t;
- // Accessor functions for base atomic_flag type.
- bool
- atomic_flag_test_and_set_explicit(volatile __atomic_flag_base*, memory_order);
- inline bool
- atomic_flag_test_and_set(volatile __atomic_flag_base* __a)
- { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
-
- void
- atomic_flag_clear_explicit(volatile __atomic_flag_base*, memory_order);
- inline void
- atomic_flag_clear(volatile __atomic_flag_base* __a)
- { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
- void
- __atomic_flag_wait_explicit(volatile __atomic_flag_base*, memory_order);
-
- volatile __atomic_flag_base*
- __atomic_flag_for_address(const volatile void* __z) __attribute__((const));
- // Implementation specific defines.
- #define _ATOMIC_LOAD_(__a, __x) \
- ({ volatile __typeof__ _ATOMIC_MEMBER_* __p = &_ATOMIC_MEMBER_; \
- volatile atomic_flag* __g = __atomic_flag_for_address(__p); \
- __atomic_flag_wait_explicit(__g, __x); \
- __typeof__ _ATOMIC_MEMBER_ __r = *__p; \
- atomic_flag_clear_explicit(__g, __x); \
- __r; })
- #define _ATOMIC_STORE_(__a, __m, __x) \
- ({ volatile __typeof__ _ATOMIC_MEMBER_* __p = &_ATOMIC_MEMBER_; \
- __typeof__(__m) __v = (__m); \
- volatile atomic_flag* __g = __atomic_flag_for_address(__p); \
- __atomic_flag_wait_explicit(__g, __x); \
- *__p = __v; \
- atomic_flag_clear_explicit(__g, __x); \
- __v; })
- #define _ATOMIC_MODIFY_(__a, __o, __m, __x) \
- ({ volatile __typeof__ _ATOMIC_MEMBER_* __p = &_ATOMIC_MEMBER_; \
- __typeof__(__m) __v = (__m); \
- volatile atomic_flag* __g = __atomic_flag_for_address(__p); \
- __atomic_flag_wait_explicit(__g, __x); \
- __typeof__ _ATOMIC_MEMBER_ __r = *__p; \
- *__p __o __v; \
- atomic_flag_clear_explicit(__g, __x); \
- __r; })
- #define _ATOMIC_CMPEXCHNG_(__a, __e, __m, __x) \
- ({ volatile __typeof__ _ATOMIC_MEMBER_* __p = &_ATOMIC_MEMBER_; \
- __typeof__(__e) __q = (__e); \
- __typeof__(__m) __v = (__m); \
- bool __r; \
- volatile atomic_flag* __g = __atomic_flag_for_address(__p); \
- __atomic_flag_wait_explicit(__g, __x); \
- __typeof__ _ATOMIC_MEMBER_ __t__ = *__p; \
- if (__t__ == *__q) { *__p = __v; __r = true; } \
- else { *__q = __t__; __r = false; } \
- atomic_flag_clear_explicit(__g, __x); \
- __r; })
- // @} group atomics
- _GLIBCXX_END_EXTERN_C
- _GLIBCXX_END_NAMESPACE
- // Inject into global namespace.
- #ifdef __cplusplus
- #include <cstdatomic>
- using std::memory_order;
- using std::memory_order_relaxed;
- using std::memory_order_consume;
- using std::memory_order_acquire;
- using std::memory_order_release;
- using std::memory_order_acq_rel;
- using std::memory_order_seq_cst;
- using std::atomic_flag;
- 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_wchar_t;
- using std::atomic_char16_t;
- using std::atomic_char32_t;
- using std::atomic_address;
- using std::atomic;
- #endif
- #endif
|