3 #include "cppunit/thread.h"
4 #include "pqueue/pqueue_item.h"
5 #include "pqueue/pqueue_type.h"
12 #define TEST_CASE( Q ) void Q() { test< Types<pqueue::SimpleValue>::Q >(); }
13 #define TEST_BOUNDED( Q ) void Q() { test_bounded< Types<pqueue::SimpleValue>::Q >(); }
16 static size_t s_nThreadCount = 8;
17 static size_t s_nQueueSize = 2000000;
23 class PQueue_Pop: public CppUnitMini::TestCase
26 template <class PQueue>
27 class Pusher: public CppUnitMini::TestThread
29 virtual TestThread * clone()
31 return new Pusher( *this );
37 typedef std::vector<size_t> array_type;
41 Pusher( CppUnitMini::ThreadPool& pool, PQueue& q )
42 : CppUnitMini::TestThread( pool )
46 : CppUnitMini::TestThread( src )
47 , m_Queue( src.m_Queue )
52 return static_cast<PQueue_Pop&>( m_Pool.m_Test );
57 cds::threading::Manager::attachThread();
61 cds::threading::Manager::detachThread();
68 for ( array_type::const_iterator it = m_arr.begin(); it != m_arr.end(); ++it ) {
69 if ( !m_Queue.push( SimpleValue( *it ) ))
74 void prepare( size_t nStart, size_t nEnd )
76 m_arr.reserve( nEnd - nStart );
77 for ( size_t i = nStart; i < nEnd; ++i )
79 shuffle( m_arr.begin(), m_arr.end() );
83 template <class PQueue>
84 class Popper: public CppUnitMini::TestThread
86 virtual TestThread * clone()
88 return new Popper( *this );
98 Popper( CppUnitMini::ThreadPool& pool, PQueue& q )
99 : CppUnitMini::TestThread( pool )
102 Popper( Popper& src )
103 : CppUnitMini::TestThread( src )
104 , m_Queue( src.m_Queue )
107 PQueue_Pop& getTest()
109 return static_cast<PQueue_Pop&>( m_Pool.m_Test );
114 cds::threading::Manager::attachThread();
118 cds::threading::Manager::detachThread();
130 if ( m_Queue.pop( val )) {
134 while ( !m_Queue.empty() ) {
135 if ( m_Queue.pop( val )) {
137 if ( val.key > nPrevKey )
139 else if ( val.key == nPrevKey )
153 template <class PQueue>
157 test_with( testQueue );
160 template <class PQueue>
163 std::unique_ptr<PQueue> pq( new PQueue(s_nQueueSize) );
164 test_with( *pq.get() );
167 template <class PQueue>
168 void test_with( PQueue& testQueue )
170 size_t const nThreadItemCount = s_nQueueSize / s_nThreadCount;
174 CppUnitMini::ThreadPool pool( *this );
175 pool.add( new Pusher<PQueue>( pool, testQueue ), s_nThreadCount );
178 for ( CppUnitMini::ThreadPool::iterator it = pool.begin(); it != pool.end(); ++it ) {
179 Pusher<PQueue> * pThread = static_cast<Pusher<PQueue> *>(*it);
180 pThread->prepare( nStart, nStart + nThreadItemCount );
181 nStart += nThreadItemCount;
184 CPPUNIT_MSG( " Push, thread count=" << s_nThreadCount << ", item count=" << nThreadItemCount * s_nThreadCount << " ..." );
186 CPPUNIT_MSG( " Duration=" << pool.avgDuration() );
191 CppUnitMini::ThreadPool pool( *this );
192 pool.add( new Popper<PQueue>( pool, testQueue ), s_nThreadCount );
194 CPPUNIT_MSG( " Pop, thread count=" << s_nThreadCount << ", item count=" << nThreadItemCount * s_nThreadCount << " ..." );
196 CPPUNIT_MSG( " Duration=" << pool.avgDuration() );
199 size_t nTotalPopped = 0;
200 size_t nTotalError = 0;
201 size_t nTotalErrorEq = 0;
202 size_t nTotalFailed = 0;
203 for ( CppUnitMini::ThreadPool::iterator it = pool.begin(); it != pool.end(); ++it ) {
204 Popper<PQueue> * pThread = static_cast<Popper<PQueue> *>(*it);
206 nTotalPopped += pThread->m_nPopSuccess;
207 nTotalError += pThread->m_nPopError;
208 nTotalErrorEq += pThread->m_nPopErrorEq;
209 nTotalFailed += pThread->m_nPopFailed;
212 CPPUNIT_MSG( " Total: popped=" << nTotalPopped << ", empty pop=" << nTotalFailed
213 << "\n Errors: pop equal=" << nTotalErrorEq << ", priority violation=" << nTotalError
215 CPPUNIT_CHECK( nTotalPopped == nThreadItemCount * s_nThreadCount );
216 CPPUNIT_CHECK( nTotalError == 0 );
217 CPPUNIT_CHECK( nTotalErrorEq == 0 );
220 CPPUNIT_MSG( testQueue.statistics() );
223 void setUpParams( const CppUnitMini::TestCfg& cfg ) {
224 s_nThreadCount = cfg.getULong("ThreadCount", (unsigned long) s_nThreadCount );
225 s_nQueueSize = cfg.getULong("QueueSize", (unsigned long) s_nQueueSize );
229 #include "pqueue/pqueue_defs.h"
230 CDSUNIT_DECLARE_MSPriorityQueue
231 CDSUNIT_DECLARE_EllenBinTree
232 CDSUNIT_DECLARE_SkipList
233 CDSUNIT_DECLARE_FCPriorityQueue
234 CDSUNIT_DECLARE_StdPQueue
236 CPPUNIT_TEST_SUITE_(PQueue_Pop, "PQueue_Push")
237 CDSUNIT_TEST_MSPriorityQueue
238 CDSUNIT_TEST_EllenBinTree
239 CDSUNIT_TEST_SkipList
240 CDSUNIT_TEST_FCPriorityQueue
241 CDUNIT_TEST_StdPQueue
242 CPPUNIT_TEST_SUITE_END();
247 CPPUNIT_TEST_SUITE_REGISTRATION(pqueue::PQueue_Pop);