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

- File List
- File Members

# tbb_thread.h

    00001 /*
    00002     Copyright 2005-2012 Intel Corporation.  All Rights Reserved.
    00003
    00004     This file is part of Threading Building Blocks.
    00005
    00006     Threading Building Blocks is free software; you can redistribute it
    00007     and/or modify it under the terms of the GNU General Public License
    00008     version 2 as published by the Free Software Foundation.
    00009
    00010     Threading Building Blocks is distributed in the hope that it will be
    00011     useful, but WITHOUT ANY WARRANTY; without even the implied warranty
    00012     of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    00013     GNU General Public License for more details.
    00014
    00015     You should have received a copy of the GNU General Public License
    00016     along with Threading Building Blocks; if not, write to the Free Software
    00017     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    00018
    00019     As a special exception, you may use this file as part of a free software
    00020     library without restriction.  Specifically, if other files instantiate
    00021     templates or use macros or inline functions from this file, or you compile
    00022     this file and link it with other files to produce an executable, this
    00023     file does not by itself cause the resulting executable to be covered by
    00024     the GNU General Public License.  This exception does not however
    00025     invalidate any other reasons why the executable file might be covered by
    00026     the GNU General Public License.
    00027 */
    00028
    00029 #ifndef __TBB_tbb_thread_H
    00030 #define __TBB_tbb_thread_H
    00031
    00032 #include "tbb_stddef.h"
    00033 #if _WIN32||_WIN64
    00034 #include "machine/windows_api.h"
    00035 #define __TBB_NATIVE_THREAD_ROUTINE unsigned WINAPI
    00036 #define __TBB_NATIVE_THREAD_ROUTINE_PTR(r) unsigned (WINAPI* r)( void* )
    00037 #if __TBB_WIN8UI_SUPPORT
    00038 typedef size_t thread_id_type;
    00039 #else  // __TBB_WIN8UI_SUPPORT
    00040 typedef DWORD thread_id_type;
    00041 #endif // __TBB_WIN8UI_SUPPORT
    00042 #else
    00043 #define __TBB_NATIVE_THREAD_ROUTINE void*
    00044 #define __TBB_NATIVE_THREAD_ROUTINE_PTR(r) void* (*r)( void* )
    00045 #include <pthread.h>
    00046 #endif // _WIN32||_WIN64
    00047
    00048 #include "tick_count.h"
    00049
    00050 #if !TBB_USE_EXCEPTIONS && _MSC_VER
    00051     // Suppress "C++ exception handler used, but unwind semantics are not enabled" warning in STL headers
    00052     #pragma warning (push)
    00053     #pragma warning (disable: 4530)
    00054 #endif
    00055
    00056 #include <iosfwd>
    00057
    00058 #if !TBB_USE_EXCEPTIONS && _MSC_VER
    00059     #pragma warning (pop)
    00060 #endif
    00061
    00062 namespace tbb {
    00063
    00065 namespace internal {
    00066
    00067     class tbb_thread_v3;
    00068
    00069 } // namespace internal
    00070
    00071 inline void swap( internal::tbb_thread_v3& t1, internal::tbb_thread_v3& t2 );
    00072
    00073 namespace internal {
    00074
    00076     void* __TBB_EXPORTED_FUNC allocate_closure_v3( size_t size );
    00078     void __TBB_EXPORTED_FUNC free_closure_v3( void* );
    00079
    00080     struct thread_closure_base {
    00081         void* operator new( size_t size ) {return allocate_closure_v3(size);}
    00082         void operator delete( void* ptr ) {free_closure_v3(ptr);}
    00083     };
    00084
    00085     template<class F> struct thread_closure_0: thread_closure_base {
    00086         F function;
    00087
    00088         static __TBB_NATIVE_THREAD_ROUTINE start_routine( void* c ) {
    00089             thread_closure_0 *self = static_cast<thread_closure_0*>(c);
    00090             self->function();
    00091             delete self;
    00092             return 0;
    00093         }
    00094         thread_closure_0( const F& f ) : function(f) {}
    00095     };
    00097     template<class F, class X> struct thread_closure_1: thread_closure_base {
    00098         F function;
    00099         X arg1;
    00101         static __TBB_NATIVE_THREAD_ROUTINE start_routine( void* c ) {
    00102             thread_closure_1 *self = static_cast<thread_closure_1*>(c);
    00103             self->function(self->arg1);
    00104             delete self;
    00105             return 0;
    00106         }
    00107         thread_closure_1( const F& f, const X& x ) : function(f), arg1(x) {}
    00108     };
    00109     template<class F, class X, class Y> struct thread_closure_2: thread_closure_base {
    00110         F function;
    00111         X arg1;
    00112         Y arg2;
    00114         static __TBB_NATIVE_THREAD_ROUTINE start_routine( void* c ) {
    00115             thread_closure_2 *self = static_cast<thread_closure_2*>(c);
    00116             self->function(self->arg1, self->arg2);
    00117             delete self;
    00118             return 0;
    00119         }
    00120         thread_closure_2( const F& f, const X& x, const Y& y ) : function(f), arg1(x), arg2(y) {}
    00121     };
    00122
    00124     class tbb_thread_v3 {
    00125         tbb_thread_v3(const tbb_thread_v3&); // = delete;   // Deny access
    00126     public:
    00127 #if _WIN32||_WIN64
    00128         typedef HANDLE native_handle_type;
    00129 #else
    00130         typedef pthread_t native_handle_type;
    00131 #endif // _WIN32||_WIN64
    00132
    00133         class id;
    00135         tbb_thread_v3() : my_handle(0)
    00136 #if _WIN32||_WIN64
    00137             , my_thread_id(0)
    00138 #endif // _WIN32||_WIN64
    00139         {}
    00140
    00142         template <class F> explicit tbb_thread_v3(F f) {
    00143             typedef internal::thread_closure_0<F> closure_type;
    00144             internal_start(closure_type::start_routine, new closure_type(f));
    00145         }
    00147         template <class F, class X> tbb_thread_v3(F f, X x) {
    00148             typedef internal::thread_closure_1<F,X> closure_type;
    00149             internal_start(closure_type::start_routine, new closure_type(f,x));
    00150         }
    00152         template <class F, class X, class Y> tbb_thread_v3(F f, X x, Y y) {
    00153             typedef internal::thread_closure_2<F,X,Y> closure_type;
    00154             internal_start(closure_type::start_routine, new closure_type(f,x,y));
    00155         }
    00156
    00157         tbb_thread_v3& operator=(tbb_thread_v3& x) {
    00158             if (joinable()) detach();
    00159             my_handle = x.my_handle;
    00160             x.my_handle = 0;
    00161 #if _WIN32||_WIN64
    00162             my_thread_id = x.my_thread_id;
    00163             x.my_thread_id = 0;
    00164 #endif // _WIN32||_WIN64
    00165             return *this;
    00166         }
    00167         void swap( tbb_thread_v3& t ) {tbb::swap( *this, t );}
    00168         bool joinable() const {return my_handle!=0; }
    00170         void __TBB_EXPORTED_METHOD join();
    00172         void __TBB_EXPORTED_METHOD detach();
    00173         ~tbb_thread_v3() {if( joinable() ) detach();}
    00174         inline id get_id() const;
    00175         native_handle_type native_handle() { return my_handle; }
    00176
    00178
    00187         static unsigned __TBB_EXPORTED_FUNC hardware_concurrency();
    00188     private:
    00189         native_handle_type my_handle;
    00190 #if _WIN32||_WIN64
    00191         thread_id_type my_thread_id;
    00192 #endif // _WIN32||_WIN64
    00193
    00195         void __TBB_EXPORTED_METHOD internal_start( __TBB_NATIVE_THREAD_ROUTINE_PTR(start_routine),
    00196                              void* closure );
    00197         friend void __TBB_EXPORTED_FUNC move_v3( tbb_thread_v3& t1, tbb_thread_v3& t2 );
    00198         friend void tbb::swap( tbb_thread_v3& t1, tbb_thread_v3& t2 );
    00199     };
    00200
    00201     class tbb_thread_v3::id {
    00202 #if _WIN32||_WIN64
    00203         thread_id_type my_id;
    00204         id( thread_id_type id_ ) : my_id(id_) {}
    00205 #else
    00206         pthread_t my_id;
    00207         id( pthread_t id_ ) : my_id(id_) {}
    00208 #endif // _WIN32||_WIN64
    00209         friend class tbb_thread_v3;
    00210     public:
    00211         id() : my_id(0) {}
    00212
    00213         friend bool operator==( tbb_thread_v3::id x, tbb_thread_v3::id y );
    00214         friend bool operator!=( tbb_thread_v3::id x, tbb_thread_v3::id y );
    00215         friend bool operator<( tbb_thread_v3::id x, tbb_thread_v3::id y );
    00216         friend bool operator<=( tbb_thread_v3::id x, tbb_thread_v3::id y );
    00217         friend bool operator>( tbb_thread_v3::id x, tbb_thread_v3::id y );
    00218         friend bool operator>=( tbb_thread_v3::id x, tbb_thread_v3::id y );
    00219
    00220         template<class charT, class traits>
    00221         friend std::basic_ostream<charT, traits>&
    00222         operator<< (std::basic_ostream<charT, traits> &out,
    00223                     tbb_thread_v3::id id)
    00224         {
    00225             out << id.my_id;
    00226             return out;
    00227         }
    00228         friend tbb_thread_v3::id __TBB_EXPORTED_FUNC thread_get_id_v3();
    00229     }; // tbb_thread_v3::id
    00230
    00231     tbb_thread_v3::id tbb_thread_v3::get_id() const {
    00232 #if _WIN32||_WIN64
    00233         return id(my_thread_id);
    00234 #else
    00235         return id(my_handle);
    00236 #endif // _WIN32||_WIN64
    00237     }
    00238     void __TBB_EXPORTED_FUNC move_v3( tbb_thread_v3& t1, tbb_thread_v3& t2 );
    00239     tbb_thread_v3::id __TBB_EXPORTED_FUNC thread_get_id_v3();
    00240     void __TBB_EXPORTED_FUNC thread_yield_v3();
    00241     void __TBB_EXPORTED_FUNC thread_sleep_v3(const tick_count::interval_t &i);
    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     inline bool operator!=(tbb_thread_v3::id x, tbb_thread_v3::id y)
    00248     {
    00249         return x.my_id != y.my_id;
    00250     }
    00251     inline bool operator<(tbb_thread_v3::id x, tbb_thread_v3::id y)
    00252     {
    00253         return x.my_id < y.my_id;
    00254     }
    00255     inline bool operator<=(tbb_thread_v3::id x, tbb_thread_v3::id y)
    00256     {
    00257         return x.my_id <= y.my_id;
    00258     }
    00259     inline bool operator>(tbb_thread_v3::id x, tbb_thread_v3::id y)
    00260     {
    00261         return x.my_id > y.my_id;
    00262     }
    00263     inline bool operator>=(tbb_thread_v3::id x, tbb_thread_v3::id y)
    00264     {
    00265         return x.my_id >= y.my_id;
    00266     }
    00267
    00268 } // namespace internal;
    00269
    00271 typedef internal::tbb_thread_v3 tbb_thread;
    00272
    00273 using internal::operator==;
    00274 using internal::operator!=;
    00275 using internal::operator<;
    00276 using internal::operator>;
    00277 using internal::operator<=;
    00278 using internal::operator>=;
    00279
    00280 inline void move( tbb_thread& t1, tbb_thread& t2 ) {
    00281     internal::move_v3(t1, t2);
    00282 }
    00283
    00284 inline void swap( internal::tbb_thread_v3& t1, internal::tbb_thread_v3& t2 ) {
    00285     tbb::tbb_thread::native_handle_type h = t1.my_handle;
    00286     t1.my_handle = t2.my_handle;
    00287     t2.my_handle = h;
    00288 #if _WIN32||_WIN64
    00289     thread_id_type i = t1.my_thread_id;
    00290     t1.my_thread_id  = t2.my_thread_id;
    00291     t2.my_thread_id  = i;
    00292 #endif /* _WIN32||_WIN64 */
    00293 }
    00294
    00295 namespace this_tbb_thread {
    00296     inline tbb_thread::id get_id() { return internal::thread_get_id_v3(); }
    00298     inline void yield() { internal::thread_yield_v3(); }
    00300     inline void sleep(const tick_count::interval_t &i) {
    00301         internal::thread_sleep_v3(i);
    00302     }
    00303 }  // namespace this_tbb_thread
    00304
    00305 } // namespace tbb
    00306
    00307 #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.