Merged revisions 143552,143554,143557,143560,143562,143564-143567,143570-143573,14357...
[official-gcc.git] / libstdc++-v3 / include / c_compatibility / stdatomic.h
blob776f6071a88c3c46ef6e6ec88ce0424c49590b56
1 // -*- C++ -*- compatibility header.
3 // Copyright (C) 2008, 2009 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 2, or (at your option)
9 // any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this library; see the file COPYING. If not, write to
18 // the Free Software Foundation, 51 Franklin Street, Fifth Floor,
19 // Boston, MA 02110-1301, USA.
21 // As a special exception, you may use this file as part of a free software
22 // library without restriction. Specifically, if other files instantiate
23 // templates or use macros or inline functions from this file, or you compile
24 // this file and link it with other files to produce an executable, this
25 // file does not by itself cause the resulting executable to be covered by
26 // the GNU General Public License. This exception does not however
27 // invalidate any other reasons why the executable file might be covered by
28 // the GNU General Public License.
30 /** @file stdatomic.h
31 * This is a Standard C++ Library header.
34 #include <bits/c++config.h>
35 #include <stddef.h>
36 #include <stdbool.h> // XXX need to define bool w/o stdbool.h in tr1/cstdbool
38 #ifndef _GLIBCXX_STDATOMIC_H
39 #define _GLIBCXX_STDATOMIC_H 1
41 _GLIBCXX_BEGIN_NAMESPACE(std)
42 _GLIBCXX_BEGIN_EXTERN_C
44 /**
45 * @defgroup atomics Atomics
47 * Components for performing atomic operations.
48 * @{
51 /// Enumeration for memory_order
52 typedef enum memory_order
54 memory_order_relaxed,
55 memory_order_consume,
56 memory_order_acquire,
57 memory_order_release,
58 memory_order_acq_rel,
59 memory_order_seq_cst
60 } memory_order;
62 // Base for atomic_flag.
63 typedef struct __atomic_flag_base
65 bool _M_i;
66 } __atomic_flag_base;
68 #define ATOMIC_FLAG_INIT { false }
70 /// 29.2 Lock-free Property
71 #if defined(_GLIBCXX_ATOMIC_BUILTINS_1) && defined(_GLIBCXX_ATOMIC_BUILTINS_2) \
72 && defined(_GLIBCXX_ATOMIC_BUILTINS_4) && defined(_GLIBCXX_ATOMIC_BUILTINS_8)
73 # define _GLIBCXX_ATOMIC_PROPERTY 2
74 # define _GLIBCXX_ATOMIC_NAMESPACE __atomic2
75 #elif defined(_GLIBCXX_ATOMIC_BUILTINS_1)
76 # define _GLIBCXX_ATOMIC_PROPERTY 1
77 # define _GLIBCXX_ATOMIC_NAMESPACE __atomic1
78 #else
79 # define _GLIBCXX_ATOMIC_PROPERTY 0
80 # define _GLIBCXX_ATOMIC_NAMESPACE __atomic0
81 #endif
83 #define ATOMIC_INTEGRAL_LOCK_FREE _GLIBCXX_ATOMIC_PROPERTY
84 #define ATOMIC_ADDRESS_LOCK_FREE _GLIBCXX_ATOMIC_PROPERTY
86 // Switch atomic integral base types based on C or C++. In
87 // addition, for "C" only provide type-generic macros for atomic
88 // operations. (As C++ accomplishes the same thing with sets of
89 // overloaded functions.
90 #ifdef __cplusplus
91 inline namespace _GLIBCXX_ATOMIC_NAMESPACE { }
92 # include <bits/atomicfwd_cxx.h>
93 #else
94 # include <bits/atomicfwd_c.h>
95 #endif
97 // Typedefs for other atomic integral types.
98 typedef atomic_schar atomic_int_least8_t;
99 typedef atomic_uchar atomic_uint_least8_t;
100 typedef atomic_short atomic_int_least16_t;
101 typedef atomic_ushort atomic_uint_least16_t;
102 typedef atomic_int atomic_int_least32_t;
103 typedef atomic_uint atomic_uint_least32_t;
104 typedef atomic_llong atomic_int_least64_t;
105 typedef atomic_ullong atomic_uint_least64_t;
107 typedef atomic_schar atomic_int_fast8_t;
108 typedef atomic_uchar atomic_uint_fast8_t;
109 typedef atomic_short atomic_int_fast16_t;
110 typedef atomic_ushort atomic_uint_fast16_t;
111 typedef atomic_int atomic_int_fast32_t;
112 typedef atomic_uint atomic_uint_fast32_t;
113 typedef atomic_llong atomic_int_fast64_t;
114 typedef atomic_ullong atomic_uint_fast64_t;
116 typedef atomic_long atomic_intptr_t;
117 typedef atomic_ulong atomic_uintptr_t;
119 typedef atomic_long atomic_ssize_t;
120 typedef atomic_ulong atomic_size_t;
122 typedef atomic_llong atomic_intmax_t;
123 typedef atomic_ullong atomic_uintmax_t;
125 typedef atomic_long atomic_ptrdiff_t;
127 // Accessor functions for base atomic_flag type.
128 bool
129 atomic_flag_test_and_set_explicit(volatile __atomic_flag_base*, memory_order);
131 inline bool
132 atomic_flag_test_and_set(volatile __atomic_flag_base* __a)
133 { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
135 void
136 atomic_flag_clear_explicit(volatile __atomic_flag_base*, memory_order);
138 inline void
139 atomic_flag_clear(volatile __atomic_flag_base* __a)
140 { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
142 void
143 __atomic_flag_wait_explicit(volatile __atomic_flag_base*, memory_order);
145 volatile __atomic_flag_base*
146 __atomic_flag_for_address(const volatile void* __z) __attribute__((const));
148 // Implementation specific defines.
149 #define _ATOMIC_LOAD_(__a, __x) \
150 ({ volatile __typeof__ _ATOMIC_MEMBER_* __p = &_ATOMIC_MEMBER_; \
151 volatile atomic_flag* __g = __atomic_flag_for_address(__p); \
152 __atomic_flag_wait_explicit(__g, __x); \
153 __typeof__ _ATOMIC_MEMBER_ __r = *__p; \
154 atomic_flag_clear_explicit(__g, __x); \
155 __r; })
157 #define _ATOMIC_STORE_(__a, __m, __x) \
158 ({ volatile __typeof__ _ATOMIC_MEMBER_* __p = &_ATOMIC_MEMBER_; \
159 __typeof__(__m) __v = (__m); \
160 volatile atomic_flag* __g = __atomic_flag_for_address(__p); \
161 __atomic_flag_wait_explicit(__g, __x); \
162 *__p = __v; \
163 atomic_flag_clear_explicit(__g, __x); \
164 __v; })
166 #define _ATOMIC_MODIFY_(__a, __o, __m, __x) \
167 ({ volatile __typeof__ _ATOMIC_MEMBER_* __p = &_ATOMIC_MEMBER_; \
168 __typeof__(__m) __v = (__m); \
169 volatile atomic_flag* __g = __atomic_flag_for_address(__p); \
170 __atomic_flag_wait_explicit(__g, __x); \
171 __typeof__ _ATOMIC_MEMBER_ __r = *__p; \
172 *__p __o __v; \
173 atomic_flag_clear_explicit(__g, __x); \
174 __r; })
176 #define _ATOMIC_CMPEXCHNG_(__a, __e, __m, __x) \
177 ({ volatile __typeof__ _ATOMIC_MEMBER_* __p = &_ATOMIC_MEMBER_; \
178 __typeof__(__e) __q = (__e); \
179 __typeof__(__m) __v = (__m); \
180 bool __r; \
181 volatile atomic_flag* __g = __atomic_flag_for_address(__p); \
182 __atomic_flag_wait_explicit(__g, __x); \
183 __typeof__ _ATOMIC_MEMBER_ __t__ = *__p; \
184 if (__t__ == *__q) { *__p = __v; __r = true; } \
185 else { *__q = __t__; __r = false; } \
186 atomic_flag_clear_explicit(__g, __x); \
187 __r; })
189 // @} group atomics
191 _GLIBCXX_END_EXTERN_C
192 _GLIBCXX_END_NAMESPACE
194 // Inject into global namespace. XXX
195 #if defined(__cplusplus) && !defined(_GLIBCXX_STDATOMIC)
196 using std::memory_order;
197 using std::memory_order_relaxed;
198 using std::memory_order_consume;
199 using std::memory_order_acquire;
200 using std::memory_order_release;
201 using std::memory_order_acq_rel;
202 using std::memory_order_seq_cst;
203 using std::atomic_flag;
204 using std::atomic_bool;
205 using std::atomic_char;
206 using std::atomic_schar;
207 using std::atomic_uchar;
208 using std::atomic_short;
209 using std::atomic_ushort;
210 using std::atomic_int;
211 using std::atomic_uint;
212 using std::atomic_long;
213 using std::atomic_ulong;
214 using std::atomic_llong;
215 using std::atomic_ullong;
216 using std::atomic_wchar_t;
217 using std::atomic_char16_t;
218 using std::atomic_char32_t;
219 using std::atomic_address;
220 using std::atomic;
221 #endif
223 #endif