tbb_thread.h

00001 /*
00002     Copyright 2005-2013 Intel Corporation.  All Rights Reserved.
00003 
00004     The source code contained or described herein and all documents related
00005     to the source code ("Material") are owned by Intel Corporation or its
00006     suppliers or licensors.  Title to the Material remains with Intel
00007     Corporation or its suppliers and licensors.  The Material is protected
00008     by worldwide copyright laws and treaty provisions.  No part of the
00009     Material may be used, copied, reproduced, modified, published, uploaded,
00010     posted, transmitted, distributed, or disclosed in any way without
00011     Intel's prior express written permission.
00012 
00013     No license under any patent, copyright, trade secret or other
00014     intellectual property right is granted to or conferred upon you by
00015     disclosure or delivery of the Materials, either expressly, by
00016     implication, inducement, estoppel or otherwise.  Any license under such
00017     intellectual property rights must be express and approved by Intel in
00018     writing.
00019 */
00020 
00021 #ifndef __TBB_tbb_thread_H
00022 #define __TBB_tbb_thread_H
00023 
00024 #include "tbb_stddef.h"
00025 #if _WIN32||_WIN64
00026 #include "machine/windows_api.h"
00027 #define __TBB_NATIVE_THREAD_ROUTINE unsigned WINAPI
00028 #define __TBB_NATIVE_THREAD_ROUTINE_PTR(r) unsigned (WINAPI* r)( void* )
00029 #if __TBB_WIN8UI_SUPPORT
00030 typedef size_t thread_id_type;
00031 #else  // __TBB_WIN8UI_SUPPORT
00032 typedef DWORD thread_id_type;
00033 #endif // __TBB_WIN8UI_SUPPORT
00034 #else
00035 #define __TBB_NATIVE_THREAD_ROUTINE void*
00036 #define __TBB_NATIVE_THREAD_ROUTINE_PTR(r) void* (*r)( void* )
00037 #include <pthread.h>
00038 #endif // _WIN32||_WIN64
00039 
00040 #include "tick_count.h"
00041 
00042 #if !TBB_USE_EXCEPTIONS && _MSC_VER
00043     // Suppress "C++ exception handler used, but unwind semantics are not enabled" warning in STL headers
00044     #pragma warning (push)
00045     #pragma warning (disable: 4530)
00046 #endif
00047 
00048 #include <iosfwd>
00049 
00050 #if !TBB_USE_EXCEPTIONS && _MSC_VER
00051     #pragma warning (pop)
00052 #endif
00053 
00054 namespace tbb {
00055 
00057 namespace internal {
00058     
00059     class tbb_thread_v3;
00060 
00061 } // namespace internal
00062 
00063 inline void swap( internal::tbb_thread_v3& t1, internal::tbb_thread_v3& t2 ); 
00064 
00065 namespace internal {
00066 
00068     void* __TBB_EXPORTED_FUNC allocate_closure_v3( size_t size );
00070     void __TBB_EXPORTED_FUNC free_closure_v3( void* );
00071    
00072     struct thread_closure_base {
00073         void* operator new( size_t size ) {return allocate_closure_v3(size);}
00074         void operator delete( void* ptr ) {free_closure_v3(ptr);}
00075     };
00076 
00077     template<class F> struct thread_closure_0: thread_closure_base {
00078         F function;
00079 
00080         static __TBB_NATIVE_THREAD_ROUTINE start_routine( void* c ) {
00081             thread_closure_0 *self = static_cast<thread_closure_0*>(c);
00082             self->function();
00083             delete self;
00084             return 0;
00085         }
00086         thread_closure_0( const F& f ) : function(f) {}
00087     };
00089     template<class F, class X> struct thread_closure_1: thread_closure_base {
00090         F function;
00091         X arg1;
00093         static __TBB_NATIVE_THREAD_ROUTINE start_routine( void* c ) {
00094             thread_closure_1 *self = static_cast<thread_closure_1*>(c);
00095             self->function(self->arg1);
00096             delete self;
00097             return 0;
00098         }
00099         thread_closure_1( const F& f, const X& x ) : function(f), arg1(x) {}
00100     };
00101     template<class F, class X, class Y> struct thread_closure_2: thread_closure_base {
00102         F function;
00103         X arg1;
00104         Y arg2;
00106         static __TBB_NATIVE_THREAD_ROUTINE start_routine( void* c ) {
00107             thread_closure_2 *self = static_cast<thread_closure_2*>(c);
00108             self->function(self->arg1, self->arg2);
00109             delete self;
00110             return 0;
00111         }
00112         thread_closure_2( const F& f, const X& x, const Y& y ) : function(f), arg1(x), arg2(y) {}
00113     };
00114 
00116     class tbb_thread_v3 {
00117         tbb_thread_v3(const tbb_thread_v3&); // = delete;   // Deny access
00118     public:
00119 #if _WIN32||_WIN64
00120         typedef HANDLE native_handle_type; 
00121 #else
00122         typedef pthread_t native_handle_type; 
00123 #endif // _WIN32||_WIN64
00124 
00125         class id;
00127         tbb_thread_v3() : my_handle(0)
00128 #if _WIN32||_WIN64
00129             , my_thread_id(0)
00130 #endif // _WIN32||_WIN64
00131         {}
00132         
00134         template <class F> explicit tbb_thread_v3(F f) {
00135             typedef internal::thread_closure_0<F> closure_type;
00136             internal_start(closure_type::start_routine, new closure_type(f));
00137         }
00139         template <class F, class X> tbb_thread_v3(F f, X x) {
00140             typedef internal::thread_closure_1<F,X> closure_type;
00141             internal_start(closure_type::start_routine, new closure_type(f,x));
00142         }
00144         template <class F, class X, class Y> tbb_thread_v3(F f, X x, Y y) {
00145             typedef internal::thread_closure_2<F,X,Y> closure_type;
00146             internal_start(closure_type::start_routine, new closure_type(f,x,y));
00147         }
00148 
00149         tbb_thread_v3& operator=(tbb_thread_v3& x) {
00150             if (joinable()) detach();
00151             my_handle = x.my_handle;
00152             x.my_handle = 0;
00153 #if _WIN32||_WIN64
00154             my_thread_id = x.my_thread_id;
00155             x.my_thread_id = 0;
00156 #endif // _WIN32||_WIN64
00157             return *this;
00158         }
00159         void swap( tbb_thread_v3& t ) {tbb::swap( *this, t );}
00160         bool joinable() const {return my_handle!=0; }
00162         void __TBB_EXPORTED_METHOD join();
00164         void __TBB_EXPORTED_METHOD detach();
00165         ~tbb_thread_v3() {if( joinable() ) detach();}
00166         inline id get_id() const;
00167         native_handle_type native_handle() { return my_handle; }
00168     
00170 
00179         static unsigned __TBB_EXPORTED_FUNC hardware_concurrency();
00180     private:
00181         native_handle_type my_handle; 
00182 #if _WIN32||_WIN64
00183         thread_id_type my_thread_id;
00184 #endif // _WIN32||_WIN64
00185 
00187         void __TBB_EXPORTED_METHOD internal_start( __TBB_NATIVE_THREAD_ROUTINE_PTR(start_routine), 
00188                              void* closure );
00189         friend void __TBB_EXPORTED_FUNC move_v3( tbb_thread_v3& t1, tbb_thread_v3& t2 );
00190         friend void tbb::swap( tbb_thread_v3& t1, tbb_thread_v3& t2 ); 
00191     };
00192         
00193     class tbb_thread_v3::id { 
00194 #if _WIN32||_WIN64
00195         thread_id_type my_id;
00196         id( thread_id_type id_ ) : my_id(id_) {}
00197 #else
00198         pthread_t my_id;
00199         id( pthread_t id_ ) : my_id(id_) {}
00200 #endif // _WIN32||_WIN64
00201         friend class tbb_thread_v3;
00202     public:
00203         id() : my_id(0) {}
00204 
00205         friend bool operator==( tbb_thread_v3::id x, tbb_thread_v3::id y );
00206         friend bool operator!=( tbb_thread_v3::id x, tbb_thread_v3::id y );
00207         friend bool operator<( tbb_thread_v3::id x, tbb_thread_v3::id y );
00208         friend bool operator<=( tbb_thread_v3::id x, tbb_thread_v3::id y );
00209         friend bool operator>( tbb_thread_v3::id x, tbb_thread_v3::id y );
00210         friend bool operator>=( tbb_thread_v3::id x, tbb_thread_v3::id y );
00211         
00212         template<class charT, class traits>
00213         friend std::basic_ostream<charT, traits>&
00214         operator<< (std::basic_ostream<charT, traits> &out, 
00215                     tbb_thread_v3::id id)
00216         {
00217             out << id.my_id;
00218             return out;
00219         }
00220         friend tbb_thread_v3::id __TBB_EXPORTED_FUNC thread_get_id_v3();
00221     }; // tbb_thread_v3::id
00222 
00223     tbb_thread_v3::id tbb_thread_v3::get_id() const {
00224 #if _WIN32||_WIN64
00225         return id(my_thread_id);
00226 #else
00227         return id(my_handle);
00228 #endif // _WIN32||_WIN64
00229     }
00230     void __TBB_EXPORTED_FUNC move_v3( tbb_thread_v3& t1, tbb_thread_v3& t2 );
00231     tbb_thread_v3::id __TBB_EXPORTED_FUNC thread_get_id_v3();
00232     void __TBB_EXPORTED_FUNC thread_yield_v3();
00233     void __TBB_EXPORTED_FUNC thread_sleep_v3(const tick_count::interval_t &i);
00234 
00235     inline bool operator==(tbb_thread_v3::id x, tbb_thread_v3::id y)
00236     {
00237         return x.my_id == y.my_id;
00238     }
00239     inline bool operator!=(tbb_thread_v3::id x, tbb_thread_v3::id y)
00240     {
00241         return x.my_id != y.my_id;
00242     }
00243     inline bool operator<(tbb_thread_v3::id x, tbb_thread_v3::id y)
00244     {
00245         return x.my_id < y.my_id;
00246     }
00247     inline bool operator<=(tbb_thread_v3::id x, tbb_thread_v3::id y)
00248     {
00249         return x.my_id <= y.my_id;
00250     }
00251     inline bool operator>(tbb_thread_v3::id x, tbb_thread_v3::id y)
00252     {
00253         return x.my_id > y.my_id;
00254     }
00255     inline bool operator>=(tbb_thread_v3::id x, tbb_thread_v3::id y)
00256     {
00257         return x.my_id >= y.my_id;
00258     }
00259 
00260 } // namespace internal;
00261 
00263 typedef internal::tbb_thread_v3 tbb_thread;
00264 
00265 using internal::operator==;
00266 using internal::operator!=;
00267 using internal::operator<;
00268 using internal::operator>;
00269 using internal::operator<=;
00270 using internal::operator>=;
00271 
00272 inline void move( tbb_thread& t1, tbb_thread& t2 ) {
00273     internal::move_v3(t1, t2);
00274 }
00275 
00276 inline void swap( internal::tbb_thread_v3& t1, internal::tbb_thread_v3& t2 ) {
00277     tbb::tbb_thread::native_handle_type h = t1.my_handle;
00278     t1.my_handle = t2.my_handle;
00279     t2.my_handle = h;
00280 #if _WIN32||_WIN64
00281     thread_id_type i = t1.my_thread_id;
00282     t1.my_thread_id  = t2.my_thread_id;
00283     t2.my_thread_id  = i;
00284 #endif /* _WIN32||_WIN64 */
00285 }
00286 
00287 namespace this_tbb_thread {
00288     inline tbb_thread::id get_id() { return internal::thread_get_id_v3(); }
00290     inline void yield() { internal::thread_yield_v3(); }
00292     inline void sleep(const tick_count::interval_t &i) { 
00293         internal::thread_sleep_v3(i);  
00294     }
00295 }  // namespace this_tbb_thread
00296 
00297 } // namespace tbb
00298 
00299 #endif /* __TBB_tbb_thread_H */

Copyright © 2005-2013 Intel Corporation. All Rights Reserved.

Intel, Pentium, Intel Xeon, Itanium, Intel XScale and VTune are registered trademarks or trademarks of Intel Corporation or its subsidiaries in the United States and other countries.

* Other names and brands may be claimed as the property of others.