Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:13:01

0001 /*
0002     Copyright (c) 2005-2020 Intel Corporation
0003 
0004     Licensed under the Apache License, Version 2.0 (the "License");
0005     you may not use this file except in compliance with the License.
0006     You may obtain a copy of the License at
0007 
0008         http://www.apache.org/licenses/LICENSE-2.0
0009 
0010     Unless required by applicable law or agreed to in writing, software
0011     distributed under the License is distributed on an "AS IS" BASIS,
0012     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013     See the License for the specific language governing permissions and
0014     limitations under the License.
0015 */
0016 
0017 #include "internal/_deprecated_header_message_guard.h"
0018 
0019 #if !defined(__TBB_show_deprecation_message_tbb_thread_H) && defined(__TBB_show_deprecated_header_message)
0020 #define  __TBB_show_deprecation_message_tbb_thread_H
0021 #pragma message("TBB Warning: tbb/tbb_thread.h is deprecated. For details, please see Deprecated Features appendix in the TBB reference manual.")
0022 #endif
0023 
0024 #if defined(__TBB_show_deprecated_header_message)
0025 #undef __TBB_show_deprecated_header_message
0026 #endif
0027 
0028 #ifndef __TBB_tbb_thread_H
0029 #define __TBB_tbb_thread_H
0030 
0031 #define __TBB_tbb_thread_H_include_area
0032 #include "internal/_warning_suppress_enable_notice.h"
0033 
0034 #include "tbb_stddef.h"
0035 
0036 #if _WIN32||_WIN64
0037 #include "machine/windows_api.h"
0038 #define __TBB_NATIVE_THREAD_ROUTINE unsigned WINAPI
0039 #define __TBB_NATIVE_THREAD_ROUTINE_PTR(r) unsigned (WINAPI* r)( void* )
0040 namespace tbb { namespace internal {
0041 #if __TBB_WIN8UI_SUPPORT
0042     typedef size_t thread_id_type;
0043 #else  // __TBB_WIN8UI_SUPPORT
0044     typedef DWORD thread_id_type;
0045 #endif // __TBB_WIN8UI_SUPPORT
0046 }} //namespace tbb::internal
0047 #else
0048 #define __TBB_NATIVE_THREAD_ROUTINE void*
0049 #define __TBB_NATIVE_THREAD_ROUTINE_PTR(r) void* (*r)( void* )
0050 #include <pthread.h>
0051 namespace tbb { namespace internal {
0052     typedef pthread_t thread_id_type;
0053 }} //namespace tbb::internal
0054 #endif // _WIN32||_WIN64
0055 
0056 #include "atomic.h"
0057 #include "internal/_tbb_hash_compare_impl.h"
0058 #include "tick_count.h"
0059 
0060 #include __TBB_STD_SWAP_HEADER
0061 #include <iosfwd>
0062 
0063 namespace tbb {
0064 
0065 namespace internal {
0066     class tbb_thread_v3;
0067 }
0068 
0069 inline void swap( internal::tbb_thread_v3& t1, internal::tbb_thread_v3& t2 ) __TBB_NOEXCEPT(true);
0070 
0071 namespace internal {
0072 
0073     //! Allocate a closure
0074     void* __TBB_EXPORTED_FUNC allocate_closure_v3( size_t size );
0075     //! Free a closure allocated by allocate_closure_v3
0076     void __TBB_EXPORTED_FUNC free_closure_v3( void* );
0077 
0078     struct thread_closure_base {
0079         void* operator new( size_t size ) {return allocate_closure_v3(size);}
0080         void operator delete( void* ptr ) {free_closure_v3(ptr);}
0081     };
0082 
0083     template<class F> struct thread_closure_0: thread_closure_base {
0084         F function;
0085 
0086         static __TBB_NATIVE_THREAD_ROUTINE start_routine( void* c ) {
0087             thread_closure_0 *self = static_cast<thread_closure_0*>(c);
0088             self->function();
0089             delete self;
0090             return 0;
0091         }
0092         thread_closure_0( const F& f ) : function(f) {}
0093     };
0094     //! Structure used to pass user function with 1 argument to thread.
0095     template<class F, class X> struct thread_closure_1: thread_closure_base {
0096         F function;
0097         X arg1;
0098         //! Routine passed to Windows's _beginthreadex by thread::internal_start() inside tbb.dll
0099         static __TBB_NATIVE_THREAD_ROUTINE start_routine( void* c ) {
0100             thread_closure_1 *self = static_cast<thread_closure_1*>(c);
0101             self->function(self->arg1);
0102             delete self;
0103             return 0;
0104         }
0105         thread_closure_1( const F& f, const X& x ) : function(f), arg1(x) {}
0106     };
0107     template<class F, class X, class Y> struct thread_closure_2: thread_closure_base {
0108         F function;
0109         X arg1;
0110         Y arg2;
0111         //! Routine passed to Windows's _beginthreadex by thread::internal_start() inside tbb.dll
0112         static __TBB_NATIVE_THREAD_ROUTINE start_routine( void* c ) {
0113             thread_closure_2 *self = static_cast<thread_closure_2*>(c);
0114             self->function(self->arg1, self->arg2);
0115             delete self;
0116             return 0;
0117         }
0118         thread_closure_2( const F& f, const X& x, const Y& y ) : function(f), arg1(x), arg2(y) {}
0119     };
0120 
0121     //! Versioned thread class.
0122     class tbb_thread_v3 {
0123 #if __TBB_IF_NO_COPY_CTOR_MOVE_SEMANTICS_BROKEN
0124         // Workaround for a compiler bug: declaring the copy constructor as public
0125         // enables use of the moving constructor.
0126         // The definition is not provided in order to prohibit copying.
0127     public:
0128 #endif
0129         tbb_thread_v3(const tbb_thread_v3&); // = delete;   // Deny access
0130     public:
0131 #if _WIN32||_WIN64
0132         typedef HANDLE native_handle_type;
0133 #else
0134         typedef pthread_t native_handle_type;
0135 #endif // _WIN32||_WIN64
0136 
0137         class id;
0138         //! Constructs a thread object that does not represent a thread of execution.
0139         tbb_thread_v3() __TBB_NOEXCEPT(true) : my_handle(0)
0140 #if _WIN32||_WIN64
0141             , my_thread_id(0)
0142 #endif // _WIN32||_WIN64
0143         {}
0144 
0145         //! Constructs an object and executes f() in a new thread
0146         template <class F> explicit tbb_thread_v3(F f) {
0147             typedef internal::thread_closure_0<F> closure_type;
0148             internal_start(closure_type::start_routine, new closure_type(f));
0149         }
0150         //! Constructs an object and executes f(x) in a new thread
0151         template <class F, class X> tbb_thread_v3(F f, X x) {
0152             typedef internal::thread_closure_1<F,X> closure_type;
0153             internal_start(closure_type::start_routine, new closure_type(f,x));
0154         }
0155         //! Constructs an object and executes f(x,y) in a new thread
0156         template <class F, class X, class Y> tbb_thread_v3(F f, X x, Y y) {
0157             typedef internal::thread_closure_2<F,X,Y> closure_type;
0158             internal_start(closure_type::start_routine, new closure_type(f,x,y));
0159         }
0160 
0161 #if __TBB_CPP11_RVALUE_REF_PRESENT
0162         tbb_thread_v3(tbb_thread_v3&& x) __TBB_NOEXCEPT(true)
0163             : my_handle(x.my_handle)
0164 #if _WIN32||_WIN64
0165             , my_thread_id(x.my_thread_id)
0166 #endif
0167         {
0168             x.internal_wipe();
0169         }
0170         tbb_thread_v3& operator=(tbb_thread_v3&& x) __TBB_NOEXCEPT(true) {
0171             internal_move(x);
0172             return *this;
0173         }
0174     private:
0175         tbb_thread_v3& operator=(const tbb_thread_v3& x); // = delete;
0176     public:
0177 #else  // __TBB_CPP11_RVALUE_REF_PRESENT
0178         tbb_thread_v3& operator=(tbb_thread_v3& x) {
0179             internal_move(x);
0180             return *this;
0181         }
0182 #endif // __TBB_CPP11_RVALUE_REF_PRESENT
0183 
0184         void swap( tbb_thread_v3& t ) __TBB_NOEXCEPT(true) {tbb::swap( *this, t );}
0185         bool joinable() const __TBB_NOEXCEPT(true) {return my_handle!=0; }
0186         //! The completion of the thread represented by *this happens before join() returns.
0187         void __TBB_EXPORTED_METHOD join();
0188         //! When detach() returns, *this no longer represents the possibly continuing thread of execution.
0189         void __TBB_EXPORTED_METHOD detach();
0190         ~tbb_thread_v3() {if( joinable() ) detach();}
0191         inline id get_id() const __TBB_NOEXCEPT(true);
0192         native_handle_type native_handle() { return my_handle; }
0193 
0194         //! The number of hardware thread contexts.
0195         /** Before TBB 3.0 U4 this methods returned the number of logical CPU in
0196             the system. Currently on Windows, Linux and FreeBSD it returns the
0197             number of logical CPUs available to the current process in accordance
0198             with its affinity mask.
0199 
0200             NOTE: The return value of this method never changes after its first
0201             invocation. This means that changes in the process affinity mask that
0202             took place after this method was first invoked will not affect the
0203             number of worker threads in the TBB worker threads pool. **/
0204         static unsigned __TBB_EXPORTED_FUNC hardware_concurrency() __TBB_NOEXCEPT(true);
0205     private:
0206         native_handle_type my_handle;
0207 #if _WIN32||_WIN64
0208         thread_id_type my_thread_id;
0209 #endif // _WIN32||_WIN64
0210 
0211         void internal_wipe() __TBB_NOEXCEPT(true) {
0212             my_handle = 0;
0213 #if _WIN32||_WIN64
0214             my_thread_id = 0;
0215 #endif
0216         }
0217         void internal_move(tbb_thread_v3& x) __TBB_NOEXCEPT(true) {
0218             if (joinable()) detach();
0219             my_handle = x.my_handle;
0220 #if _WIN32||_WIN64
0221             my_thread_id = x.my_thread_id;
0222 #endif // _WIN32||_WIN64
0223             x.internal_wipe();
0224         }
0225 
0226         /** Runs start_routine(closure) on another thread and sets my_handle to the handle of the created thread. */
0227         void __TBB_EXPORTED_METHOD internal_start( __TBB_NATIVE_THREAD_ROUTINE_PTR(start_routine),
0228                              void* closure );
0229         friend void __TBB_EXPORTED_FUNC move_v3( tbb_thread_v3& t1, tbb_thread_v3& t2 );
0230         friend void tbb::swap( tbb_thread_v3& t1, tbb_thread_v3& t2 ) __TBB_NOEXCEPT(true);
0231     };
0232 
0233     class tbb_thread_v3::id {
0234         thread_id_type my_id;
0235         id( thread_id_type id_ ) : my_id(id_) {}
0236 
0237         friend class tbb_thread_v3;
0238     public:
0239         id() __TBB_NOEXCEPT(true) : my_id(0) {}
0240 
0241         friend bool operator==( tbb_thread_v3::id x, tbb_thread_v3::id y ) __TBB_NOEXCEPT(true);
0242         friend bool operator!=( tbb_thread_v3::id x, tbb_thread_v3::id y ) __TBB_NOEXCEPT(true);
0243         friend bool operator<( tbb_thread_v3::id x, tbb_thread_v3::id y ) __TBB_NOEXCEPT(true);
0244         friend bool operator<=( tbb_thread_v3::id x, tbb_thread_v3::id y ) __TBB_NOEXCEPT(true);
0245         friend bool operator>( tbb_thread_v3::id x, tbb_thread_v3::id y ) __TBB_NOEXCEPT(true);
0246         friend bool operator>=( tbb_thread_v3::id x, tbb_thread_v3::id y ) __TBB_NOEXCEPT(true);
0247 
0248         template<class charT, class traits>
0249         friend std::basic_ostream<charT, traits>&
0250         operator<< (std::basic_ostream<charT, traits> &out,
0251                     tbb_thread_v3::id id)
0252         {
0253             out << id.my_id;
0254             return out;
0255         }
0256         friend tbb_thread_v3::id __TBB_EXPORTED_FUNC thread_get_id_v3();
0257 
0258         friend inline size_t tbb_hasher( const tbb_thread_v3::id& id ) {
0259             __TBB_STATIC_ASSERT(sizeof(id.my_id) <= sizeof(size_t), "Implementation assumes that thread_id_type fits into machine word");
0260             return tbb::tbb_hasher(id.my_id);
0261         }
0262 
0263         // A workaround for lack of tbb::atomic<id> (which would require id to be POD in C++03).
0264         friend id atomic_compare_and_swap(id& location, const id& value, const id& comparand){
0265             return as_atomic(location.my_id).compare_and_swap(value.my_id, comparand.my_id);
0266         }
0267     }; // tbb_thread_v3::id
0268 
0269     tbb_thread_v3::id tbb_thread_v3::get_id() const __TBB_NOEXCEPT(true) {
0270 #if _WIN32||_WIN64
0271         return id(my_thread_id);
0272 #else
0273         return id(my_handle);
0274 #endif // _WIN32||_WIN64
0275     }
0276 
0277     void __TBB_EXPORTED_FUNC move_v3( tbb_thread_v3& t1, tbb_thread_v3& t2 );
0278     tbb_thread_v3::id __TBB_EXPORTED_FUNC thread_get_id_v3();
0279     void __TBB_EXPORTED_FUNC thread_yield_v3();
0280     void __TBB_EXPORTED_FUNC thread_sleep_v3(const tick_count::interval_t &i);
0281 
0282     inline bool operator==(tbb_thread_v3::id x, tbb_thread_v3::id y) __TBB_NOEXCEPT(true)
0283     {
0284         return x.my_id == y.my_id;
0285     }
0286     inline bool operator!=(tbb_thread_v3::id x, tbb_thread_v3::id y) __TBB_NOEXCEPT(true)
0287     {
0288         return x.my_id != y.my_id;
0289     }
0290     inline bool operator<(tbb_thread_v3::id x, tbb_thread_v3::id y) __TBB_NOEXCEPT(true)
0291     {
0292         return x.my_id < y.my_id;
0293     }
0294     inline bool operator<=(tbb_thread_v3::id x, tbb_thread_v3::id y) __TBB_NOEXCEPT(true)
0295     {
0296         return x.my_id <= y.my_id;
0297     }
0298     inline bool operator>(tbb_thread_v3::id x, tbb_thread_v3::id y) __TBB_NOEXCEPT(true)
0299     {
0300         return x.my_id > y.my_id;
0301     }
0302     inline bool operator>=(tbb_thread_v3::id x, tbb_thread_v3::id y) __TBB_NOEXCEPT(true)
0303     {
0304         return x.my_id >= y.my_id;
0305     }
0306 
0307 } // namespace internal;
0308 
0309 //! Users reference thread class by name tbb_thread
0310 __TBB_DEPRECATED_IN_VERBOSE_MODE_MSG("tbb::thread is deprecated, use std::thread") typedef internal::tbb_thread_v3 tbb_thread;
0311 
0312 using internal::operator==;
0313 using internal::operator!=;
0314 using internal::operator<;
0315 using internal::operator>;
0316 using internal::operator<=;
0317 using internal::operator>=;
0318 
0319 inline void move( tbb_thread& t1, tbb_thread& t2 ) {
0320     internal::move_v3(t1, t2);
0321 }
0322 
0323 inline void swap( internal::tbb_thread_v3& t1, internal::tbb_thread_v3& t2 )  __TBB_NOEXCEPT(true) {
0324     std::swap(t1.my_handle, t2.my_handle);
0325 #if _WIN32||_WIN64
0326     std::swap(t1.my_thread_id, t2.my_thread_id);
0327 #endif /* _WIN32||_WIN64 */
0328 }
0329 
0330 namespace this_tbb_thread {
0331     __TBB_DEPRECATED_IN_VERBOSE_MODE inline tbb_thread::id get_id() { return internal::thread_get_id_v3(); }
0332     //! Offers the operating system the opportunity to schedule another thread.
0333     __TBB_DEPRECATED_IN_VERBOSE_MODE inline void yield() { internal::thread_yield_v3(); }
0334     //! The current thread blocks at least until the time specified.
0335     __TBB_DEPRECATED_IN_VERBOSE_MODE inline void sleep(const tick_count::interval_t &i) {
0336         internal::thread_sleep_v3(i);
0337     }
0338 }  // namespace this_tbb_thread
0339 
0340 } // namespace tbb
0341 
0342 #include "internal/_warning_suppress_disable_notice.h"
0343 #undef __TBB_tbb_thread_H_include_area
0344 
0345 #endif /* __TBB_tbb_thread_H */