3 #include "cppunit/thread.h"
4 #include "pqueue/pqueue_item.h"
5 #include "pqueue/pqueue_type.h"
8 #include <algorithm> // random_shuffle
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_Push: 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 )
50 PQueue_Push& getTest()
52 return static_cast<PQueue_Push&>( 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 std::random_shuffle( m_arr.begin(), m_arr.end() );
84 template <class PQueue>
85 void analyze( CppUnitMini::ThreadPool& pool, PQueue& testQueue )
87 size_t nThreadItems = s_nQueueSize / s_nThreadCount;
88 for ( CppUnitMini::ThreadPool::iterator it = pool.begin(); it != pool.end(); ++it ) {
89 Pusher<PQueue> * pThread = static_cast<Pusher<PQueue> *>(*it);
90 CPPUNIT_CHECK_EX( pThread->m_nPushError == 0, "Thread push error count=" << pThread->m_nPushError );
92 CPPUNIT_MSG( " Duration=" << pool.avgDuration() );
93 CPPUNIT_ASSERT( !testQueue.empty() );
95 typedef std::vector<size_t> vector_type;
97 arr.reserve( s_nQueueSize );
100 CPPUNIT_MSG( " Pop (single-threaded)..." );
103 while ( testQueue.pop( val )) {
105 arr.push_back( val.key );
107 CPPUNIT_MSG( " Duration=" << timer.duration() );
109 CPPUNIT_CHECK( arr.size() == nThreadItems * s_nThreadCount );
110 vector_type::const_iterator it = arr.begin();
113 size_t nErrCount = 0;
114 for ( vector_type::const_iterator itEnd = arr.end(); it != itEnd; ++it ) {
115 if ( nPrev - 1 != *it ) {
116 if ( ++nErrCount < 10 ) {
117 CPPUNIT_CHECK_EX( nPrev - 1 == *it, "Expected=" << nPrev - 1 << ", current=" << *it );
123 CPPUNIT_CHECK_EX( nErrCount == 0, "Error count=" << nErrCount );
126 template <class PQueue>
131 CppUnitMini::ThreadPool pool( *this );
132 pool.add( new Pusher<PQueue>( pool, testQueue ), s_nThreadCount );
135 size_t nThreadItemCount = s_nQueueSize / s_nThreadCount;
136 for ( CppUnitMini::ThreadPool::iterator it = pool.begin(); it != pool.end(); ++it ) {
137 Pusher<PQueue> * pThread = static_cast<Pusher<PQueue> *>(*it);
138 pThread->prepare( nStart, nStart + nThreadItemCount );
139 nStart += nThreadItemCount;
142 CPPUNIT_MSG( " Push test, thread count=" << s_nThreadCount << ", item count=" << nThreadItemCount * s_nThreadCount << " ..." );
145 analyze( pool, testQueue );
147 CPPUNIT_MSG( testQueue.statistics() );
150 template <class PQueue>
154 size_t nThreadItemCount = s_nQueueSize / s_nThreadCount;
156 std::unique_ptr<PQueue> pq( new PQueue(s_nQueueSize) );
158 CppUnitMini::ThreadPool pool( *this );
159 pool.add( new Pusher<PQueue>( pool, *pq ), s_nThreadCount );
161 for ( CppUnitMini::ThreadPool::iterator it = pool.begin(); it != pool.end(); ++it ) {
162 Pusher<PQueue> * pThread = static_cast<Pusher<PQueue> *>(*it);
163 pThread->prepare( nStart, nStart + nThreadItemCount );
164 nStart += nThreadItemCount;
167 CPPUNIT_MSG( " Push test, thread count=" << s_nThreadCount << ", item count=" << nThreadItemCount * s_nThreadCount << " ..." );
170 analyze( pool, *pq );
172 CPPUNIT_MSG( pq->statistics() );
175 void setUpParams( const CppUnitMini::TestCfg& cfg ) {
176 s_nThreadCount = cfg.getULong("ThreadCount", (unsigned long) s_nThreadCount );
177 s_nQueueSize = cfg.getULong("QueueSize", (unsigned long) s_nQueueSize );
181 #include "pqueue/pqueue_defs.h"
182 CDSUNIT_DECLARE_MSPriorityQueue
183 CDSUNIT_DECLARE_EllenBinTree
184 CDSUNIT_DECLARE_SkipList
185 CDSUNIT_DECLARE_FCPriorityQueue
186 CDSUNIT_DECLARE_StdPQueue
188 CPPUNIT_TEST_SUITE(PQueue_Push)
189 CDSUNIT_TEST_MSPriorityQueue
190 CDSUNIT_TEST_EllenBinTree
191 CDSUNIT_TEST_SkipList
192 CDSUNIT_TEST_FCPriorityQueue
193 CDUNIT_TEST_StdPQueue
194 CPPUNIT_TEST_SUITE_END();
199 CPPUNIT_TEST_SUITE_REGISTRATION(pqueue::PQueue_Push);