mirror of
https://github.com/libretro/RetroArch
synced 2025-02-21 00:40:09 +00:00
Attempt to workaround odd crashes in glslang.
I accidentally managed to reproduce an issue which has been plaguing users for a while, where glslang throws an assert after closing a game (and starting a new one). pthread_setspecific was somehow failing with an EINVAL call, despite the key never having been freed. I suspect some kind of corruption happening when dynamic libraries are unloaded, but I doubt this is a bug in either RetroArch or glslang per-se. My workaround here is to tear down all TLS use in glslang after we're done compiling. Somehow this works around the problem for me, and I don't really see another viable fix. Valgrind does not say anything about the issue, so doubt it's memory corruption either. I had to fix a minor TLS leak in glslang as DetachProcess does not free the PoolIndex TLS.
This commit is contained in:
parent
3cfed7ba01
commit
4437cd1eac
25
deps/glslang/glslang.cpp
vendored
25
deps/glslang/glslang.cpp
vendored
@ -21,6 +21,7 @@
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <mutex>
|
||||
|
||||
#include "../../verbosity.h"
|
||||
|
||||
@ -31,18 +32,33 @@ struct SlangProcess
|
||||
{
|
||||
public:
|
||||
SlangProcess();
|
||||
|
||||
TBuiltInResource& GetResources() { return Resources; }
|
||||
~SlangProcess() { FinalizeProcess(); }
|
||||
|
||||
private:
|
||||
TBuiltInResource Resources;
|
||||
};
|
||||
|
||||
// We don't use glslang from multiple threads, but to be sure.
|
||||
// Initializing TLS and freeing it for glslang works around a really bizarre issue
|
||||
// where the TLS key is suddenly corrupted *somehow*.
|
||||
static std::mutex glslang_global_lock;
|
||||
struct SlangProcessHolder
|
||||
{
|
||||
SlangProcessHolder()
|
||||
{
|
||||
glslang_global_lock.lock();
|
||||
InitializeProcess();
|
||||
}
|
||||
|
||||
~SlangProcessHolder()
|
||||
{
|
||||
FinalizeProcess();
|
||||
glslang_global_lock.unlock();
|
||||
}
|
||||
};
|
||||
|
||||
SlangProcess::SlangProcess()
|
||||
{
|
||||
InitializeProcess();
|
||||
|
||||
char DefaultConfig[] =
|
||||
"MaxLights 32\n"
|
||||
"MaxClipPlanes 6\n"
|
||||
@ -337,6 +353,7 @@ SlangProcess::SlangProcess()
|
||||
bool glslang::compile_spirv(const string &source, Stage stage, std::vector<uint32_t> *spirv)
|
||||
{
|
||||
static SlangProcess process;
|
||||
SlangProcessHolder process_holder;
|
||||
|
||||
TProgram program;
|
||||
EShLanguage language;
|
||||
|
@ -158,6 +158,7 @@ bool DetachProcess()
|
||||
|
||||
OS_FreeTLSIndex(ThreadInitializeIndex);
|
||||
ThreadInitializeIndex = OS_INVALID_TLS_INDEX;
|
||||
DeinitializePoolIndex();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
@ -38,6 +38,7 @@
|
||||
namespace glslang {
|
||||
|
||||
bool InitializePoolIndex();
|
||||
bool DeinitializePoolIndex();
|
||||
|
||||
} // end namespace glslang
|
||||
|
||||
|
@ -65,6 +65,15 @@ bool InitializePoolIndex()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DeinitializePoolIndex()
|
||||
{
|
||||
if (PoolIndex == OS_INVALID_TLS_INDEX)
|
||||
return false;
|
||||
OS_FreeTLSIndex(PoolIndex);
|
||||
PoolIndex = OS_INVALID_TLS_INDEX;
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// Implement the functionality of the TPoolAllocator class, which
|
||||
// is documented in PoolAlloc.h.
|
||||
|
@ -1312,6 +1312,7 @@ int __fastcall ShFinalize()
|
||||
glslang::HlslScanContext::deleteKeywordMap();
|
||||
#endif
|
||||
|
||||
DetachProcess();
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user