Install gcc-4.4.0-tdm-1-g++-2.tar.gz
[git/jnareb-git.git] / mingw / lib / gcc / mingw32 / 4.4.0 / include / c++ / stdatomic.h
blob71ddb8507a4cc930fda319ecda18877783b3691c
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 3, 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 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
25 /** @file stdatomic.h
26 * This is a Standard C++ Library header.
29 #include <bits/c++config.h>
30 #include <stddef.h>
31 #include <stdbool.h> // XXX need to define bool w/o stdbool.h in tr1/cstdbool
33 #ifndef _GLIBCXX_STDATOMIC_H
34 #define _GLIBCXX_STDATOMIC_H 1
36 _GLIBCXX_BEGIN_NAMESPACE(std)
37 _GLIBCXX_BEGIN_EXTERN_C
39 /**
40 * @defgroup atomics Atomics
42 * Components for performing atomic operations.
43 * @{
46 /// Enumeration for memory_order
47 typedef enum memory_order
49 memory_order_relaxed,
50 memory_order_consume,
51 memory_order_acquire,
52 memory_order_release,
53 memory_order_acq_rel,
54 memory_order_seq_cst
55 } memory_order;
57 // Base for atomic_flag.
58 typedef struct __atomic_flag_base
60 bool _M_i;
61 } __atomic_flag_base;
63 #define ATOMIC_FLAG_INIT { false }
65 /// 29.2 Lock-free Property
66 #if defined(_GLIBCXX_ATOMIC_BUILTINS_1) && defined(_GLIBCXX_ATOMIC_BUILTINS_2) \
67 && defined(_GLIBCXX_ATOMIC_BUILTINS_4) && defined(_GLIBCXX_ATOMIC_BUILTINS_8)
68 # define _GLIBCXX_ATOMIC_PROPERTY 2
69 # define _GLIBCXX_ATOMIC_NAMESPACE __atomic2
70 #elif defined(_GLIBCXX_ATOMIC_BUILTINS_1)
71 # define _GLIBCXX_ATOMIC_PROPERTY 1
72 # define _GLIBCXX_ATOMIC_NAMESPACE __atomic1
73 #else
74 # define _GLIBCXX_ATOMIC_PROPERTY 0
75 # define _GLIBCXX_ATOMIC_NAMESPACE __atomic0
76 #endif
78 #define ATOMIC_INTEGRAL_LOCK_FREE _GLIBCXX_ATOMIC_PROPERTY
79 #define ATOMIC_ADDRESS_LOCK_FREE _GLIBCXX_ATOMIC_PROPERTY
81 // Switch atomic integral base types based on C or C++. In
82 // addition, for "C" only provide type-generic macros for atomic
83 // operations. (As C++ accomplishes the same thing with sets of
84 // overloaded functions.
85 #ifdef __cplusplus
86 inline namespace _GLIBCXX_ATOMIC_NAMESPACE { }
87 # include <bits/atomicfwd_cxx.h>
88 #else
89 # include <bits/atomicfwd_c.h>
90 #endif
92 // Typedefs for other atomic integral types.
93 typedef atomic_schar atomic_int_least8_t;
94 typedef atomic_uchar atomic_uint_least8_t;
95 typedef atomic_short atomic_int_least16_t;
96 typedef atomic_ushort atomic_uint_least16_t;
97 typedef atomic_int atomic_int_least32_t;
98 typedef atomic_uint atomic_uint_least32_t;
99 typedef atomic_llong atomic_int_least64_t;
100 typedef atomic_ullong atomic_uint_least64_t;
102 typedef atomic_schar atomic_int_fast8_t;
103 typedef atomic_uchar atomic_uint_fast8_t;
104 typedef atomic_short atomic_int_fast16_t;
105 typedef atomic_ushort atomic_uint_fast16_t;
106 typedef atomic_int atomic_int_fast32_t;
107 typedef atomic_uint atomic_uint_fast32_t;
108 typedef atomic_llong atomic_int_fast64_t;
109 typedef atomic_ullong atomic_uint_fast64_t;
111 typedef atomic_long atomic_intptr_t;
112 typedef atomic_ulong atomic_uintptr_t;
114 typedef atomic_long atomic_ssize_t;
115 typedef atomic_ulong atomic_size_t;
117 typedef atomic_llong atomic_intmax_t;
118 typedef atomic_ullong atomic_uintmax_t;
120 typedef atomic_long atomic_ptrdiff_t;
122 // Accessor functions for base atomic_flag type.
123 bool
124 atomic_flag_test_and_set_explicit(volatile __atomic_flag_base*, memory_order);
126 inline bool
127 atomic_flag_test_and_set(volatile __atomic_flag_base* __a)
128 { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
130 void
131 atomic_flag_clear_explicit(volatile __atomic_flag_base*, memory_order);
133 inline void
134 atomic_flag_clear(volatile __atomic_flag_base* __a)
135 { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
137 void
138 __atomic_flag_wait_explicit(volatile __atomic_flag_base*, memory_order);
140 volatile __atomic_flag_base*
141 __atomic_flag_for_address(const volatile void* __z) __attribute__((const));
143 // Implementation specific defines.
144 #define _ATOMIC_LOAD_(__a, __x) \
145 ({ volatile __typeof__ _ATOMIC_MEMBER_* __p = &_ATOMIC_MEMBER_; \
146 volatile atomic_flag* __g = __atomic_flag_for_address(__p); \
147 __atomic_flag_wait_explicit(__g, __x); \
148 __typeof__ _ATOMIC_MEMBER_ __r = *__p; \
149 atomic_flag_clear_explicit(__g, __x); \
150 __r; })
152 #define _ATOMIC_STORE_(__a, __m, __x) \
153 ({ volatile __typeof__ _ATOMIC_MEMBER_* __p = &_ATOMIC_MEMBER_; \
154 __typeof__(__m) __v = (__m); \
155 volatile atomic_flag* __g = __atomic_flag_for_address(__p); \
156 __atomic_flag_wait_explicit(__g, __x); \
157 *__p = __v; \
158 atomic_flag_clear_explicit(__g, __x); \
159 __v; })
161 #define _ATOMIC_MODIFY_(__a, __o, __m, __x) \
162 ({ volatile __typeof__ _ATOMIC_MEMBER_* __p = &_ATOMIC_MEMBER_; \
163 __typeof__(__m) __v = (__m); \
164 volatile atomic_flag* __g = __atomic_flag_for_address(__p); \
165 __atomic_flag_wait_explicit(__g, __x); \
166 __typeof__ _ATOMIC_MEMBER_ __r = *__p; \
167 *__p __o __v; \
168 atomic_flag_clear_explicit(__g, __x); \
169 __r; })
171 #define _ATOMIC_CMPEXCHNG_(__a, __e, __m, __x) \
172 ({ volatile __typeof__ _ATOMIC_MEMBER_* __p = &_ATOMIC_MEMBER_; \
173 __typeof__(__e) __q = (__e); \
174 __typeof__(__m) __v = (__m); \
175 bool __r; \
176 volatile atomic_flag* __g = __atomic_flag_for_address(__p); \
177 __atomic_flag_wait_explicit(__g, __x); \
178 __typeof__ _ATOMIC_MEMBER_ __t__ = *__p; \
179 if (__t__ == *__q) { *__p = __v; __r = true; } \
180 else { *__q = __t__; __r = false; } \
181 atomic_flag_clear_explicit(__g, __x); \
182 __r; })
184 // @} group atomics
186 _GLIBCXX_END_EXTERN_C
187 _GLIBCXX_END_NAMESPACE
189 // Inject into global namespace. XXX
190 #if defined(__cplusplus) && !defined(_GLIBCXX_STDATOMIC)
191 using std::memory_order;
192 using std::memory_order_relaxed;
193 using std::memory_order_consume;
194 using std::memory_order_acquire;
195 using std::memory_order_release;
196 using std::memory_order_acq_rel;
197 using std::memory_order_seq_cst;
198 using std::atomic_flag;
199 using std::atomic_bool;
200 using std::atomic_char;
201 using std::atomic_schar;
202 using std::atomic_uchar;
203 using std::atomic_short;
204 using std::atomic_ushort;
205 using std::atomic_int;
206 using std::atomic_uint;
207 using std::atomic_long;
208 using std::atomic_ulong;
209 using std::atomic_llong;
210 using std::atomic_ullong;
211 using std::atomic_wchar_t;
212 using std::atomic_char16_t;
213 using std::atomic_char32_t;
214 using std::atomic_address;
215 using std::atomic;
216 #endif
218 #endif