i tried implement countdownlatch using boost mutexes , condition variable. below code , know if need add else.
how can unit test code well?
template< class typeval > class atomiccounter { public: atomiccounter( typeval val ) : m_typeval( val ) { } atomiccounter() : m_typeval(0) { } atomiccounter(const atomiccounter& cpy) : m_typeval(cpy.m_typeval) { boost::mutex::scoped_lock scoped_lock(cpy.m_atomicmutex); m_typeval = cpy.m_typeval; } const atomiccounter& operator=(const atomiccounter& other) { if (this == &other) return *this; boost::mutex::scoped_lock lock1(&m_atomicmutex < &other.m_atomicmutex ? m_atomicmutex : other.m_atomicmutex); boost::mutex::scoped_lock lock2(&m_atomicmutex > &other.m_atomicmutex ? m_atomicmutex : other.m_atomicmutex); m_typeval = other.m_typeval; return *this; } virtual ~atomiccounter() { } const typeval& getcount() const { boost::mutex::scoped_lock lock( m_atomicmutex ); return m_typeval; } const typeval& setcount( const typeval &val ) { boost::mutex::scoped_lock lock( m_atomicmutex ); m_typeval = val; return m_typeval; } const typeval& increment() { boost::mutex::scoped_lock lock( m_atomicmutex ); m_typeval++ ; return m_typeval; } const typeval& decrement() { boost::mutex::scoped_lock lock( m_atomicmutex ); m_typeval-- ; return m_typeval; } const typeval& increment(const typeval& t) { boost::mutex::scoped_lock lock( m_atomicmutex ); m_typeval+=t ; return m_typeval; } const typeval& decrement(const typeval& t) { boost::mutex::scoped_lock lock( m_atomicmutex ); m_typeval-=t ; return m_typeval; } private: mutable boost::mutex m_atomicmutex; typeval m_typeval; }; class countdownlatch { public: countdownlatch( int count ): m_cdlcount( count ) { } countdownlatch(const countdownlatch& cpy) { boost::unique_lock<boost::mutex>::unique_lock(const_cast<boost::mutex&>(cpy.m_cdlmutex)); m_cdlcount = cpy.m_cdlcount; } const countdownlatch& operator=(const countdownlatch& other) { if (this == &other) return *this; boost::mutex::scoped_lock lock1(const_cast<boost::mutex&>(&m_cdlmutex < &other.m_cdlmutex ? m_cdlmutex : other.m_cdlmutex)); boost::mutex::scoped_lock lock2(const_cast<boost::mutex&>(&m_cdlmutex > &other.m_cdlmutex ? m_cdlmutex : other.m_cdlmutex)); m_cdlcount = other.m_cdlcount; return *this; } virtual ~countdownlatch() { } void wait() { boost::mutex::scoped_lock lock( m_cdlmutex ); if( m_cdlcount.getcount() > 0 ) { m_cdlcondition.wait( lock ); } } void wait( uint64_t timeoutmicros ) { boost::mutex::scoped_lock lock( m_cdlmutex ); if( m_cdlcount.getcount() > 0 ) { boost::posix_time::time_duration td = boost::posix_time::milliseconds( timeoutmicros ); m_cdlcondition.timed_wait( lock, td ); } } void countdown() { boost::mutex::scoped_lock lock( m_cdlmutex ); if( m_cdlcount.decrement() == 0 ) { m_cdlcondition.notify_all(); } } int getcount() { return m_cdlcount.getcount(); } private: boost::mutex m_cdlmutex; boost::condition_variable m_cdlcondition; atomiccounter< int > m_cdlcount; };
for unit testing, can try stress-testing. example, countdownlatch, create 25 test threads simultaneously call countdownlatch::countdown()
, 25 other threads simultaneously call countdownlatch::getcount()
, , 25 others threads call countdownlatch::wait()
. make things more simultaneous, use barrier, or make threads sleep until same absolute time. make sure threads terminate (no deadlocks) joining of them. make sure countdownlatch::m_cdlcount
ends @ zero.
run same test many times (for reasonable amount of time).
you can use same basic idea atomiccounter.
there other techniques testing multitheaded code, 1 i'm familiar with.
Comments
Post a Comment