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 "machine/windows_api.h"
00026 #else
00027 #include <pthread.h>
00028 #endif
00029
00030 #include <new>
00031 #include "aligned_space.h"
00032 #include "tbb_stddef.h"
00033 #include "tbb_profiling.h"
00034
00035 namespace tbb {
00036
00038
00040 class mutex {
00041 public:
00043 mutex() {
00044 #if TBB_USE_ASSERT || TBB_USE_THREADING_TOOLS
00045 internal_construct();
00046 #else
00047 #if _WIN32||_WIN64
00048 InitializeCriticalSection(&impl);
00049 #else
00050 int error_code = pthread_mutex_init(&impl,NULL);
00051 if( error_code )
00052 tbb::internal::handle_perror(error_code,"mutex: pthread_mutex_init failed");
00053 #endif
00054 #endif
00055 };
00056
00057 ~mutex() {
00058 #if TBB_USE_ASSERT
00059 internal_destroy();
00060 #else
00061 #if _WIN32||_WIN64
00062 DeleteCriticalSection(&impl);
00063 #else
00064 pthread_mutex_destroy(&impl);
00065
00066 #endif
00067 #endif
00068 };
00069
00070 class scoped_lock;
00071 friend class scoped_lock;
00072
00074
00076 class scoped_lock : internal::no_copy {
00077 public:
00079 scoped_lock() : my_mutex(NULL) {};
00080
00082 scoped_lock( mutex& mutex ) {
00083 acquire( mutex );
00084 }
00085
00087 ~scoped_lock() {
00088 if( my_mutex )
00089 release();
00090 }
00091
00093 void acquire( mutex& mutex ) {
00094 #if TBB_USE_ASSERT
00095 internal_acquire(mutex);
00096 #else
00097 mutex.lock();
00098 my_mutex = &mutex;
00099 #endif
00100 }
00101
00103 bool try_acquire( mutex& mutex ) {
00104 #if TBB_USE_ASSERT
00105 return internal_try_acquire (mutex);
00106 #else
00107 bool result = mutex.try_lock();
00108 if( result )
00109 my_mutex = &mutex;
00110 return result;
00111 #endif
00112 }
00113
00115 void release() {
00116 #if TBB_USE_ASSERT
00117 internal_release ();
00118 #else
00119 my_mutex->unlock();
00120 my_mutex = NULL;
00121 #endif
00122 }
00123
00124 private:
00126 mutex* my_mutex;
00127
00129 void __TBB_EXPORTED_METHOD internal_acquire( mutex& m );
00130
00132 bool __TBB_EXPORTED_METHOD internal_try_acquire( mutex& m );
00133
00135 void __TBB_EXPORTED_METHOD internal_release();
00136
00137 friend class mutex;
00138 };
00139
00140
00141 static const bool is_rw_mutex = false;
00142 static const bool is_recursive_mutex = false;
00143 static const bool is_fair_mutex = false;
00144
00145
00146
00148 void lock() {
00149 #if TBB_USE_ASSERT
00150 aligned_space<scoped_lock,1> tmp;
00151 new(tmp.begin()) scoped_lock(*this);
00152 #else
00153 #if _WIN32||_WIN64
00154 EnterCriticalSection(&impl);
00155 #else
00156 pthread_mutex_lock(&impl);
00157 #endif
00158 #endif
00159 }
00160
00162
00163 bool try_lock() {
00164 #if TBB_USE_ASSERT
00165 aligned_space<scoped_lock,1> tmp;
00166 scoped_lock& s = *tmp.begin();
00167 s.my_mutex = NULL;
00168 return s.internal_try_acquire(*this);
00169 #else
00170 #if _WIN32||_WIN64
00171 return TryEnterCriticalSection(&impl)!=0;
00172 #else
00173 return pthread_mutex_trylock(&impl)==0;
00174 #endif
00175 #endif
00176 }
00177
00179 void unlock() {
00180 #if TBB_USE_ASSERT
00181 aligned_space<scoped_lock,1> tmp;
00182 scoped_lock& s = *tmp.begin();
00183 s.my_mutex = this;
00184 s.internal_release();
00185 #else
00186 #if _WIN32||_WIN64
00187 LeaveCriticalSection(&impl);
00188 #else
00189 pthread_mutex_unlock(&impl);
00190 #endif
00191 #endif
00192 }
00193
00195 #if _WIN32||_WIN64
00196 typedef LPCRITICAL_SECTION native_handle_type;
00197 #else
00198 typedef pthread_mutex_t* native_handle_type;
00199 #endif
00200 native_handle_type native_handle() { return (native_handle_type) &impl; }
00201
00202 enum state_t {
00203 INITIALIZED=0x1234,
00204 DESTROYED=0x789A,
00205 HELD=0x56CD
00206 };
00207 private:
00208 #if _WIN32||_WIN64
00209 CRITICAL_SECTION impl;
00210 enum state_t state;
00211 #else
00212 pthread_mutex_t impl;
00213 #endif
00214
00216 void __TBB_EXPORTED_METHOD internal_construct();
00217
00219 void __TBB_EXPORTED_METHOD internal_destroy();
00220
00221 #if _WIN32||_WIN64
00222 public:
00224 void set_state( state_t to ) { state = to; }
00225 #endif
00226 };
00227
00228 __TBB_DEFINE_PROFILING_SET_NAME(mutex)
00229
00230 }
00231
00232 #endif