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