00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef __TBB_mutex_H
00030 #define __TBB_mutex_H
00031
00032 #if _WIN32||_WIN64
00033 #include "machine/windows_api.h"
00034 #else
00035 #include <pthread.h>
00036 #endif
00037
00038 #include <new>
00039 #include "aligned_space.h"
00040 #include "tbb_stddef.h"
00041 #include "tbb_profiling.h"
00042
00043 namespace tbb {
00044
00046
00048 class mutex {
00049 public:
00051 mutex() {
00052 #if TBB_USE_ASSERT || TBB_USE_THREADING_TOOLS
00053 internal_construct();
00054 #else
00055 #if _WIN32||_WIN64
00056 InitializeCriticalSectionEx(&impl, 4000, 0);
00057 #else
00058 int error_code = pthread_mutex_init(&impl,NULL);
00059 if( error_code )
00060 tbb::internal::handle_perror(error_code,"mutex: pthread_mutex_init failed");
00061 #endif
00062 #endif
00063 };
00064
00065 ~mutex() {
00066 #if TBB_USE_ASSERT
00067 internal_destroy();
00068 #else
00069 #if _WIN32||_WIN64
00070 DeleteCriticalSection(&impl);
00071 #else
00072 pthread_mutex_destroy(&impl);
00073
00074 #endif
00075 #endif
00076 };
00077
00078 class scoped_lock;
00079 friend class scoped_lock;
00080
00082
00084 class scoped_lock : internal::no_copy {
00085 public:
00087 scoped_lock() : my_mutex(NULL) {};
00088
00090 scoped_lock( mutex& mutex ) {
00091 acquire( mutex );
00092 }
00093
00095 ~scoped_lock() {
00096 if( my_mutex )
00097 release();
00098 }
00099
00101 void acquire( mutex& mutex ) {
00102 #if TBB_USE_ASSERT
00103 internal_acquire(mutex);
00104 #else
00105 mutex.lock();
00106 my_mutex = &mutex;
00107 #endif
00108 }
00109
00111 bool try_acquire( mutex& mutex ) {
00112 #if TBB_USE_ASSERT
00113 return internal_try_acquire (mutex);
00114 #else
00115 bool result = mutex.try_lock();
00116 if( result )
00117 my_mutex = &mutex;
00118 return result;
00119 #endif
00120 }
00121
00123 void release() {
00124 #if TBB_USE_ASSERT
00125 internal_release ();
00126 #else
00127 my_mutex->unlock();
00128 my_mutex = NULL;
00129 #endif
00130 }
00131
00132 private:
00134 mutex* my_mutex;
00135
00137 void __TBB_EXPORTED_METHOD internal_acquire( mutex& m );
00138
00140 bool __TBB_EXPORTED_METHOD internal_try_acquire( mutex& m );
00141
00143 void __TBB_EXPORTED_METHOD internal_release();
00144
00145 friend class mutex;
00146 };
00147
00148
00149 static const bool is_rw_mutex = false;
00150 static const bool is_recursive_mutex = false;
00151 static const bool is_fair_mutex = false;
00152
00153
00154
00156 void lock() {
00157 #if TBB_USE_ASSERT
00158 aligned_space<scoped_lock,1> tmp;
00159 new(tmp.begin()) scoped_lock(*this);
00160 #else
00161 #if _WIN32||_WIN64
00162 EnterCriticalSection(&impl);
00163 #else
00164 pthread_mutex_lock(&impl);
00165 #endif
00166 #endif
00167 }
00168
00170
00171 bool try_lock() {
00172 #if TBB_USE_ASSERT
00173 aligned_space<scoped_lock,1> tmp;
00174 scoped_lock& s = *tmp.begin();
00175 s.my_mutex = NULL;
00176 return s.internal_try_acquire(*this);
00177 #else
00178 #if _WIN32||_WIN64
00179 return TryEnterCriticalSection(&impl)!=0;
00180 #else
00181 return pthread_mutex_trylock(&impl)==0;
00182 #endif
00183 #endif
00184 }
00185
00187 void unlock() {
00188 #if TBB_USE_ASSERT
00189 aligned_space<scoped_lock,1> tmp;
00190 scoped_lock& s = *tmp.begin();
00191 s.my_mutex = this;
00192 s.internal_release();
00193 #else
00194 #if _WIN32||_WIN64
00195 LeaveCriticalSection(&impl);
00196 #else
00197 pthread_mutex_unlock(&impl);
00198 #endif
00199 #endif
00200 }
00201
00203 #if _WIN32||_WIN64
00204 typedef LPCRITICAL_SECTION native_handle_type;
00205 #else
00206 typedef pthread_mutex_t* native_handle_type;
00207 #endif
00208 native_handle_type native_handle() { return (native_handle_type) &impl; }
00209
00210 enum state_t {
00211 INITIALIZED=0x1234,
00212 DESTROYED=0x789A,
00213 HELD=0x56CD
00214 };
00215 private:
00216 #if _WIN32||_WIN64
00217 CRITICAL_SECTION impl;
00218 enum state_t state;
00219 #else
00220 pthread_mutex_t impl;
00221 #endif
00222
00224 void __TBB_EXPORTED_METHOD internal_construct();
00225
00227 void __TBB_EXPORTED_METHOD internal_destroy();
00228
00229 #if _WIN32||_WIN64
00230 public:
00232 void set_state( state_t to ) { state = to; }
00233 #endif
00234 };
00235
00236 __TBB_DEFINE_PROFILING_SET_NAME(mutex)
00237
00238 }
00239
00240 #endif