1 /* 2 Copyright (c) 2005-2023 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 "threading_control.h" 22 #include "environment.h" 23 #include "market.h" 24 #include "misc.h" 25 #include "itt_notify.h" 26 27 namespace tbb { 28 namespace detail { 29 namespace r1 { 30 31 //------------------------------------------------------------------------ 32 // Begin shared data layout. 33 // The following global data items are mostly read-only after initialization. 34 //------------------------------------------------------------------------ 35 36 //------------------------------------------------------------------------ 37 // governor data 38 basic_tls<thread_data*> governor::theTLS; 39 rml::tbb_factory governor::theRMLServerFactory; 40 bool governor::UsePrivateRML; 41 bool governor::is_rethrow_broken; 42 43 //------------------------------------------------------------------------ 44 // threading_control data 45 threading_control* threading_control::g_threading_control; 46 threading_control::global_mutex_type threading_control::g_threading_control_mutex; 47 48 //------------------------------------------------------------------------ 49 // context propagation data 50 context_state_propagation_mutex_type the_context_state_propagation_mutex; 51 std::atomic<uintptr_t> the_context_state_propagation_epoch{}; 52 53 //------------------------------------------------------------------------ 54 // One time initialization data 55 56 //! Counter of references to global shared resources such as TLS. 57 std::atomic<int> __TBB_InitOnce::count{}; 58 59 std::atomic_flag __TBB_InitOnce::InitializationLock = ATOMIC_FLAG_INIT; 60 61 //! Flag that is set to true after one-time initializations are done. 62 std::atomic<bool> __TBB_InitOnce::InitializationDone{}; 63 64 #if __TBB_USE_ITT_NOTIFY 65 //! Defined in profiling.cpp 66 extern bool ITT_Present; 67 void ITT_DoUnsafeOneTimeInitialization(); 68 #endif 69 70 #if !(_WIN32||_WIN64) || __TBB_SOURCE_DIRECTLY_INCLUDED 71 static __TBB_InitOnce __TBB_InitOnceHiddenInstance; 72 #endif 73 74 #if TBB_USE_ASSERT 75 std::atomic<int> the_observer_proxy_count; 76 77 struct check_observer_proxy_count { 78 ~check_observer_proxy_count() { 79 if (the_observer_proxy_count != 0) { 80 runtime_warning("Leaked %ld observer_proxy objects\n", long(the_observer_proxy_count)); 81 } 82 } 83 }; 84 // The proxy count checker shall be defined after __TBB_InitOnceHiddenInstance to check the count 85 // after auto termination. 86 static check_observer_proxy_count the_check_observer_proxy_count; 87 #endif /* TBB_USE_ASSERT */ 88 89 //------------------------------------------------------------------------ 90 // __TBB_InitOnce 91 //------------------------------------------------------------------------ 92 93 void __TBB_InitOnce::add_ref() { 94 if( ++count==1 ) 95 governor::acquire_resources(); 96 } 97 98 void __TBB_InitOnce::remove_ref() { 99 int k = --count; 100 __TBB_ASSERT(k>=0,"removed __TBB_InitOnce ref that was not added?"); 101 if( k==0 ) { 102 governor::release_resources(); 103 ITT_FINI_ITTLIB(); 104 ITT_RELEASE_RESOURCES(); 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 == nullptr ) { // 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