00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef FALCON_MT_POSIX_H
00018 #define FALCON_MT_POSIX_H
00019
00020 #include <pthread.h>
00021 #include <errno.h>
00022 #include <falcon/setup.h>
00023 #include <falcon/types.h>
00024 #include <falcon/fassert.h>
00025
00026 namespace Falcon
00027 {
00028
00029 inline void mutex_lock( pthread_mutex_t& mtx )
00030 {
00031 #ifdef NDEBUG
00032 pthread_mutex_lock(&mtx);
00033 #else
00034 int res = pthread_mutex_lock(&mtx);
00035 fassert( res != EINVAL );
00036 fassert( res != EDEADLK );
00037 fassert( res == 0 );
00038 #endif
00039 }
00040
00041 inline void mutex_unlock( pthread_mutex_t& mtx )
00042 {
00043 #ifdef NDEBUG
00044 pthread_mutex_unlock(&mtx);
00045 #else
00046 int res = pthread_mutex_unlock(&mtx);
00047 fassert( res == 0 );
00048 #endif
00049 }
00050
00051
00052 inline void cv_wait( pthread_cond_t& cv, pthread_mutex_t& mtx )
00053 {
00054 #ifdef NDEBUG
00055 pthread_cond_wait(&cv, &mtx);
00056 #else
00057 int res = pthread_cond_wait(&cv, &mtx);
00058 fassert( res == 0 );
00059 #endif
00060 }
00061
00062 inline void cv_broadcast( pthread_cond_t& cv )
00063 {
00064 #ifdef NDEBUG
00065 pthread_cond_broadcast(&cv);
00066 #else
00067 int res = pthread_cond_broadcast(&cv);
00068 fassert( res == 0 );
00069 #endif
00070 }
00071
00079 class Mutex
00080 {
00081 pthread_mutex_t m_mtx;
00082
00083 public:
00087 inline Mutex()
00088 {
00089 #ifdef NDEBUG
00090 pthread_mutex_init( &m_mtx, 0 );
00091 #else
00092 int result = pthread_mutex_init( &m_mtx, 0 );
00093 fassert( result == 0 );
00094 #endif
00095 }
00096
00102 inline ~Mutex() {
00103 #ifdef NDEBUG
00104 pthread_mutex_destroy( &m_mtx );
00105 #else
00106 int result = pthread_mutex_destroy( &m_mtx );
00107 fassert( result == 0 );
00108 #endif
00109 }
00110
00116 inline void lock()
00117 {
00118 #ifdef NDEBUG
00119 pthread_mutex_lock( &m_mtx );
00120 #else
00121 int result = pthread_mutex_lock( &m_mtx );
00122 fassert( result != EINVAL );
00123 fassert( result != EDEADLK );
00124 #endif
00125 }
00126
00132 inline void unlock()
00133 {
00134 #ifdef NDEBUG
00135 pthread_mutex_unlock( &m_mtx );
00136 #else
00137 int result = pthread_mutex_unlock( &m_mtx );
00138 fassert( result == 0 );
00139 #endif
00140 }
00141
00147 inline bool trylock()
00148 {
00149 int result = pthread_mutex_trylock( &m_mtx );
00150 if ( result == EBUSY )
00151 return false;
00152
00153 #ifndef NDEBUG
00154 fassert( result == 0 );
00155 #endif
00156
00157 return true;
00158 }
00159
00160 };
00161
00178 class Event
00179 {
00180 pthread_mutex_t m_mtx;
00181 pthread_cond_t m_cv;
00182 bool m_bIsSet;
00183 bool m_bAutoReset;
00184
00185 public:
00189 inline Event( bool bAutoReset = true, bool initState = false ):
00190 m_bIsSet( initState ),
00191 m_bAutoReset( bAutoReset )
00192 {
00193 #ifdef NDEBUG
00194 pthread_mutex_init( &m_mtx, 0 );
00195 pthread_cond_init( &m_cv, 0 );
00196 #else
00197 int result = pthread_mutex_init( &m_mtx, 0 );
00198 fassert( result == 0 );
00199 result = pthread_cond_init( &m_cv, 0 );
00200 fassert( result == 0 );
00201 #endif
00202 }
00203
00209 inline ~Event() {
00210 #ifdef NDEBUG
00211 pthread_mutex_destroy( &m_mtx );
00212 pthread_cond_destroy( &m_cv );
00213 #else
00214 int result = pthread_mutex_destroy( &m_mtx );
00215 fassert( result == 0 );
00216 result = pthread_cond_destroy( &m_cv );
00217 fassert( result == 0 );
00218 #endif
00219 }
00220
00225 void set();
00226
00227
00232 inline void reset()
00233 {
00234 #ifdef NDEBUG
00235 pthread_mutex_lock( &m_mtx );
00236 m_bIsSet = false;
00237 pthread_mutex_unlock( &m_mtx );
00238 #else
00239 int result = pthread_mutex_lock( &m_mtx );
00240 fassert( result == 0 );
00241 m_bIsSet = false;
00242 result = pthread_mutex_unlock( &m_mtx );
00243 fassert( result == 0 );
00244 #endif
00245 }
00246
00262 bool wait( int32 to = -1 );
00263 };
00264
00265
00271 class ThreadSpecific
00272 {
00273 private:
00274 pthread_key_t m_key;
00275
00276 public:
00277 ThreadSpecific()
00278 {
00279 pthread_key_create( &m_key, NULL );
00280 }
00281
00282 ThreadSpecific( void (*destructor)(void*) );
00283
00284 virtual ~ThreadSpecific()
00285 {
00286 #ifndef NDEBUG
00287 int value = pthread_key_delete( m_key );
00288 fassert( value == 0 );
00289 #else
00290 pthread_key_delete( m_key );
00291 #endif
00292 }
00293
00294 void set( void *value )
00295 {
00296 #ifndef NDEBUG
00297 int res = pthread_setspecific( m_key, value );
00298 fassert( res == 0 );
00299 #else
00300 pthread_setspecific( m_key, value );
00301 #endif
00302 }
00303
00304 void* get() const
00305 {
00306 return pthread_getspecific( m_key );
00307 }
00308 };
00309
00310
00311 struct SYSTH_DATA {
00312 pthread_t pth;
00314 pthread_mutex_t m_mtxT;
00316 bool m_bDone;
00318 bool m_bDetached;
00319
00320 int m_lastError;
00321 };
00322
00324 int32 atomicInc( volatile int32 &data );
00325
00327 int32 atomicDec( volatile int32 &data );
00328
00329 }
00330
00331 #endif
00332
00333