Skip to content

Commit 9f7cef6

Browse files
sberube1igcbot
authored andcommitted
Fixed memory leak
Fixed memory leak
1 parent 57460e8 commit 9f7cef6

File tree

2 files changed

+68
-11
lines changed

2 files changed

+68
-11
lines changed

IGC/common/igc_regkeys.cpp

+64-11
Original file line numberDiff line numberDiff line change
@@ -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;
10471063
static thread_local ShaderHash g_CurrentShaderHash;
1048-
static thread_local std::vector<std::string> g_CurrentEntryPointNames;
10491064
void 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
10551070
void 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

10601084
void 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

10651113
bool 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
}

IGC/common/igc_regkeys.hpp

+4
Original file line numberDiff line numberDiff line change
@@ -224,8 +224,12 @@ bool ReadIGCRegistry(const char* pName, void* pValue, unsigned int size, bool re
224224
void SetCurrentDebugHash(const ShaderHash &hash);
225225
void SetCurrentEntryPoints(const std::vector<std::string> &entry_points);
226226
void ClearCurrentEntryPoints();
227+
void FreeEntryPointsTLSContainers();
227228
#undef LINUX_RELEASE_MODE
228229
#else
230+
static inline void FreeEntryPointsTLSContainers()
231+
{
232+
}
229233
static inline void GetKeysSetExplicitly(std::string* KeyValuePairs, std::string* OptionKeys)
230234
{
231235
IGC_UNUSED(KeyValuePairs);

0 commit comments

Comments
 (0)