unit testing - CountDownLatch in C++ using Boost Mutexes and Condition -


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