@@ -1044,8 +1044,23 @@ void appendToOptionsLogFile(std::string const &message)
1044
1044
os.close ();
1045
1045
}
1046
1046
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;
1047
1063
static thread_local ShaderHash g_CurrentShaderHash;
1048
- static thread_local std::vector<std::string> g_CurrentEntryPointNames;
1049
1064
void SetCurrentDebugHash (const ShaderHash& hash)
1050
1065
{
1051
1066
g_CurrentShaderHash = hash;
@@ -1054,12 +1069,45 @@ void SetCurrentDebugHash(const ShaderHash& hash)
1054
1069
// ray tracing shader can have multiple access point
1055
1070
void SetCurrentEntryPoints (const std::vector<std::string>& entry_points)
1056
1071
{
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;
1058
1082
}
1059
1083
1060
1084
void ClearCurrentEntryPoints ()
1061
1085
{
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
+ }
1063
1111
}
1064
1112
1065
1113
bool CheckHashRange (SRegKeyVariableMetaData& varname)
@@ -1113,21 +1161,26 @@ bool CheckEntryPoint(SRegKeyVariableMetaData& varname)
1113
1161
}
1114
1162
}
1115
1163
1116
- if (g_CurrentEntryPointNames.size () == 0 )
1164
+ if (!g_pCurrentEntryPointNames ||
1165
+ g_pCurrentEntryPointNames->size () == 0 )
1117
1166
{
1118
1167
std::string msg = " Warning: entry point not set yet; IGC_GET_FLAG_VALUE(" + std::string (varname.GetName ()) + " ) returned default value" ;
1119
1168
appendToOptionsLogFile (msg);
1120
1169
}
1121
- // looping entry point recorded by regkey metadata
1122
- for ( auto & it : varname. entry_points )
1170
+
1171
+ if (g_pCurrentEntryPointNames != NULL )
1123
1172
{
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 )
1126
1175
{
1127
- if (CurrEntryPoint == it.entry_point_name )
1176
+ // looping each entry point of current shader
1177
+ for (std::string& CurrEntryPoint : *g_pCurrentEntryPointNames)
1128
1178
{
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
+ }
1131
1184
}
1132
1185
}
1133
1186
}
0 commit comments