tbb_thread.h

00001 /*
00002     Copyright 2005-2011 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 #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     // Suppress "C++ exception handler used, but unwind semantics are not enabled" warning in STL headers
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 } // namespace internal
00057 
00058 inline 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&); // = delete;   // Deny access
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 // _WIN32||_WIN64
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 
00174         static unsigned __TBB_EXPORTED_FUNC hardware_concurrency();
00175     private:
00176         native_handle_type my_handle; 
00177 #if _WIN32||_WIN64
00178         DWORD my_thread_id;
00179 #endif // _WIN32||_WIN64
00180 
00182         void __TBB_EXPORTED_METHOD internal_start( __TBB_NATIVE_THREAD_ROUTINE_PTR(start_routine), 
00183                              void* closure );
00184         friend void __TBB_EXPORTED_FUNC move_v3( tbb_thread_v3& t1, tbb_thread_v3& t2 );
00185         friend void tbb::swap( tbb_thread_v3& t1, tbb_thread_v3& t2 ); 
00186     };
00187         
00188     class tbb_thread_v3::id { 
00189 #if _WIN32||_WIN64
00190         DWORD my_id;
00191         id( DWORD id_ ) : my_id(id_) {}
00192 #else
00193         pthread_t my_id;
00194         id( pthread_t id_ ) : my_id(id_) {}
00195 #endif // _WIN32||_WIN64
00196         friend class tbb_thread_v3;
00197     public:
00198         id() : my_id(0) {}
00199 
00200         friend bool operator==( tbb_thread_v3::id x, tbb_thread_v3::id y );
00201         friend bool operator!=( tbb_thread_v3::id x, tbb_thread_v3::id y );
00202         friend bool operator<( tbb_thread_v3::id x, tbb_thread_v3::id y );
00203         friend bool operator<=( tbb_thread_v3::id x, tbb_thread_v3::id y );
00204         friend bool operator>( tbb_thread_v3::id x, tbb_thread_v3::id y );
00205         friend bool operator>=( tbb_thread_v3::id x, tbb_thread_v3::id y );
00206         
00207         template<class charT, class traits>
00208         friend std::basic_ostream<charT, traits>&
00209         operator<< (std::basic_ostream<charT, traits> &out, 
00210                     tbb_thread_v3::id id)
00211         {
00212             out << id.my_id;
00213             return out;
00214         }
00215         friend tbb_thread_v3::id __TBB_EXPORTED_FUNC thread_get_id_v3();
00216     }; // tbb_thread_v3::id
00217 
00218     tbb_thread_v3::id tbb_thread_v3::get_id() const {
00219 #if _WIN32||_WIN64
00220         return id(my_thread_id);
00221 #else
00222         return id(my_handle);
00223 #endif // _WIN32||_WIN64
00224     }
00225     void __TBB_EXPORTED_FUNC move_v3( tbb_thread_v3& t1, tbb_thread_v3& t2 );
00226     tbb_thread_v3::id __TBB_EXPORTED_FUNC thread_get_id_v3();
00227     void __TBB_EXPORTED_FUNC thread_yield_v3();
00228     void __TBB_EXPORTED_FUNC thread_sleep_v3(const tick_count::interval_t &i);
00229 
00230     inline bool operator==(tbb_thread_v3::id x, tbb_thread_v3::id y)
00231     {
00232         return x.my_id == y.my_id;
00233     }
00234     inline bool operator!=(tbb_thread_v3::id x, tbb_thread_v3::id y)
00235     {
00236         return x.my_id != y.my_id;
00237     }
00238     inline bool operator<(tbb_thread_v3::id x, tbb_thread_v3::id y)
00239     {
00240         return x.my_id < y.my_id;
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 
00255 } // namespace internal;
00256 
00258 typedef internal::tbb_thread_v3 tbb_thread;
00259 
00260 using internal::operator==;
00261 using internal::operator!=;
00262 using internal::operator<;
00263 using internal::operator>;
00264 using internal::operator<=;
00265 using internal::operator>=;
00266 
00267 inline void move( tbb_thread& t1, tbb_thread& t2 ) {
00268     internal::move_v3(t1, t2);
00269 }
00270 
00271 inline void swap( internal::tbb_thread_v3& t1, internal::tbb_thread_v3& t2 ) {
00272     tbb::tbb_thread::native_handle_type h = t1.my_handle;
00273     t1.my_handle = t2.my_handle;
00274     t2.my_handle = h;
00275 #if _WIN32||_WIN64
00276     DWORD i = t1.my_thread_id;
00277     t1.my_thread_id = t2.my_thread_id;
00278     t2.my_thread_id = i;
00279 #endif /* _WIN32||_WIN64 */
00280 }
00281 
00282 namespace this_tbb_thread {
00283     inline tbb_thread::id get_id() { return internal::thread_get_id_v3(); }
00285     inline void yield() { internal::thread_yield_v3(); }
00287     inline void sleep(const tick_count::interval_t &i) { 
00288         internal::thread_sleep_v3(i);  
00289     }
00290 }  // namespace this_tbb_thread
00291 
00292 } // namespace tbb
00293 
00294 #endif /* __TBB_tbb_thread_H */

Copyright © 2005-2011 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.