tbb_thread.h Source File

- Main Page
- Modules
- Namespaces
- Classes
- Files
- Related Pages

- File List
- File Members

# tbb_thread.h

    00001 /*
    00002     Copyright 2005-2012 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-2012 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.