tbb_thread.h

00001 /*
00002     Copyright 2005-2010 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 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         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     }; // tbb_thread_v3::id
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 } // namespace internal;
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 /* _WIN32||_WIN64 */
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 }  // namespace this_tbb_thread
00282 
00283 } // namespace tbb
00284 
00285 #endif /* __TBB_tbb_thread_H */

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