Shadowrun: Awakened 29 September 2011 - Build 871
tbb_thread.h
Go to the documentation of this file.
00001 /*
00002     Copyright 2005-2010 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 #if _WIN32||_WIN64
00033 #include <windows.h>
00034 #define __TBB_NATIVE_THREAD_ROUTINE unsigned WINAPI
00035 #define __TBB_NATIVE_THREAD_ROUTINE_PTR(r) unsigned (WINAPI* r)( void* )
00036 #else
00037 #define __TBB_NATIVE_THREAD_ROUTINE void*
00038 #define __TBB_NATIVE_THREAD_ROUTINE_PTR(r) void* (*r)( void* )
00039 #include <pthread.h>
00040 #endif // _WIN32||_WIN64
00041 
00042 #include "tbb_stddef.h"
00043 #include "tick_count.h"
00044 #include <exception>             // Need std::terminate from here.
00045 
00046 #if !TBB_USE_EXCEPTIONS && _MSC_VER
00047     // Suppress "C++ exception handler used, but unwind semantics are not enabled" warning in STL headers
00048     #pragma warning (push)
00049     #pragma warning (disable: 4530)
00050 #endif
00051 
00052 #include <iosfwd>
00053 
00054 #if !TBB_USE_EXCEPTIONS && _MSC_VER
00055     #pragma warning (pop)
00056 #endif
00057 
00058 namespace tbb {
00059 
00061 namespace internal {
00062     
00063     class tbb_thread_v3;
00064 
00065 } // namespace internal
00066 
00067 void swap( internal::tbb_thread_v3& t1, internal::tbb_thread_v3& t2 ); 
00068 
00069 namespace internal {
00070 
00072     void* __TBB_EXPORTED_FUNC allocate_closure_v3( size_t size );
00074     void __TBB_EXPORTED_FUNC free_closure_v3( void* );
00075    
00076     struct thread_closure_base {
00077         void* operator new( size_t size ) {return allocate_closure_v3(size);}
00078         void operator delete( void* ptr ) {free_closure_v3(ptr);}
00079     };
00080 
00081     template<class F> struct thread_closure_0: thread_closure_base {
00082         F function;
00083 
00084         static __TBB_NATIVE_THREAD_ROUTINE start_routine( void* c ) {
00085             thread_closure_0 *self = static_cast<thread_closure_0*>(c);
00086             __TBB_TRY {
00087                 self->function();
00088             } __TBB_CATCH( ... ) {
00089                 std::terminate();
00090             }
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             __TBB_TRY {
00104                 self->function(self->arg1);
00105             } __TBB_CATCH( ... ) {
00106                 std::terminate();
00107             }
00108             delete self;
00109             return 0;
00110         }
00111         thread_closure_1( const F& f, const X& x ) : function(f), arg1(x) {}
00112     };
00113     template<class F, class X, class Y> struct thread_closure_2: thread_closure_base {
00114         F function;
00115         X arg1;
00116         Y arg2;
00118         static __TBB_NATIVE_THREAD_ROUTINE start_routine( void* c ) {
00119             thread_closure_2 *self = static_cast<thread_closure_2*>(c);
00120             __TBB_TRY {
00121                 self->function(self->arg1, self->arg2);
00122             } __TBB_CATCH( ... ) {
00123                 std::terminate();
00124             }
00125             delete self;
00126             return 0;
00127         }
00128         thread_closure_2( const F& f, const X& x, const Y& y ) : function(f), arg1(x), arg2(y) {}
00129     };
00130 
00132     class tbb_thread_v3 {
00133         tbb_thread_v3(const tbb_thread_v3&); // = delete;   // Deny access
00134     public:
00135 #if _WIN32||_WIN64
00136         typedef HANDLE native_handle_type; 
00137 #else
00138         typedef pthread_t native_handle_type; 
00139 #endif // _WIN32||_WIN64
00140 
00141         class id;
00143         tbb_thread_v3() : my_handle(0)
00144 #if _WIN32||_WIN64
00145             , my_thread_id(0)
00146 #endif // _WIN32||_WIN64
00147         {}
00148         
00150         template <class F> explicit tbb_thread_v3(F f) {
00151             typedef internal::thread_closure_0<F> closure_type;
00152             internal_start(closure_type::start_routine, new closure_type(f));
00153         }
00155         template <class F, class X> tbb_thread_v3(F f, X x) {
00156             typedef internal::thread_closure_1<F,X> closure_type;
00157             internal_start(closure_type::start_routine, new closure_type(f,x));
00158         }
00160         template <class F, class X, class Y> tbb_thread_v3(F f, X x, Y y) {
00161             typedef internal::thread_closure_2<F,X,Y> closure_type;
00162             internal_start(closure_type::start_routine, new closure_type(f,x,y));
00163         }
00164 
00165         tbb_thread_v3& operator=(tbb_thread_v3& x) {
00166             if (joinable()) detach();
00167             my_handle = x.my_handle;
00168             x.my_handle = 0;
00169 #if _WIN32||_WIN64
00170             my_thread_id = x.my_thread_id;
00171             x.my_thread_id = 0;
00172 #endif // _WIN32||_WIN64
00173             return *this;
00174         }
00175         void swap( tbb_thread_v3& t ) {tbb::swap( *this, t );}
00176         bool joinable() const {return my_handle!=0; }
00178         void __TBB_EXPORTED_METHOD join();
00180         void __TBB_EXPORTED_METHOD detach();
00181         ~tbb_thread_v3() {if( joinable() ) detach();}
00182         inline id get_id() const;
00183         native_handle_type native_handle() { return my_handle; }
00184     
00186         static unsigned __TBB_EXPORTED_FUNC hardware_concurrency();
00187     private:
00188         native_handle_type my_handle; 
00189 #if _WIN32||_WIN64
00190         DWORD my_thread_id;
00191 #endif // _WIN32||_WIN64
00192 
00194         void __TBB_EXPORTED_METHOD internal_start( __TBB_NATIVE_THREAD_ROUTINE_PTR(start_routine), 
00195                              void* closure );
00196         friend void __TBB_EXPORTED_FUNC move_v3( tbb_thread_v3& t1, tbb_thread_v3& t2 );
00197         friend void tbb::swap( tbb_thread_v3& t1, tbb_thread_v3& t2 ); 
00198     };
00199         
00200     class tbb_thread_v3::id { 
00201 #if _WIN32||_WIN64
00202         DWORD my_id;
00203         id( DWORD id_ ) : my_id(id_) {}
00204 #else
00205         pthread_t my_id;
00206         id( pthread_t id_ ) : my_id(id_) {}
00207 #endif // _WIN32||_WIN64
00208         friend class tbb_thread_v3;
00209     public:
00210         id() : my_id(0) {}
00211 
00212         friend bool operator==( tbb_thread_v3::id x, tbb_thread_v3::id y );
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         
00219         template<class charT, class traits>
00220         friend std::basic_ostream<charT, traits>&
00221         operator<< (std::basic_ostream<charT, traits> &out, 
00222                     tbb_thread_v3::id id)
00223         {
00224             out << id.my_id;
00225             return out;
00226         }
00227         friend tbb_thread_v3::id __TBB_EXPORTED_FUNC thread_get_id_v3();
00228     }; // tbb_thread_v3::id
00229 
00230     tbb_thread_v3::id tbb_thread_v3::get_id() const {
00231 #if _WIN32||_WIN64
00232         return id(my_thread_id);
00233 #else
00234         return id(my_handle);
00235 #endif // _WIN32||_WIN64
00236     }
00237     void __TBB_EXPORTED_FUNC move_v3( tbb_thread_v3& t1, tbb_thread_v3& t2 );
00238     tbb_thread_v3::id __TBB_EXPORTED_FUNC thread_get_id_v3();
00239     void __TBB_EXPORTED_FUNC thread_yield_v3();
00240     void __TBB_EXPORTED_FUNC thread_sleep_v3(const tick_count::interval_t &i);
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     inline bool operator<=(tbb_thread_v3::id x, tbb_thread_v3::id y)
00255     {
00256         return x.my_id <= y.my_id;
00257     }
00258     inline bool operator>(tbb_thread_v3::id x, tbb_thread_v3::id y)
00259     {
00260         return x.my_id > y.my_id;
00261     }
00262     inline bool operator>=(tbb_thread_v3::id x, tbb_thread_v3::id y)
00263     {
00264         return x.my_id >= y.my_id;
00265     }
00266 
00267 } // namespace internal;
00268 
00270 typedef internal::tbb_thread_v3 tbb_thread;
00271 
00272 using internal::operator==;
00273 using internal::operator!=;
00274 using internal::operator<;
00275 using internal::operator>;
00276 using internal::operator<=;
00277 using internal::operator>=;
00278 
00279 inline void move( tbb_thread& t1, tbb_thread& t2 ) {
00280     internal::move_v3(t1, t2);
00281 }
00282 
00283 inline void swap( internal::tbb_thread_v3& t1, internal::tbb_thread_v3& t2 ) {
00284     tbb::tbb_thread::native_handle_type h = t1.my_handle;
00285     t1.my_handle = t2.my_handle;
00286     t2.my_handle = h;
00287 #if _WIN32||_WIN64
00288     DWORD i = t1.my_thread_id;
00289     t1.my_thread_id = t2.my_thread_id;
00290     t2.my_thread_id = i;
00291 #endif /* _WIN32||_WIN64 */
00292 }
00293 
00294 namespace this_tbb_thread {
00295     inline tbb_thread::id get_id() { return internal::thread_get_id_v3(); }
00297     inline void yield() { internal::thread_yield_v3(); }
00299     inline void sleep(const tick_count::interval_t &i) { 
00300         internal::thread_sleep_v3(i);  
00301     }
00302 }  // namespace this_tbb_thread
00303 
00304 } // namespace tbb
00305 
00306 #endif /* __TBB_tbb_thread_H */

Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.

GNU Lesser General Public License 3 Sourceforge.net