X-Git-Url: http://plrg.eecs.uci.edu/git/?p=libcds.git;a=blobdiff_plain;f=test%2Fstress%2Fqueue%2Fpush_pop.cpp;h=f696bc11ffeac6f565b8dd01b45ff868ba66cbb2;hp=7c3ff6f442d794cac4fd052b8de41fb697edcc8b;hb=HEAD;hpb=025501fba2f37ec3e8dd0f187c49fc22c18ed951 diff --git a/test/stress/queue/push_pop.cpp b/test/stress/queue/push_pop.cpp index 7c3ff6f4..f696bc11 100644 --- a/test/stress/queue/push_pop.cpp +++ b/test/stress/queue/push_pop.cpp @@ -1,7 +1,7 @@ /* This file is a part of libcds - Concurrent Data Structures library - (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016 + (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017 Source code repo: http://github.com/khizmax/libcds/ Download: http://sourceforge.net/projects/libcds/files/ @@ -32,6 +32,7 @@ #include #include +#include // Multi-threaded queue push/pop test namespace { @@ -39,17 +40,28 @@ namespace { static size_t s_nConsumerThreadCount = 4; static size_t s_nProducerThreadCount = 4; static size_t s_nQueueSize = 4000000; + static size_t s_nMSQueueSize = 4000000; + static size_t s_nMoirQueueSize = 4000000; + static size_t s_nBasketQueueSize = 4000000; + static size_t s_nOptimisticQueueSize = 4000000; + static size_t s_nRWQueueSize = 4000000; + static size_t s_nSegmentedQueueSize = 400000; + static size_t s_nVyukovQueueSize = 40000; + static size_t s_nHeavyValueSize = 100; static std::atomic s_nProducerDone( 0 ); + struct old_value + { + size_t nNo; + size_t nWriterNo; + }; + + template class queue_push_pop: public cds_test::stress_fixture { protected: - struct value_type - { - size_t nNo; - size_t nWriterNo; - }; + using value_type = Value; enum { producer_thread, @@ -167,7 +179,7 @@ namespace { const size_t nTotalWriters = s_nProducerThreadCount; value_type v; while ( true ) { - if ( m_Queue.pop( v ) ) { + if ( m_Queue.pop( v )) { ++m_nPopped; if ( v.nWriterNo < nTotalWriters ) m_WriterData[ v.nWriterNo ].push_back( v.nNo ); @@ -178,7 +190,7 @@ namespace { ++m_nPopEmpty; if ( s_nProducerDone.load() >= nTotalWriters ) { - if ( m_Queue.empty() ) + if ( m_Queue.empty()) break; } } @@ -195,8 +207,8 @@ namespace { { cds_test::thread_pool& pool = get_pool(); - typedef Consumer Consumer; - typedef Producer Producer; + typedef Consumer consumer_type; + typedef Producer producer_type; size_t nPostTestPops = 0; { @@ -210,12 +222,12 @@ namespace { size_t nPoppedItems = 0; size_t nPushFailed = 0; - std::vector< Consumer * > arrConsumer; + std::vector< consumer_type * > arrConsumer; for ( size_t i = 0; i < pool.size(); ++i ) { cds_test::thread& thr = pool.get(i); if ( thr.type() == consumer_thread ) { - Consumer& consumer = static_cast( thr ); + consumer_type& consumer = static_cast( thr ); nTotalPops += consumer.m_nPopped; nPopFalse += consumer.m_nPopEmpty; arrConsumer.push_back( &consumer ); @@ -230,15 +242,15 @@ namespace { else { assert( thr.type() == producer_thread ); - Producer& producer = static_cast( thr ); + producer_type& producer = static_cast( thr ); nPushFailed += producer.m_nPushFailed; - EXPECT_EQ( producer.m_nPushFailed, 0 ) << "producer_thread_no " << i; + EXPECT_EQ( producer.m_nPushFailed, 0u ) << "producer_thread_no " << i; } } EXPECT_EQ( nTotalPops, nPoppedItems ); EXPECT_EQ( nTotalPops + nPostTestPops, s_nQueueSize ) << "nTotalPops=" << nTotalPops << ", nPostTestPops=" << nPostTestPops; - EXPECT_TRUE( q.empty() ); + EXPECT_TRUE( q.empty()); // Test consistency of popped sequence for ( size_t nWriter = 0; nWriter < s_nProducerThreadCount; ++nWriter ) { @@ -259,12 +271,12 @@ namespace { arrData.push_back( *it ); } - std::sort( arrData.begin(), arrData.end() ); + std::sort( arrData.begin(), arrData.end()); for ( size_t i=1; i < arrData.size(); ++i ) { EXPECT_EQ( arrData[i - 1] + 1, arrData[i] ) << "producer=" << nWriter; } - EXPECT_EQ( arrData[0], 0 ) << "producer=" << nWriter; + EXPECT_EQ( arrData[0], 0u ) << "producer=" << nWriter; EXPECT_EQ( arrData[arrData.size() - 1], m_nThreadPushCount - 1 ) << "producer=" << nWriter; } } @@ -298,6 +310,20 @@ namespace { propout() << q.statistics(); } + private: + static void set_array_size( size_t size ) { + const bool tmp = fc_test::has_set_array_size::value; + set_array_size(size, std::integral_constant()); + } + + static void set_array_size(size_t size, std::true_type){ + value_type::set_array_size(size); + } + + static void set_array_size(size_t, std::false_type) + { + } + public: static void SetUpTestCase() { @@ -307,50 +333,112 @@ namespace { s_nProducerThreadCount = cfg.get_size_t( "ProducerCount", s_nProducerThreadCount ); s_nQueueSize = cfg.get_size_t( "QueueSize", s_nQueueSize ); + s_nMSQueueSize = cfg.get_size_t( "MSQueueSize", s_nMSQueueSize ); + s_nMoirQueueSize = cfg.get_size_t( "MoirQueueSize", s_nMoirQueueSize ); + s_nBasketQueueSize = cfg.get_size_t( "BasketQueueSize", s_nBasketQueueSize ); + s_nOptimisticQueueSize = cfg.get_size_t( "OptimisticQueueSize", s_nOptimisticQueueSize ); + s_nRWQueueSize = cfg.get_size_t( "RWQueueSize", s_nRWQueueSize ); + + s_nVyukovQueueSize = cfg.get_size_t( "VyukovQueueSize", s_nVyukovQueueSize ); + s_nSegmentedQueueSize = cfg.get_size_t( "SegmentedQueueSize", s_nSegmentedQueueSize ); + s_nHeavyValueSize = cfg.get_size_t( "HeavyValueSize", s_nHeavyValueSize ); + if ( s_nConsumerThreadCount == 0u ) s_nConsumerThreadCount = 1; if ( s_nProducerThreadCount == 0u ) s_nProducerThreadCount = 1; if ( s_nQueueSize == 0u ) s_nQueueSize = 1000; + if ( s_nHeavyValueSize == 0 ) + s_nHeavyValueSize = 1; + + set_array_size( s_nHeavyValueSize ); } //static void TearDownTestCase(); }; - CDSSTRESS_MSQueue( queue_push_pop ) - CDSSTRESS_MoirQueue( queue_push_pop ) - CDSSTRESS_BasketQueue( queue_push_pop ) - CDSSTRESS_OptimsticQueue( queue_push_pop ) - CDSSTRESS_FCQueue( queue_push_pop ) - CDSSTRESS_FCDeque( queue_push_pop ) - CDSSTRESS_RWQueue( queue_push_pop ) - CDSSTRESS_StdQueue( queue_push_pop ) + using fc_with_heavy_value = queue_push_pop< fc_test::heavy_value<36000> >; + using simple_queue_push_pop = queue_push_pop<>; #undef CDSSTRESS_Queue_F -#define CDSSTRESS_Queue_F( test_fixture, type_name, level ) \ +#define CDSSTRESS_Queue_F( test_fixture, type_name ) \ TEST_F( test_fixture, type_name ) \ { \ - if ( !check_detail_level( level )) return; \ typedef queue::Types< value_type >::type_name queue_type; \ - queue_type queue( s_nQueueSize ); \ + queue_type queue; \ + s_nQueueSize = s_nMSQueueSize; \ + test( queue ); \ + } + + CDSSTRESS_MSQueue( simple_queue_push_pop ) + +#undef CDSSTRESS_Queue_F +#define CDSSTRESS_Queue_F( test_fixture, type_name ) \ + TEST_F( test_fixture, type_name ) \ + { \ + typedef queue::Types< value_type >::type_name queue_type; \ + queue_type queue; \ + s_nQueueSize = s_nMoirQueueSize; \ + test( queue ); \ + } + CDSSTRESS_MoirQueue( simple_queue_push_pop ) + +#undef CDSSTRESS_Queue_F +#define CDSSTRESS_Queue_F( test_fixture, type_name ) \ + TEST_F( test_fixture, type_name ) \ + { \ + typedef queue::Types< value_type >::type_name queue_type; \ + queue_type queue; \ + s_nQueueSize = s_nBasketQueueSize; \ + test( queue ); \ + } + CDSSTRESS_BasketQueue( simple_queue_push_pop ) + +#undef CDSSTRESS_Queue_F +#define CDSSTRESS_Queue_F( test_fixture, type_name ) \ + TEST_F( test_fixture, type_name ) \ + { \ + typedef queue::Types< value_type >::type_name queue_type; \ + queue_type queue; \ + s_nQueueSize = s_nOptimisticQueueSize; \ test( queue ); \ } + CDSSTRESS_OptimsticQueue( simple_queue_push_pop ) - CDSSTRESS_TsigasQueue( queue_push_pop ) - CDSSTRESS_VyukovQueue( queue_push_pop ) +#undef CDSSTRESS_Queue_F +#define CDSSTRESS_Queue_F( test_fixture, type_name ) \ + TEST_F( test_fixture, type_name ) \ + { \ + typedef queue::Types< value_type >::type_name queue_type; \ + queue_type queue; \ + s_nQueueSize = s_nRWQueueSize; \ + test( queue ); \ + } + CDSSTRESS_RWQueue( simple_queue_push_pop ) #undef CDSSTRESS_Queue_F +#define CDSSTRESS_Queue_F( test_fixture, type_name ) \ + TEST_F( test_fixture, type_name ) \ + { \ + size_t old_queue_size = s_nQueueSize; \ + s_nQueueSize = s_nVyukovQueueSize; \ + typedef queue::Types< value_type >::type_name queue_type; \ + queue_type queue( s_nQueueSize ); \ + test( queue ); \ + s_nQueueSize = old_queue_size; \ + } + //CDSSTRESS_VyukovQueue( simple_queue_push_pop ) // ******************************************************************** // SegmentedQueue test class segmented_queue_push_pop - : public queue_push_pop + : public queue_push_pop<> , public ::testing::WithParamInterface< size_t > { - typedef queue_push_pop base_class; + typedef queue_push_pop<> base_class; protected: @@ -377,8 +465,7 @@ namespace { if ( bIterative && quasi_factor > 4 ) { for ( size_t qf = 4; qf <= quasi_factor; qf *= 2 ) args.push_back( qf ); - } - else { + } else { if ( quasi_factor > 2 ) args.push_back( quasi_factor ); else @@ -389,18 +476,29 @@ namespace { } }; -#define CDSSTRESS_Queue_F( test_fixture, type_name, level ) \ +#undef CDSSTRESS_Queue_F +#define CDSSTRESS_Queue_F( test_fixture, type_name ) \ TEST_P( test_fixture, type_name ) \ { \ - if ( !check_detail_level( level )) return; \ typedef typename queue::Types::type_name queue_type; \ + s_nQueueSize = s_nSegmentedQueueSize; \ test< queue_type >(); \ } CDSSTRESS_SegmentedQueue( segmented_queue_push_pop ) +#ifdef CDSTEST_GTEST_INSTANTIATE_TEST_CASE_P_HAS_4TH_ARG + static std::string get_test_parameter_name( testing::TestParamInfo const& p ) + { + return std::to_string( p.param ); + } + INSTANTIATE_TEST_CASE_P( SQ, + segmented_queue_push_pop, + ::testing::ValuesIn( segmented_queue_push_pop::get_test_parameters()), get_test_parameter_name ); +#else INSTANTIATE_TEST_CASE_P( SQ, segmented_queue_push_pop, ::testing::ValuesIn( segmented_queue_push_pop::get_test_parameters())); +#endif } // namespace