00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef __TBB_tbb_thread_H
00022 #define __TBB_tbb_thread_H
00023
00024 #if _WIN32||_WIN64
00025 #include "machine/windows_api.h"
00026 #define __TBB_NATIVE_THREAD_ROUTINE unsigned WINAPI
00027 #define __TBB_NATIVE_THREAD_ROUTINE_PTR(r) unsigned (WINAPI* r)( void* )
00028 #else
00029 #define __TBB_NATIVE_THREAD_ROUTINE void*
00030 #define __TBB_NATIVE_THREAD_ROUTINE_PTR(r) void* (*r)( void* )
00031 #include <pthread.h>
00032 #endif // _WIN32||_WIN64
00033
00034 #include "tbb_stddef.h"
00035 #include "tick_count.h"
00036
00037 #if !TBB_USE_EXCEPTIONS && _MSC_VER
00038
00039 #pragma warning (push)
00040 #pragma warning (disable: 4530)
00041 #endif
00042
00043 #include <iosfwd>
00044
00045 #if !TBB_USE_EXCEPTIONS && _MSC_VER
00046 #pragma warning (pop)
00047 #endif
00048
00049 namespace tbb {
00050
00052 namespace internal {
00053
00054 class tbb_thread_v3;
00055
00056 }
00057
00058 void swap( internal::tbb_thread_v3& t1, internal::tbb_thread_v3& t2 );
00059
00060 namespace internal {
00061
00063 void* __TBB_EXPORTED_FUNC allocate_closure_v3( size_t size );
00065 void __TBB_EXPORTED_FUNC free_closure_v3( void* );
00066
00067 struct thread_closure_base {
00068 void* operator new( size_t size ) {return allocate_closure_v3(size);}
00069 void operator delete( void* ptr ) {free_closure_v3(ptr);}
00070 };
00071
00072 template<class F> struct thread_closure_0: thread_closure_base {
00073 F function;
00074
00075 static __TBB_NATIVE_THREAD_ROUTINE start_routine( void* c ) {
00076 thread_closure_0 *self = static_cast<thread_closure_0*>(c);
00077 self->function();
00078 delete self;
00079 return 0;
00080 }
00081 thread_closure_0( const F& f ) : function(f) {}
00082 };
00084 template<class F, class X> struct thread_closure_1: thread_closure_base {
00085 F function;
00086 X arg1;
00088 static __TBB_NATIVE_THREAD_ROUTINE start_routine( void* c ) {
00089 thread_closure_1 *self = static_cast<thread_closure_1*>(c);
00090 self->function(self->arg1);
00091 delete self;
00092 return 0;
00093 }
00094 thread_closure_1( const F& f, const X& x ) : function(f), arg1(x) {}
00095 };
00096 template<class F, class X, class Y> struct thread_closure_2: thread_closure_base {
00097 F function;
00098 X arg1;
00099 Y arg2;
00101 static __TBB_NATIVE_THREAD_ROUTINE start_routine( void* c ) {
00102 thread_closure_2 *self = static_cast<thread_closure_2*>(c);
00103 self->function(self->arg1, self->arg2);
00104 delete self;
00105 return 0;
00106 }
00107 thread_closure_2( const F& f, const X& x, const Y& y ) : function(f), arg1(x), arg2(y) {}
00108 };
00109
00111 class tbb_thread_v3 {
00112 tbb_thread_v3(const tbb_thread_v3&);
00113 public:
00114 #if _WIN32||_WIN64
00115 typedef HANDLE native_handle_type;
00116 #else
00117 typedef pthread_t native_handle_type;
00118 #endif // _WIN32||_WIN64
00119
00120 class id;
00122 tbb_thread_v3() : my_handle(0)
00123 #if _WIN32||_WIN64
00124 , my_thread_id(0)
00125 #endif
00126 {}
00127
00129 template <class F> explicit tbb_thread_v3(F f) {
00130 typedef internal::thread_closure_0<F> closure_type;
00131 internal_start(closure_type::start_routine, new closure_type(f));
00132 }
00134 template <class F, class X> tbb_thread_v3(F f, X x) {
00135 typedef internal::thread_closure_1<F,X> closure_type;
00136 internal_start(closure_type::start_routine, new closure_type(f,x));
00137 }
00139 template <class F, class X, class Y> tbb_thread_v3(F f, X x, Y y) {
00140 typedef internal::thread_closure_2<F,X,Y> closure_type;
00141 internal_start(closure_type::start_routine, new closure_type(f,x,y));
00142 }
00143
00144 tbb_thread_v3& operator=(tbb_thread_v3& x) {
00145 if (joinable()) detach();
00146 my_handle = x.my_handle;
00147 x.my_handle = 0;
00148 #if _WIN32||_WIN64
00149 my_thread_id = x.my_thread_id;
00150 x.my_thread_id = 0;
00151 #endif // _WIN32||_WIN64
00152 return *this;
00153 }
00154 void swap( tbb_thread_v3& t ) {tbb::swap( *this, t );}
00155 bool joinable() const {return my_handle!=0; }
00157 void __TBB_EXPORTED_METHOD join();
00159 void __TBB_EXPORTED_METHOD detach();
00160 ~tbb_thread_v3() {if( joinable() ) detach();}
00161 inline id get_id() const;
00162 native_handle_type native_handle() { return my_handle; }
00163
00165 static unsigned __TBB_EXPORTED_FUNC hardware_concurrency();
00166 private:
00167 native_handle_type my_handle;
00168 #if _WIN32||_WIN64
00169 DWORD my_thread_id;
00170 #endif // _WIN32||_WIN64
00171
00173 void __TBB_EXPORTED_METHOD internal_start( __TBB_NATIVE_THREAD_ROUTINE_PTR(start_routine),
00174 void* closure );
00175 friend void __TBB_EXPORTED_FUNC move_v3( tbb_thread_v3& t1, tbb_thread_v3& t2 );
00176 friend void tbb::swap( tbb_thread_v3& t1, tbb_thread_v3& t2 );
00177 };
00178
00179 class tbb_thread_v3::id {
00180 #if _WIN32||_WIN64
00181 DWORD my_id;
00182 id( DWORD id_ ) : my_id(id_) {}
00183 #else
00184 pthread_t my_id;
00185 id( pthread_t id_ ) : my_id(id_) {}
00186 #endif // _WIN32||_WIN64
00187 friend class tbb_thread_v3;
00188 public:
00189 id() : my_id(0) {}
00190
00191 friend bool operator==( tbb_thread_v3::id x, tbb_thread_v3::id y );
00192 friend bool operator!=( tbb_thread_v3::id x, tbb_thread_v3::id y );
00193 friend bool operator<( tbb_thread_v3::id x, tbb_thread_v3::id y );
00194 friend bool operator<=( tbb_thread_v3::id x, tbb_thread_v3::id y );
00195 friend bool operator>( tbb_thread_v3::id x, tbb_thread_v3::id y );
00196 friend bool operator>=( tbb_thread_v3::id x, tbb_thread_v3::id y );
00197
00198 template<class charT, class traits>
00199 friend std::basic_ostream<charT, traits>&
00200 operator<< (std::basic_ostream<charT, traits> &out,
00201 tbb_thread_v3::id id)
00202 {
00203 out << id.my_id;
00204 return out;
00205 }
00206 friend tbb_thread_v3::id __TBB_EXPORTED_FUNC thread_get_id_v3();
00207 };
00208
00209 tbb_thread_v3::id tbb_thread_v3::get_id() const {
00210 #if _WIN32||_WIN64
00211 return id(my_thread_id);
00212 #else
00213 return id(my_handle);
00214 #endif // _WIN32||_WIN64
00215 }
00216 void __TBB_EXPORTED_FUNC move_v3( tbb_thread_v3& t1, tbb_thread_v3& t2 );
00217 tbb_thread_v3::id __TBB_EXPORTED_FUNC thread_get_id_v3();
00218 void __TBB_EXPORTED_FUNC thread_yield_v3();
00219 void __TBB_EXPORTED_FUNC thread_sleep_v3(const tick_count::interval_t &i);
00220
00221 inline bool operator==(tbb_thread_v3::id x, tbb_thread_v3::id y)
00222 {
00223 return x.my_id == y.my_id;
00224 }
00225 inline bool operator!=(tbb_thread_v3::id x, tbb_thread_v3::id y)
00226 {
00227 return x.my_id != y.my_id;
00228 }
00229 inline bool operator<(tbb_thread_v3::id x, tbb_thread_v3::id y)
00230 {
00231 return x.my_id < y.my_id;
00232 }
00233 inline bool operator<=(tbb_thread_v3::id x, tbb_thread_v3::id y)
00234 {
00235 return x.my_id <= y.my_id;
00236 }
00237 inline bool operator>(tbb_thread_v3::id x, tbb_thread_v3::id y)
00238 {
00239 return x.my_id > y.my_id;
00240 }
00241 inline bool operator>=(tbb_thread_v3::id x, tbb_thread_v3::id y)
00242 {
00243 return x.my_id >= y.my_id;
00244 }
00245
00246 }
00247
00249 typedef internal::tbb_thread_v3 tbb_thread;
00250
00251 using internal::operator==;
00252 using internal::operator!=;
00253 using internal::operator<;
00254 using internal::operator>;
00255 using internal::operator<=;
00256 using internal::operator>=;
00257
00258 inline void move( tbb_thread& t1, tbb_thread& t2 ) {
00259 internal::move_v3(t1, t2);
00260 }
00261
00262 inline void swap( internal::tbb_thread_v3& t1, internal::tbb_thread_v3& t2 ) {
00263 tbb::tbb_thread::native_handle_type h = t1.my_handle;
00264 t1.my_handle = t2.my_handle;
00265 t2.my_handle = h;
00266 #if _WIN32||_WIN64
00267 DWORD i = t1.my_thread_id;
00268 t1.my_thread_id = t2.my_thread_id;
00269 t2.my_thread_id = i;
00270 #endif
00271 }
00272
00273 namespace this_tbb_thread {
00274 inline tbb_thread::id get_id() { return internal::thread_get_id_v3(); }
00276 inline void yield() { internal::thread_yield_v3(); }
00278 inline void sleep(const tick_count::interval_t &i) {
00279 internal::thread_sleep_v3(i);
00280 }
00281 }
00282
00283 }
00284
00285 #endif