![]() |
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_tbb_thread_H 00030 #define __TBB_tbb_thread_H 00031 00032 #if _WIN32||_WIN64 00033 #include <windows.h> 00034 #define __TBB_NATIVE_THREAD_ROUTINE unsigned WINAPI 00035 #define __TBB_NATIVE_THREAD_ROUTINE_PTR(r) unsigned (WINAPI* r)( void* ) 00036 #else 00037 #define __TBB_NATIVE_THREAD_ROUTINE void* 00038 #define __TBB_NATIVE_THREAD_ROUTINE_PTR(r) void* (*r)( void* ) 00039 #include <pthread.h> 00040 #endif // _WIN32||_WIN64 00041 00042 #include "tbb_stddef.h" 00043 #include "tick_count.h" 00044 #include <exception> // Need std::terminate from here. 00045 00046 #if !TBB_USE_EXCEPTIONS && _MSC_VER 00047 // Suppress "C++ exception handler used, but unwind semantics are not enabled" warning in STL headers 00048 #pragma warning (push) 00049 #pragma warning (disable: 4530) 00050 #endif 00051 00052 #include <iosfwd> 00053 00054 #if !TBB_USE_EXCEPTIONS && _MSC_VER 00055 #pragma warning (pop) 00056 #endif 00057 00058 namespace tbb { 00059 00061 namespace internal { 00062 00063 class tbb_thread_v3; 00064 00065 } // namespace internal 00066 00067 void swap( internal::tbb_thread_v3& t1, internal::tbb_thread_v3& t2 ); 00068 00069 namespace internal { 00070 00072 void* __TBB_EXPORTED_FUNC allocate_closure_v3( size_t size ); 00074 void __TBB_EXPORTED_FUNC free_closure_v3( void* ); 00075 00076 struct thread_closure_base { 00077 void* operator new( size_t size ) {return allocate_closure_v3(size);} 00078 void operator delete( void* ptr ) {free_closure_v3(ptr);} 00079 }; 00080 00081 template<class F> struct thread_closure_0: thread_closure_base { 00082 F function; 00083 00084 static __TBB_NATIVE_THREAD_ROUTINE start_routine( void* c ) { 00085 thread_closure_0 *self = static_cast<thread_closure_0*>(c); 00086 __TBB_TRY { 00087 self->function(); 00088 } __TBB_CATCH( ... ) { 00089 std::terminate(); 00090 } 00091 delete self; 00092 return 0; 00093 } 00094 thread_closure_0( const F& f ) : function(f) {} 00095 }; 00097 template<class F, class X> struct thread_closure_1: thread_closure_base { 00098 F function; 00099 X arg1; 00101 static __TBB_NATIVE_THREAD_ROUTINE start_routine( void* c ) { 00102 thread_closure_1 *self = static_cast<thread_closure_1*>(c); 00103 __TBB_TRY { 00104 self->function(self->arg1); 00105 } __TBB_CATCH( ... ) { 00106 std::terminate(); 00107 } 00108 delete self; 00109 return 0; 00110 } 00111 thread_closure_1( const F& f, const X& x ) : function(f), arg1(x) {} 00112 }; 00113 template<class F, class X, class Y> struct thread_closure_2: thread_closure_base { 00114 F function; 00115 X arg1; 00116 Y arg2; 00118 static __TBB_NATIVE_THREAD_ROUTINE start_routine( void* c ) { 00119 thread_closure_2 *self = static_cast<thread_closure_2*>(c); 00120 __TBB_TRY { 00121 self->function(self->arg1, self->arg2); 00122 } __TBB_CATCH( ... ) { 00123 std::terminate(); 00124 } 00125 delete self; 00126 return 0; 00127 } 00128 thread_closure_2( const F& f, const X& x, const Y& y ) : function(f), arg1(x), arg2(y) {} 00129 }; 00130 00132 class tbb_thread_v3 { 00133 tbb_thread_v3(const tbb_thread_v3&); // = delete; // Deny access 00134 public: 00135 #if _WIN32||_WIN64 00136 typedef HANDLE native_handle_type; 00137 #else 00138 typedef pthread_t native_handle_type; 00139 #endif // _WIN32||_WIN64 00140 00141 class id; 00143 tbb_thread_v3() : my_handle(0) 00144 #if _WIN32||_WIN64 00145 , my_thread_id(0) 00146 #endif // _WIN32||_WIN64 00147 {} 00148 00150 template <class F> explicit tbb_thread_v3(F f) { 00151 typedef internal::thread_closure_0<F> closure_type; 00152 internal_start(closure_type::start_routine, new closure_type(f)); 00153 } 00155 template <class F, class X> tbb_thread_v3(F f, X x) { 00156 typedef internal::thread_closure_1<F,X> closure_type; 00157 internal_start(closure_type::start_routine, new closure_type(f,x)); 00158 } 00160 template <class F, class X, class Y> tbb_thread_v3(F f, X x, Y y) { 00161 typedef internal::thread_closure_2<F,X,Y> closure_type; 00162 internal_start(closure_type::start_routine, new closure_type(f,x,y)); 00163 } 00164 00165 tbb_thread_v3& operator=(tbb_thread_v3& x) { 00166 if (joinable()) detach(); 00167 my_handle = x.my_handle; 00168 x.my_handle = 0; 00169 #if _WIN32||_WIN64 00170 my_thread_id = x.my_thread_id; 00171 x.my_thread_id = 0; 00172 #endif // _WIN32||_WIN64 00173 return *this; 00174 } 00175 void swap( tbb_thread_v3& t ) {tbb::swap( *this, t );} 00176 bool joinable() const {return my_handle!=0; } 00178 void __TBB_EXPORTED_METHOD join(); 00180 void __TBB_EXPORTED_METHOD detach(); 00181 ~tbb_thread_v3() {if( joinable() ) detach();} 00182 inline id get_id() const; 00183 native_handle_type native_handle() { return my_handle; } 00184 00186 static unsigned __TBB_EXPORTED_FUNC hardware_concurrency(); 00187 private: 00188 native_handle_type my_handle; 00189 #if _WIN32||_WIN64 00190 DWORD my_thread_id; 00191 #endif // _WIN32||_WIN64 00192 00194 void __TBB_EXPORTED_METHOD internal_start( __TBB_NATIVE_THREAD_ROUTINE_PTR(start_routine), 00195 void* closure ); 00196 friend void __TBB_EXPORTED_FUNC move_v3( tbb_thread_v3& t1, tbb_thread_v3& t2 ); 00197 friend void tbb::swap( tbb_thread_v3& t1, tbb_thread_v3& t2 ); 00198 }; 00199 00200 class tbb_thread_v3::id { 00201 #if _WIN32||_WIN64 00202 DWORD my_id; 00203 id( DWORD id_ ) : my_id(id_) {} 00204 #else 00205 pthread_t my_id; 00206 id( pthread_t id_ ) : my_id(id_) {} 00207 #endif // _WIN32||_WIN64 00208 friend class tbb_thread_v3; 00209 public: 00210 id() : my_id(0) {} 00211 00212 friend bool operator==( tbb_thread_v3::id x, tbb_thread_v3::id y ); 00213 friend bool operator!=( tbb_thread_v3::id x, tbb_thread_v3::id y ); 00214 friend bool operator<( tbb_thread_v3::id x, tbb_thread_v3::id y ); 00215 friend bool operator<=( tbb_thread_v3::id x, tbb_thread_v3::id y ); 00216 friend bool operator>( tbb_thread_v3::id x, tbb_thread_v3::id y ); 00217 friend bool operator>=( tbb_thread_v3::id x, tbb_thread_v3::id y ); 00218 00219 template<class charT, class traits> 00220 friend std::basic_ostream<charT, traits>& 00221 operator<< (std::basic_ostream<charT, traits> &out, 00222 tbb_thread_v3::id id) 00223 { 00224 out << id.my_id; 00225 return out; 00226 } 00227 friend tbb_thread_v3::id __TBB_EXPORTED_FUNC thread_get_id_v3(); 00228 }; // tbb_thread_v3::id 00229 00230 tbb_thread_v3::id tbb_thread_v3::get_id() const { 00231 #if _WIN32||_WIN64 00232 return id(my_thread_id); 00233 #else 00234 return id(my_handle); 00235 #endif // _WIN32||_WIN64 00236 } 00237 void __TBB_EXPORTED_FUNC move_v3( tbb_thread_v3& t1, tbb_thread_v3& t2 ); 00238 tbb_thread_v3::id __TBB_EXPORTED_FUNC thread_get_id_v3(); 00239 void __TBB_EXPORTED_FUNC thread_yield_v3(); 00240 void __TBB_EXPORTED_FUNC thread_sleep_v3(const tick_count::interval_t &i); 00241 00242 inline bool operator==(tbb_thread_v3::id x, tbb_thread_v3::id y) 00243 { 00244 return x.my_id == y.my_id; 00245 } 00246 inline bool operator!=(tbb_thread_v3::id x, tbb_thread_v3::id y) 00247 { 00248 return x.my_id != y.my_id; 00249 } 00250 inline bool operator<(tbb_thread_v3::id x, tbb_thread_v3::id y) 00251 { 00252 return x.my_id < y.my_id; 00253 } 00254 inline bool operator<=(tbb_thread_v3::id x, tbb_thread_v3::id y) 00255 { 00256 return x.my_id <= y.my_id; 00257 } 00258 inline bool operator>(tbb_thread_v3::id x, tbb_thread_v3::id y) 00259 { 00260 return x.my_id > y.my_id; 00261 } 00262 inline bool operator>=(tbb_thread_v3::id x, tbb_thread_v3::id y) 00263 { 00264 return x.my_id >= y.my_id; 00265 } 00266 00267 } // namespace internal; 00268 00270 typedef internal::tbb_thread_v3 tbb_thread; 00271 00272 using internal::operator==; 00273 using internal::operator!=; 00274 using internal::operator<; 00275 using internal::operator>; 00276 using internal::operator<=; 00277 using internal::operator>=; 00278 00279 inline void move( tbb_thread& t1, tbb_thread& t2 ) { 00280 internal::move_v3(t1, t2); 00281 } 00282 00283 inline void swap( internal::tbb_thread_v3& t1, internal::tbb_thread_v3& t2 ) { 00284 tbb::tbb_thread::native_handle_type h = t1.my_handle; 00285 t1.my_handle = t2.my_handle; 00286 t2.my_handle = h; 00287 #if _WIN32||_WIN64 00288 DWORD i = t1.my_thread_id; 00289 t1.my_thread_id = t2.my_thread_id; 00290 t2.my_thread_id = i; 00291 #endif /* _WIN32||_WIN64 */ 00292 } 00293 00294 namespace this_tbb_thread { 00295 inline tbb_thread::id get_id() { return internal::thread_get_id_v3(); } 00297 inline void yield() { internal::thread_yield_v3(); } 00299 inline void sleep(const tick_count::interval_t &i) { 00300 internal::thread_sleep_v3(i); 00301 } 00302 } // namespace this_tbb_thread 00303 00304 } // namespace tbb 00305 00306 #endif /* __TBB_tbb_thread_H */
Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.