atomic_sp_test.cpp 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. #include <boost/config.hpp>
  2. // atomic_sp_test.cpp
  3. //
  4. // Copyright 2008, 2017 Peter Dimov
  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. #include <boost/smart_ptr/atomic_shared_ptr.hpp>
  10. #include <boost/core/lightweight_test.hpp>
  11. #include <boost/memory_order.hpp>
  12. //
  13. struct X
  14. {
  15. };
  16. #define BOOST_TEST_SP_EQ( p, q ) BOOST_TEST( p == q && !( p < q ) && !( q < p ) )
  17. int main()
  18. {
  19. // default constructor
  20. {
  21. boost::atomic_shared_ptr<X> apx;
  22. boost::shared_ptr<X> p2 = apx.load();
  23. BOOST_TEST_EQ( p2.get(), (X*)0 );
  24. BOOST_TEST_EQ( p2.use_count(), 0 );
  25. }
  26. // shared_ptr constructor
  27. {
  28. boost::shared_ptr<X> px( new X );
  29. boost::atomic_shared_ptr<X> apx( px );
  30. boost::shared_ptr<X> p2 = apx.load();
  31. BOOST_TEST_EQ( px, p2 );
  32. BOOST_TEST_EQ( px.use_count(), 3 );
  33. BOOST_TEST_EQ( p2.use_count(), 3 );
  34. }
  35. // shared_ptr assignment
  36. {
  37. boost::shared_ptr<X> px0( new X );
  38. boost::atomic_shared_ptr<X> apx( px0 );
  39. boost::shared_ptr<X> px( new X );
  40. apx = px;
  41. boost::shared_ptr<X> p2 = apx.load();
  42. BOOST_TEST_EQ( px, p2 );
  43. BOOST_TEST_EQ( px.use_count(), 3 );
  44. BOOST_TEST_EQ( p2.use_count(), 3 );
  45. }
  46. // load, w/ mo
  47. {
  48. boost::shared_ptr<X> px( new X );
  49. boost::atomic_shared_ptr<X> apx( px );
  50. boost::shared_ptr<X> p2 = apx.load( boost::memory_order_acquire );
  51. BOOST_TEST_EQ( px, p2 );
  52. BOOST_TEST_EQ( px.use_count(), 3 );
  53. BOOST_TEST_EQ( p2.use_count(), 3 );
  54. }
  55. // operator shared_ptr
  56. {
  57. boost::shared_ptr<X> px( new X );
  58. boost::atomic_shared_ptr<X> apx( px );
  59. boost::shared_ptr<X> p2 = apx;
  60. BOOST_TEST_EQ( px, p2 );
  61. BOOST_TEST_EQ( px.use_count(), 3 );
  62. BOOST_TEST_EQ( p2.use_count(), 3 );
  63. }
  64. // store
  65. {
  66. boost::shared_ptr<X> px0( new X );
  67. boost::atomic_shared_ptr<X> apx( px0 );
  68. boost::shared_ptr<X> px( new X );
  69. apx.store( px );
  70. boost::shared_ptr<X> p2 = apx.load();
  71. BOOST_TEST_EQ( px, p2 );
  72. BOOST_TEST_EQ( px.use_count(), 3 );
  73. BOOST_TEST_EQ( p2.use_count(), 3 );
  74. }
  75. // store, w/ mo
  76. {
  77. boost::shared_ptr<X> px0( new X );
  78. boost::atomic_shared_ptr<X> apx( px0 );
  79. boost::shared_ptr<X> px( new X );
  80. apx.store( px, boost::memory_order_release );
  81. boost::shared_ptr<X> p2 = apx.load();
  82. BOOST_TEST_EQ( px, p2 );
  83. BOOST_TEST_EQ( px.use_count(), 3 );
  84. BOOST_TEST_EQ( p2.use_count(), 3 );
  85. }
  86. // exchange
  87. {
  88. boost::shared_ptr<X> px0( new X );
  89. boost::atomic_shared_ptr<X> apx( px0 );
  90. boost::shared_ptr<X> px( new X );
  91. boost::shared_ptr<X> p1 = apx.exchange( px );
  92. BOOST_TEST_EQ( px0, p1 );
  93. BOOST_TEST_EQ( px0.use_count(), 2 );
  94. BOOST_TEST_EQ( p1.use_count(), 2 );
  95. boost::shared_ptr<X> p2 = apx.load();
  96. BOOST_TEST_EQ( px, p2 );
  97. BOOST_TEST_EQ( px.use_count(), 3 );
  98. BOOST_TEST_EQ( p2.use_count(), 3 );
  99. }
  100. // exchange, w/ mo
  101. {
  102. boost::shared_ptr<X> px0( new X );
  103. boost::atomic_shared_ptr<X> apx( px0 );
  104. boost::shared_ptr<X> px( new X );
  105. boost::shared_ptr<X> p1 = apx.exchange( px, boost::memory_order_acq_rel );
  106. BOOST_TEST_EQ( px0, p1 );
  107. BOOST_TEST_EQ( px0.use_count(), 2 );
  108. BOOST_TEST_EQ( p1.use_count(), 2 );
  109. boost::shared_ptr<X> p2 = apx.load();
  110. BOOST_TEST_EQ( px, p2 );
  111. BOOST_TEST_EQ( px.use_count(), 3 );
  112. BOOST_TEST_EQ( p2.use_count(), 3 );
  113. }
  114. // compare_exchange_weak
  115. {
  116. boost::shared_ptr<X> px( new X );
  117. boost::atomic_shared_ptr<X> apx( px );
  118. boost::shared_ptr<X> px2( new X );
  119. boost::shared_ptr<X> cmp;
  120. bool r = apx.compare_exchange_weak( cmp, px2 );
  121. BOOST_TEST( !r );
  122. BOOST_TEST_SP_EQ( apx.load(), px );
  123. BOOST_TEST_SP_EQ( cmp, px );
  124. r = apx.compare_exchange_weak( cmp, px2 );
  125. BOOST_TEST( r );
  126. BOOST_TEST_SP_EQ( apx.load(), px2 );
  127. }
  128. // compare_exchange_weak, w/ mo
  129. {
  130. boost::shared_ptr<X> px( new X );
  131. boost::atomic_shared_ptr<X> apx( px );
  132. boost::shared_ptr<X> px2( new X );
  133. boost::shared_ptr<X> cmp;
  134. bool r = apx.compare_exchange_weak( cmp, px2, boost::memory_order_seq_cst, boost::memory_order_seq_cst );
  135. BOOST_TEST( !r );
  136. BOOST_TEST_SP_EQ( apx.load(), px );
  137. BOOST_TEST_SP_EQ( cmp, px );
  138. r = apx.compare_exchange_weak( cmp, px2, boost::memory_order_seq_cst, boost::memory_order_seq_cst );
  139. BOOST_TEST( r );
  140. BOOST_TEST_SP_EQ( apx.load(), px2 );
  141. }
  142. // compare_exchange_weak, rv
  143. {
  144. boost::shared_ptr<X> px( new X );
  145. boost::atomic_shared_ptr<X> apx( px );
  146. boost::shared_ptr<X> cmp;
  147. bool r = apx.compare_exchange_weak( cmp, boost::shared_ptr<X>() );
  148. BOOST_TEST( !r );
  149. BOOST_TEST_SP_EQ( apx.load(), px );
  150. BOOST_TEST_SP_EQ( cmp, px );
  151. r = apx.compare_exchange_weak( cmp, boost::shared_ptr<X>() );
  152. BOOST_TEST( r );
  153. BOOST_TEST( apx.load().get() == 0 );
  154. BOOST_TEST( apx.load().use_count() == 0 );
  155. }
  156. // compare_exchange_weak, rv, w/ mo
  157. {
  158. boost::shared_ptr<X> px( new X );
  159. boost::atomic_shared_ptr<X> apx( px );
  160. boost::shared_ptr<X> cmp;
  161. bool r = apx.compare_exchange_weak( cmp, boost::shared_ptr<X>(), boost::memory_order_seq_cst, boost::memory_order_seq_cst );
  162. BOOST_TEST( !r );
  163. BOOST_TEST_SP_EQ( apx.load(), px );
  164. BOOST_TEST_SP_EQ( cmp, px );
  165. r = apx.compare_exchange_weak( cmp, boost::shared_ptr<X>(), boost::memory_order_seq_cst, boost::memory_order_seq_cst );
  166. BOOST_TEST( r );
  167. BOOST_TEST( apx.load().get() == 0 );
  168. BOOST_TEST( apx.load().use_count() == 0 );
  169. }
  170. // compare_exchange_strong
  171. {
  172. boost::shared_ptr<X> px( new X );
  173. boost::atomic_shared_ptr<X> apx( px );
  174. boost::shared_ptr<X> px2( new X );
  175. boost::shared_ptr<X> cmp;
  176. bool r = apx.compare_exchange_strong( cmp, px2 );
  177. BOOST_TEST( !r );
  178. BOOST_TEST_SP_EQ( apx.load(), px );
  179. BOOST_TEST_SP_EQ( cmp, px );
  180. r = apx.compare_exchange_strong( cmp, px2 );
  181. BOOST_TEST( r );
  182. BOOST_TEST_SP_EQ( apx.load(), px2 );
  183. }
  184. // compare_exchange_strong, w/ mo
  185. {
  186. boost::shared_ptr<X> px( new X );
  187. boost::atomic_shared_ptr<X> apx( px );
  188. boost::shared_ptr<X> px2( new X );
  189. boost::shared_ptr<X> cmp;
  190. bool r = apx.compare_exchange_strong( cmp, px2, boost::memory_order_seq_cst, boost::memory_order_seq_cst );
  191. BOOST_TEST( !r );
  192. BOOST_TEST_SP_EQ( apx.load(), px );
  193. BOOST_TEST_SP_EQ( cmp, px );
  194. r = apx.compare_exchange_strong( cmp, px2, boost::memory_order_seq_cst, boost::memory_order_seq_cst );
  195. BOOST_TEST( r );
  196. BOOST_TEST_SP_EQ( apx.load(), px2 );
  197. }
  198. // compare_exchange_strong, rv
  199. {
  200. boost::shared_ptr<X> px( new X );
  201. boost::atomic_shared_ptr<X> apx( px );
  202. boost::shared_ptr<X> cmp;
  203. bool r = apx.compare_exchange_strong( cmp, boost::shared_ptr<X>() );
  204. BOOST_TEST( !r );
  205. BOOST_TEST_SP_EQ( apx.load(), px );
  206. BOOST_TEST_SP_EQ( cmp, px );
  207. r = apx.compare_exchange_strong( cmp, boost::shared_ptr<X>() );
  208. BOOST_TEST( r );
  209. BOOST_TEST( apx.load().get() == 0 );
  210. BOOST_TEST( apx.load().use_count() == 0 );
  211. }
  212. // compare_exchange_strong, rv, w/ mo
  213. {
  214. boost::shared_ptr<X> px( new X );
  215. boost::atomic_shared_ptr<X> apx( px );
  216. boost::shared_ptr<X> cmp;
  217. bool r = apx.compare_exchange_strong( cmp, boost::shared_ptr<X>(), boost::memory_order_seq_cst, boost::memory_order_seq_cst );
  218. BOOST_TEST( !r );
  219. BOOST_TEST_SP_EQ( apx.load(), px );
  220. BOOST_TEST_SP_EQ( cmp, px );
  221. r = apx.compare_exchange_strong( cmp, boost::shared_ptr<X>(), boost::memory_order_seq_cst, boost::memory_order_seq_cst );
  222. BOOST_TEST( r );
  223. BOOST_TEST( apx.load().get() == 0 );
  224. BOOST_TEST( apx.load().use_count() == 0 );
  225. }
  226. return boost::report_errors();
  227. }