Fix issue#10: removed unnecessary null pointer checks
[libcds.git] / tests / cppunit / thread.cpp
1 //$$CDS-header$$
2
3 #include "cppunit/thread.h"
4 #include <boost/date_time/posix_time/posix_time_types.hpp>
5
6 namespace CppUnitMini {
7
8     void TestThread::threadEntryPoint( TestThread * pInst )
9     {
10         pInst->run();
11     }
12
13     void TestThread::create()
14     {
15         m_pThread = new boost::thread( threadEntryPoint, this );
16     }
17
18     void TestThread::run()
19     {
20         try {
21             init();
22             m_Pool.onThreadInitDone( this );
23
24             test();
25             m_Pool.onThreadTestDone( this );
26
27             fini();
28             m_Pool.onThreadFiniDone( this );
29         }
30         catch ( std::exception& ex )
31         {
32             m_Pool.m_Test.message( "EXCEPTION in working thread: ");
33             m_Pool.m_Test.message( ex.what() );
34         }
35     }
36
37     void TestThread::error(const char *in_macroName, const char *in_macro, const char *in_file, int in_line)
38     {
39         m_Pool.m_Test.error( in_macroName, in_macro, in_file, in_line );
40     }
41
42
43     ThreadPool::~ThreadPool()
44     {
45         delete m_pBarrierStart;
46         delete m_pBarrierDone;
47
48         for ( size_t i = 0; i < m_arrThreads.size(); ++i )
49             delete m_arrThreads[i];
50         m_arrThreads.resize( 0 );
51     }
52
53     void    ThreadPool::add( TestThread * pThread, size_t nCount )
54     {
55         pThread->m_nThreadNo = m_arrThreads.size();
56         m_arrThreads.push_back( pThread );
57         while ( --nCount ) {
58             TestThread * p = pThread->clone();
59             if ( p ) {
60                 p->m_nThreadNo = m_arrThreads.size();
61                 m_arrThreads.push_back( p );
62             }
63         }
64     }
65
66     void    ThreadPool::run()
67     {
68         const size_t nThreadCount = m_arrThreads.size();
69         m_pBarrierStart = new boost::barrier( (unsigned int) nThreadCount );
70         // nThreadCount threads + current thread
71         m_pBarrierDone = new boost::barrier( (unsigned int) (nThreadCount + 1) );
72
73         for ( size_t i = 0; i < nThreadCount; ++i )
74             m_arrThreads[i]->create();
75
76         // Wait while all threads is done
77         m_pBarrierDone->wait();
78         boost::this_thread::sleep(boost::posix_time::milliseconds(500));
79     }
80
81     void ThreadPool::run( unsigned int nDuration )
82     {
83         const size_t nThreadCount = m_arrThreads.size();
84         m_pBarrierStart = new boost::barrier( (unsigned int) nThreadCount );
85         m_pBarrierDone = new boost::barrier( (unsigned int) (nThreadCount + 1) );
86
87         for ( size_t i = 0; i < nThreadCount; ++i )
88             m_arrThreads[i]->create();
89
90         boost::system_time stEnd( boost::get_system_time() + boost::posix_time::seconds( nDuration ) );
91         do {
92             boost::this_thread::sleep( stEnd );
93         } while ( boost::get_system_time() < stEnd );
94
95         for ( size_t i = 0; i < nThreadCount; ++i )
96             m_arrThreads[i]->stop();
97
98         // Wait while all threads is done
99         m_pBarrierDone->wait();
100         boost::this_thread::sleep(boost::posix_time::milliseconds(500));
101     }
102
103     void    ThreadPool::onThreadInitDone( TestThread * pThread )
104     {
105         // Calls in context of caller thread
106         // Wait while all threads started
107         m_pBarrierStart->wait();
108
109         pThread->m_Timer.reset();
110     }
111
112     void    ThreadPool::onThreadTestDone( TestThread * pThread )
113     {
114         // Calls in context of caller thread
115         pThread->m_nDuration = pThread->m_Timer.duration();
116     }
117
118     void    ThreadPool::onThreadFiniDone( TestThread * /*pThread*/ )
119     {
120         // Calls in context of caller thread
121         // Wait while all threads done
122         m_pBarrierDone->wait();
123     }
124 }