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
00032 #else
00033 #include <pthread.h>
00034 namespace tbb { namespace internal {
00035
00036 extern void handle_perror( int error_code, const char* what );
00037 } }
00038 #endif
00039
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 InitializeCriticalSection(&impl);
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
00091 scoped_lock( mutex& mutex ) {
00092 acquire( mutex );
00093 }
00094
00096 ~scoped_lock() {
00097 if( my_mutex )
00098 release();
00099 }
00100
00102 void acquire( mutex& mutex ) {
00103 #if TBB_USE_ASSERT
00104 internal_acquire(mutex);
00105 #else
00106 my_mutex = &mutex;
00107 #if _WIN32||_WIN64
00108 EnterCriticalSection(&mutex.impl);
00109 #else
00110 pthread_mutex_lock(&mutex.impl);
00111 #endif
00112 #endif
00113 }
00114
00116 bool try_acquire( mutex& mutex ) {
00117 #if TBB_USE_ASSERT
00118 return internal_try_acquire (mutex);
00119 #else
00120 bool result;
00121 #if _WIN32||_WIN64
00122 result = TryEnterCriticalSection(&mutex.impl)!=0;
00123 #else
00124 result = pthread_mutex_trylock(&mutex.impl)==0;
00125 #endif
00126 if( result )
00127 my_mutex = &mutex;
00128 return result;
00129 #endif
00130 }
00131
00133 void release() {
00134 #if TBB_USE_ASSERT
00135 internal_release ();
00136 #else
00137 #if _WIN32||_WIN64
00138 LeaveCriticalSection(&my_mutex->impl);
00139 #else
00140 pthread_mutex_unlock(&my_mutex->impl);
00141 #endif
00142 my_mutex = NULL;
00143 #endif
00144 }
00145
00146 private:
00148 mutex* my_mutex;
00149
00151 void __TBB_EXPORTED_METHOD internal_acquire( mutex& m );
00152
00154 bool __TBB_EXPORTED_METHOD internal_try_acquire( mutex& m );
00155
00157 void __TBB_EXPORTED_METHOD internal_release();
00158 };
00159
00160
00161 static const bool is_rw_mutex = false;
00162 static const bool is_recursive_mutex = false;
00163 static const bool is_fair_mutex = false;
00164
00165 private:
00166 #if _WIN32||_WIN64
00167 CRITICAL_SECTION impl;
00168 enum state_t {
00169 INITIALIZED=0x1234,
00170 DESTROYED=0x789A,
00171 HELD=0x56CD
00172 } state;
00173 #else
00174 pthread_mutex_t impl;
00175 #endif
00176
00178 void __TBB_EXPORTED_METHOD internal_construct();
00179
00181 void __TBB_EXPORTED_METHOD internal_destroy();
00182 };
00183
00184 __TBB_DEFINE_PROFILING_SET_NAME(mutex)
00185
00186 }
00187
00188 #endif