vyukov_mpmc_queue.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  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 "test_bounded_queue.h"
  6. #include <cds/container/vyukov_mpmc_cycle_queue.h>
  7. namespace {
  8. namespace cc = cds::container;
  9. class VyukovMPMCCycleQueue: public cds_test::bounded_queue
  10. {
  11. public:
  12. template <typename Queue>
  13. void test_single_consumer( Queue& q )
  14. {
  15. typedef typename Queue::value_type value_type;
  16. const size_t nSize = q.capacity();
  17. ASSERT_TRUE( q.empty());
  18. ASSERT_CONTAINER_SIZE( q, 0 );
  19. // enqueue/dequeue
  20. for ( unsigned pass = 0; pass < 3; ++pass ) {
  21. for ( size_t i = 0; i < nSize; ++i ) {
  22. ASSERT_TRUE( q.enqueue( static_cast<value_type>( i )));
  23. ASSERT_CONTAINER_SIZE( q, i + 1 );
  24. }
  25. ASSERT_FALSE( q.empty());
  26. ASSERT_CONTAINER_SIZE( q, nSize );
  27. ASSERT_FALSE( q.enqueue( static_cast<value_type>( nSize ) * 2 ));
  28. for ( size_t i = 0; i < nSize; ++i ) {
  29. value_type* fr = q.front();
  30. ASSERT_TRUE( fr != nullptr );
  31. ASSERT_EQ( *fr, static_cast<value_type>( i ));
  32. ASSERT_TRUE( q.pop_front());
  33. ASSERT_CONTAINER_SIZE( q, nSize - i - 1 );
  34. }
  35. ASSERT_TRUE( q.empty());
  36. ASSERT_CONTAINER_SIZE( q, 0 );
  37. ASSERT_TRUE( q.front() == nullptr );
  38. ASSERT_FALSE( q.pop_front());
  39. }
  40. }
  41. };
  42. TEST_F( VyukovMPMCCycleQueue, defaulted )
  43. {
  44. typedef cds::container::VyukovMPMCCycleQueue< int > test_queue;
  45. test_queue q( 128 );
  46. test(q);
  47. }
  48. TEST_F( VyukovMPMCCycleQueue, stat )
  49. {
  50. struct traits: public cds::container::vyukov_queue::traits
  51. {
  52. typedef cds::opt::v::uninitialized_static_buffer<int, 128> buffer;
  53. };
  54. typedef cds::container::VyukovMPMCCycleQueue< int, traits > test_queue;
  55. test_queue q;
  56. test( q );
  57. }
  58. TEST_F( VyukovMPMCCycleQueue, stat_item_counting )
  59. {
  60. typedef cds::container::VyukovMPMCCycleQueue< int,
  61. cds::container::vyukov_queue::make_traits<
  62. cds::opt::buffer< cds::opt::v::uninitialized_static_buffer<int, 128>>
  63. , cds::opt::item_counter< cds::atomicity::item_counter>
  64. >::type
  65. > test_queue;
  66. test_queue q;
  67. test( q );
  68. }
  69. TEST_F( VyukovMPMCCycleQueue, dynamic )
  70. {
  71. struct traits : public cds::container::vyukov_queue::traits
  72. {
  73. typedef cds::opt::v::uninitialized_dynamic_buffer<int> buffer;
  74. };
  75. typedef cds::container::VyukovMPMCCycleQueue< int, traits > test_queue;
  76. test_queue q( 128 );
  77. test( q );
  78. }
  79. TEST_F( VyukovMPMCCycleQueue, dynamic_item_counting )
  80. {
  81. typedef cds::container::VyukovMPMCCycleQueue< int,
  82. cds::container::vyukov_queue::make_traits<
  83. cds::opt::buffer< cds::opt::v::uninitialized_dynamic_buffer<int>>
  84. , cds::opt::item_counter< cds::atomicity::item_counter>
  85. >::type
  86. > test_queue;
  87. test_queue q( 128 );
  88. test( q );
  89. }
  90. TEST_F( VyukovMPMCCycleQueue, dynamic_padding )
  91. {
  92. struct traits : public cds::container::vyukov_queue::traits
  93. {
  94. typedef cds::opt::v::uninitialized_dynamic_buffer<int> buffer;
  95. enum { padding = 64 };
  96. };
  97. typedef cds::container::VyukovMPMCCycleQueue< int, traits > test_queue;
  98. test_queue q( 128 );
  99. test( q );
  100. }
  101. TEST_F( VyukovMPMCCycleQueue, move )
  102. {
  103. typedef cds::container::VyukovMPMCCycleQueue< std::string > test_queue;
  104. test_queue q( 128 );
  105. test_string( q );
  106. }
  107. TEST_F( VyukovMPMCCycleQueue, move_item_counting )
  108. {
  109. struct traits : public cds::container::vyukov_queue::traits
  110. {
  111. typedef cds::atomicity::item_counter item_counter;
  112. };
  113. typedef cds::container::VyukovMPMCCycleQueue< std::string, traits > test_queue;
  114. test_queue q( 128 );
  115. test_string( q );
  116. }
  117. TEST_F( VyukovMPMCCycleQueue, single_consumer )
  118. {
  119. struct traits: public cds::container::vyukov_queue::traits
  120. {
  121. enum: bool { single_consumer = true };
  122. };
  123. typedef cds::container::VyukovMPMCCycleQueue< int, traits > test_queue;
  124. test_queue q( 128 );
  125. test( q );
  126. test_single_consumer( q );
  127. }
  128. } // namespace