base.hpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605
  1. #ifndef BOOST_ATOMIC_DETAIL_BASE_HPP
  2. #define BOOST_ATOMIC_DETAIL_BASE_HPP
  3. // Copyright (c) 2009 Helge Bahmann
  4. // Copyright (c) 2013 Tim Blechmann
  5. //
  6. // Distributed under the Boost Software License, Version 1.0.
  7. // See accompanying file LICENSE_1_0.txt or copy at
  8. // http://www.boost.org/LICENSE_1_0.txt)
  9. // Base class definition and fallback implementation.
  10. // To be overridden (through partial specialization) by
  11. // platform implementations.
  12. #include <string.h>
  13. #include <cstddef>
  14. #include <boost/cstdint.hpp>
  15. #include <boost/atomic/detail/config.hpp>
  16. #include <boost/atomic/detail/lockpool.hpp>
  17. #ifdef BOOST_HAS_PRAGMA_ONCE
  18. #pragma once
  19. #endif
  20. #define BOOST_ATOMIC_DECLARE_BASE_OPERATORS \
  21. bool \
  22. compare_exchange_strong( \
  23. value_type & expected, \
  24. value_type desired, \
  25. memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT \
  26. { \
  27. return compare_exchange_strong(expected, desired, order, calculate_failure_order(order)); \
  28. } \
  29. \
  30. bool \
  31. compare_exchange_weak( \
  32. value_type & expected, \
  33. value_type desired, \
  34. memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT \
  35. { \
  36. return compare_exchange_weak(expected, desired, order, calculate_failure_order(order)); \
  37. } \
  38. #define BOOST_ATOMIC_DECLARE_ADDITIVE_OPERATORS \
  39. value_type \
  40. operator++(int) volatile BOOST_NOEXCEPT \
  41. { \
  42. return fetch_add(1); \
  43. } \
  44. \
  45. value_type \
  46. operator++(void) volatile BOOST_NOEXCEPT \
  47. { \
  48. return fetch_add(1) + 1; \
  49. } \
  50. \
  51. value_type \
  52. operator--(int) volatile BOOST_NOEXCEPT \
  53. { \
  54. return fetch_sub(1); \
  55. } \
  56. \
  57. value_type \
  58. operator--(void) volatile BOOST_NOEXCEPT \
  59. { \
  60. return fetch_sub(1) - 1; \
  61. } \
  62. \
  63. value_type \
  64. operator+=(difference_type v) volatile BOOST_NOEXCEPT \
  65. { \
  66. return fetch_add(v) + v; \
  67. } \
  68. \
  69. value_type \
  70. operator-=(difference_type v) volatile BOOST_NOEXCEPT \
  71. { \
  72. return fetch_sub(v) - v; \
  73. } \
  74. #define BOOST_ATOMIC_DECLARE_VOID_POINTER_ADDITIVE_OPERATORS \
  75. value_type \
  76. operator++(int) volatile BOOST_NOEXCEPT \
  77. { \
  78. return fetch_add(1); \
  79. } \
  80. \
  81. value_type \
  82. operator++(void) volatile BOOST_NOEXCEPT \
  83. { \
  84. return (char*)fetch_add(1) + 1; \
  85. } \
  86. \
  87. value_type \
  88. operator--(int) volatile BOOST_NOEXCEPT \
  89. { \
  90. return fetch_sub(1); \
  91. } \
  92. \
  93. value_type \
  94. operator--(void) volatile BOOST_NOEXCEPT \
  95. { \
  96. return (char*)fetch_sub(1) - 1; \
  97. } \
  98. \
  99. value_type \
  100. operator+=(difference_type v) volatile BOOST_NOEXCEPT \
  101. { \
  102. return (char*)fetch_add(v) + v; \
  103. } \
  104. \
  105. value_type \
  106. operator-=(difference_type v) volatile BOOST_NOEXCEPT \
  107. { \
  108. return (char*)fetch_sub(v) - v; \
  109. } \
  110. #define BOOST_ATOMIC_DECLARE_BIT_OPERATORS \
  111. value_type \
  112. operator&=(difference_type v) volatile BOOST_NOEXCEPT \
  113. { \
  114. return fetch_and(v) & v; \
  115. } \
  116. \
  117. value_type \
  118. operator|=(difference_type v) volatile BOOST_NOEXCEPT \
  119. { \
  120. return fetch_or(v) | v; \
  121. } \
  122. \
  123. value_type \
  124. operator^=(difference_type v) volatile BOOST_NOEXCEPT\
  125. { \
  126. return fetch_xor(v) ^ v; \
  127. } \
  128. #define BOOST_ATOMIC_DECLARE_POINTER_OPERATORS \
  129. BOOST_ATOMIC_DECLARE_BASE_OPERATORS \
  130. BOOST_ATOMIC_DECLARE_ADDITIVE_OPERATORS \
  131. #define BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS \
  132. BOOST_ATOMIC_DECLARE_BASE_OPERATORS \
  133. BOOST_ATOMIC_DECLARE_VOID_POINTER_ADDITIVE_OPERATORS \
  134. #define BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS \
  135. BOOST_ATOMIC_DECLARE_BASE_OPERATORS \
  136. BOOST_ATOMIC_DECLARE_ADDITIVE_OPERATORS \
  137. BOOST_ATOMIC_DECLARE_BIT_OPERATORS \
  138. namespace boost {
  139. namespace atomics {
  140. namespace detail {
  141. inline memory_order
  142. calculate_failure_order(memory_order order)
  143. {
  144. switch(order)
  145. {
  146. case memory_order_acq_rel:
  147. return memory_order_acquire;
  148. case memory_order_release:
  149. return memory_order_relaxed;
  150. default:
  151. return order;
  152. }
  153. }
  154. template<typename T, typename C, unsigned int Size, bool Sign>
  155. class base_atomic
  156. {
  157. private:
  158. typedef base_atomic this_type;
  159. typedef T value_type;
  160. typedef lockpool::scoped_lock guard_type;
  161. protected:
  162. typedef value_type const& value_arg_type;
  163. public:
  164. BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
  165. BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(v)
  166. {}
  167. void
  168. store(value_type const& v, memory_order /*order*/ = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  169. {
  170. char * storage = storage_ptr();
  171. guard_type guard(storage);
  172. memcpy(storage, &v, sizeof(value_type));
  173. }
  174. value_type
  175. load(memory_order /*order*/ = memory_order_seq_cst) volatile const BOOST_NOEXCEPT
  176. {
  177. char * storage = storage_ptr();
  178. guard_type guard(storage);
  179. value_type v;
  180. memcpy(&v, storage, sizeof(value_type));
  181. return v;
  182. }
  183. bool
  184. compare_exchange_strong(
  185. value_type & expected,
  186. value_type const& desired,
  187. memory_order /*success_order*/,
  188. memory_order /*failure_order*/) volatile BOOST_NOEXCEPT
  189. {
  190. char * storage = storage_ptr();
  191. guard_type guard(storage);
  192. if (memcmp(storage, &expected, sizeof(value_type)) == 0) {
  193. memcpy(storage, &desired, sizeof(value_type));
  194. return true;
  195. } else {
  196. memcpy(&expected, storage, sizeof(value_type));
  197. return false;
  198. }
  199. }
  200. bool
  201. compare_exchange_weak(
  202. value_type & expected,
  203. value_type const& desired,
  204. memory_order success_order,
  205. memory_order failure_order) volatile BOOST_NOEXCEPT
  206. {
  207. return compare_exchange_strong(expected, desired, success_order, failure_order);
  208. }
  209. value_type
  210. exchange(value_type const& v, memory_order /*order*/=memory_order_seq_cst) volatile BOOST_NOEXCEPT
  211. {
  212. char * storage = storage_ptr();
  213. guard_type guard(storage);
  214. value_type tmp;
  215. memcpy(&tmp, storage, sizeof(value_type));
  216. memcpy(storage, &v, sizeof(value_type));
  217. return tmp;
  218. }
  219. bool
  220. is_lock_free(void) const volatile BOOST_NOEXCEPT
  221. {
  222. return false;
  223. }
  224. BOOST_ATOMIC_DECLARE_BASE_OPERATORS
  225. BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
  226. BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
  227. private:
  228. char * storage_ptr() volatile const BOOST_NOEXCEPT
  229. {
  230. return const_cast<char *>(&reinterpret_cast<char const volatile &>(v_));
  231. }
  232. T v_;
  233. };
  234. template<typename T, unsigned int Size, bool Sign>
  235. class base_atomic<T, int, Size, Sign>
  236. {
  237. private:
  238. typedef base_atomic this_type;
  239. typedef T value_type;
  240. typedef T difference_type;
  241. typedef lockpool::scoped_lock guard_type;
  242. protected:
  243. typedef value_type value_arg_type;
  244. public:
  245. BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
  246. BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
  247. void
  248. store(value_type v, memory_order /*order*/ = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  249. {
  250. guard_type guard(const_cast<value_type *>(&v_));
  251. v_ = v;
  252. }
  253. value_type
  254. load(memory_order /*order*/ = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
  255. {
  256. guard_type guard(const_cast<value_type *>(&v_));
  257. value_type v = const_cast<const volatile value_type &>(v_);
  258. return v;
  259. }
  260. value_type
  261. exchange(value_type v, memory_order /*order*/ = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  262. {
  263. guard_type guard(const_cast<value_type *>(&v_));
  264. value_type old = v_;
  265. v_ = v;
  266. return old;
  267. }
  268. bool
  269. compare_exchange_strong(value_type & expected, value_type desired,
  270. memory_order /*success_order*/,
  271. memory_order /*failure_order*/) volatile BOOST_NOEXCEPT
  272. {
  273. guard_type guard(const_cast<value_type *>(&v_));
  274. if (v_ == expected) {
  275. v_ = desired;
  276. return true;
  277. } else {
  278. expected = v_;
  279. return false;
  280. }
  281. }
  282. bool
  283. compare_exchange_weak(value_type & expected, value_type desired,
  284. memory_order success_order,
  285. memory_order failure_order) volatile BOOST_NOEXCEPT
  286. {
  287. return compare_exchange_strong(expected, desired, success_order, failure_order);
  288. }
  289. value_type
  290. fetch_add(difference_type v, memory_order /*order*/ = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  291. {
  292. guard_type guard(const_cast<value_type *>(&v_));
  293. value_type old = v_;
  294. v_ += v;
  295. return old;
  296. }
  297. value_type
  298. fetch_sub(difference_type v, memory_order /*order*/ = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  299. {
  300. guard_type guard(const_cast<value_type *>(&v_));
  301. value_type old = v_;
  302. v_ -= v;
  303. return old;
  304. }
  305. value_type
  306. fetch_and(value_type v, memory_order /*order*/ = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  307. {
  308. guard_type guard(const_cast<value_type *>(&v_));
  309. value_type old = v_;
  310. v_ &= v;
  311. return old;
  312. }
  313. value_type
  314. fetch_or(value_type v, memory_order /*order*/ = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  315. {
  316. guard_type guard(const_cast<value_type *>(&v_));
  317. value_type old = v_;
  318. v_ |= v;
  319. return old;
  320. }
  321. value_type
  322. fetch_xor(value_type v, memory_order /*order*/ = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  323. {
  324. guard_type guard(const_cast<value_type *>(&v_));
  325. value_type old = v_;
  326. v_ ^= v;
  327. return old;
  328. }
  329. bool
  330. is_lock_free(void) const volatile BOOST_NOEXCEPT
  331. {
  332. return false;
  333. }
  334. BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
  335. BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
  336. BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
  337. private:
  338. value_type v_;
  339. };
  340. template<typename T, unsigned int Size, bool Sign>
  341. class base_atomic<T *, void *, Size, Sign>
  342. {
  343. private:
  344. typedef base_atomic this_type;
  345. typedef T * value_type;
  346. typedef std::ptrdiff_t difference_type;
  347. typedef lockpool::scoped_lock guard_type;
  348. protected:
  349. typedef value_type value_arg_type;
  350. public:
  351. BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
  352. BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
  353. void
  354. store(value_type v, memory_order /*order*/ = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  355. {
  356. guard_type guard(const_cast<value_type *>(&v_));
  357. v_ = v;
  358. }
  359. value_type
  360. load(memory_order /*order*/ = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
  361. {
  362. guard_type guard(const_cast<value_type *>(&v_));
  363. value_type v = const_cast<const volatile value_type &>(v_);
  364. return v;
  365. }
  366. value_type
  367. exchange(value_type v, memory_order /*order*/ = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  368. {
  369. guard_type guard(const_cast<value_type *>(&v_));
  370. value_type old = v_;
  371. v_ = v;
  372. return old;
  373. }
  374. bool
  375. compare_exchange_strong(value_type & expected, value_type desired,
  376. memory_order /*success_order*/,
  377. memory_order /*failure_order*/) volatile BOOST_NOEXCEPT
  378. {
  379. guard_type guard(const_cast<value_type *>(&v_));
  380. if (v_ == expected) {
  381. v_ = desired;
  382. return true;
  383. } else {
  384. expected = v_;
  385. return false;
  386. }
  387. }
  388. bool
  389. compare_exchange_weak(value_type & expected, value_type desired,
  390. memory_order success_order,
  391. memory_order failure_order) volatile BOOST_NOEXCEPT
  392. {
  393. return compare_exchange_strong(expected, desired, success_order, failure_order);
  394. }
  395. value_type fetch_add(difference_type v, memory_order /*order*/ = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  396. {
  397. guard_type guard(const_cast<value_type *>(&v_));
  398. value_type old = v_;
  399. v_ += v;
  400. return old;
  401. }
  402. value_type fetch_sub(difference_type v, memory_order /*order*/ = memory_order_seq_cst) volatile
  403. {
  404. guard_type guard(const_cast<value_type *>(&v_));
  405. value_type old = v_;
  406. v_ -= v;
  407. return old;
  408. }
  409. bool
  410. is_lock_free(void) const volatile BOOST_NOEXCEPT
  411. {
  412. return false;
  413. }
  414. BOOST_ATOMIC_DECLARE_POINTER_OPERATORS
  415. BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
  416. BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
  417. private:
  418. value_type v_;
  419. };
  420. template<unsigned int Size, bool Sign>
  421. class base_atomic<void *, void *, Size, Sign>
  422. {
  423. private:
  424. typedef base_atomic this_type;
  425. typedef std::ptrdiff_t difference_type;
  426. typedef void * value_type;
  427. typedef lockpool::scoped_lock guard_type;
  428. protected:
  429. typedef value_type value_arg_type;
  430. public:
  431. BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
  432. BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
  433. void
  434. store(value_type v, memory_order /*order*/ = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  435. {
  436. guard_type guard(const_cast<value_type *>(&v_));
  437. v_ = v;
  438. }
  439. value_type
  440. load(memory_order /*order*/ = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
  441. {
  442. guard_type guard(const_cast<value_type *>(&v_));
  443. value_type v = const_cast<const volatile value_type &>(v_);
  444. return v;
  445. }
  446. value_type
  447. exchange(value_type v, memory_order /*order*/ = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  448. {
  449. guard_type guard(const_cast<value_type *>(&v_));
  450. value_type old = v_;
  451. v_ = v;
  452. return old;
  453. }
  454. bool
  455. compare_exchange_strong(value_type & expected, value_type desired,
  456. memory_order /*success_order*/,
  457. memory_order /*failure_order*/) volatile BOOST_NOEXCEPT
  458. {
  459. guard_type guard(const_cast<value_type *>(&v_));
  460. if (v_ == expected) {
  461. v_ = desired;
  462. return true;
  463. } else {
  464. expected = v_;
  465. return false;
  466. }
  467. }
  468. bool
  469. compare_exchange_weak(value_type & expected, value_type desired,
  470. memory_order success_order,
  471. memory_order failure_order) volatile BOOST_NOEXCEPT
  472. {
  473. return compare_exchange_strong(expected, desired, success_order, failure_order);
  474. }
  475. bool
  476. is_lock_free(void) const volatile BOOST_NOEXCEPT
  477. {
  478. return false;
  479. }
  480. value_type fetch_add(difference_type v, memory_order /*order*/ = memory_order_seq_cst) volatile BOOST_NOEXCEPT
  481. {
  482. guard_type guard(const_cast<value_type *>(&v_));
  483. value_type old = v_;
  484. char * cv = reinterpret_cast<char*>(old);
  485. cv += v;
  486. v_ = cv;
  487. return old;
  488. }
  489. value_type fetch_sub(difference_type v, memory_order /*order*/ = memory_order_seq_cst) volatile
  490. {
  491. guard_type guard(const_cast<value_type *>(&v_));
  492. value_type old = v_;
  493. char * cv = reinterpret_cast<char*>(old);
  494. cv -= v;
  495. v_ = cv;
  496. return old;
  497. }
  498. BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS
  499. BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
  500. BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
  501. private:
  502. value_type v_;
  503. };
  504. }
  505. }
  506. }
  507. #endif