cas32strong.hpp 26 KB

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