![]() |
Shadowrun: Awakened 29 September 2011 - Build 871
|
00001 /* 00002 Copyright 2005-2010 Intel Corporation. All Rights Reserved. 00003 00004 This file is part of Threading Building Blocks. 00005 00006 Threading Building Blocks is free software; you can redistribute it 00007 and/or modify it under the terms of the GNU General Public License 00008 version 2 as published by the Free Software Foundation. 00009 00010 Threading Building Blocks is distributed in the hope that it will be 00011 useful, but WITHOUT ANY WARRANTY; without even the implied warranty 00012 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with Threading Building Blocks; if not, write to the Free Software 00017 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00018 00019 As a special exception, you may use this file as part of a free software 00020 library without restriction. Specifically, if other files instantiate 00021 templates or use macros or inline functions from this file, or you compile 00022 this file and link it with other files to produce an executable, this 00023 file does not by itself cause the resulting executable to be covered by 00024 the GNU General Public License. This exception does not however 00025 invalidate any other reasons why the executable file might be covered by 00026 the GNU General Public License. 00027 */ 00028 00029 #ifndef __TBB_mutex_H 00030 #define __TBB_mutex_H 00031 00032 #if _WIN32||_WIN64 00033 #include <windows.h> 00034 #if !defined(_WIN32_WINNT) 00035 // The following Windows API function is declared explicitly; 00036 // otherwise any user would have to specify /D_WIN32_WINNT=0x0400 00037 extern "C" BOOL WINAPI TryEnterCriticalSection( LPCRITICAL_SECTION ); 00038 #endif 00039 #else /* if not _WIN32||_WIN64 */ 00040 #include <pthread.h> 00041 #endif /* _WIN32||_WIN64 */ 00042 00043 #include <new> 00044 #include "aligned_space.h" 00045 #include "tbb_stddef.h" 00046 #include "tbb_profiling.h" 00047 00048 namespace tbb { 00049 00051 00053 class mutex { 00054 public: 00056 mutex() { 00057 #if TBB_USE_ASSERT || TBB_USE_THREADING_TOOLS 00058 internal_construct(); 00059 #else 00060 #if _WIN32||_WIN64 00061 InitializeCriticalSection(&impl); 00062 #else 00063 int error_code = pthread_mutex_init(&impl,NULL); 00064 if( error_code ) 00065 tbb::internal::handle_perror(error_code,"mutex: pthread_mutex_init failed"); 00066 #endif /* _WIN32||_WIN64*/ 00067 #endif /* TBB_USE_ASSERT */ 00068 }; 00069 00070 ~mutex() { 00071 #if TBB_USE_ASSERT 00072 internal_destroy(); 00073 #else 00074 #if _WIN32||_WIN64 00075 DeleteCriticalSection(&impl); 00076 #else 00077 pthread_mutex_destroy(&impl); 00078 00079 #endif /* _WIN32||_WIN64 */ 00080 #endif /* TBB_USE_ASSERT */ 00081 }; 00082 00083 class scoped_lock; 00084 friend class scoped_lock; 00085 00087 00089 class scoped_lock : internal::no_copy { 00090 public: 00092 scoped_lock() : my_mutex(NULL) {}; 00093 00095 scoped_lock( mutex& mutex ) { 00096 acquire( mutex ); 00097 } 00098 00100 ~scoped_lock() { 00101 if( my_mutex ) 00102 release(); 00103 } 00104 00106 void acquire( mutex& mutex ) { 00107 #if TBB_USE_ASSERT 00108 internal_acquire(mutex); 00109 #else 00110 mutex.lock(); 00111 my_mutex = &mutex; 00112 #endif /* TBB_USE_ASSERT */ 00113 } 00114 00116 bool try_acquire( mutex& mutex ) { 00117 #if TBB_USE_ASSERT 00118 return internal_try_acquire (mutex); 00119 #else 00120 bool result = mutex.try_lock(); 00121 if( result ) 00122 my_mutex = &mutex; 00123 return result; 00124 #endif /* TBB_USE_ASSERT */ 00125 } 00126 00128 void release() { 00129 #if TBB_USE_ASSERT 00130 internal_release (); 00131 #else 00132 my_mutex->unlock(); 00133 my_mutex = NULL; 00134 #endif /* TBB_USE_ASSERT */ 00135 } 00136 00137 private: 00139 mutex* my_mutex; 00140 00142 void __TBB_EXPORTED_METHOD internal_acquire( mutex& m ); 00143 00145 bool __TBB_EXPORTED_METHOD internal_try_acquire( mutex& m ); 00146 00148 void __TBB_EXPORTED_METHOD internal_release(); 00149 00150 friend class mutex; 00151 }; 00152 00153 // Mutex traits 00154 static const bool is_rw_mutex = false; 00155 static const bool is_recursive_mutex = false; 00156 static const bool is_fair_mutex = false; 00157 00158 // ISO C++0x compatibility methods 00159 00161 void lock() { 00162 #if TBB_USE_ASSERT 00163 aligned_space<scoped_lock,1> tmp; 00164 new(tmp.begin()) scoped_lock(*this); 00165 #else 00166 #if _WIN32||_WIN64 00167 EnterCriticalSection(&impl); 00168 #else 00169 pthread_mutex_lock(&impl); 00170 #endif /* _WIN32||_WIN64 */ 00171 #endif /* TBB_USE_ASSERT */ 00172 } 00173 00175 00176 bool try_lock() { 00177 #if TBB_USE_ASSERT 00178 aligned_space<scoped_lock,1> tmp; 00179 scoped_lock& s = *tmp.begin(); 00180 s.my_mutex = NULL; 00181 return s.internal_try_acquire(*this); 00182 #else 00183 #if _WIN32||_WIN64 00184 return TryEnterCriticalSection(&impl)!=0; 00185 #else 00186 return pthread_mutex_trylock(&impl)==0; 00187 #endif /* _WIN32||_WIN64 */ 00188 #endif /* TBB_USE_ASSERT */ 00189 } 00190 00192 void unlock() { 00193 #if TBB_USE_ASSERT 00194 aligned_space<scoped_lock,1> tmp; 00195 scoped_lock& s = *tmp.begin(); 00196 s.my_mutex = this; 00197 s.internal_release(); 00198 #else 00199 #if _WIN32||_WIN64 00200 LeaveCriticalSection(&impl); 00201 #else 00202 pthread_mutex_unlock(&impl); 00203 #endif /* _WIN32||_WIN64 */ 00204 #endif /* TBB_USE_ASSERT */ 00205 } 00206 00208 #if _WIN32||_WIN64 00209 typedef LPCRITICAL_SECTION native_handle_type; 00210 #else 00211 typedef pthread_mutex_t* native_handle_type; 00212 #endif 00213 native_handle_type native_handle() { return (native_handle_type) &impl; } 00214 00215 enum state_t { 00216 INITIALIZED=0x1234, 00217 DESTROYED=0x789A, 00218 HELD=0x56CD 00219 }; 00220 private: 00221 #if _WIN32||_WIN64 00222 CRITICAL_SECTION impl; 00223 enum state_t state; 00224 #else 00225 pthread_mutex_t impl; 00226 #endif /* _WIN32||_WIN64 */ 00227 00229 void __TBB_EXPORTED_METHOD internal_construct(); 00230 00232 void __TBB_EXPORTED_METHOD internal_destroy(); 00233 00234 #if _WIN32||_WIN64 00235 public: 00237 void set_state( state_t to ) { state = to; } 00238 #endif 00239 }; 00240 00241 __TBB_DEFINE_PROFILING_SET_NAME(mutex) 00242 00243 } // namespace tbb 00244 00245 #endif /* __TBB_mutex_H */
Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.