atomic 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252
  1. // -*- C++ -*- header.
  2. // Copyright (C) 2008-2015 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the
  6. // terms of the GNU General Public License as published by the
  7. // Free Software Foundation; either version 3, or (at your option)
  8. // any later version.
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // Under Section 7 of GPL version 3, you are granted additional
  14. // permissions described in the GCC Runtime Library Exception, version
  15. // 3.1, as published by the Free Software Foundation.
  16. // You should have received a copy of the GNU General Public License and
  17. // a copy of the GCC Runtime Library Exception along with this program;
  18. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. // <http://www.gnu.org/licenses/>.
  20. /** @file include/atomic
  21. * This is a Standard C++ Library header.
  22. */
  23. // Based on "C++ Atomic Types and Operations" by Hans Boehm and Lawrence Crowl.
  24. // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2427.html
  25. #ifndef _GLIBCXX_ATOMIC
  26. #define _GLIBCXX_ATOMIC 1
  27. #pragma GCC system_header
  28. #if __cplusplus < 201103L
  29. # include <bits/c++0x_warning.h>
  30. #else
  31. #include <bits/atomic_base.h>
  32. namespace std _GLIBCXX_VISIBILITY(default)
  33. {
  34. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  35. /**
  36. * @addtogroup atomics
  37. * @{
  38. */
  39. template<typename _Tp>
  40. struct atomic;
  41. /// atomic<bool>
  42. // NB: No operators or fetch-operations for this type.
  43. template<>
  44. struct atomic<bool>
  45. {
  46. private:
  47. __atomic_base<bool> _M_base;
  48. public:
  49. atomic() noexcept = default;
  50. ~atomic() noexcept = default;
  51. atomic(const atomic&) = delete;
  52. atomic& operator=(const atomic&) = delete;
  53. atomic& operator=(const atomic&) volatile = delete;
  54. constexpr atomic(bool __i) noexcept : _M_base(__i) { }
  55. bool
  56. operator=(bool __i) noexcept
  57. { return _M_base.operator=(__i); }
  58. bool
  59. operator=(bool __i) volatile noexcept
  60. { return _M_base.operator=(__i); }
  61. operator bool() const noexcept
  62. { return _M_base.load(); }
  63. operator bool() const volatile noexcept
  64. { return _M_base.load(); }
  65. bool
  66. is_lock_free() const noexcept { return _M_base.is_lock_free(); }
  67. bool
  68. is_lock_free() const volatile noexcept { return _M_base.is_lock_free(); }
  69. void
  70. store(bool __i, memory_order __m = memory_order_seq_cst) noexcept
  71. { _M_base.store(__i, __m); }
  72. void
  73. store(bool __i, memory_order __m = memory_order_seq_cst) volatile noexcept
  74. { _M_base.store(__i, __m); }
  75. bool
  76. load(memory_order __m = memory_order_seq_cst) const noexcept
  77. { return _M_base.load(__m); }
  78. bool
  79. load(memory_order __m = memory_order_seq_cst) const volatile noexcept
  80. { return _M_base.load(__m); }
  81. bool
  82. exchange(bool __i, memory_order __m = memory_order_seq_cst) noexcept
  83. { return _M_base.exchange(__i, __m); }
  84. bool
  85. exchange(bool __i,
  86. memory_order __m = memory_order_seq_cst) volatile noexcept
  87. { return _M_base.exchange(__i, __m); }
  88. bool
  89. compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
  90. memory_order __m2) noexcept
  91. { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
  92. bool
  93. compare_exchange_weak(bool& __i1, bool __i2, memory_order __m1,
  94. memory_order __m2) volatile noexcept
  95. { return _M_base.compare_exchange_weak(__i1, __i2, __m1, __m2); }
  96. bool
  97. compare_exchange_weak(bool& __i1, bool __i2,
  98. memory_order __m = memory_order_seq_cst) noexcept
  99. { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
  100. bool
  101. compare_exchange_weak(bool& __i1, bool __i2,
  102. memory_order __m = memory_order_seq_cst) volatile noexcept
  103. { return _M_base.compare_exchange_weak(__i1, __i2, __m); }
  104. bool
  105. compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
  106. memory_order __m2) noexcept
  107. { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
  108. bool
  109. compare_exchange_strong(bool& __i1, bool __i2, memory_order __m1,
  110. memory_order __m2) volatile noexcept
  111. { return _M_base.compare_exchange_strong(__i1, __i2, __m1, __m2); }
  112. bool
  113. compare_exchange_strong(bool& __i1, bool __i2,
  114. memory_order __m = memory_order_seq_cst) noexcept
  115. { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
  116. bool
  117. compare_exchange_strong(bool& __i1, bool __i2,
  118. memory_order __m = memory_order_seq_cst) volatile noexcept
  119. { return _M_base.compare_exchange_strong(__i1, __i2, __m); }
  120. };
  121. /**
  122. * @brief Generic atomic type, primary class template.
  123. *
  124. * @tparam _Tp Type to be made atomic, must be trivally copyable.
  125. */
  126. template<typename _Tp>
  127. struct atomic
  128. {
  129. private:
  130. // Align 1/2/4/8/16-byte types to at least their size.
  131. static constexpr int _S_min_alignment
  132. = (sizeof(_Tp) & (sizeof(_Tp) - 1)) || sizeof(_Tp) > 16
  133. ? 0 : sizeof(_Tp);
  134. static constexpr int _S_alignment
  135. = _S_min_alignment > alignof(_Tp) ? _S_min_alignment : alignof(_Tp);
  136. alignas(_S_alignment) _Tp _M_i;
  137. static_assert(__is_trivially_copyable(_Tp),
  138. "std::atomic requires a trivially copyable type");
  139. static_assert(sizeof(_Tp) > 0,
  140. "Incomplete or zero-sized types are not supported");
  141. public:
  142. atomic() noexcept = default;
  143. ~atomic() noexcept = default;
  144. atomic(const atomic&) = delete;
  145. atomic& operator=(const atomic&) = delete;
  146. atomic& operator=(const atomic&) volatile = delete;
  147. constexpr atomic(_Tp __i) noexcept : _M_i(__i) { }
  148. operator _Tp() const noexcept
  149. { return load(); }
  150. operator _Tp() const volatile noexcept
  151. { return load(); }
  152. _Tp
  153. operator=(_Tp __i) noexcept
  154. { store(__i); return __i; }
  155. _Tp
  156. operator=(_Tp __i) volatile noexcept
  157. { store(__i); return __i; }
  158. bool
  159. is_lock_free() const noexcept
  160. {
  161. // Produce a fake, minimally aligned pointer.
  162. return __atomic_is_lock_free(sizeof(_M_i),
  163. reinterpret_cast<void *>(-__alignof(_M_i)));
  164. }
  165. bool
  166. is_lock_free() const volatile noexcept
  167. {
  168. // Produce a fake, minimally aligned pointer.
  169. return __atomic_is_lock_free(sizeof(_M_i),
  170. reinterpret_cast<void *>(-__alignof(_M_i)));
  171. }
  172. void
  173. store(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept
  174. { __atomic_store(&_M_i, &__i, __m); }
  175. void
  176. store(_Tp __i, memory_order __m = memory_order_seq_cst) volatile noexcept
  177. { __atomic_store(&_M_i, &__i, __m); }
  178. _Tp
  179. load(memory_order __m = memory_order_seq_cst) const noexcept
  180. {
  181. _Tp tmp;
  182. __atomic_load(&_M_i, &tmp, __m);
  183. return tmp;
  184. }
  185. _Tp
  186. load(memory_order __m = memory_order_seq_cst) const volatile noexcept
  187. {
  188. _Tp tmp;
  189. __atomic_load(&_M_i, &tmp, __m);
  190. return tmp;
  191. }
  192. _Tp
  193. exchange(_Tp __i, memory_order __m = memory_order_seq_cst) noexcept
  194. {
  195. _Tp tmp;
  196. __atomic_exchange(&_M_i, &__i, &tmp, __m);
  197. return tmp;
  198. }
  199. _Tp
  200. exchange(_Tp __i,
  201. memory_order __m = memory_order_seq_cst) volatile noexcept
  202. {
  203. _Tp tmp;
  204. __atomic_exchange(&_M_i, &__i, &tmp, __m);
  205. return tmp;
  206. }
  207. bool
  208. compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s,
  209. memory_order __f) noexcept
  210. {
  211. return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f);
  212. }
  213. bool
  214. compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s,
  215. memory_order __f) volatile noexcept
  216. {
  217. return __atomic_compare_exchange(&_M_i, &__e, &__i, true, __s, __f);
  218. }
  219. bool
  220. compare_exchange_weak(_Tp& __e, _Tp __i,
  221. memory_order __m = memory_order_seq_cst) noexcept
  222. { return compare_exchange_weak(__e, __i, __m,
  223. __cmpexch_failure_order(__m)); }
  224. bool
  225. compare_exchange_weak(_Tp& __e, _Tp __i,
  226. memory_order __m = memory_order_seq_cst) volatile noexcept
  227. { return compare_exchange_weak(__e, __i, __m,
  228. __cmpexch_failure_order(__m)); }
  229. bool
  230. compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s,
  231. memory_order __f) noexcept
  232. {
  233. return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f);
  234. }
  235. bool
  236. compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s,
  237. memory_order __f) volatile noexcept
  238. {
  239. return __atomic_compare_exchange(&_M_i, &__e, &__i, false, __s, __f);
  240. }
  241. bool
  242. compare_exchange_strong(_Tp& __e, _Tp __i,
  243. memory_order __m = memory_order_seq_cst) noexcept
  244. { return compare_exchange_strong(__e, __i, __m,
  245. __cmpexch_failure_order(__m)); }
  246. bool
  247. compare_exchange_strong(_Tp& __e, _Tp __i,
  248. memory_order __m = memory_order_seq_cst) volatile noexcept
  249. { return compare_exchange_strong(__e, __i, __m,
  250. __cmpexch_failure_order(__m)); }
  251. };
  252. /// Partial specialization for pointer types.
  253. template<typename _Tp>
  254. struct atomic<_Tp*>
  255. {
  256. typedef _Tp* __pointer_type;
  257. typedef __atomic_base<_Tp*> __base_type;
  258. __base_type _M_b;
  259. atomic() noexcept = default;
  260. ~atomic() noexcept = default;
  261. atomic(const atomic&) = delete;
  262. atomic& operator=(const atomic&) = delete;
  263. atomic& operator=(const atomic&) volatile = delete;
  264. constexpr atomic(__pointer_type __p) noexcept : _M_b(__p) { }
  265. operator __pointer_type() const noexcept
  266. { return __pointer_type(_M_b); }
  267. operator __pointer_type() const volatile noexcept
  268. { return __pointer_type(_M_b); }
  269. __pointer_type
  270. operator=(__pointer_type __p) noexcept
  271. { return _M_b.operator=(__p); }
  272. __pointer_type
  273. operator=(__pointer_type __p) volatile noexcept
  274. { return _M_b.operator=(__p); }
  275. __pointer_type
  276. operator++(int) noexcept
  277. { return _M_b++; }
  278. __pointer_type
  279. operator++(int) volatile noexcept
  280. { return _M_b++; }
  281. __pointer_type
  282. operator--(int) noexcept
  283. { return _M_b--; }
  284. __pointer_type
  285. operator--(int) volatile noexcept
  286. { return _M_b--; }
  287. __pointer_type
  288. operator++() noexcept
  289. { return ++_M_b; }
  290. __pointer_type
  291. operator++() volatile noexcept
  292. { return ++_M_b; }
  293. __pointer_type
  294. operator--() noexcept
  295. { return --_M_b; }
  296. __pointer_type
  297. operator--() volatile noexcept
  298. { return --_M_b; }
  299. __pointer_type
  300. operator+=(ptrdiff_t __d) noexcept
  301. { return _M_b.operator+=(__d); }
  302. __pointer_type
  303. operator+=(ptrdiff_t __d) volatile noexcept
  304. { return _M_b.operator+=(__d); }
  305. __pointer_type
  306. operator-=(ptrdiff_t __d) noexcept
  307. { return _M_b.operator-=(__d); }
  308. __pointer_type
  309. operator-=(ptrdiff_t __d) volatile noexcept
  310. { return _M_b.operator-=(__d); }
  311. bool
  312. is_lock_free() const noexcept
  313. { return _M_b.is_lock_free(); }
  314. bool
  315. is_lock_free() const volatile noexcept
  316. { return _M_b.is_lock_free(); }
  317. void
  318. store(__pointer_type __p,
  319. memory_order __m = memory_order_seq_cst) noexcept
  320. { return _M_b.store(__p, __m); }
  321. void
  322. store(__pointer_type __p,
  323. memory_order __m = memory_order_seq_cst) volatile noexcept
  324. { return _M_b.store(__p, __m); }
  325. __pointer_type
  326. load(memory_order __m = memory_order_seq_cst) const noexcept
  327. { return _M_b.load(__m); }
  328. __pointer_type
  329. load(memory_order __m = memory_order_seq_cst) const volatile noexcept
  330. { return _M_b.load(__m); }
  331. __pointer_type
  332. exchange(__pointer_type __p,
  333. memory_order __m = memory_order_seq_cst) noexcept
  334. { return _M_b.exchange(__p, __m); }
  335. __pointer_type
  336. exchange(__pointer_type __p,
  337. memory_order __m = memory_order_seq_cst) volatile noexcept
  338. { return _M_b.exchange(__p, __m); }
  339. bool
  340. compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
  341. memory_order __m1, memory_order __m2) noexcept
  342. { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
  343. bool
  344. compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
  345. memory_order __m1,
  346. memory_order __m2) volatile noexcept
  347. { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
  348. bool
  349. compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
  350. memory_order __m = memory_order_seq_cst) noexcept
  351. {
  352. return compare_exchange_weak(__p1, __p2, __m,
  353. __cmpexch_failure_order(__m));
  354. }
  355. bool
  356. compare_exchange_weak(__pointer_type& __p1, __pointer_type __p2,
  357. memory_order __m = memory_order_seq_cst) volatile noexcept
  358. {
  359. return compare_exchange_weak(__p1, __p2, __m,
  360. __cmpexch_failure_order(__m));
  361. }
  362. bool
  363. compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
  364. memory_order __m1, memory_order __m2) noexcept
  365. { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
  366. bool
  367. compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
  368. memory_order __m1,
  369. memory_order __m2) volatile noexcept
  370. { return _M_b.compare_exchange_strong(__p1, __p2, __m1, __m2); }
  371. bool
  372. compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
  373. memory_order __m = memory_order_seq_cst) noexcept
  374. {
  375. return _M_b.compare_exchange_strong(__p1, __p2, __m,
  376. __cmpexch_failure_order(__m));
  377. }
  378. bool
  379. compare_exchange_strong(__pointer_type& __p1, __pointer_type __p2,
  380. memory_order __m = memory_order_seq_cst) volatile noexcept
  381. {
  382. return _M_b.compare_exchange_strong(__p1, __p2, __m,
  383. __cmpexch_failure_order(__m));
  384. }
  385. __pointer_type
  386. fetch_add(ptrdiff_t __d,
  387. memory_order __m = memory_order_seq_cst) noexcept
  388. { return _M_b.fetch_add(__d, __m); }
  389. __pointer_type
  390. fetch_add(ptrdiff_t __d,
  391. memory_order __m = memory_order_seq_cst) volatile noexcept
  392. { return _M_b.fetch_add(__d, __m); }
  393. __pointer_type
  394. fetch_sub(ptrdiff_t __d,
  395. memory_order __m = memory_order_seq_cst) noexcept
  396. { return _M_b.fetch_sub(__d, __m); }
  397. __pointer_type
  398. fetch_sub(ptrdiff_t __d,
  399. memory_order __m = memory_order_seq_cst) volatile noexcept
  400. { return _M_b.fetch_sub(__d, __m); }
  401. };
  402. /// Explicit specialization for char.
  403. template<>
  404. struct atomic<char> : __atomic_base<char>
  405. {
  406. typedef char __integral_type;
  407. typedef __atomic_base<char> __base_type;
  408. atomic() noexcept = default;
  409. ~atomic() noexcept = default;
  410. atomic(const atomic&) = delete;
  411. atomic& operator=(const atomic&) = delete;
  412. atomic& operator=(const atomic&) volatile = delete;
  413. constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
  414. using __base_type::operator __integral_type;
  415. using __base_type::operator=;
  416. };
  417. /// Explicit specialization for signed char.
  418. template<>
  419. struct atomic<signed char> : __atomic_base<signed char>
  420. {
  421. typedef signed char __integral_type;
  422. typedef __atomic_base<signed char> __base_type;
  423. atomic() noexcept= default;
  424. ~atomic() noexcept = default;
  425. atomic(const atomic&) = delete;
  426. atomic& operator=(const atomic&) = delete;
  427. atomic& operator=(const atomic&) volatile = delete;
  428. constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
  429. using __base_type::operator __integral_type;
  430. using __base_type::operator=;
  431. };
  432. /// Explicit specialization for unsigned char.
  433. template<>
  434. struct atomic<unsigned char> : __atomic_base<unsigned char>
  435. {
  436. typedef unsigned char __integral_type;
  437. typedef __atomic_base<unsigned char> __base_type;
  438. atomic() noexcept= default;
  439. ~atomic() noexcept = default;
  440. atomic(const atomic&) = delete;
  441. atomic& operator=(const atomic&) = delete;
  442. atomic& operator=(const atomic&) volatile = delete;
  443. constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
  444. using __base_type::operator __integral_type;
  445. using __base_type::operator=;
  446. };
  447. /// Explicit specialization for short.
  448. template<>
  449. struct atomic<short> : __atomic_base<short>
  450. {
  451. typedef short __integral_type;
  452. typedef __atomic_base<short> __base_type;
  453. atomic() noexcept = default;
  454. ~atomic() noexcept = default;
  455. atomic(const atomic&) = delete;
  456. atomic& operator=(const atomic&) = delete;
  457. atomic& operator=(const atomic&) volatile = delete;
  458. constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
  459. using __base_type::operator __integral_type;
  460. using __base_type::operator=;
  461. };
  462. /// Explicit specialization for unsigned short.
  463. template<>
  464. struct atomic<unsigned short> : __atomic_base<unsigned short>
  465. {
  466. typedef unsigned short __integral_type;
  467. typedef __atomic_base<unsigned short> __base_type;
  468. atomic() noexcept = default;
  469. ~atomic() noexcept = default;
  470. atomic(const atomic&) = delete;
  471. atomic& operator=(const atomic&) = delete;
  472. atomic& operator=(const atomic&) volatile = delete;
  473. constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
  474. using __base_type::operator __integral_type;
  475. using __base_type::operator=;
  476. };
  477. /// Explicit specialization for int.
  478. template<>
  479. struct atomic<int> : __atomic_base<int>
  480. {
  481. typedef int __integral_type;
  482. typedef __atomic_base<int> __base_type;
  483. atomic() noexcept = default;
  484. ~atomic() noexcept = default;
  485. atomic(const atomic&) = delete;
  486. atomic& operator=(const atomic&) = delete;
  487. atomic& operator=(const atomic&) volatile = delete;
  488. constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
  489. using __base_type::operator __integral_type;
  490. using __base_type::operator=;
  491. };
  492. /// Explicit specialization for unsigned int.
  493. template<>
  494. struct atomic<unsigned int> : __atomic_base<unsigned int>
  495. {
  496. typedef unsigned int __integral_type;
  497. typedef __atomic_base<unsigned int> __base_type;
  498. atomic() noexcept = default;
  499. ~atomic() noexcept = default;
  500. atomic(const atomic&) = delete;
  501. atomic& operator=(const atomic&) = delete;
  502. atomic& operator=(const atomic&) volatile = delete;
  503. constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
  504. using __base_type::operator __integral_type;
  505. using __base_type::operator=;
  506. };
  507. /// Explicit specialization for long.
  508. template<>
  509. struct atomic<long> : __atomic_base<long>
  510. {
  511. typedef long __integral_type;
  512. typedef __atomic_base<long> __base_type;
  513. atomic() noexcept = default;
  514. ~atomic() noexcept = default;
  515. atomic(const atomic&) = delete;
  516. atomic& operator=(const atomic&) = delete;
  517. atomic& operator=(const atomic&) volatile = delete;
  518. constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
  519. using __base_type::operator __integral_type;
  520. using __base_type::operator=;
  521. };
  522. /// Explicit specialization for unsigned long.
  523. template<>
  524. struct atomic<unsigned long> : __atomic_base<unsigned long>
  525. {
  526. typedef unsigned long __integral_type;
  527. typedef __atomic_base<unsigned long> __base_type;
  528. atomic() noexcept = default;
  529. ~atomic() noexcept = default;
  530. atomic(const atomic&) = delete;
  531. atomic& operator=(const atomic&) = delete;
  532. atomic& operator=(const atomic&) volatile = delete;
  533. constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
  534. using __base_type::operator __integral_type;
  535. using __base_type::operator=;
  536. };
  537. /// Explicit specialization for long long.
  538. template<>
  539. struct atomic<long long> : __atomic_base<long long>
  540. {
  541. typedef long long __integral_type;
  542. typedef __atomic_base<long long> __base_type;
  543. atomic() noexcept = default;
  544. ~atomic() noexcept = default;
  545. atomic(const atomic&) = delete;
  546. atomic& operator=(const atomic&) = delete;
  547. atomic& operator=(const atomic&) volatile = delete;
  548. constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
  549. using __base_type::operator __integral_type;
  550. using __base_type::operator=;
  551. };
  552. /// Explicit specialization for unsigned long long.
  553. template<>
  554. struct atomic<unsigned long long> : __atomic_base<unsigned long long>
  555. {
  556. typedef unsigned long long __integral_type;
  557. typedef __atomic_base<unsigned long long> __base_type;
  558. atomic() noexcept = default;
  559. ~atomic() noexcept = default;
  560. atomic(const atomic&) = delete;
  561. atomic& operator=(const atomic&) = delete;
  562. atomic& operator=(const atomic&) volatile = delete;
  563. constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
  564. using __base_type::operator __integral_type;
  565. using __base_type::operator=;
  566. };
  567. /// Explicit specialization for wchar_t.
  568. template<>
  569. struct atomic<wchar_t> : __atomic_base<wchar_t>
  570. {
  571. typedef wchar_t __integral_type;
  572. typedef __atomic_base<wchar_t> __base_type;
  573. atomic() noexcept = default;
  574. ~atomic() noexcept = default;
  575. atomic(const atomic&) = delete;
  576. atomic& operator=(const atomic&) = delete;
  577. atomic& operator=(const atomic&) volatile = delete;
  578. constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
  579. using __base_type::operator __integral_type;
  580. using __base_type::operator=;
  581. };
  582. /// Explicit specialization for char16_t.
  583. template<>
  584. struct atomic<char16_t> : __atomic_base<char16_t>
  585. {
  586. typedef char16_t __integral_type;
  587. typedef __atomic_base<char16_t> __base_type;
  588. atomic() noexcept = default;
  589. ~atomic() noexcept = default;
  590. atomic(const atomic&) = delete;
  591. atomic& operator=(const atomic&) = delete;
  592. atomic& operator=(const atomic&) volatile = delete;
  593. constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
  594. using __base_type::operator __integral_type;
  595. using __base_type::operator=;
  596. };
  597. /// Explicit specialization for char32_t.
  598. template<>
  599. struct atomic<char32_t> : __atomic_base<char32_t>
  600. {
  601. typedef char32_t __integral_type;
  602. typedef __atomic_base<char32_t> __base_type;
  603. atomic() noexcept = default;
  604. ~atomic() noexcept = default;
  605. atomic(const atomic&) = delete;
  606. atomic& operator=(const atomic&) = delete;
  607. atomic& operator=(const atomic&) volatile = delete;
  608. constexpr atomic(__integral_type __i) noexcept : __base_type(__i) { }
  609. using __base_type::operator __integral_type;
  610. using __base_type::operator=;
  611. };
  612. /// atomic_bool
  613. typedef atomic<bool> atomic_bool;
  614. /// atomic_char
  615. typedef atomic<char> atomic_char;
  616. /// atomic_schar
  617. typedef atomic<signed char> atomic_schar;
  618. /// atomic_uchar
  619. typedef atomic<unsigned char> atomic_uchar;
  620. /// atomic_short
  621. typedef atomic<short> atomic_short;
  622. /// atomic_ushort
  623. typedef atomic<unsigned short> atomic_ushort;
  624. /// atomic_int
  625. typedef atomic<int> atomic_int;
  626. /// atomic_uint
  627. typedef atomic<unsigned int> atomic_uint;
  628. /// atomic_long
  629. typedef atomic<long> atomic_long;
  630. /// atomic_ulong
  631. typedef atomic<unsigned long> atomic_ulong;
  632. /// atomic_llong
  633. typedef atomic<long long> atomic_llong;
  634. /// atomic_ullong
  635. typedef atomic<unsigned long long> atomic_ullong;
  636. /// atomic_wchar_t
  637. typedef atomic<wchar_t> atomic_wchar_t;
  638. /// atomic_char16_t
  639. typedef atomic<char16_t> atomic_char16_t;
  640. /// atomic_char32_t
  641. typedef atomic<char32_t> atomic_char32_t;
  642. /// atomic_int_least8_t
  643. typedef atomic<int_least8_t> atomic_int_least8_t;
  644. /// atomic_uint_least8_t
  645. typedef atomic<uint_least8_t> atomic_uint_least8_t;
  646. /// atomic_int_least16_t
  647. typedef atomic<int_least16_t> atomic_int_least16_t;
  648. /// atomic_uint_least16_t
  649. typedef atomic<uint_least16_t> atomic_uint_least16_t;
  650. /// atomic_int_least32_t
  651. typedef atomic<int_least32_t> atomic_int_least32_t;
  652. /// atomic_uint_least32_t
  653. typedef atomic<uint_least32_t> atomic_uint_least32_t;
  654. /// atomic_int_least64_t
  655. typedef atomic<int_least64_t> atomic_int_least64_t;
  656. /// atomic_uint_least64_t
  657. typedef atomic<uint_least64_t> atomic_uint_least64_t;
  658. /// atomic_int_fast8_t
  659. typedef atomic<int_fast8_t> atomic_int_fast8_t;
  660. /// atomic_uint_fast8_t
  661. typedef atomic<uint_fast8_t> atomic_uint_fast8_t;
  662. /// atomic_int_fast16_t
  663. typedef atomic<int_fast16_t> atomic_int_fast16_t;
  664. /// atomic_uint_fast16_t
  665. typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
  666. /// atomic_int_fast32_t
  667. typedef atomic<int_fast32_t> atomic_int_fast32_t;
  668. /// atomic_uint_fast32_t
  669. typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
  670. /// atomic_int_fast64_t
  671. typedef atomic<int_fast64_t> atomic_int_fast64_t;
  672. /// atomic_uint_fast64_t
  673. typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
  674. /// atomic_intptr_t
  675. typedef atomic<intptr_t> atomic_intptr_t;
  676. /// atomic_uintptr_t
  677. typedef atomic<uintptr_t> atomic_uintptr_t;
  678. /// atomic_size_t
  679. typedef atomic<size_t> atomic_size_t;
  680. /// atomic_intmax_t
  681. typedef atomic<intmax_t> atomic_intmax_t;
  682. /// atomic_uintmax_t
  683. typedef atomic<uintmax_t> atomic_uintmax_t;
  684. /// atomic_ptrdiff_t
  685. typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
  686. // Function definitions, atomic_flag operations.
  687. inline bool
  688. atomic_flag_test_and_set_explicit(atomic_flag* __a,
  689. memory_order __m) noexcept
  690. { return __a->test_and_set(__m); }
  691. inline bool
  692. atomic_flag_test_and_set_explicit(volatile atomic_flag* __a,
  693. memory_order __m) noexcept
  694. { return __a->test_and_set(__m); }
  695. inline void
  696. atomic_flag_clear_explicit(atomic_flag* __a, memory_order __m) noexcept
  697. { __a->clear(__m); }
  698. inline void
  699. atomic_flag_clear_explicit(volatile atomic_flag* __a,
  700. memory_order __m) noexcept
  701. { __a->clear(__m); }
  702. inline bool
  703. atomic_flag_test_and_set(atomic_flag* __a) noexcept
  704. { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
  705. inline bool
  706. atomic_flag_test_and_set(volatile atomic_flag* __a) noexcept
  707. { return atomic_flag_test_and_set_explicit(__a, memory_order_seq_cst); }
  708. inline void
  709. atomic_flag_clear(atomic_flag* __a) noexcept
  710. { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
  711. inline void
  712. atomic_flag_clear(volatile atomic_flag* __a) noexcept
  713. { atomic_flag_clear_explicit(__a, memory_order_seq_cst); }
  714. // Function templates generally applicable to atomic types.
  715. template<typename _ITp>
  716. inline bool
  717. atomic_is_lock_free(const atomic<_ITp>* __a) noexcept
  718. { return __a->is_lock_free(); }
  719. template<typename _ITp>
  720. inline bool
  721. atomic_is_lock_free(const volatile atomic<_ITp>* __a) noexcept
  722. { return __a->is_lock_free(); }
  723. template<typename _ITp>
  724. inline void
  725. atomic_init(atomic<_ITp>* __a, _ITp __i) noexcept
  726. { __a->store(__i, memory_order_relaxed); }
  727. template<typename _ITp>
  728. inline void
  729. atomic_init(volatile atomic<_ITp>* __a, _ITp __i) noexcept
  730. { __a->store(__i, memory_order_relaxed); }
  731. template<typename _ITp>
  732. inline void
  733. atomic_store_explicit(atomic<_ITp>* __a, _ITp __i,
  734. memory_order __m) noexcept
  735. { __a->store(__i, __m); }
  736. template<typename _ITp>
  737. inline void
  738. atomic_store_explicit(volatile atomic<_ITp>* __a, _ITp __i,
  739. memory_order __m) noexcept
  740. { __a->store(__i, __m); }
  741. template<typename _ITp>
  742. inline _ITp
  743. atomic_load_explicit(const atomic<_ITp>* __a, memory_order __m) noexcept
  744. { return __a->load(__m); }
  745. template<typename _ITp>
  746. inline _ITp
  747. atomic_load_explicit(const volatile atomic<_ITp>* __a,
  748. memory_order __m) noexcept
  749. { return __a->load(__m); }
  750. template<typename _ITp>
  751. inline _ITp
  752. atomic_exchange_explicit(atomic<_ITp>* __a, _ITp __i,
  753. memory_order __m) noexcept
  754. { return __a->exchange(__i, __m); }
  755. template<typename _ITp>
  756. inline _ITp
  757. atomic_exchange_explicit(volatile atomic<_ITp>* __a, _ITp __i,
  758. memory_order __m) noexcept
  759. { return __a->exchange(__i, __m); }
  760. template<typename _ITp>
  761. inline bool
  762. atomic_compare_exchange_weak_explicit(atomic<_ITp>* __a,
  763. _ITp* __i1, _ITp __i2,
  764. memory_order __m1,
  765. memory_order __m2) noexcept
  766. { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
  767. template<typename _ITp>
  768. inline bool
  769. atomic_compare_exchange_weak_explicit(volatile atomic<_ITp>* __a,
  770. _ITp* __i1, _ITp __i2,
  771. memory_order __m1,
  772. memory_order __m2) noexcept
  773. { return __a->compare_exchange_weak(*__i1, __i2, __m1, __m2); }
  774. template<typename _ITp>
  775. inline bool
  776. atomic_compare_exchange_strong_explicit(atomic<_ITp>* __a,
  777. _ITp* __i1, _ITp __i2,
  778. memory_order __m1,
  779. memory_order __m2) noexcept
  780. { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
  781. template<typename _ITp>
  782. inline bool
  783. atomic_compare_exchange_strong_explicit(volatile atomic<_ITp>* __a,
  784. _ITp* __i1, _ITp __i2,
  785. memory_order __m1,
  786. memory_order __m2) noexcept
  787. { return __a->compare_exchange_strong(*__i1, __i2, __m1, __m2); }
  788. template<typename _ITp>
  789. inline void
  790. atomic_store(atomic<_ITp>* __a, _ITp __i) noexcept
  791. { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
  792. template<typename _ITp>
  793. inline void
  794. atomic_store(volatile atomic<_ITp>* __a, _ITp __i) noexcept
  795. { atomic_store_explicit(__a, __i, memory_order_seq_cst); }
  796. template<typename _ITp>
  797. inline _ITp
  798. atomic_load(const atomic<_ITp>* __a) noexcept
  799. { return atomic_load_explicit(__a, memory_order_seq_cst); }
  800. template<typename _ITp>
  801. inline _ITp
  802. atomic_load(const volatile atomic<_ITp>* __a) noexcept
  803. { return atomic_load_explicit(__a, memory_order_seq_cst); }
  804. template<typename _ITp>
  805. inline _ITp
  806. atomic_exchange(atomic<_ITp>* __a, _ITp __i) noexcept
  807. { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
  808. template<typename _ITp>
  809. inline _ITp
  810. atomic_exchange(volatile atomic<_ITp>* __a, _ITp __i) noexcept
  811. { return atomic_exchange_explicit(__a, __i, memory_order_seq_cst); }
  812. template<typename _ITp>
  813. inline bool
  814. atomic_compare_exchange_weak(atomic<_ITp>* __a,
  815. _ITp* __i1, _ITp __i2) noexcept
  816. {
  817. return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
  818. memory_order_seq_cst,
  819. memory_order_seq_cst);
  820. }
  821. template<typename _ITp>
  822. inline bool
  823. atomic_compare_exchange_weak(volatile atomic<_ITp>* __a,
  824. _ITp* __i1, _ITp __i2) noexcept
  825. {
  826. return atomic_compare_exchange_weak_explicit(__a, __i1, __i2,
  827. memory_order_seq_cst,
  828. memory_order_seq_cst);
  829. }
  830. template<typename _ITp>
  831. inline bool
  832. atomic_compare_exchange_strong(atomic<_ITp>* __a,
  833. _ITp* __i1, _ITp __i2) noexcept
  834. {
  835. return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
  836. memory_order_seq_cst,
  837. memory_order_seq_cst);
  838. }
  839. template<typename _ITp>
  840. inline bool
  841. atomic_compare_exchange_strong(volatile atomic<_ITp>* __a,
  842. _ITp* __i1, _ITp __i2) noexcept
  843. {
  844. return atomic_compare_exchange_strong_explicit(__a, __i1, __i2,
  845. memory_order_seq_cst,
  846. memory_order_seq_cst);
  847. }
  848. // Function templates for atomic_integral operations only, using
  849. // __atomic_base. Template argument should be constricted to
  850. // intergral types as specified in the standard, excluding address
  851. // types.
  852. template<typename _ITp>
  853. inline _ITp
  854. atomic_fetch_add_explicit(__atomic_base<_ITp>* __a, _ITp __i,
  855. memory_order __m) noexcept
  856. { return __a->fetch_add(__i, __m); }
  857. template<typename _ITp>
  858. inline _ITp
  859. atomic_fetch_add_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
  860. memory_order __m) noexcept
  861. { return __a->fetch_add(__i, __m); }
  862. template<typename _ITp>
  863. inline _ITp
  864. atomic_fetch_sub_explicit(__atomic_base<_ITp>* __a, _ITp __i,
  865. memory_order __m) noexcept
  866. { return __a->fetch_sub(__i, __m); }
  867. template<typename _ITp>
  868. inline _ITp
  869. atomic_fetch_sub_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
  870. memory_order __m) noexcept
  871. { return __a->fetch_sub(__i, __m); }
  872. template<typename _ITp>
  873. inline _ITp
  874. atomic_fetch_and_explicit(__atomic_base<_ITp>* __a, _ITp __i,
  875. memory_order __m) noexcept
  876. { return __a->fetch_and(__i, __m); }
  877. template<typename _ITp>
  878. inline _ITp
  879. atomic_fetch_and_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
  880. memory_order __m) noexcept
  881. { return __a->fetch_and(__i, __m); }
  882. template<typename _ITp>
  883. inline _ITp
  884. atomic_fetch_or_explicit(__atomic_base<_ITp>* __a, _ITp __i,
  885. memory_order __m) noexcept
  886. { return __a->fetch_or(__i, __m); }
  887. template<typename _ITp>
  888. inline _ITp
  889. atomic_fetch_or_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
  890. memory_order __m) noexcept
  891. { return __a->fetch_or(__i, __m); }
  892. template<typename _ITp>
  893. inline _ITp
  894. atomic_fetch_xor_explicit(__atomic_base<_ITp>* __a, _ITp __i,
  895. memory_order __m) noexcept
  896. { return __a->fetch_xor(__i, __m); }
  897. template<typename _ITp>
  898. inline _ITp
  899. atomic_fetch_xor_explicit(volatile __atomic_base<_ITp>* __a, _ITp __i,
  900. memory_order __m) noexcept
  901. { return __a->fetch_xor(__i, __m); }
  902. template<typename _ITp>
  903. inline _ITp
  904. atomic_fetch_add(__atomic_base<_ITp>* __a, _ITp __i) noexcept
  905. { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
  906. template<typename _ITp>
  907. inline _ITp
  908. atomic_fetch_add(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
  909. { return atomic_fetch_add_explicit(__a, __i, memory_order_seq_cst); }
  910. template<typename _ITp>
  911. inline _ITp
  912. atomic_fetch_sub(__atomic_base<_ITp>* __a, _ITp __i) noexcept
  913. { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
  914. template<typename _ITp>
  915. inline _ITp
  916. atomic_fetch_sub(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
  917. { return atomic_fetch_sub_explicit(__a, __i, memory_order_seq_cst); }
  918. template<typename _ITp>
  919. inline _ITp
  920. atomic_fetch_and(__atomic_base<_ITp>* __a, _ITp __i) noexcept
  921. { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
  922. template<typename _ITp>
  923. inline _ITp
  924. atomic_fetch_and(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
  925. { return atomic_fetch_and_explicit(__a, __i, memory_order_seq_cst); }
  926. template<typename _ITp>
  927. inline _ITp
  928. atomic_fetch_or(__atomic_base<_ITp>* __a, _ITp __i) noexcept
  929. { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
  930. template<typename _ITp>
  931. inline _ITp
  932. atomic_fetch_or(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
  933. { return atomic_fetch_or_explicit(__a, __i, memory_order_seq_cst); }
  934. template<typename _ITp>
  935. inline _ITp
  936. atomic_fetch_xor(__atomic_base<_ITp>* __a, _ITp __i) noexcept
  937. { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
  938. template<typename _ITp>
  939. inline _ITp
  940. atomic_fetch_xor(volatile __atomic_base<_ITp>* __a, _ITp __i) noexcept
  941. { return atomic_fetch_xor_explicit(__a, __i, memory_order_seq_cst); }
  942. // Partial specializations for pointers.
  943. template<typename _ITp>
  944. inline _ITp*
  945. atomic_fetch_add_explicit(atomic<_ITp*>* __a, ptrdiff_t __d,
  946. memory_order __m) noexcept
  947. { return __a->fetch_add(__d, __m); }
  948. template<typename _ITp>
  949. inline _ITp*
  950. atomic_fetch_add_explicit(volatile atomic<_ITp*>* __a, ptrdiff_t __d,
  951. memory_order __m) noexcept
  952. { return __a->fetch_add(__d, __m); }
  953. template<typename _ITp>
  954. inline _ITp*
  955. atomic_fetch_add(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
  956. { return __a->fetch_add(__d); }
  957. template<typename _ITp>
  958. inline _ITp*
  959. atomic_fetch_add(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
  960. { return __a->fetch_add(__d); }
  961. template<typename _ITp>
  962. inline _ITp*
  963. atomic_fetch_sub_explicit(volatile atomic<_ITp*>* __a,
  964. ptrdiff_t __d, memory_order __m) noexcept
  965. { return __a->fetch_sub(__d, __m); }
  966. template<typename _ITp>
  967. inline _ITp*
  968. atomic_fetch_sub_explicit(atomic<_ITp*>* __a, ptrdiff_t __d,
  969. memory_order __m) noexcept
  970. { return __a->fetch_sub(__d, __m); }
  971. template<typename _ITp>
  972. inline _ITp*
  973. atomic_fetch_sub(volatile atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
  974. { return __a->fetch_sub(__d); }
  975. template<typename _ITp>
  976. inline _ITp*
  977. atomic_fetch_sub(atomic<_ITp*>* __a, ptrdiff_t __d) noexcept
  978. { return __a->fetch_sub(__d); }
  979. // @} group atomics
  980. _GLIBCXX_END_NAMESPACE_VERSION
  981. } // namespace
  982. #endif // C++11
  983. #endif // _GLIBCXX_ATOMIC