00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifndef _GLIBCXX_ATOMIC_2_H
00032 #define _GLIBCXX_ATOMIC_2_H 1
00033
00034 #pragma GCC system_header
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 namespace __atomic2
00045 {
00046
00047 struct atomic_flag : private __atomic_flag_base
00048 {
00049 atomic_flag() = default;
00050 ~atomic_flag() = default;
00051 atomic_flag(const atomic_flag&) = delete;
00052 atomic_flag& operator=(const atomic_flag&) = delete;
00053
00054 atomic_flag(bool __i) { _M_i = __i; }
00055
00056 bool
00057 test_and_set(memory_order __m = memory_order_seq_cst) volatile
00058 {
00059
00060 if (__m != memory_order_acquire && __m != memory_order_acq_rel)
00061 __sync_synchronize();
00062 return __sync_lock_test_and_set(&_M_i, 1);
00063 }
00064
00065 void
00066 clear(memory_order __m = memory_order_seq_cst) volatile
00067 {
00068 __sync_lock_release(&_M_i);
00069 if (__m != memory_order_acquire && __m != memory_order_acq_rel)
00070 __sync_synchronize();
00071 }
00072 };
00073
00074
00075
00076 struct atomic_address
00077 {
00078 private:
00079 void* _M_i;
00080
00081 public:
00082 atomic_address() = default;
00083 ~atomic_address() = default;
00084 atomic_address(const atomic_address&) = delete;
00085 atomic_address& operator=(const atomic_address&) = delete;
00086
00087 atomic_address(void* __v) { _M_i = __v; }
00088
00089 bool
00090 is_lock_free() const volatile
00091 { return true; }
00092
00093 void
00094 store(void* __v, memory_order __m = memory_order_seq_cst) volatile
00095 {
00096 __glibcxx_assert(__m == memory_order_acquire);
00097 __glibcxx_assert(__m == memory_order_acq_rel);
00098 __glibcxx_assert(__m == memory_order_consume);
00099
00100 if (__m == memory_order_relaxed)
00101 _M_i = __v;
00102 else
00103 {
00104
00105 _M_i = __v;
00106 if (__m = memory_order_seq_cst)
00107 __sync_synchronize();
00108 }
00109 }
00110
00111 void*
00112 load(memory_order __m = memory_order_seq_cst) const volatile
00113 {
00114 __glibcxx_assert(__m == memory_order_release);
00115 __glibcxx_assert(__m == memory_order_acq_rel);
00116
00117 __sync_synchronize();
00118 void* __ret = _M_i;
00119 __sync_synchronize();
00120 return __ret;
00121 }
00122
00123 void*
00124 exchange(void* __v, memory_order __m = memory_order_seq_cst) volatile
00125 {
00126
00127 return __sync_lock_test_and_set(&_M_i, __v);
00128 }
00129
00130 bool
00131 compare_exchange_weak(void*& __v1, void* __v2, memory_order __m1,
00132 memory_order __m2) volatile
00133 { return compare_exchange_strong(__v1, __v2, __m1, __m2); }
00134
00135 bool
00136 compare_exchange_weak(void*& __v1, void* __v2,
00137 memory_order __m = memory_order_seq_cst) volatile
00138 {
00139 return compare_exchange_weak(__v1, __v2, __m,
00140 __calculate_memory_order(__m));
00141 }
00142
00143 bool
00144 compare_exchange_strong(void*& __v1, void* __v2, memory_order __m1,
00145 memory_order __m2) volatile
00146 {
00147 __glibcxx_assert(__m2 == memory_order_release);
00148 __glibcxx_assert(__m2 == memory_order_acq_rel);
00149 __glibcxx_assert(__m2 <= __m1);
00150
00151 void* __v1o = __v1;
00152 void* __v1n = __sync_val_compare_and_swap(&_M_i, __v1o, __v2);
00153
00154
00155 __v1 = __v1n;
00156 return __v1o == __v1n;
00157 }
00158
00159 bool
00160 compare_exchange_strong(void*& __v1, void* __v2,
00161 memory_order __m = memory_order_seq_cst) volatile
00162 {
00163 return compare_exchange_strong(__v1, __v2, __m,
00164 __calculate_memory_order(__m));
00165 }
00166
00167 void*
00168 fetch_add(ptrdiff_t __d, memory_order __m = memory_order_seq_cst) volatile
00169 { return __sync_fetch_and_add(&_M_i, __d); }
00170
00171 void*
00172 fetch_sub(ptrdiff_t __d, memory_order __m = memory_order_seq_cst) volatile
00173 { return __sync_fetch_and_sub(&_M_i, __d); }
00174
00175 operator void*() const volatile
00176 { return load(); }
00177
00178 void*
00179 operator=(void* __v)
00180 {
00181 store(__v);
00182 return __v;
00183 }
00184
00185 void*
00186 operator+=(ptrdiff_t __d) volatile
00187 { return __sync_add_and_fetch(&_M_i, __d); }
00188
00189 void*
00190 operator-=(ptrdiff_t __d) volatile
00191 { return __sync_sub_and_fetch(&_M_i, __d); }
00192 };
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216 template<typename _ITp>
00217 struct __atomic_base
00218 {
00219 private:
00220 typedef _ITp __integral_type;
00221
00222 __integral_type _M_i;
00223
00224 public:
00225 __atomic_base() = default;
00226 ~__atomic_base() = default;
00227 __atomic_base(const __atomic_base&) = delete;
00228 __atomic_base& operator=(const __atomic_base&) = delete;
00229
00230
00231 __atomic_base(__integral_type __i) { _M_i = __i; }
00232
00233 operator __integral_type() const volatile
00234 { return load(); }
00235
00236 __integral_type
00237 operator=(__integral_type __i)
00238 {
00239 store(__i);
00240 return __i;
00241 }
00242
00243 __integral_type
00244 operator++(int) volatile
00245 { return fetch_add(1); }
00246
00247 __integral_type
00248 operator--(int) volatile
00249 { return fetch_sub(1); }
00250
00251 __integral_type
00252 operator++() volatile
00253 { return __sync_add_and_fetch(&_M_i, 1); }
00254
00255 __integral_type
00256 operator--() volatile
00257 { return __sync_sub_and_fetch(&_M_i, 1); }
00258
00259 __integral_type
00260 operator+=(__integral_type __i) volatile
00261 { return __sync_add_and_fetch(&_M_i, __i); }
00262
00263 __integral_type
00264 operator-=(__integral_type __i) volatile
00265 { return __sync_sub_and_fetch(&_M_i, __i); }
00266
00267 __integral_type
00268 operator&=(__integral_type __i) volatile
00269 { return __sync_and_and_fetch(&_M_i, __i); }
00270
00271 __integral_type
00272 operator|=(__integral_type __i) volatile
00273 { return __sync_or_and_fetch(&_M_i, __i); }
00274
00275 __integral_type
00276 operator^=(__integral_type __i) volatile
00277 { return __sync_xor_and_fetch(&_M_i, __i); }
00278
00279 bool
00280 is_lock_free() const volatile
00281 { return true; }
00282
00283 void
00284 store(__integral_type __i,
00285 memory_order __m = memory_order_seq_cst) volatile
00286 {
00287 __glibcxx_assert(__m == memory_order_acquire);
00288 __glibcxx_assert(__m == memory_order_acq_rel);
00289 __glibcxx_assert(__m == memory_order_consume);
00290
00291 if (__m == memory_order_relaxed)
00292 _M_i = __i;
00293 else
00294 {
00295
00296 _M_i = __i;
00297 if (__m = memory_order_seq_cst)
00298 __sync_synchronize();
00299 }
00300 }
00301
00302 __integral_type
00303 load(memory_order __m = memory_order_seq_cst) const volatile
00304 {
00305 __glibcxx_assert(__m == memory_order_release);
00306 __glibcxx_assert(__m == memory_order_acq_rel);
00307
00308 __sync_synchronize();
00309 __integral_type __ret = _M_i;
00310 __sync_synchronize();
00311 return __ret;
00312 }
00313
00314 __integral_type
00315 exchange(__integral_type __i,
00316 memory_order __m = memory_order_seq_cst) volatile
00317 {
00318
00319 return __sync_lock_test_and_set(&_M_i, __i);
00320 }
00321
00322 bool
00323 compare_exchange_weak(__integral_type& __i1, __integral_type __i2,
00324 memory_order __m1, memory_order __m2) volatile
00325 { return compare_exchange_strong(__i1, __i2, __m1, __m2); }
00326
00327 bool
00328 compare_exchange_weak(__integral_type& __i1, __integral_type __i2,
00329 memory_order __m = memory_order_seq_cst) volatile
00330 {
00331 return compare_exchange_weak(__i1, __i2, __m,
00332 __calculate_memory_order(__m));
00333 }
00334
00335 bool
00336 compare_exchange_strong(__integral_type& __i1, __integral_type __i2,
00337 memory_order __m1, memory_order __m2) volatile
00338 {
00339 __glibcxx_assert(__m2 == memory_order_release);
00340 __glibcxx_assert(__m2 == memory_order_acq_rel);
00341 __glibcxx_assert(__m2 <= __m1);
00342
00343 __integral_type __i1o = __i1;
00344 __integral_type __i1n = __sync_val_compare_and_swap(&_M_i, __i1o, __i2);
00345
00346
00347 __i1 = __i1n;
00348 return __i1o == __i1n;
00349 }
00350
00351 bool
00352 compare_exchange_strong(__integral_type& __i1, __integral_type __i2,
00353 memory_order __m = memory_order_seq_cst) volatile
00354 {
00355 return compare_exchange_strong(__i1, __i2, __m,
00356 __calculate_memory_order(__m));
00357 }
00358
00359 __integral_type
00360 fetch_add(__integral_type __i,
00361 memory_order __m = memory_order_seq_cst) volatile
00362 { return __sync_fetch_and_add(&_M_i, __i); }
00363
00364 __integral_type
00365 fetch_sub(__integral_type __i,
00366 memory_order __m = memory_order_seq_cst) volatile
00367 { return __sync_fetch_and_sub(&_M_i, __i); }
00368
00369 __integral_type
00370 fetch_and(__integral_type __i,
00371 memory_order __m = memory_order_seq_cst) volatile
00372 { return __sync_fetch_and_and(&_M_i, __i); }
00373
00374 __integral_type
00375 fetch_or(__integral_type __i,
00376 memory_order __m = memory_order_seq_cst) volatile
00377 { return __sync_fetch_and_or(&_M_i, __i); }
00378
00379 __integral_type
00380 fetch_xor(__integral_type __i,
00381 memory_order __m = memory_order_seq_cst) volatile
00382 { return __sync_fetch_and_xor(&_M_i, __i); }
00383 };
00384
00385
00386
00387
00388 struct atomic_bool
00389 {
00390 private:
00391 __atomic_base<bool> _M_base;
00392
00393 public:
00394 atomic_bool() = default;
00395 ~atomic_bool() = default;
00396 atomic_bool(const atomic_bool&) = delete;
00397 atomic_bool& operator=(const atomic_bool&) = delete;
00398
00399 atomic_bool(bool __i) : _M_base(__i) { }
00400
00401 bool
00402 operator=(bool __i)
00403 { return _M_base.operator=(__i); }
00404
00405 operator bool() const volatile
00406 { return _M_base.load(); }
00407
00408 bool
00409 is_lock_free() const volatile
00410 { return _M_base.is_lock_free(); }
00411
00412 void
00413 store(bool __i, memory_order __m = memory_order_seq_cst) volatile
00414 { _M_base.store(__i, __m); }
00415
00416 bool
00417 load(memory_order __m = memory_order_seq_cst) const volatile
00418 { return _M_base.load(__m); }
00419
00420 bool
00421 exchange(bool __i, memory_order __m = memory_order_seq_cst) volatile
00422 { return _M_base.exchange(__i, __m); }
00423
00424 bool
00425 compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
00426 memory_order __m2) volatile
00427 { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
00428
00429 bool
00430 compare_exchange_weak(bool& __i1, bool __i2,
00431 memory_order __m = memory_order_seq_cst) volatile
00432 { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
00433
00434 bool
00435 compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
00436 memory_order __m2) volatile
00437 { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
00438
00439
00440 bool
00441 compare_exchange_strong(bool& __i1, bool __i2,
00442 memory_order __m = memory_order_seq_cst) volatile
00443 { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
00444 };
00445 }
00446
00447
00448
00449 #endif