@@ -1044,8 +1044,23 @@ void appendToOptionsLogFile(std::string const &message)
10441044 os.close ();
10451045}
10461046
1047+ static thread_local std::vector<std::string>* g_pCurrentEntryPointNames = nullptr ;
1048+ static std::list<void *> g_AllTlsVectorToCleanup;
1049+ static std::mutex g_AllTlsVectorToCleanupMutex;
1050+
1051+ // This class contains only a destructor; to be called on thread detach
1052+ class RemoveTlsPointerFromCleanupVector
1053+ {
1054+ public:
1055+ virtual ~RemoveTlsPointerFromCleanupVector ()
1056+ {
1057+ std::lock_guard<std::mutex> lock (g_AllTlsVectorToCleanupMutex);
1058+ g_AllTlsVectorToCleanup.remove_if ([](void * it) { return ((*static_cast <std::vector<std::string>**>(it)) == g_pCurrentEntryPointNames); });
1059+ };
1060+ };
1061+ // Dummy object below will get destroyed on thread detach, thus calling ~RemoveTlsPointerFromCleanupVector()
1062+ static thread_local RemoveTlsPointerFromCleanupVector dummyObjectForTlsCleanup;
10471063static thread_local ShaderHash g_CurrentShaderHash;
1048- static thread_local std::vector<std::string> g_CurrentEntryPointNames;
10491064void SetCurrentDebugHash (const ShaderHash& hash)
10501065{
10511066 g_CurrentShaderHash = hash;
@@ -1054,12 +1069,45 @@ void SetCurrentDebugHash(const ShaderHash& hash)
10541069// ray tracing shader can have multiple access point
10551070void SetCurrentEntryPoints (const std::vector<std::string>& entry_points)
10561071{
1057- g_CurrentEntryPointNames = entry_points;
1072+ if (g_pCurrentEntryPointNames == nullptr )
1073+ {
1074+ std::lock_guard<std::mutex> lock (g_AllTlsVectorToCleanupMutex);
1075+ g_pCurrentEntryPointNames = new std::vector<std::string>;
1076+
1077+ // Push the address, of the address. This will allow us to avoid dangling TLS pointers in some threads
1078+ g_AllTlsVectorToCleanup.push_back (&g_pCurrentEntryPointNames);
1079+ }
1080+
1081+ *g_pCurrentEntryPointNames = entry_points;
10581082}
10591083
10601084void ClearCurrentEntryPoints ()
10611085{
1062- g_CurrentEntryPointNames.clear ();
1086+ if (g_pCurrentEntryPointNames)
1087+ {
1088+ g_pCurrentEntryPointNames->clear ();
1089+ }
1090+ }
1091+
1092+ void FreeEntryPointsTLSContainers ()
1093+ {
1094+ std::lock_guard<std::mutex> lock (g_AllTlsVectorToCleanupMutex);
1095+
1096+ // This loop basically frees all "thread_local" g_pCurrentEntryPointNames pointers, regardless of thread_local
1097+ while (!g_AllTlsVectorToCleanup.empty ())
1098+ {
1099+ void * ptrOfPtr = g_AllTlsVectorToCleanup.front ();
1100+ g_AllTlsVectorToCleanup.pop_front ();
1101+
1102+ std::vector<std::string>** containerPtrOfPtr = static_cast <std::vector<std::string>**>(ptrOfPtr);
1103+ std::vector<std::string>* containerPtr = *containerPtrOfPtr;
1104+ if (containerPtr)
1105+ {
1106+ containerPtr->clear ();
1107+ delete containerPtr;
1108+ *containerPtrOfPtr = nullptr ; // equivalent of doing "g_pCurrentEntryPointNames = nullptr;" but TLS-independent
1109+ }
1110+ }
10631111}
10641112
10651113bool CheckHashRange (SRegKeyVariableMetaData& varname)
@@ -1113,21 +1161,26 @@ bool CheckEntryPoint(SRegKeyVariableMetaData& varname)
11131161 }
11141162 }
11151163
1116- if (g_CurrentEntryPointNames.size () == 0 )
1164+ if (!g_pCurrentEntryPointNames ||
1165+ g_pCurrentEntryPointNames->size () == 0 )
11171166 {
11181167 std::string msg = " Warning: entry point not set yet; IGC_GET_FLAG_VALUE(" + std::string (varname.GetName ()) + " ) returned default value" ;
11191168 appendToOptionsLogFile (msg);
11201169 }
1121- // looping entry point recorded by regkey metadata
1122- for ( auto & it : varname. entry_points )
1170+
1171+ if (g_pCurrentEntryPointNames != NULL )
11231172 {
1124- // looping each entry point of current shader
1125- for (std::string& CurrEntryPoint : g_CurrentEntryPointNames )
1173+ // looping entry point recorded by regkey metadata
1174+ for (auto & it : varname. entry_points )
11261175 {
1127- if (CurrEntryPoint == it.entry_point_name )
1176+ // looping each entry point of current shader
1177+ for (std::string& CurrEntryPoint : *g_pCurrentEntryPointNames)
11281178 {
1129- varname.m_Value = it.m_Value ;
1130- return true ;
1179+ if (CurrEntryPoint == it.entry_point_name )
1180+ {
1181+ varname.m_Value = it.m_Value ;
1182+ return true ;
1183+ }
11311184 }
11321185 }
11331186 }
0 commit comments