Go to the documentation of this file.00001
00002
00003
00004
00005
00006
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
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
00097 SleepConditionVariableCS( &m_allThreadsReachedSync, &m_numThreadsReachedSyncLock, INFINITE);
00098 };
00099
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 }
00238
00239 #endif //OGDF_THREAD_BARRIER_H