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