Main Page | Modules | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | Related Pages

tbb_thread.h

00001 /*
00002     Copyright 2005-2008 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* allocate_closure_v3( size_t size );
00055     void 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& operator=(const tbb_thread_v3&); // Deny access
00115         tbb_thread_v3(const tbb_thread_v3&); // = delete;   // Deny access
00116     public:
00117 #if _WIN32||_WIN64
00118         typedef HANDLE native_handle_type; 
00119 #else
00120         typedef pthread_t native_handle_type; 
00121 #endif // _WIN32||_WIN64
00122 
00123         class id;
00125         tbb_thread_v3() : my_handle(0)
00126 #if _WIN32||_WIN64
00127             , my_thread_id(0)
00128 #endif // _WIN32||_WIN64
00129         {}
00130         
00132         template <class F> explicit tbb_thread_v3(F f) {
00133             typedef internal::thread_closure_0<F> closure_type;
00134             internal_start(closure_type::start_routine, new closure_type(f));
00135         }
00137         template <class F, class X> tbb_thread_v3(F f, X x) {
00138             typedef internal::thread_closure_1<F,X> closure_type;
00139             internal_start(closure_type::start_routine, new closure_type(f,x));
00140         }
00142         template <class F, class X, class Y> tbb_thread_v3(F f, X x, Y y) {
00143             typedef internal::thread_closure_2<F,X,Y> closure_type;
00144             internal_start(closure_type::start_routine, new closure_type(f,x,y));
00145         }
00146 
00147         bool joinable() const {return my_handle!=0; }
00149         void join();
00151         void detach();
00152         ~tbb_thread_v3() {if( joinable() ) detach();}
00153         inline id get_id() const;
00154         native_handle_type native_handle() { return my_handle; }
00155     
00157         static unsigned hardware_concurrency();
00158     private:
00159         native_handle_type my_handle; 
00160 #if _WIN32||_WIN64
00161         DWORD my_thread_id;
00162 #endif // _WIN32||_WIN64
00163 
00165         void internal_start( __TBB_NATIVE_THREAD_ROUTINE_PTR(start_routine), 
00166                              void* closure );
00167         friend void move_v3( tbb_thread_v3& t1, tbb_thread_v3& t2 );
00168         friend void tbb::swap( tbb_thread_v3& t1, tbb_thread_v3& t2 ); 
00169     };
00170         
00171     class tbb_thread_v3::id { 
00172 #if _WIN32||_WIN64
00173         DWORD my_id;
00174         id( DWORD my_id ) : my_id(my_id) {}
00175 #else
00176         pthread_t my_id;
00177         id( pthread_t my_id ) : my_id(my_id) {}
00178 #endif // _WIN32||_WIN64
00179         friend class tbb_thread_v3;
00180     public:
00181         id() : my_id(0) {}
00182 
00183         friend bool operator==( tbb_thread_v3::id x, tbb_thread_v3::id y );
00184         friend bool operator!=( tbb_thread_v3::id x, tbb_thread_v3::id y );
00185         friend bool operator<( tbb_thread_v3::id x, tbb_thread_v3::id y );
00186         friend bool operator<=( tbb_thread_v3::id x, tbb_thread_v3::id y );
00187         friend bool operator>( tbb_thread_v3::id x, tbb_thread_v3::id y );
00188         friend bool operator>=( tbb_thread_v3::id x, tbb_thread_v3::id y );
00189         
00190         template<class charT, class traits>
00191         friend std::basic_ostream<charT, traits>&
00192         operator<< (std::basic_ostream<charT, traits> &out, 
00193                     tbb_thread_v3::id id)
00194         {
00195             out << id.my_id;
00196             return out;
00197         }
00198         friend tbb_thread_v3::id thread_get_id_v3();
00199     }; // tbb_thread_v3::id
00200 
00201     tbb_thread_v3::id tbb_thread_v3::get_id() const {
00202 #if _WIN32||_WIN64
00203         return id(my_thread_id);
00204 #else
00205         return id(my_handle);
00206 #endif // _WIN32||_WIN64
00207     }
00208     void move_v3( tbb_thread_v3& t1, tbb_thread_v3& t2 );
00209     tbb_thread_v3::id thread_get_id_v3();
00210     void thread_yield_v3();
00211     void thread_sleep_v3(const tick_count::interval_t &i);
00212 
00213     inline bool operator==(tbb_thread_v3::id x, tbb_thread_v3::id y)
00214     {
00215         return x.my_id == y.my_id;
00216     }
00217     inline bool operator!=(tbb_thread_v3::id x, tbb_thread_v3::id y)
00218     {
00219         return x.my_id != y.my_id;
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 
00238 } // namespace internal;
00239 
00241 typedef internal::tbb_thread_v3 tbb_thread;
00242 
00243 using internal::operator==;
00244 using internal::operator!=;
00245 using internal::operator<;
00246 using internal::operator>;
00247 using internal::operator<=;
00248 using internal::operator>=;
00249 
00250 inline void move( tbb_thread& t1, tbb_thread& t2 ) {
00251     internal::move_v3(t1, t2);
00252 }
00253 
00254 inline void swap( internal::tbb_thread_v3& t1, internal::tbb_thread_v3& t2 ) {
00255     tbb::tbb_thread::native_handle_type h = t1.my_handle;
00256     t1.my_handle = t2.my_handle;
00257     t2.my_handle = h;
00258 #if _WIN32||_WIN64
00259     DWORD i = t1.my_thread_id;
00260     t1.my_thread_id = t2.my_thread_id;
00261     t2.my_thread_id = i;
00262 #endif /* _WIN32||_WIN64 */
00263 }
00264 
00265 namespace this_tbb_thread {
00266     inline tbb_thread::id get_id() { return internal::thread_get_id_v3(); }
00268     inline void yield() { internal::thread_yield_v3(); }
00270     inline void sleep(const tick_count::interval_t &i) { 
00271         internal::thread_sleep_v3(i);  
00272     }
00273 }  // namespace this_tbb_thread
00274 
00275 } // namespace tbb
00276 
00277 #endif /* __TBB_tbb_thread_H */

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