fcqueue.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. // Copyright (c) 2006-2018 Maxim Khizhinsky
  2. //
  3. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  4. // file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
  5. #include <cds_test/ext_gtest.h>
  6. #include <cds/container/fcqueue.h>
  7. #include <test/include/cds_test/fc_hevy_value.h>
  8. #include <list>
  9. namespace {
  10. class FCQueue: public ::testing::Test
  11. {
  12. protected:
  13. template <class Queue>
  14. void test( Queue& q )
  15. {
  16. typedef typename Queue::value_type value_type;
  17. value_type it;
  18. const int nSize = 100;
  19. ASSERT_TRUE( q.empty());
  20. ASSERT_EQ( q.size(), 0u );
  21. // enqueue/dequeue
  22. for ( int i = 0; i < nSize; ++i ) {
  23. ASSERT_TRUE( q.enqueue( value_type(i)));
  24. ASSERT_EQ( q.size(), static_cast<size_t>(i + 1));
  25. }
  26. ASSERT_FALSE( q.empty());
  27. ASSERT_EQ( q.size(), static_cast<size_t>( nSize ));
  28. for ( int i = 0; i < nSize; ++i ) {
  29. it = value_type( -1 );
  30. ASSERT_TRUE( q.dequeue( it ));
  31. ASSERT_EQ( it, value_type( i ));
  32. ASSERT_EQ( q.size(), static_cast<size_t>( nSize - i - 1 ));
  33. }
  34. ASSERT_TRUE( q.empty());
  35. ASSERT_EQ( q.size(), 0u );
  36. // push/pop
  37. for ( int i = 0; i < nSize; ++i ) {
  38. ASSERT_TRUE( q.push( value_type(i)));
  39. ASSERT_EQ( q.size(), static_cast<size_t>( i + 1 ));
  40. }
  41. ASSERT_FALSE( q.empty());
  42. ASSERT_EQ( q.size(), static_cast<size_t>( nSize ));
  43. for ( int i = 0; i < nSize; ++i ) {
  44. it = value_type( -1 );
  45. ASSERT_TRUE( q.pop( it ));
  46. ASSERT_EQ( it, value_type( i ));
  47. ASSERT_EQ( q.size(), static_cast<size_t>( nSize - i - 1 ));
  48. }
  49. ASSERT_TRUE( q.empty());
  50. ASSERT_EQ( q.size(), 0u );
  51. // clear
  52. for ( int i = 0; i < nSize; ++i ) {
  53. ASSERT_TRUE( q.push( value_type( i )));
  54. }
  55. ASSERT_FALSE( q.empty());
  56. ASSERT_EQ( q.size(), static_cast<size_t>( nSize ));
  57. q.clear();
  58. ASSERT_TRUE( q.empty());
  59. ASSERT_EQ( q.size(), 0u );
  60. // pop from empty queue
  61. it = value_type( nSize * 2 );
  62. ASSERT_FALSE( q.pop( it ));
  63. ASSERT_EQ( it, static_cast<value_type>( nSize * 2 ));
  64. ASSERT_TRUE( q.empty());
  65. ASSERT_EQ( q.size(), 0u );
  66. ASSERT_FALSE( q.dequeue( it ));
  67. ASSERT_EQ( it, static_cast<value_type>( nSize * 2 ));
  68. ASSERT_TRUE( q.empty());
  69. ASSERT_EQ( q.size(), 0u );
  70. }
  71. template <class Queue>
  72. void test_string( Queue& q )
  73. {
  74. std::string str[3];
  75. str[0] = "one";
  76. str[1] = "two";
  77. str[2] = "three";
  78. const size_t nSize = sizeof( str ) / sizeof( str[0] );
  79. // move push
  80. for ( size_t i = 0; i < nSize; ++i ) {
  81. std::string s = str[i];
  82. ASSERT_FALSE( s.empty());
  83. ASSERT_TRUE( q.enqueue( std::move( s )));
  84. ASSERT_FALSE( s.empty());
  85. ASSERT_EQ( q.size(), i + 1 );
  86. }
  87. ASSERT_FALSE( q.empty());
  88. ASSERT_EQ( q.size(), nSize );
  89. for ( size_t i = 0; i < nSize; ++i ) {
  90. std::string s;
  91. ASSERT_TRUE( q.pop( s ));
  92. ASSERT_EQ( q.size(), nSize - i - 1 );
  93. ASSERT_EQ( s, str[i] );
  94. }
  95. ASSERT_TRUE( q.empty());
  96. ASSERT_EQ( q.size(), 0u );
  97. }
  98. template <class Queue>
  99. void test_heavy( Queue& q )
  100. {
  101. typedef typename Queue::value_type value_type;
  102. value_type it;
  103. const int nSize = 100;
  104. ASSERT_TRUE( q.empty());
  105. ASSERT_EQ( q.size(), 0u );
  106. // enqueue/dequeue
  107. for ( int i = 0; i < nSize; ++i ) {
  108. ASSERT_TRUE( q.enqueue( value_type( i )));
  109. ASSERT_EQ( q.size(), static_cast<size_t>( i + 1 ));
  110. }
  111. ASSERT_FALSE( q.empty());
  112. ASSERT_EQ( q.size(), static_cast<size_t>( nSize ));
  113. for ( int i = 0; i < nSize; ++i ) {
  114. it.value = -1;
  115. ASSERT_TRUE( q.dequeue( it ));
  116. ASSERT_EQ( it.value, i );
  117. ASSERT_EQ( q.size(), static_cast<size_t>( nSize - i - 1 ));
  118. }
  119. ASSERT_TRUE( q.empty());
  120. ASSERT_EQ( q.size(), 0u );
  121. // push/pop
  122. for ( int i = 0; i < nSize; ++i ) {
  123. ASSERT_TRUE( q.push( value_type( i )));
  124. ASSERT_EQ( q.size(), static_cast<size_t>( i + 1 ));
  125. }
  126. ASSERT_FALSE( q.empty());
  127. ASSERT_EQ( q.size(), static_cast<size_t>( nSize ));
  128. for ( int i = 0; i < nSize; ++i ) {
  129. it.value = -1;
  130. ASSERT_TRUE( q.pop( it ));
  131. ASSERT_EQ( it.value, i );
  132. ASSERT_EQ( q.size(), static_cast<size_t>( nSize - i - 1 ));
  133. }
  134. ASSERT_TRUE( q.empty());
  135. ASSERT_EQ( q.size(), 0u );
  136. // clear
  137. for ( int i = 0; i < nSize; ++i ) {
  138. ASSERT_TRUE( q.push( value_type( i )));
  139. }
  140. ASSERT_FALSE( q.empty());
  141. ASSERT_EQ( q.size(), static_cast<size_t>( nSize ));
  142. q.clear();
  143. ASSERT_TRUE( q.empty());
  144. ASSERT_EQ( q.size(), 0u );
  145. // pop from empty queue
  146. it = value_type( nSize * 2 );
  147. ASSERT_FALSE( q.pop( it ));
  148. ASSERT_EQ( it.value, nSize * 2 );
  149. ASSERT_TRUE( q.empty());
  150. ASSERT_EQ( q.size(), 0u );
  151. ASSERT_FALSE( q.dequeue( it ));
  152. ASSERT_EQ( it.value, nSize * 2 );
  153. ASSERT_TRUE( q.empty());
  154. ASSERT_EQ( q.size(), 0u );
  155. }
  156. };
  157. TEST_F( FCQueue, std_deque )
  158. {
  159. typedef cds::container::FCQueue<int> queue_type;
  160. queue_type q;
  161. test( q );
  162. }
  163. TEST_F( FCQueue, std_deque_move )
  164. {
  165. typedef cds::container::FCQueue<std::string> queue_type;
  166. queue_type q;
  167. test_string( q );
  168. }
  169. TEST_F( FCQueue, std_empty_wait_strategy )
  170. {
  171. typedef cds::container::FCQueue<int, std::queue< int, std::deque<int>>,
  172. cds::container::fcqueue::make_traits<
  173. cds::opt::wait_strategy< cds::algo::flat_combining::wait_strategy::empty >
  174. >::type
  175. > queue_type;
  176. queue_type q;
  177. test( q );
  178. }
  179. TEST_F( FCQueue, std_deque_heavy_value )
  180. {
  181. typedef fc_test::heavy_value<> ValueType;
  182. typedef cds::container::FCQueue<ValueType> queue_type;
  183. queue_type q;
  184. test_heavy( q );
  185. }
  186. TEST_F( FCQueue, std_empty_wait_strategy_heavy_value )
  187. {
  188. typedef fc_test::heavy_value<> ValueType;
  189. typedef cds::container::FCQueue<ValueType, std::queue< ValueType, std::deque<ValueType>>,
  190. cds::container::fcqueue::make_traits<
  191. cds::opt::wait_strategy< cds::algo::flat_combining::wait_strategy::empty >
  192. >::type
  193. > queue_type;
  194. queue_type q;
  195. test_heavy( q );
  196. }
  197. TEST_F( FCQueue, std_single_mutex_single_condvar_heavy_value )
  198. {
  199. typedef fc_test::heavy_value<> ValueType;
  200. typedef cds::container::FCQueue<ValueType, std::queue< ValueType, std::deque<ValueType>>,
  201. cds::container::fcqueue::make_traits<
  202. cds::opt::wait_strategy< cds::algo::flat_combining::wait_strategy::single_mutex_single_condvar<> >
  203. >::type
  204. > queue_type;
  205. queue_type q;
  206. test_heavy( q );
  207. }
  208. TEST_F( FCQueue, std_single_mutex_multi_condvar_heavy_value )
  209. {
  210. typedef fc_test::heavy_value<> ValueType;
  211. typedef cds::container::FCQueue<ValueType, std::queue< ValueType, std::deque<ValueType>>,
  212. cds::container::fcqueue::make_traits<
  213. cds::opt::wait_strategy< cds::algo::flat_combining::wait_strategy::single_mutex_multi_condvar<> >
  214. >::type
  215. > queue_type;
  216. queue_type q;
  217. test_heavy( q );
  218. }
  219. TEST_F( FCQueue, std_multi_mutex_multi_condvar_heavy_value )
  220. {
  221. typedef fc_test::heavy_value<> ValueType;
  222. typedef cds::container::FCQueue<ValueType, std::queue< ValueType, std::deque<ValueType>>,
  223. cds::container::fcqueue::make_traits<
  224. cds::opt::wait_strategy< cds::algo::flat_combining::wait_strategy::multi_mutex_multi_condvar<> >
  225. >::type
  226. > queue_type;
  227. queue_type q;
  228. test_heavy( q );
  229. }
  230. TEST_F( FCQueue, std_single_mutex_single_condvar )
  231. {
  232. typedef cds::container::FCQueue<int, std::queue< int, std::deque<int>>,
  233. cds::container::fcqueue::make_traits<
  234. cds::opt::wait_strategy< cds::algo::flat_combining::wait_strategy::single_mutex_single_condvar<>>
  235. >::type
  236. > queue_type;
  237. queue_type q;
  238. test( q );
  239. }
  240. TEST_F( FCQueue, std_deque_elimination )
  241. {
  242. typedef cds::container::FCQueue<int, std::queue< int, std::deque<int>>,
  243. cds::container::fcqueue::make_traits<
  244. cds::opt::enable_elimination< true >
  245. >::type
  246. > queue_type;
  247. queue_type q;
  248. test( q );
  249. }
  250. TEST_F( FCQueue, std_deque_elimination_single_mutex_multi_condvar )
  251. {
  252. typedef cds::container::FCQueue<int, std::queue< int, std::deque<int>>,
  253. cds::container::fcqueue::make_traits<
  254. cds::opt::enable_elimination< true >
  255. , cds::opt::wait_strategy< cds::algo::flat_combining::wait_strategy::single_mutex_multi_condvar<2>>
  256. >::type
  257. > queue_type;
  258. queue_type q;
  259. test( q );
  260. }
  261. TEST_F( FCQueue, std_deque_elimination_move )
  262. {
  263. typedef cds::container::FCQueue<std::string, std::queue< std::string, std::deque<std::string>>,
  264. cds::container::fcqueue::make_traits<
  265. cds::opt::enable_elimination< true >
  266. >::type
  267. > queue_type;
  268. queue_type q;
  269. test_string( q );
  270. }
  271. TEST_F( FCQueue, std_deque_elimination_move_multi_mutex_multi_condvar )
  272. {
  273. typedef cds::container::FCQueue<std::string, std::queue< std::string, std::deque<std::string>>,
  274. cds::container::fcqueue::make_traits<
  275. cds::opt::enable_elimination< true >
  276. , cds::opt::wait_strategy< cds::algo::flat_combining::wait_strategy::multi_mutex_multi_condvar<>>
  277. >::type
  278. > queue_type;
  279. queue_type q;
  280. test_string( q );
  281. }
  282. TEST_F( FCQueue, std_deque_mutex )
  283. {
  284. typedef cds::container::FCQueue<int, std::queue< int, std::deque<int>>,
  285. cds::container::fcqueue::make_traits<
  286. cds::opt::lock_type< std::mutex >
  287. >::type
  288. > queue_type;
  289. queue_type q;
  290. test( q );
  291. }
  292. TEST_F( FCQueue, std_list )
  293. {
  294. typedef cds::container::FCQueue<int, std::queue< int, std::list<int>>> queue_type;
  295. queue_type q;
  296. test( q );
  297. }
  298. TEST_F( FCQueue, std_list_move )
  299. {
  300. typedef cds::container::FCQueue<std::string, std::queue< std::string, std::list<std::string>>> queue_type;
  301. queue_type q;
  302. test_string( q );
  303. }
  304. TEST_F( FCQueue, std_list_empty_wait_strategy )
  305. {
  306. typedef cds::container::FCQueue<int, std::queue< int, std::list<int> >,
  307. cds::container::fcqueue::make_traits<
  308. cds::opt::wait_strategy< cds::algo::flat_combining::wait_strategy::empty >
  309. >::type
  310. > queue_type;
  311. queue_type q;
  312. test( q );
  313. }
  314. TEST_F( FCQueue, std_list_single_mutex_single_condvar )
  315. {
  316. typedef cds::container::FCQueue<int, std::queue< int, std::list<int> >,
  317. cds::container::fcqueue::make_traits<
  318. cds::opt::wait_strategy< cds::algo::flat_combining::wait_strategy::single_mutex_single_condvar<5>>
  319. >::type
  320. > queue_type;
  321. queue_type q;
  322. test( q );
  323. }
  324. TEST_F( FCQueue, std_list_elimination )
  325. {
  326. typedef cds::container::FCQueue<int, std::queue< int, std::list<int> >,
  327. cds::container::fcqueue::make_traits<
  328. cds::opt::enable_elimination< true >
  329. >::type
  330. > queue_type;
  331. queue_type q;
  332. test( q );
  333. }
  334. TEST_F( FCQueue, std_list_elimination_multi_mutex_multi_condvar )
  335. {
  336. typedef cds::container::FCQueue<int, std::queue< int, std::list<int> >,
  337. cds::container::fcqueue::make_traits<
  338. cds::opt::enable_elimination< true >
  339. ,cds::opt::wait_strategy< cds::algo::flat_combining::wait_strategy::multi_mutex_multi_condvar<5>>
  340. >::type
  341. > queue_type;
  342. queue_type q;
  343. test( q );
  344. }
  345. TEST_F( FCQueue, std_list_elimination_move )
  346. {
  347. typedef cds::container::FCQueue<std::string, std::queue< std::string, std::list<std::string> >,
  348. cds::container::fcqueue::make_traits<
  349. cds::opt::enable_elimination< true >
  350. >::type
  351. > queue_type;
  352. queue_type q;
  353. test_string( q );
  354. }
  355. TEST_F( FCQueue, std_list_mutex )
  356. {
  357. typedef cds::container::FCQueue<int, std::queue<int, std::list<int> >,
  358. cds::container::fcqueue::make_traits<
  359. cds::opt::lock_type< std::mutex >
  360. >::type
  361. > queue_type;
  362. queue_type q;
  363. test( q );
  364. }
  365. } // namespace