File indexing completed on 2025-01-18 10:13:01
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #include "internal/_deprecated_header_message_guard.h"
0018
0019 #if !defined(__TBB_show_deprecation_message_tbb_thread_H) && defined(__TBB_show_deprecated_header_message)
0020 #define __TBB_show_deprecation_message_tbb_thread_H
0021 #pragma message("TBB Warning: tbb/tbb_thread.h is deprecated. For details, please see Deprecated Features appendix in the TBB reference manual.")
0022 #endif
0023
0024 #if defined(__TBB_show_deprecated_header_message)
0025 #undef __TBB_show_deprecated_header_message
0026 #endif
0027
0028 #ifndef __TBB_tbb_thread_H
0029 #define __TBB_tbb_thread_H
0030
0031 #define __TBB_tbb_thread_H_include_area
0032 #include "internal/_warning_suppress_enable_notice.h"
0033
0034 #include "tbb_stddef.h"
0035
0036 #if _WIN32||_WIN64
0037 #include "machine/windows_api.h"
0038 #define __TBB_NATIVE_THREAD_ROUTINE unsigned WINAPI
0039 #define __TBB_NATIVE_THREAD_ROUTINE_PTR(r) unsigned (WINAPI* r)( void* )
0040 namespace tbb { namespace internal {
0041 #if __TBB_WIN8UI_SUPPORT
0042 typedef size_t thread_id_type;
0043 #else
0044 typedef DWORD thread_id_type;
0045 #endif
0046 }}
0047 #else
0048 #define __TBB_NATIVE_THREAD_ROUTINE void*
0049 #define __TBB_NATIVE_THREAD_ROUTINE_PTR(r) void* (*r)( void* )
0050 #include <pthread.h>
0051 namespace tbb { namespace internal {
0052 typedef pthread_t thread_id_type;
0053 }}
0054 #endif
0055
0056 #include "atomic.h"
0057 #include "internal/_tbb_hash_compare_impl.h"
0058 #include "tick_count.h"
0059
0060 #include __TBB_STD_SWAP_HEADER
0061 #include <iosfwd>
0062
0063 namespace tbb {
0064
0065 namespace internal {
0066 class tbb_thread_v3;
0067 }
0068
0069 inline void swap( internal::tbb_thread_v3& t1, internal::tbb_thread_v3& t2 ) __TBB_NOEXCEPT(true);
0070
0071 namespace internal {
0072
0073
0074 void* __TBB_EXPORTED_FUNC allocate_closure_v3( size_t size );
0075
0076 void __TBB_EXPORTED_FUNC free_closure_v3( void* );
0077
0078 struct thread_closure_base {
0079 void* operator new( size_t size ) {return allocate_closure_v3(size);}
0080 void operator delete( void* ptr ) {free_closure_v3(ptr);}
0081 };
0082
0083 template<class F> struct thread_closure_0: thread_closure_base {
0084 F function;
0085
0086 static __TBB_NATIVE_THREAD_ROUTINE start_routine( void* c ) {
0087 thread_closure_0 *self = static_cast<thread_closure_0*>(c);
0088 self->function();
0089 delete self;
0090 return 0;
0091 }
0092 thread_closure_0( const F& f ) : function(f) {}
0093 };
0094
0095 template<class F, class X> struct thread_closure_1: thread_closure_base {
0096 F function;
0097 X arg1;
0098
0099 static __TBB_NATIVE_THREAD_ROUTINE start_routine( void* c ) {
0100 thread_closure_1 *self = static_cast<thread_closure_1*>(c);
0101 self->function(self->arg1);
0102 delete self;
0103 return 0;
0104 }
0105 thread_closure_1( const F& f, const X& x ) : function(f), arg1(x) {}
0106 };
0107 template<class F, class X, class Y> struct thread_closure_2: thread_closure_base {
0108 F function;
0109 X arg1;
0110 Y arg2;
0111
0112 static __TBB_NATIVE_THREAD_ROUTINE start_routine( void* c ) {
0113 thread_closure_2 *self = static_cast<thread_closure_2*>(c);
0114 self->function(self->arg1, self->arg2);
0115 delete self;
0116 return 0;
0117 }
0118 thread_closure_2( const F& f, const X& x, const Y& y ) : function(f), arg1(x), arg2(y) {}
0119 };
0120
0121
0122 class tbb_thread_v3 {
0123 #if __TBB_IF_NO_COPY_CTOR_MOVE_SEMANTICS_BROKEN
0124
0125
0126
0127 public:
0128 #endif
0129 tbb_thread_v3(const tbb_thread_v3&);
0130 public:
0131 #if _WIN32||_WIN64
0132 typedef HANDLE native_handle_type;
0133 #else
0134 typedef pthread_t native_handle_type;
0135 #endif
0136
0137 class id;
0138
0139 tbb_thread_v3() __TBB_NOEXCEPT(true) : my_handle(0)
0140 #if _WIN32||_WIN64
0141 , my_thread_id(0)
0142 #endif
0143 {}
0144
0145
0146 template <class F> explicit tbb_thread_v3(F f) {
0147 typedef internal::thread_closure_0<F> closure_type;
0148 internal_start(closure_type::start_routine, new closure_type(f));
0149 }
0150
0151 template <class F, class X> tbb_thread_v3(F f, X x) {
0152 typedef internal::thread_closure_1<F,X> closure_type;
0153 internal_start(closure_type::start_routine, new closure_type(f,x));
0154 }
0155
0156 template <class F, class X, class Y> tbb_thread_v3(F f, X x, Y y) {
0157 typedef internal::thread_closure_2<F,X,Y> closure_type;
0158 internal_start(closure_type::start_routine, new closure_type(f,x,y));
0159 }
0160
0161 #if __TBB_CPP11_RVALUE_REF_PRESENT
0162 tbb_thread_v3(tbb_thread_v3&& x) __TBB_NOEXCEPT(true)
0163 : my_handle(x.my_handle)
0164 #if _WIN32||_WIN64
0165 , my_thread_id(x.my_thread_id)
0166 #endif
0167 {
0168 x.internal_wipe();
0169 }
0170 tbb_thread_v3& operator=(tbb_thread_v3&& x) __TBB_NOEXCEPT(true) {
0171 internal_move(x);
0172 return *this;
0173 }
0174 private:
0175 tbb_thread_v3& operator=(const tbb_thread_v3& x);
0176 public:
0177 #else
0178 tbb_thread_v3& operator=(tbb_thread_v3& x) {
0179 internal_move(x);
0180 return *this;
0181 }
0182 #endif
0183
0184 void swap( tbb_thread_v3& t ) __TBB_NOEXCEPT(true) {tbb::swap( *this, t );}
0185 bool joinable() const __TBB_NOEXCEPT(true) {return my_handle!=0; }
0186
0187 void __TBB_EXPORTED_METHOD join();
0188
0189 void __TBB_EXPORTED_METHOD detach();
0190 ~tbb_thread_v3() {if( joinable() ) detach();}
0191 inline id get_id() const __TBB_NOEXCEPT(true);
0192 native_handle_type native_handle() { return my_handle; }
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204 static unsigned __TBB_EXPORTED_FUNC hardware_concurrency() __TBB_NOEXCEPT(true);
0205 private:
0206 native_handle_type my_handle;
0207 #if _WIN32||_WIN64
0208 thread_id_type my_thread_id;
0209 #endif
0210
0211 void internal_wipe() __TBB_NOEXCEPT(true) {
0212 my_handle = 0;
0213 #if _WIN32||_WIN64
0214 my_thread_id = 0;
0215 #endif
0216 }
0217 void internal_move(tbb_thread_v3& x) __TBB_NOEXCEPT(true) {
0218 if (joinable()) detach();
0219 my_handle = x.my_handle;
0220 #if _WIN32||_WIN64
0221 my_thread_id = x.my_thread_id;
0222 #endif
0223 x.internal_wipe();
0224 }
0225
0226
0227 void __TBB_EXPORTED_METHOD internal_start( __TBB_NATIVE_THREAD_ROUTINE_PTR(start_routine),
0228 void* closure );
0229 friend void __TBB_EXPORTED_FUNC move_v3( tbb_thread_v3& t1, tbb_thread_v3& t2 );
0230 friend void tbb::swap( tbb_thread_v3& t1, tbb_thread_v3& t2 ) __TBB_NOEXCEPT(true);
0231 };
0232
0233 class tbb_thread_v3::id {
0234 thread_id_type my_id;
0235 id( thread_id_type id_ ) : my_id(id_) {}
0236
0237 friend class tbb_thread_v3;
0238 public:
0239 id() __TBB_NOEXCEPT(true) : my_id(0) {}
0240
0241 friend bool operator==( tbb_thread_v3::id x, tbb_thread_v3::id y ) __TBB_NOEXCEPT(true);
0242 friend bool operator!=( tbb_thread_v3::id x, tbb_thread_v3::id y ) __TBB_NOEXCEPT(true);
0243 friend bool operator<( tbb_thread_v3::id x, tbb_thread_v3::id y ) __TBB_NOEXCEPT(true);
0244 friend bool operator<=( tbb_thread_v3::id x, tbb_thread_v3::id y ) __TBB_NOEXCEPT(true);
0245 friend bool operator>( tbb_thread_v3::id x, tbb_thread_v3::id y ) __TBB_NOEXCEPT(true);
0246 friend bool operator>=( tbb_thread_v3::id x, tbb_thread_v3::id y ) __TBB_NOEXCEPT(true);
0247
0248 template<class charT, class traits>
0249 friend std::basic_ostream<charT, traits>&
0250 operator<< (std::basic_ostream<charT, traits> &out,
0251 tbb_thread_v3::id id)
0252 {
0253 out << id.my_id;
0254 return out;
0255 }
0256 friend tbb_thread_v3::id __TBB_EXPORTED_FUNC thread_get_id_v3();
0257
0258 friend inline size_t tbb_hasher( const tbb_thread_v3::id& id ) {
0259 __TBB_STATIC_ASSERT(sizeof(id.my_id) <= sizeof(size_t), "Implementation assumes that thread_id_type fits into machine word");
0260 return tbb::tbb_hasher(id.my_id);
0261 }
0262
0263
0264 friend id atomic_compare_and_swap(id& location, const id& value, const id& comparand){
0265 return as_atomic(location.my_id).compare_and_swap(value.my_id, comparand.my_id);
0266 }
0267 };
0268
0269 tbb_thread_v3::id tbb_thread_v3::get_id() const __TBB_NOEXCEPT(true) {
0270 #if _WIN32||_WIN64
0271 return id(my_thread_id);
0272 #else
0273 return id(my_handle);
0274 #endif
0275 }
0276
0277 void __TBB_EXPORTED_FUNC move_v3( tbb_thread_v3& t1, tbb_thread_v3& t2 );
0278 tbb_thread_v3::id __TBB_EXPORTED_FUNC thread_get_id_v3();
0279 void __TBB_EXPORTED_FUNC thread_yield_v3();
0280 void __TBB_EXPORTED_FUNC thread_sleep_v3(const tick_count::interval_t &i);
0281
0282 inline bool operator==(tbb_thread_v3::id x, tbb_thread_v3::id y) __TBB_NOEXCEPT(true)
0283 {
0284 return x.my_id == y.my_id;
0285 }
0286 inline bool operator!=(tbb_thread_v3::id x, tbb_thread_v3::id y) __TBB_NOEXCEPT(true)
0287 {
0288 return x.my_id != y.my_id;
0289 }
0290 inline bool operator<(tbb_thread_v3::id x, tbb_thread_v3::id y) __TBB_NOEXCEPT(true)
0291 {
0292 return x.my_id < y.my_id;
0293 }
0294 inline bool operator<=(tbb_thread_v3::id x, tbb_thread_v3::id y) __TBB_NOEXCEPT(true)
0295 {
0296 return x.my_id <= y.my_id;
0297 }
0298 inline bool operator>(tbb_thread_v3::id x, tbb_thread_v3::id y) __TBB_NOEXCEPT(true)
0299 {
0300 return x.my_id > y.my_id;
0301 }
0302 inline bool operator>=(tbb_thread_v3::id x, tbb_thread_v3::id y) __TBB_NOEXCEPT(true)
0303 {
0304 return x.my_id >= y.my_id;
0305 }
0306
0307 }
0308
0309
0310 __TBB_DEPRECATED_IN_VERBOSE_MODE_MSG("tbb::thread is deprecated, use std::thread") typedef internal::tbb_thread_v3 tbb_thread;
0311
0312 using internal::operator==;
0313 using internal::operator!=;
0314 using internal::operator<;
0315 using internal::operator>;
0316 using internal::operator<=;
0317 using internal::operator>=;
0318
0319 inline void move( tbb_thread& t1, tbb_thread& t2 ) {
0320 internal::move_v3(t1, t2);
0321 }
0322
0323 inline void swap( internal::tbb_thread_v3& t1, internal::tbb_thread_v3& t2 ) __TBB_NOEXCEPT(true) {
0324 std::swap(t1.my_handle, t2.my_handle);
0325 #if _WIN32||_WIN64
0326 std::swap(t1.my_thread_id, t2.my_thread_id);
0327 #endif
0328 }
0329
0330 namespace this_tbb_thread {
0331 __TBB_DEPRECATED_IN_VERBOSE_MODE inline tbb_thread::id get_id() { return internal::thread_get_id_v3(); }
0332
0333 __TBB_DEPRECATED_IN_VERBOSE_MODE inline void yield() { internal::thread_yield_v3(); }
0334
0335 __TBB_DEPRECATED_IN_VERBOSE_MODE inline void sleep(const tick_count::interval_t &i) {
0336 internal::thread_sleep_v3(i);
0337 }
0338 }
0339
0340 }
0341
0342 #include "internal/_warning_suppress_disable_notice.h"
0343 #undef __TBB_tbb_thread_H_include_area
0344
0345 #endif