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 <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         void swap( tbb_thread_v3& t ) {tbb::swap( *this, t );}
00157         bool joinable() const {return my_handle!=0; }
00159         void __TBB_EXPORTED_METHOD join();
00161         void __TBB_EXPORTED_METHOD detach();
00162         ~tbb_thread_v3() {if( joinable() ) detach();}
00163         inline id get_id() const;
00164         native_handle_type native_handle() { return my_handle; }
00165     
00167         static unsigned __TBB_EXPORTED_FUNC hardware_concurrency();
00168     private:
00169         native_handle_type my_handle; 
00170 #if _WIN32||_WIN64
00171         DWORD my_thread_id;
00172 #endif // _WIN32||_WIN64
00173 
00175         void __TBB_EXPORTED_METHOD internal_start( __TBB_NATIVE_THREAD_ROUTINE_PTR(start_routine), 
00176                              void* closure );
00177         friend void __TBB_EXPORTED_FUNC move_v3( tbb_thread_v3& t1, tbb_thread_v3& t2 );
00178         friend void tbb::swap( tbb_thread_v3& t1, tbb_thread_v3& t2 ); 
00179     };
00180         
00181     class tbb_thread_v3::id { 
00182 #if _WIN32||_WIN64
00183         DWORD my_id;
00184         id( DWORD my_id ) : my_id(my_id) {}
00185 #else
00186         pthread_t my_id;
00187         id( pthread_t my_id ) : my_id(my_id) {}
00188 #endif // _WIN32||_WIN64
00189         friend class tbb_thread_v3;
00190     public:
00191         id() : my_id(0) {}
00192 
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         friend bool operator>=( tbb_thread_v3::id x, tbb_thread_v3::id y );
00199         
00200         template<class charT, class traits>
00201         friend std::basic_ostream<charT, traits>&
00202         operator<< (std::basic_ostream<charT, traits> &out, 
00203                     tbb_thread_v3::id id)
00204         {
00205             out << id.my_id;
00206             return out;
00207         }
00208         friend tbb_thread_v3::id __TBB_EXPORTED_FUNC thread_get_id_v3();
00209     }; // tbb_thread_v3::id
00210 
00211     tbb_thread_v3::id tbb_thread_v3::get_id() const {
00212 #if _WIN32||_WIN64
00213         return id(my_thread_id);
00214 #else
00215         return id(my_handle);
00216 #endif // _WIN32||_WIN64
00217     }
00218     void __TBB_EXPORTED_FUNC move_v3( tbb_thread_v3& t1, tbb_thread_v3& t2 );
00219     tbb_thread_v3::id __TBB_EXPORTED_FUNC thread_get_id_v3();
00220     void __TBB_EXPORTED_FUNC thread_yield_v3();
00221     void __TBB_EXPORTED_FUNC thread_sleep_v3(const tick_count::interval_t &i);
00222 
00223     inline bool operator==(tbb_thread_v3::id x, tbb_thread_v3::id y)
00224     {
00225         return x.my_id == y.my_id;
00226     }
00227     inline bool operator!=(tbb_thread_v3::id x, tbb_thread_v3::id y)
00228     {
00229         return x.my_id != y.my_id;
00230     }
00231     inline bool operator<(tbb_thread_v3::id x, tbb_thread_v3::id y)
00232     {
00233         return x.my_id < y.my_id;
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 
00248 } // namespace internal;
00249 
00251 typedef internal::tbb_thread_v3 tbb_thread;
00252 
00253 using internal::operator==;
00254 using internal::operator!=;
00255 using internal::operator<;
00256 using internal::operator>;
00257 using internal::operator<=;
00258 using internal::operator>=;
00259 
00260 inline void move( tbb_thread& t1, tbb_thread& t2 ) {
00261     internal::move_v3(t1, t2);
00262 }
00263 
00264 inline void swap( internal::tbb_thread_v3& t1, internal::tbb_thread_v3& t2 ) {
00265     tbb::tbb_thread::native_handle_type h = t1.my_handle;
00266     t1.my_handle = t2.my_handle;
00267     t2.my_handle = h;
00268 #if _WIN32||_WIN64
00269     DWORD i = t1.my_thread_id;
00270     t1.my_thread_id = t2.my_thread_id;
00271     t2.my_thread_id = i;
00272 #endif /* _WIN32||_WIN64 */
00273 }
00274 
00275 namespace this_tbb_thread {
00276     inline tbb_thread::id get_id() { return internal::thread_get_id_v3(); }
00278     inline void yield() { internal::thread_yield_v3(); }
00280     inline void sleep(const tick_count::interval_t &i) { 
00281         internal::thread_sleep_v3(i);  
00282     }
00283 }  // namespace this_tbb_thread
00284 
00285 } // namespace tbb
00286 
00287 #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.