cas32weak.hpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017
  1. #ifndef BOOST_ATOMIC_DETAIL_CAS32WEAK_HPP
  2. #define BOOST_ATOMIC_DETAIL_CAS32WEAK_HPP
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // See accompanying file LICENSE_1_0.txt or copy at
  5. // http://www.boost.org/LICENSE_1_0.txt)
  6. //
  7. // Copyright (c) 2011 Helge Bahmann
  8. // Copyright (c) 2013 Tim Blechmann
  9. #include <string.h>
  10. #include <cstddef>
  11. #include <boost/cstdint.hpp>
  12. #include <boost/memory_order.hpp>
  13. #include <boost/atomic/detail/config.hpp>
  14. #include <boost/atomic/detail/base.hpp>
  15. #ifdef BOOST_HAS_PRAGMA_ONCE
  16. #pragma once
  17. #endif
  18. namespace boost {
  19. namespace atomics {
  20. namespace detail {
  21. /* integral types */
  22. template<typename T, bool Sign>
  23. class base_atomic<T, int, 1, Sign>
  24. {
  25. private:
  26. typedef base_atomic this_type;
  27. typedef T value_type;
  28. typedef T difference_type;
  29. typedef uint32_t storage_type;
  30. protected:
  31. typedef value_type value_arg_type;
  32. public:
  33. BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
  34. BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
  35. void
  36. store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  37. {
  38. platform_fence_before_store(order);
  39. const_cast<volatile storage_type &>(v_) = v;
  40. platform_fence_after_store(order);
  41. }
  42. value_type
  43. load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
  44. {
  45. value_type v = const_cast<const volatile storage_type &>(v_);
  46. platform_fence_after_load(order);
  47. return v;
  48. }
  49. value_type
  50. exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  51. {
  52. value_type original = load(memory_order_relaxed);
  53. do {
  54. } while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
  55. return original;
  56. }
  57. bool
  58. compare_exchange_weak(
  59. value_type & expected,
  60. value_type desired,
  61. memory_order success_order,
  62. memory_order failure_order) volatile BOOST_NOEXCEPT
  63. {
  64. platform_fence_before(success_order);
  65. storage_type expected_s = (storage_type) expected;
  66. storage_type desired_s = (storage_type) desired;
  67. bool success = platform_cmpxchg32(expected_s, desired_s, &v_);
  68. if (success) {
  69. platform_fence_after(success_order);
  70. } else {
  71. platform_fence_after(failure_order);
  72. expected = (value_type) expected_s;
  73. }
  74. return success;
  75. }
  76. bool
  77. compare_exchange_strong(
  78. value_type & expected,
  79. value_type desired,
  80. memory_order success_order,
  81. memory_order failure_order) volatile BOOST_NOEXCEPT
  82. {
  83. while (true)
  84. {
  85. value_type tmp = expected;
  86. if (compare_exchange_weak(tmp, desired, success_order, failure_order))
  87. return true;
  88. if (tmp != expected)
  89. {
  90. expected = tmp;
  91. return false;
  92. }
  93. }
  94. }
  95. value_type
  96. fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  97. {
  98. value_type original = load(memory_order_relaxed);
  99. do {
  100. } while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed));
  101. return original;
  102. }
  103. value_type
  104. fetch_sub(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  105. {
  106. value_type original = load(memory_order_relaxed);
  107. do {
  108. } while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed));
  109. return original;
  110. }
  111. value_type
  112. fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  113. {
  114. value_type original = load(memory_order_relaxed);
  115. do {
  116. } while (!compare_exchange_weak(original, original & v, order, memory_order_relaxed));
  117. return original;
  118. }
  119. value_type
  120. fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  121. {
  122. value_type original = load(memory_order_relaxed);
  123. do {
  124. } while (!compare_exchange_weak(original, original | v, order, memory_order_relaxed));
  125. return original;
  126. }
  127. value_type
  128. fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  129. {
  130. value_type original = load(memory_order_relaxed);
  131. do {
  132. } while (!compare_exchange_weak(original, original ^ v, order, memory_order_relaxed));
  133. return original;
  134. }
  135. bool
  136. is_lock_free(void) const volatile BOOST_NOEXCEPT
  137. {
  138. return true;
  139. }
  140. BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
  141. BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
  142. BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
  143. private:
  144. storage_type v_;
  145. };
  146. template<typename T, bool Sign>
  147. class base_atomic<T, int, 2, Sign>
  148. {
  149. private:
  150. typedef base_atomic this_type;
  151. typedef T value_type;
  152. typedef T difference_type;
  153. typedef uint32_t storage_type;
  154. protected:
  155. typedef value_type value_arg_type;
  156. public:
  157. BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
  158. BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
  159. void
  160. store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  161. {
  162. platform_fence_before_store(order);
  163. const_cast<volatile storage_type &>(v_) = v;
  164. platform_fence_after_store(order);
  165. }
  166. value_type
  167. load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
  168. {
  169. value_type v = const_cast<const volatile storage_type &>(v_);
  170. platform_fence_after_load(order);
  171. return v;
  172. }
  173. value_type
  174. exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  175. {
  176. value_type original = load(memory_order_relaxed);
  177. do {
  178. } while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
  179. return original;
  180. }
  181. bool
  182. compare_exchange_weak(
  183. value_type & expected,
  184. value_type desired,
  185. memory_order success_order,
  186. memory_order failure_order) volatile BOOST_NOEXCEPT
  187. {
  188. platform_fence_before(success_order);
  189. storage_type expected_s = (storage_type) expected;
  190. storage_type desired_s = (storage_type) desired;
  191. bool success = platform_cmpxchg32(expected_s, desired_s, &v_);
  192. if (success) {
  193. platform_fence_after(success_order);
  194. } else {
  195. platform_fence_after(failure_order);
  196. expected = (value_type) expected_s;
  197. }
  198. return success;
  199. }
  200. bool
  201. compare_exchange_strong(
  202. value_type & expected,
  203. value_type desired,
  204. memory_order success_order,
  205. memory_order failure_order) volatile BOOST_NOEXCEPT
  206. {
  207. while (true)
  208. {
  209. value_type tmp = expected;
  210. if (compare_exchange_weak(tmp, desired, success_order, failure_order))
  211. return true;
  212. if (tmp != expected)
  213. {
  214. expected = tmp;
  215. return false;
  216. }
  217. }
  218. }
  219. value_type
  220. fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  221. {
  222. value_type original = load(memory_order_relaxed);
  223. do {
  224. } while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed));
  225. return original;
  226. }
  227. value_type
  228. fetch_sub(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  229. {
  230. value_type original = load(memory_order_relaxed);
  231. do {
  232. } while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed));
  233. return original;
  234. }
  235. value_type
  236. fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  237. {
  238. value_type original = load(memory_order_relaxed);
  239. do {
  240. } while (!compare_exchange_weak(original, original & v, order, memory_order_relaxed));
  241. return original;
  242. }
  243. value_type
  244. fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  245. {
  246. value_type original = load(memory_order_relaxed);
  247. do {
  248. } while (!compare_exchange_weak(original, original | v, order, memory_order_relaxed));
  249. return original;
  250. }
  251. value_type
  252. fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  253. {
  254. value_type original = load(memory_order_relaxed);
  255. do {
  256. } while (!compare_exchange_weak(original, original ^ v, order, memory_order_relaxed));
  257. return original;
  258. }
  259. bool
  260. is_lock_free(void) const volatile BOOST_NOEXCEPT
  261. {
  262. return true;
  263. }
  264. BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
  265. BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
  266. BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
  267. private:
  268. storage_type v_;
  269. };
  270. template<typename T, bool Sign>
  271. class base_atomic<T, int, 4, Sign>
  272. {
  273. private:
  274. typedef base_atomic this_type;
  275. typedef T value_type;
  276. typedef T difference_type;
  277. protected:
  278. typedef value_type value_arg_type;
  279. public:
  280. BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
  281. BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
  282. void
  283. store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  284. {
  285. platform_fence_before_store(order);
  286. const_cast<volatile value_type &>(v_) = v;
  287. platform_fence_after_store(order);
  288. }
  289. value_type
  290. load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
  291. {
  292. value_type v = const_cast<const volatile value_type &>(v_);
  293. platform_fence_after_load(order);
  294. return v;
  295. }
  296. value_type
  297. exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  298. {
  299. value_type original = load(memory_order_relaxed);
  300. do {
  301. } while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
  302. return original;
  303. }
  304. bool
  305. compare_exchange_weak(
  306. value_type & expected,
  307. value_type desired,
  308. memory_order success_order,
  309. memory_order failure_order) volatile BOOST_NOEXCEPT
  310. {
  311. platform_fence_before(success_order);
  312. bool success = platform_cmpxchg32(expected, desired, &v_);
  313. if (success) {
  314. platform_fence_after(success_order);
  315. } else {
  316. platform_fence_after(failure_order);
  317. }
  318. return success;
  319. }
  320. bool
  321. compare_exchange_strong(
  322. value_type & expected,
  323. value_type desired,
  324. memory_order success_order,
  325. memory_order failure_order) volatile BOOST_NOEXCEPT
  326. {
  327. while (true)
  328. {
  329. value_type tmp = expected;
  330. if (compare_exchange_weak(tmp, desired, success_order, failure_order))
  331. return true;
  332. if (tmp != expected)
  333. {
  334. expected = tmp;
  335. return false;
  336. }
  337. }
  338. }
  339. value_type
  340. fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  341. {
  342. value_type original = load(memory_order_relaxed);
  343. do {
  344. } while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed));
  345. return original;
  346. }
  347. value_type
  348. fetch_sub(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  349. {
  350. value_type original = load(memory_order_relaxed);
  351. do {
  352. } while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed));
  353. return original;
  354. }
  355. value_type
  356. fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  357. {
  358. value_type original = load(memory_order_relaxed);
  359. do {
  360. } while (!compare_exchange_weak(original, original & v, order, memory_order_relaxed));
  361. return original;
  362. }
  363. value_type
  364. fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  365. {
  366. value_type original = load(memory_order_relaxed);
  367. do {
  368. } while (!compare_exchange_weak(original, original | v, order, memory_order_relaxed));
  369. return original;
  370. }
  371. value_type
  372. fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  373. {
  374. value_type original = load(memory_order_relaxed);
  375. do {
  376. } while (!compare_exchange_weak(original, original ^ v, order, memory_order_relaxed));
  377. return original;
  378. }
  379. bool
  380. is_lock_free(void) const volatile BOOST_NOEXCEPT
  381. {
  382. return true;
  383. }
  384. BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
  385. BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
  386. BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
  387. private:
  388. value_type v_;
  389. };
  390. /* pointer types */
  391. template<bool Sign>
  392. class base_atomic<void *, void *, 4, Sign>
  393. {
  394. private:
  395. typedef base_atomic this_type;
  396. typedef void * value_type;
  397. typedef std::ptrdiff_t difference_type;
  398. protected:
  399. typedef value_type value_arg_type;
  400. public:
  401. BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
  402. BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
  403. void
  404. store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  405. {
  406. platform_fence_before_store(order);
  407. const_cast<volatile value_type &>(v_) = v;
  408. platform_fence_after_store(order);
  409. }
  410. value_type
  411. load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
  412. {
  413. value_type v = const_cast<const volatile value_type &>(v_);
  414. platform_fence_after_load(order);
  415. return v;
  416. }
  417. value_type
  418. exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  419. {
  420. value_type original = load(memory_order_relaxed);
  421. do {
  422. } while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
  423. return original;
  424. }
  425. bool
  426. compare_exchange_weak(
  427. value_type & expected,
  428. value_type desired,
  429. memory_order success_order,
  430. memory_order failure_order) volatile BOOST_NOEXCEPT
  431. {
  432. platform_fence_before(success_order);
  433. bool success = platform_cmpxchg32(expected, desired, &v_);
  434. if (success) {
  435. platform_fence_after(success_order);
  436. } else {
  437. platform_fence_after(failure_order);
  438. }
  439. return success;
  440. }
  441. bool
  442. compare_exchange_strong(
  443. value_type & expected,
  444. value_type desired,
  445. memory_order success_order,
  446. memory_order failure_order) volatile BOOST_NOEXCEPT
  447. {
  448. while (true)
  449. {
  450. value_type tmp = expected;
  451. if (compare_exchange_weak(tmp, desired, success_order, failure_order))
  452. return true;
  453. if (tmp != expected)
  454. {
  455. expected = tmp;
  456. return false;
  457. }
  458. }
  459. }
  460. bool
  461. is_lock_free(void) const volatile BOOST_NOEXCEPT
  462. {
  463. return true;
  464. }
  465. value_type
  466. fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  467. {
  468. value_type original = load(memory_order_relaxed);
  469. do {
  470. } while (!compare_exchange_weak(original, (char*)original + v, order, memory_order_relaxed));
  471. return original;
  472. }
  473. value_type
  474. fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  475. {
  476. value_type original = load(memory_order_relaxed);
  477. do {
  478. } while (!compare_exchange_weak(original, (char*)original - v, order, memory_order_relaxed));
  479. return original;
  480. }
  481. BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS
  482. BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
  483. BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
  484. private:
  485. value_type v_;
  486. };
  487. template<typename T, bool Sign>
  488. class base_atomic<T *, void *, 4, Sign>
  489. {
  490. private:
  491. typedef base_atomic this_type;
  492. typedef T * value_type;
  493. typedef std::ptrdiff_t difference_type;
  494. protected:
  495. typedef value_type value_arg_type;
  496. public:
  497. BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
  498. BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
  499. void
  500. store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  501. {
  502. platform_fence_before_store(order);
  503. const_cast<volatile value_type &>(v_) = v;
  504. platform_fence_after_store(order);
  505. }
  506. value_type
  507. load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
  508. {
  509. value_type v = const_cast<const volatile value_type &>(v_);
  510. platform_fence_after_load(order);
  511. return v;
  512. }
  513. value_type
  514. exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  515. {
  516. value_type original = load(memory_order_relaxed);
  517. do {
  518. } while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
  519. return original;
  520. }
  521. bool
  522. compare_exchange_weak(
  523. value_type & expected,
  524. value_type desired,
  525. memory_order success_order,
  526. memory_order failure_order) volatile BOOST_NOEXCEPT
  527. {
  528. platform_fence_before(success_order);
  529. bool success = platform_cmpxchg32(expected, desired, &v_);
  530. if (success) {
  531. platform_fence_after(success_order);
  532. } else {
  533. platform_fence_after(failure_order);
  534. }
  535. return success;
  536. }
  537. bool
  538. compare_exchange_strong(
  539. value_type & expected,
  540. value_type desired,
  541. memory_order success_order,
  542. memory_order failure_order) volatile BOOST_NOEXCEPT
  543. {
  544. while (true)
  545. {
  546. value_type tmp = expected;
  547. if (compare_exchange_weak(tmp, desired, success_order, failure_order))
  548. return true;
  549. if (tmp != expected)
  550. {
  551. expected = tmp;
  552. return false;
  553. }
  554. }
  555. }
  556. value_type
  557. fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  558. {
  559. value_type original = load(memory_order_relaxed);
  560. do {
  561. } while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed));
  562. return original;
  563. }
  564. value_type
  565. fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  566. {
  567. value_type original = load(memory_order_relaxed);
  568. do {
  569. } while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed));
  570. return original;
  571. }
  572. bool
  573. is_lock_free(void) const volatile BOOST_NOEXCEPT
  574. {
  575. return true;
  576. }
  577. BOOST_ATOMIC_DECLARE_POINTER_OPERATORS
  578. BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
  579. BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
  580. private:
  581. value_type v_;
  582. };
  583. /* generic types */
  584. template<typename T, bool Sign>
  585. class base_atomic<T, void, 1, Sign>
  586. {
  587. private:
  588. typedef base_atomic this_type;
  589. typedef T value_type;
  590. typedef uint32_t storage_type;
  591. protected:
  592. typedef value_type const& value_arg_type;
  593. public:
  594. BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
  595. explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
  596. {
  597. memcpy(&v_, &v, sizeof(value_type));
  598. }
  599. void
  600. store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  601. {
  602. storage_type tmp = 0;
  603. memcpy(&tmp, &v, sizeof(value_type));
  604. platform_fence_before_store(order);
  605. const_cast<volatile storage_type &>(v_) = tmp;
  606. platform_fence_after_store(order);
  607. }
  608. value_type
  609. load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
  610. {
  611. storage_type tmp = const_cast<const volatile storage_type &>(v_);
  612. platform_fence_after_load(order);
  613. value_type v;
  614. memcpy(&v, &tmp, sizeof(value_type));
  615. return v;
  616. }
  617. value_type
  618. exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  619. {
  620. value_type original = load(memory_order_relaxed);
  621. do {
  622. } while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
  623. return original;
  624. }
  625. bool
  626. compare_exchange_weak(
  627. value_type & expected,
  628. value_type const& desired,
  629. memory_order success_order,
  630. memory_order failure_order) volatile BOOST_NOEXCEPT
  631. {
  632. storage_type expected_s = 0, desired_s = 0;
  633. memcpy(&expected_s, &expected, sizeof(value_type));
  634. memcpy(&desired_s, &desired, sizeof(value_type));
  635. platform_fence_before(success_order);
  636. bool success = platform_cmpxchg32(expected_s, desired_s, &v_);
  637. if (success) {
  638. platform_fence_after(success_order);
  639. } else {
  640. platform_fence_after(failure_order);
  641. memcpy(&expected, &expected_s, sizeof(value_type));
  642. }
  643. return success;
  644. }
  645. bool
  646. compare_exchange_strong(
  647. value_type & expected,
  648. value_type const& desired,
  649. memory_order success_order,
  650. memory_order failure_order) volatile BOOST_NOEXCEPT
  651. {
  652. while (true)
  653. {
  654. value_type tmp = expected;
  655. if (compare_exchange_weak(tmp, desired, success_order, failure_order))
  656. return true;
  657. if (tmp != expected)
  658. {
  659. expected = tmp;
  660. return false;
  661. }
  662. }
  663. }
  664. bool
  665. is_lock_free(void) const volatile BOOST_NOEXCEPT
  666. {
  667. return true;
  668. }
  669. BOOST_ATOMIC_DECLARE_BASE_OPERATORS
  670. BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
  671. BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
  672. private:
  673. storage_type v_;
  674. };
  675. template<typename T, bool Sign>
  676. class base_atomic<T, void, 2, Sign>
  677. {
  678. private:
  679. typedef base_atomic this_type;
  680. typedef T value_type;
  681. typedef uint32_t storage_type;
  682. protected:
  683. typedef value_type const& value_arg_type;
  684. public:
  685. BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
  686. explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
  687. {
  688. memcpy(&v_, &v, sizeof(value_type));
  689. }
  690. void
  691. store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  692. {
  693. storage_type tmp = 0;
  694. memcpy(&tmp, &v, sizeof(value_type));
  695. platform_fence_before_store(order);
  696. const_cast<volatile storage_type &>(v_) = tmp;
  697. platform_fence_after_store(order);
  698. }
  699. value_type
  700. load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
  701. {
  702. storage_type tmp = const_cast<const volatile storage_type &>(v_);
  703. platform_fence_after_load(order);
  704. value_type v;
  705. memcpy(&v, &tmp, sizeof(value_type));
  706. return v;
  707. }
  708. value_type
  709. exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  710. {
  711. value_type original = load(memory_order_relaxed);
  712. do {
  713. } while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
  714. return original;
  715. }
  716. bool
  717. compare_exchange_weak(
  718. value_type & expected,
  719. value_type const& desired,
  720. memory_order success_order,
  721. memory_order failure_order) volatile BOOST_NOEXCEPT
  722. {
  723. storage_type expected_s = 0, desired_s = 0;
  724. memcpy(&expected_s, &expected, sizeof(value_type));
  725. memcpy(&desired_s, &desired, sizeof(value_type));
  726. platform_fence_before(success_order);
  727. bool success = platform_cmpxchg32(expected_s, desired_s, &v_);
  728. if (success) {
  729. platform_fence_after(success_order);
  730. } else {
  731. platform_fence_after(failure_order);
  732. memcpy(&expected, &expected_s, sizeof(value_type));
  733. }
  734. return success;
  735. }
  736. bool
  737. compare_exchange_strong(
  738. value_type & expected,
  739. value_type const& desired,
  740. memory_order success_order,
  741. memory_order failure_order) volatile BOOST_NOEXCEPT
  742. {
  743. while (true)
  744. {
  745. value_type tmp = expected;
  746. if (compare_exchange_weak(tmp, desired, success_order, failure_order))
  747. return true;
  748. if (tmp != expected)
  749. {
  750. expected = tmp;
  751. return false;
  752. }
  753. }
  754. }
  755. bool
  756. is_lock_free(void) const volatile BOOST_NOEXCEPT
  757. {
  758. return true;
  759. }
  760. BOOST_ATOMIC_DECLARE_BASE_OPERATORS
  761. BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
  762. BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
  763. private:
  764. storage_type v_;
  765. };
  766. template<typename T, bool Sign>
  767. class base_atomic<T, void, 4, Sign>
  768. {
  769. private:
  770. typedef base_atomic this_type;
  771. typedef T value_type;
  772. typedef uint32_t storage_type;
  773. protected:
  774. typedef value_type const& value_arg_type;
  775. public:
  776. BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
  777. explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
  778. {
  779. memcpy(&v_, &v, sizeof(value_type));
  780. }
  781. void
  782. store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  783. {
  784. storage_type tmp = 0;
  785. memcpy(&tmp, &v, sizeof(value_type));
  786. platform_fence_before_store(order);
  787. const_cast<volatile storage_type &>(v_) = tmp;
  788. platform_fence_after_store(order);
  789. }
  790. value_type
  791. load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
  792. {
  793. storage_type tmp = const_cast<const volatile storage_type &>(v_);
  794. platform_fence_after_load(order);
  795. value_type v;
  796. memcpy(&v, &tmp, sizeof(value_type));
  797. return v;
  798. }
  799. value_type
  800. exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  801. {
  802. value_type original = load(memory_order_relaxed);
  803. do {
  804. } while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
  805. return original;
  806. }
  807. bool
  808. compare_exchange_weak(
  809. value_type & expected,
  810. value_type const& desired,
  811. memory_order success_order,
  812. memory_order failure_order) volatile BOOST_NOEXCEPT
  813. {
  814. storage_type expected_s = 0, desired_s = 0;
  815. memcpy(&expected_s, &expected, sizeof(value_type));
  816. memcpy(&desired_s, &desired, sizeof(value_type));
  817. platform_fence_before(success_order);
  818. bool success = platform_cmpxchg32(expected_s, desired_s, &v_);
  819. if (success) {
  820. platform_fence_after(success_order);
  821. } else {
  822. platform_fence_after(failure_order);
  823. memcpy(&expected, &expected_s, sizeof(value_type));
  824. }
  825. return success;
  826. }
  827. bool
  828. compare_exchange_strong(
  829. value_type & expected,
  830. value_type const& desired,
  831. memory_order success_order,
  832. memory_order failure_order) volatile BOOST_NOEXCEPT
  833. {
  834. while (true)
  835. {
  836. value_type tmp = expected;
  837. if (compare_exchange_weak(tmp, desired, success_order, failure_order))
  838. return true;
  839. if (tmp != expected)
  840. {
  841. expected = tmp;
  842. return false;
  843. }
  844. }
  845. }
  846. bool
  847. is_lock_free(void) const volatile BOOST_NOEXCEPT
  848. {
  849. return true;
  850. }
  851. BOOST_ATOMIC_DECLARE_BASE_OPERATORS
  852. BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
  853. BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
  854. private:
  855. storage_type v_;
  856. };
  857. }
  858. }
  859. }
  860. #endif