diff --git a/Core/src/Thread.cpp b/Core/src/Thread.cpp index 044a1cb..95b00b5 100644 --- a/Core/src/Thread.cpp +++ b/Core/src/Thread.cpp @@ -38,3 +38,67 @@ void TCThreadBase::CheckReferenceCount() { assert(m_Impl->GetReferenceCount() > 0); } #endif + +//////////////////////////////////////////////////////////////////////////////// +// +// Barrier Implementation +// +//////////////////////////////////////////////////////////////////////////////// + +class TCBarrierImpl : public TCThreadBaseImpl { +private: + unsigned int m_ThreadLimit; + unsigned int m_ThreadCount; + unsigned int m_Times; + + TCMutex m_Mutex; + TCConditionVariable m_CV; + +public: + TCBarrierImpl(int threads) + : TCThreadBaseImpl() + , m_ThreadCount(threads) + , m_ThreadLimit(threads) + , m_Times(0) + { + assert(threads > 0); + } + + virtual ~TCBarrierImpl() { } + + bool Wait() { + TCLock lock(m_Mutex); + unsigned int times = m_Times; + + if(--m_ThreadCount == 0) { + m_Times = 0; + m_ThreadCount = m_ThreadLimit; + m_CV.NotifyAll(); + return true; + } + + while(times == m_Times) { + m_CV.Wait(lock); + } + return false; + } +}; + +class TCBarrierImplFactory : public TCThreadBaseImplFactory { +private: + int m_NumThreads; +public: + TCBarrierImplFactory(int threads) : TCThreadBaseImplFactory(), m_NumThreads(threads) { } + virtual ~TCBarrierImplFactory() { } + virtual TCThreadBaseImpl *CreateImpl() const { + return new TCBarrierImpl(m_NumThreads); + } +}; + +TCBarrier::TCBarrier(int threads) + : TCThreadBase(TCBarrierImplFactory(threads)) +{ } + +void TCBarrier::Wait() { + ((TCBarrierImpl *)m_Impl)->Wait(); +} diff --git a/Core/src/Thread.h b/Core/src/Thread.h index 5cea1ac..b7435e1 100644 --- a/Core/src/Thread.h +++ b/Core/src/Thread.h @@ -111,4 +111,16 @@ class TCConditionVariable : public TCThreadBase { void NotifyAll(); }; +//////////////////////////////////////////////////////////////////////////////// +// +// Barrier implementation +// +//////////////////////////////////////////////////////////////////////////////// + +class TCBarrier : public TCThreadBase { + public: + TCBarrier(int threads); + void Wait(); +}; + #endif //__TEX_COMP_THREAD_H__