1 /* 2 Copyright (c) 2005-2020 Intel Corporation 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 #include "oneapi/tbb/detail/_config.h" 18 19 #include "main.h" 20 #include "governor.h" 21 #include "environment.h" 22 #include "market.h" 23 #include "misc.h" 24 #include "itt_notify.h" 25 26 namespace tbb { 27 namespace detail { 28 namespace r1 { 29 30 //------------------------------------------------------------------------ 31 // Begin shared data layout. 32 // The following global data items are mostly read-only after initialization. 33 //------------------------------------------------------------------------ 34 35 //------------------------------------------------------------------------ 36 // governor data 37 basic_tls<thread_data*> governor::theTLS; 38 unsigned governor::DefaultNumberOfThreads; 39 size_t governor::DefaultPageSize; 40 rml::tbb_factory governor::theRMLServerFactory; 41 bool governor::UsePrivateRML; 42 bool governor::is_rethrow_broken; 43 44 //------------------------------------------------------------------------ 45 // market data 46 market* market::theMarket; 47 market::global_market_mutex_type market::theMarketMutex; 48 49 //------------------------------------------------------------------------ 50 // context propagation data 51 context_state_propagation_mutex_type the_context_state_propagation_mutex; 52 std::atomic<uintptr_t> the_context_state_propagation_epoch{}; 53 54 //------------------------------------------------------------------------ 55 // One time initialization data 56 57 //! Counter of references to global shared resources such as TLS. 58 std::atomic<int> __TBB_InitOnce::count{}; 59 60 std::atomic_flag __TBB_InitOnce::InitializationLock = ATOMIC_FLAG_INIT; 61 62 //! Flag that is set to true after one-time initializations are done. 63 std::atomic<bool> __TBB_InitOnce::InitializationDone{}; 64 65 #if __TBB_USE_ITT_NOTIFY 66 //! Defined in profiling.cpp 67 extern bool ITT_Present; 68 void ITT_DoUnsafeOneTimeInitialization(); 69 #endif 70 71 #if !(_WIN32||_WIN64) || __TBB_SOURCE_DIRECTLY_INCLUDED 72 static __TBB_InitOnce __TBB_InitOnceHiddenInstance; 73 #endif 74 75 #if TBB_USE_ASSERT 76 std::atomic<int> the_observer_proxy_count; 77 78 struct check_observer_proxy_count { 79 ~check_observer_proxy_count() { 80 if (the_observer_proxy_count != 0) { 81 runtime_warning("Leaked %ld observer_proxy objects\n", long(the_observer_proxy_count)); 82 } 83 } 84 }; 85 // The proxy count checker shall be defined after __TBB_InitOnceHiddenInstance to check the count 86 // after auto termination. 87 static check_observer_proxy_count the_check_observer_proxy_count; 88 #endif /* TBB_USE_ASSERT */ 89 90 //------------------------------------------------------------------------ 91 // __TBB_InitOnce 92 //------------------------------------------------------------------------ 93 94 void __TBB_InitOnce::add_ref() { 95 if( ++count==1 ) 96 governor::acquire_resources(); 97 } 98 99 void __TBB_InitOnce::remove_ref() { 100 int k = --count; 101 __TBB_ASSERT(k>=0,"removed __TBB_InitOnce ref that was not added?"); 102 if( k==0 ) { 103 governor::release_resources(); 104 ITT_FINI_ITTLIB(); 105 } 106 } 107 108 //------------------------------------------------------------------------ 109 // One-time Initializations 110 //------------------------------------------------------------------------ 111 112 //! Defined in cache_aligned_allocator.cpp 113 void initialize_cache_aligned_allocator(); 114 115 //! Performs thread-safe lazy one-time general TBB initialization. 116 void DoOneTimeInitialization() { 117 __TBB_InitOnce::lock(); 118 // No fence required for load of InitializationDone, because we are inside a critical section. 119 if( !__TBB_InitOnce::InitializationDone ) { 120 __TBB_InitOnce::add_ref(); 121 if( GetBoolEnvironmentVariable("TBB_VERSION") ) 122 PrintVersion(); 123 bool itt_present = false; 124 #if __TBB_USE_ITT_NOTIFY 125 ITT_DoUnsafeOneTimeInitialization(); 126 itt_present = ITT_Present; 127 #endif /* __TBB_USE_ITT_NOTIFY */ 128 initialize_cache_aligned_allocator(); 129 governor::initialize_rml_factory(); 130 // Force processor groups support detection 131 governor::default_num_threads(); 132 // Force OS regular page size detection 133 governor::default_page_size(); 134 PrintExtraVersionInfo( "TOOLS SUPPORT", itt_present ? "enabled" : "disabled" ); 135 __TBB_InitOnce::InitializationDone = true; 136 } 137 __TBB_InitOnce::unlock(); 138 } 139 140 #if (_WIN32||_WIN64) && !__TBB_SOURCE_DIRECTLY_INCLUDED 141 //! Windows "DllMain" that handles startup and shutdown of dynamic library. 142 extern "C" bool WINAPI DllMain( HANDLE /*hinstDLL*/, DWORD reason, LPVOID lpvReserved ) { 143 switch( reason ) { 144 case DLL_PROCESS_ATTACH: 145 __TBB_InitOnce::add_ref(); 146 break; 147 case DLL_PROCESS_DETACH: 148 // Since THREAD_DETACH is not called for the main thread, call auto-termination 149 // here as well - but not during process shutdown (due to risk of a deadlock). 150 if ( lpvReserved==NULL ) { // library unload 151 governor::terminate_external_thread(); 152 } 153 __TBB_InitOnce::remove_ref(); 154 // It is assumed that InitializationDone is not set after DLL_PROCESS_DETACH, 155 // and thus no race on InitializationDone is possible. 156 if ( __TBB_InitOnce::initialization_done() ) { 157 // Remove reference that we added in DoOneTimeInitialization. 158 __TBB_InitOnce::remove_ref(); 159 } 160 break; 161 case DLL_THREAD_DETACH: 162 governor::terminate_external_thread(); 163 break; 164 } 165 return true; 166 } 167 #endif /* (_WIN32||_WIN64) && !__TBB_SOURCE_DIRECTLY_INCLUDED */ 168 169 } // namespace r1 170 } // namespace detail 171 } // namespace tbb 172