3 #include "cppunit/thread.h"
4 #include "pqueue/pqueue_item.h"
5 #include "pqueue/pqueue_type.h"
8 #include <algorithm> // random_shuffle
9 #include <cds/details/std/memory.h>
13 #define TEST_CASE( Q ) void Q() { test< Types<pqueue::SimpleValue>::Q >(); }
14 #define TEST_BOUNDED( Q ) void Q() { test_bounded< Types<pqueue::SimpleValue>::Q >(); }
17 static size_t s_nThreadCount = 8;
18 static size_t s_nQueueSize = 2000000;
24 class PQueue_Pop: public CppUnitMini::TestCase
27 template <class PQueue>
28 class Pusher: public CppUnitMini::TestThread
30 virtual TestThread * clone()
32 return new Pusher( *this );
38 typedef std::vector<size_t> array_type;
42 Pusher( CppUnitMini::ThreadPool& pool, PQueue& q )
43 : CppUnitMini::TestThread( pool )
47 : CppUnitMini::TestThread( src )
48 , m_Queue( src.m_Queue )
53 return static_cast<PQueue_Pop&>( m_Pool.m_Test );
58 cds::threading::Manager::attachThread();
62 cds::threading::Manager::detachThread();
69 for ( array_type::const_iterator it = m_arr.begin(); it != m_arr.end(); ++it ) {
70 if ( !m_Queue.push( SimpleValue( *it ) ))
75 void prepare( size_t nStart, size_t nEnd )
77 m_arr.reserve( nEnd - nStart );
78 for ( size_t i = nStart; i < nEnd; ++i )
80 std::random_shuffle( m_arr.begin(), m_arr.end() );
84 template <class PQueue>
85 class Popper: public CppUnitMini::TestThread
87 virtual TestThread * clone()
89 return new Popper( *this );
97 typedef std::vector<size_t> array_type;
101 Popper( CppUnitMini::ThreadPool& pool, PQueue& q )
102 : CppUnitMini::TestThread( pool )
105 Popper( Popper& src )
106 : CppUnitMini::TestThread( src )
107 , m_Queue( src.m_Queue )
110 PQueue_Pop& getTest()
112 return static_cast<PQueue_Pop&>( m_Pool.m_Test );
117 cds::threading::Manager::attachThread();
121 cds::threading::Manager::detachThread();
132 if ( m_Queue.pop( val )) {
136 while ( !m_Queue.empty() ) {
137 if ( m_Queue.pop( val )) {
139 if ( val.key >= nPrevKey )
151 template <class PQueue>
155 test_with( testQueue );
158 template <class PQueue>
161 std::unique_ptr<PQueue> pq( new PQueue(s_nQueueSize) );
162 test_with( *pq.get() );
165 template <class PQueue>
166 void test_with( PQueue& testQueue )
168 size_t const nThreadItemCount = s_nQueueSize / s_nThreadCount;
172 CppUnitMini::ThreadPool pool( *this );
173 pool.add( new Pusher<PQueue>( pool, testQueue ), s_nThreadCount );
176 for ( CppUnitMini::ThreadPool::iterator it = pool.begin(); it != pool.end(); ++it ) {
177 Pusher<PQueue> * pThread = static_cast<Pusher<PQueue> *>(*it);
178 pThread->prepare( nStart, nStart + nThreadItemCount );
179 nStart += nThreadItemCount;
182 CPPUNIT_MSG( " Push, thread count=" << s_nThreadCount << ", item count=" << nThreadItemCount * s_nThreadCount << " ..." );
184 CPPUNIT_MSG( " Duration=" << pool.avgDuration() );
189 CppUnitMini::ThreadPool pool( *this );
190 pool.add( new Popper<PQueue>( pool, testQueue ), s_nThreadCount );
192 CPPUNIT_MSG( " Pop, thread count=" << s_nThreadCount << ", item count=" << nThreadItemCount * s_nThreadCount << " ..." );
194 CPPUNIT_MSG( " Duration=" << pool.avgDuration() );
197 size_t nTotalPopped = 0;
198 size_t nTotalError = 0;
199 size_t nTotalFailed = 0;
200 for ( CppUnitMini::ThreadPool::iterator it = pool.begin(); it != pool.end(); ++it ) {
201 Popper<PQueue> * pThread = static_cast<Popper<PQueue> *>(*it);
203 nTotalPopped += pThread->m_nPopSuccess;
204 nTotalError += pThread->m_nPopError;
205 nTotalFailed += pThread->m_nPopFailed;
208 CPPUNIT_MSG( " Total: popped=" << nTotalPopped << ", error=" << nTotalError << ", empty pop=" << nTotalFailed );
209 CPPUNIT_CHECK( nTotalPopped == nThreadItemCount * s_nThreadCount );
210 CPPUNIT_CHECK( nTotalError == 0 );
213 CPPUNIT_MSG( testQueue.statistics() );
216 void setUpParams( const CppUnitMini::TestCfg& cfg ) {
217 s_nThreadCount = cfg.getULong("ThreadCount", (unsigned long) s_nThreadCount );
218 s_nQueueSize = cfg.getULong("QueueSize", (unsigned long) s_nQueueSize );
222 #include "pqueue/pqueue_defs.h"
223 CDSUNIT_DECLARE_MSPriorityQueue
224 CDSUNIT_DECLARE_EllenBinTree
225 CDSUNIT_DECLARE_SkipList
226 CDSUNIT_DECLARE_FCPriorityQueue
227 CDSUNIT_DECLARE_StdPQueue
229 CPPUNIT_TEST_SUITE_(PQueue_Pop, "PQueue_Push")
230 CDSUNIT_TEST_MSPriorityQueue
231 CDSUNIT_TEST_EllenBinTree
232 CDSUNIT_TEST_SkipList
233 CDSUNIT_TEST_FCPriorityQueue
234 CDUNIT_TEST_StdPQueue
235 CPPUNIT_TEST_SUITE_END();
240 CPPUNIT_TEST_SUITE_REGISTRATION(pqueue::PQueue_Pop);