Open
Graph Drawing
Framework

 v.2012.05
 

Barrier.h
Go to the documentation of this file.
00001 /*
00002  * $Revision: 2299 $
00003  * 
00004  * last checkin:
00005  *   $Author: gutwenger $ 
00006  *   $Date: 2012-05-07 15:57:08 +0200 (Mon, 07 May 2012) $ 
00007  ***************************************************************/
00008  
00043 #ifdef _MSC_VER
00044 #pragma once
00045 #endif
00046  
00047 #ifndef OGDF_THREAD_BARRIER_H
00048 #define OGDF_THREAD_BARRIER_H
00049 
00050 #include <ogdf/basic/basic.h>
00051 
00052 #ifdef OGDF_SYSTEM_WINDOWS
00053 #include <windows.h>
00054 #else
00055 #include <pthread.h>
00056 #endif
00057 
00058 namespace ogdf {
00059 
00060 #ifdef OGDF_SYSTEM_WINDOWS
00061 
00062 // if Windows >= Vista, Server 2008
00063 #if (_WIN32_WINNT >= 0x0600)
00064 
00068 class Barrier 
00069 {
00070 public:
00071     inline Barrier(__uint32 numThreads) : m_threadCount(numThreads)
00072     {
00073         InitializeConditionVariable( &m_allThreadsReachedSync);
00074         InitializeCriticalSection( &m_numThreadsReachedSyncLock);
00075         m_numThreadsReachedSync = 0;
00076         m_syncNumber = 0;
00077     };
00078 
00079     ~Barrier() { };
00080 
00081     inline void threadSync()
00082     {
00083         EnterCriticalSection( &m_numThreadsReachedSyncLock);
00084         __uint32 syncNr = m_syncNumber;
00085         m_numThreadsReachedSync++;
00086         if (m_numThreadsReachedSync == m_threadCount)
00087         {
00088             m_syncNumber++; 
00089             WakeAllConditionVariable( &m_allThreadsReachedSync);
00090             m_numThreadsReachedSync = 0;
00091         }
00092         else
00093         {
00094             while (syncNr == m_syncNumber)
00095             {
00096                 // Sleeping while waiting for the Condition Variable to signal, releases (leaves) the CriticalSection temporarily
00097                 SleepConditionVariableCS( &m_allThreadsReachedSync, &m_numThreadsReachedSyncLock, INFINITE);
00098             };
00099             // when awake, whe thread is again in the Critical Section
00100         };
00101         LeaveCriticalSection( &m_numThreadsReachedSyncLock);
00102     };
00103 private:
00104     __uint32 m_threadCount;
00105     CRITICAL_SECTION m_numThreadsReachedSyncLock;
00106     CONDITION_VARIABLE m_allThreadsReachedSync;
00107     __uint32 m_numThreadsReachedSync;
00108     __uint32 m_syncNumber;
00109 };
00110 
00111 #else //(_WIN32_WINNT >= 0x0600)
00112 
00116 class Barrier 
00117 {
00118 public:
00119     inline Barrier(__uint32 numThreads) : m_threadCount(numThreads)
00120     {
00121         m_allThreadsReachedSync = CreateEvent( NULL, TRUE, FALSE, NULL );
00122         InitializeCriticalSection( &m_numThreadsReachedSyncLock);
00123         m_numThreadsReachedSync = 0;
00124         m_syncNumber = 0;
00125     };
00126 
00127     ~Barrier() { };
00128 
00129     inline void threadSync()
00130     {
00131         EnterCriticalSection( &m_numThreadsReachedSyncLock);
00132         __uint32 syncNr = m_syncNumber;
00133         m_numThreadsReachedSync++;
00134         if (m_numThreadsReachedSync == m_threadCount)
00135         {
00136             SetEvent(m_allThreadsReachedSync);
00137             m_syncNumber++; 
00138             m_numThreadsReachedSync = 0;
00139             LeaveCriticalSection( &m_numThreadsReachedSyncLock);
00140         }
00141         else
00142         {           
00143             if ( (m_syncNumber == syncNr) && (m_numThreadsReachedSync == 1) )
00144             {
00145                 ResetEvent(m_allThreadsReachedSync);
00146             };
00147             while (m_syncNumber == syncNr)
00148             {
00149                 LeaveCriticalSection( &m_numThreadsReachedSyncLock);
00150                 WaitForSingleObject(m_allThreadsReachedSync, 100);
00151                 EnterCriticalSection( &m_numThreadsReachedSyncLock);
00152             };
00153             LeaveCriticalSection( &m_numThreadsReachedSyncLock);
00154         };      
00155     };
00156 private:
00157     __uint32 m_threadCount;
00158     CRITICAL_SECTION m_numThreadsReachedSyncLock;
00159     HANDLE m_allThreadsReachedSync;
00160     __uint32 m_numThreadsReachedSync;
00161     __uint32 m_syncNumber;
00162 };
00163 
00164 #endif //(_WIN32_WINNT >= 0x0600)
00165 #else //OGDF_SYSTEM_WINDOWS
00166 
00167 #ifndef OGDF_PTHREAD_BARRRIER
00168 
00169 class Barrier 
00170 {
00171 public:
00172     inline Barrier(__uint32 numThreads) : m_threadCount(numThreads)
00173     {
00174         pthread_cond_init( &m_allThreadsReachedSync, NULL);
00175         pthread_mutex_init( &m_numThreadsReachedSyncLock, NULL);
00176         m_numThreadsReachedSync = 0;
00177         m_syncNumber = 0;
00178     };
00179 
00180     ~Barrier() 
00181     {
00182         pthread_cond_destroy( &m_allThreadsReachedSync);
00183         pthread_mutex_destroy( &m_numThreadsReachedSyncLock); 
00184     };
00185 
00186     inline void threadSync()
00187     {
00188         pthread_mutex_lock( &m_numThreadsReachedSyncLock);
00189         __uint32 syncNr = m_syncNumber;
00190         m_numThreadsReachedSync++;
00191         if (m_numThreadsReachedSync == m_threadCount)
00192         {
00193             m_syncNumber++; 
00194             pthread_cond_signal( &m_allThreadsReachedSync);
00195             m_numThreadsReachedSync = 0;
00196         }
00197         else
00198         {
00199             while (syncNr == m_syncNumber)
00200                 pthread_cond_wait( &m_allThreadsReachedSync, &m_numThreadsReachedSyncLock);
00201         };
00202         pthread_mutex_unlock( &m_numThreadsReachedSyncLock);
00203     };
00204 private:
00205     __uint32 m_threadCount;
00206     pthread_mutex_t m_numThreadsReachedSyncLock;
00207     pthread_cond_t m_allThreadsReachedSync;
00208     __uint32 m_numThreadsReachedSync;
00209     __uint32 m_syncNumber;
00210 };
00211 #else
00212 class Barrier 
00213 {
00214 public:
00215     inline Barrier(__uint32 numThreads) : m_threadCount(numThreads)
00216     {
00217         pthread_barrier_init(&m_barrier, NULL, m_threadCount);
00218     };
00219 
00220     ~Barrier() 
00221     {
00222          pthread_barrier_destroy(&m_barrier);
00223     };
00224 
00225     inline void threadSync()
00226     {
00227         pthread_barrier_wait(&m_barrier);
00228     };
00229 private:
00230     pthread_barrier_t m_barrier;
00231     __uint32 m_threadCount;
00232 };
00233 #endif
00234 
00235 #endif //OGDF_SYSTEM_UNIX
00236 
00237 } // end of namespace ogdf
00238 
00239 #endif //OGDF_THREAD_BARRIER_H