tbb_thread.h

00001 /*
00002     Copyright 2005-2009 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 <windows.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 <iosfwd>
00035 #include <exception>             // Need std::terminate from here.
00036 #include "tbb_stddef.h"
00037 #include "tick_count.h"
00038 
00039 namespace tbb {
00040 
00042 namespace internal {
00043     
00044     class tbb_thread_v3;
00045 
00046 } // namespace internal
00047 
00048 void swap( internal::tbb_thread_v3& t1, internal::tbb_thread_v3& t2 ); 
00049 
00050 namespace internal {
00051 
00053     void* __TBB_EXPORTED_FUNC allocate_closure_v3( size_t size );
00055     void __TBB_EXPORTED_FUNC free_closure_v3( void* );
00056    
00057     struct thread_closure_base {
00058         void* operator new( size_t size ) {return allocate_closure_v3(size);}
00059         void operator delete( void* ptr ) {free_closure_v3(ptr);}
00060     };
00061 
00062     template<class F> struct thread_closure_0: thread_closure_base {
00063         F function;
00064 
00065         static __TBB_NATIVE_THREAD_ROUTINE start_routine( void* c ) {
00066             thread_closure_0 *self = static_cast<thread_closure_0*>(c);
00067             try {
00068                 self->function();
00069             } catch ( ... ) {
00070                 std::terminate();
00071             }
00072             delete self;
00073             return 0;
00074         }
00075         thread_closure_0( const F& f ) : function(f) {}
00076     };
00078     template<class F, class X> struct thread_closure_1: thread_closure_base {
00079         F function;
00080         X arg1;
00082         static __TBB_NATIVE_THREAD_ROUTINE start_routine( void* c ) {
00083             thread_closure_1 *self = static_cast<thread_closure_1*>(c);
00084             try {
00085                 self->function(self->arg1);
00086             } catch ( ... ) {
00087                 std::terminate();
00088             }
00089             delete self;
00090             return 0;
00091         }
00092         thread_closure_1( const F& f, const X& x ) : function(f), arg1(x) {}
00093     };
00094     template<class F, class X, class Y> struct thread_closure_2: thread_closure_base {
00095         F function;
00096         X arg1;
00097         Y arg2;
00099         static __TBB_NATIVE_THREAD_ROUTINE start_routine( void* c ) {
00100             thread_closure_2 *self = static_cast<thread_closure_2*>(c);
00101             try {
00102                 self->function(self->arg1, self->arg2);
00103             } catch ( ... ) {
00104                 std::terminate();
00105             }
00106             delete self;
00107             return 0;
00108         }
00109         thread_closure_2( const F& f, const X& x, const Y& y ) : function(f), arg1(x), arg2(y) {}
00110     };
00111 
00113     class tbb_thread_v3 {
00114         tbb_thread_v3(const tbb_thread_v3&); // = delete;   // Deny access
00115     public:
00116 #if _WIN32||_WIN64
00117         typedef HANDLE native_handle_type; 
00118 #else
00119         typedef pthread_t native_handle_type; 
00120 #endif // _WIN32||_WIN64
00121 
00122         class id;
00124         tbb_thread_v3() : my_handle(0)
00125 #if _WIN32||_WIN64
00126             , my_thread_id(0)
00127 #endif // _WIN32||_WIN64
00128         {}
00129         
00131         template <class F> explicit tbb_thread_v3(F f) {
00132             typedef internal::thread_closure_0<F> closure_type;
00133             internal_start(closure_type::start_routine, new closure_type(f));
00134         }
00136         template <class F, class X> tbb_thread_v3(F f, X x) {
00137             typedef internal::thread_closure_1<F,X> closure_type;
00138             internal_start(closure_type::start_routine, new closure_type(f,x));
00139         }
00141         template <class F, class X, class Y> tbb_thread_v3(F f, X x, Y y) {
00142             typedef internal::thread_closure_2<F,X,Y> closure_type;
00143             internal_start(closure_type::start_routine, new closure_type(f,x,y));
00144         }
00145 
00146         tbb_thread_v3& operator=(tbb_thread_v3& x) {
00147             if (joinable()) detach();
00148             my_handle = x.my_handle;
00149             x.my_handle = 0;
00150 #if _WIN32||_WIN64
00151             my_thread_id = x.my_thread_id;
00152             x.my_thread_id = 0;
00153 #endif // _WIN32||_WIN64
00154             return *this;
00155         }
00156         bool joinable() const {return my_handle!=0; }
00158         void __TBB_EXPORTED_METHOD join();
00160         void __TBB_EXPORTED_METHOD detach();
00161         ~tbb_thread_v3() {if( joinable() ) detach();}
00162         inline id get_id() const;
00163         native_handle_type native_handle() { return my_handle; }
00164     
00166         static unsigned __TBB_EXPORTED_FUNC hardware_concurrency();
00167     private:
00168         native_handle_type my_handle; 
00169 #if _WIN32||_WIN64
00170         DWORD my_thread_id;
00171 #endif // _WIN32||_WIN64
00172 
00174         void __TBB_EXPORTED_METHOD internal_start( __TBB_NATIVE_THREAD_ROUTINE_PTR(start_routine), 
00175                              void* closure );
00176         friend void __TBB_EXPORTED_FUNC move_v3( tbb_thread_v3& t1, tbb_thread_v3& t2 );
00177         friend void tbb::swap( tbb_thread_v3& t1, tbb_thread_v3& t2 ); 
00178     };
00179         
00180     class tbb_thread_v3::id { 
00181 #if _WIN32||_WIN64
00182         DWORD my_id;
00183         id( DWORD my_id ) : my_id(my_id) {}
00184 #else
00185         pthread_t my_id;
00186         id( pthread_t my_id ) : my_id(my_id) {}
00187 #endif // _WIN32||_WIN64
00188         friend class tbb_thread_v3;
00189     public:
00190         id() : my_id(0) {}
00191 
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         friend bool operator>=( tbb_thread_v3::id x, tbb_thread_v3::id y );
00198         
00199         template<class charT, class traits>
00200         friend std::basic_ostream<charT, traits>&
00201         operator<< (std::basic_ostream<charT, traits> &out, 
00202                     tbb_thread_v3::id id)
00203         {
00204             out << id.my_id;
00205             return out;
00206         }
00207         friend tbb_thread_v3::id __TBB_EXPORTED_FUNC thread_get_id_v3();
00208     }; // tbb_thread_v3::id
00209 
00210     tbb_thread_v3::id tbb_thread_v3::get_id() const {
00211 #if _WIN32||_WIN64
00212         return id(my_thread_id);
00213 #else
00214         return id(my_handle);
00215 #endif // _WIN32||_WIN64
00216     }
00217     void __TBB_EXPORTED_FUNC move_v3( tbb_thread_v3& t1, tbb_thread_v3& t2 );
00218     tbb_thread_v3::id __TBB_EXPORTED_FUNC thread_get_id_v3();
00219     void __TBB_EXPORTED_FUNC thread_yield_v3();
00220     void __TBB_EXPORTED_FUNC thread_sleep_v3(const tick_count::interval_t &i);
00221 
00222     inline bool operator==(tbb_thread_v3::id x, tbb_thread_v3::id y)
00223     {
00224         return x.my_id == y.my_id;
00225     }
00226     inline bool operator!=(tbb_thread_v3::id x, tbb_thread_v3::id y)
00227     {
00228         return x.my_id != y.my_id;
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 
00247 } // namespace internal;
00248 
00250 typedef internal::tbb_thread_v3 tbb_thread;
00251 
00252 using internal::operator==;
00253 using internal::operator!=;
00254 using internal::operator<;
00255 using internal::operator>;
00256 using internal::operator<=;
00257 using internal::operator>=;
00258 
00259 inline void move( tbb_thread& t1, tbb_thread& t2 ) {
00260     internal::move_v3(t1, t2);
00261 }
00262 
00263 inline void swap( internal::tbb_thread_v3& t1, internal::tbb_thread_v3& t2 ) {
00264     tbb::tbb_thread::native_handle_type h = t1.my_handle;
00265     t1.my_handle = t2.my_handle;
00266     t2.my_handle = h;
00267 #if _WIN32||_WIN64
00268     DWORD i = t1.my_thread_id;
00269     t1.my_thread_id = t2.my_thread_id;
00270     t2.my_thread_id = i;
00271 #endif /* _WIN32||_WIN64 */
00272 }
00273 
00274 namespace this_tbb_thread {
00275     inline tbb_thread::id get_id() { return internal::thread_get_id_v3(); }
00277     inline void yield() { internal::thread_yield_v3(); }
00279     inline void sleep(const tick_count::interval_t &i) { 
00280         internal::thread_sleep_v3(i);  
00281     }
00282 }  // namespace this_tbb_thread
00283 
00284 } // namespace tbb
00285 
00286 #endif /* __TBB_tbb_thread_H */

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