mirror of
https://github.com/KhronosGroup/glslang
synced 2024-11-08 19:40:06 +00:00
Memory: Non-Functional: Rationalize and improve encapsulation of TLS usage.
This will make the next (functional) commit easier to see.
This commit is contained in:
parent
a36997cb4a
commit
be20905582
@ -45,6 +45,10 @@ namespace glslang {
|
||||
|
||||
OS_TLSIndex ThreadInitializeIndex = OS_INVALID_TLS_INDEX;
|
||||
|
||||
// Per-process initialization.
|
||||
// Needs to be called at least once before parsing, etc. is done.
|
||||
// Will also do thread initialization for the calling thread; other
|
||||
// threads will need to do that explicitly.
|
||||
bool InitProcess()
|
||||
{
|
||||
glslang::GetGlobalLock();
|
||||
@ -85,7 +89,9 @@ bool InitProcess()
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Per-thread scoped initialization.
|
||||
// Must be called at least once by each new thread sharing the
|
||||
// symbol tables, etc., needed to parse.
|
||||
bool InitThread()
|
||||
{
|
||||
//
|
||||
@ -109,7 +115,9 @@ bool InitThread()
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Thread-scoped tear down. Needs to be done by all but the last
|
||||
// thread, which calls DetachProcess() instead.
|
||||
// NB. TODO: Not currently being executed by each thread.
|
||||
bool DetachThread()
|
||||
{
|
||||
bool success = true;
|
||||
@ -126,13 +134,13 @@ bool DetachThread()
|
||||
success = false;
|
||||
}
|
||||
|
||||
FreeGlobalPools();
|
||||
|
||||
FreeMemoryPools();
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
// Process-scoped tear down. Needs to be done by final thread in process.
|
||||
bool DetachProcess()
|
||||
{
|
||||
bool success = true;
|
||||
|
@ -40,7 +40,7 @@ namespace glslang {
|
||||
|
||||
bool InitProcess();
|
||||
bool InitThread();
|
||||
bool DetachThread();
|
||||
bool DetachThread(); // TODO: use this or remove it; ideally make it unneeded
|
||||
bool DetachProcess();
|
||||
|
||||
} // end namespace glslang
|
||||
|
@ -38,7 +38,8 @@
|
||||
namespace glslang {
|
||||
|
||||
void InitializeMemoryPools();
|
||||
void FreeGlobalPools();
|
||||
void FreeMemoryPools();
|
||||
|
||||
bool InitializePoolIndex();
|
||||
void FreePoolIndex();
|
||||
|
||||
|
@ -250,15 +250,8 @@ private:
|
||||
// different times. But a simple use is to have a global pop
|
||||
// with everyone using the same global allocator.
|
||||
//
|
||||
typedef TPoolAllocator* PoolAllocatorPointer;
|
||||
extern TPoolAllocator& GetThreadPoolAllocator();
|
||||
|
||||
struct TThreadMemoryPools
|
||||
{
|
||||
TPoolAllocator* threadPoolAllocator;
|
||||
};
|
||||
|
||||
void SetThreadPoolAllocator(TPoolAllocator& poolAllocator);
|
||||
void SetThreadPoolAllocator(TPoolAllocator* poolAllocator);
|
||||
|
||||
//
|
||||
// This STL compatible allocator is intended to be used as the allocator
|
||||
|
@ -40,35 +40,40 @@
|
||||
|
||||
namespace glslang {
|
||||
|
||||
// Process-wide TLS index
|
||||
OS_TLSIndex PoolIndex;
|
||||
|
||||
void InitializeMemoryPools()
|
||||
// Per-thread structure holding pool pointers.
|
||||
struct TThreadMemoryPools
|
||||
{
|
||||
TThreadMemoryPools* pools = static_cast<TThreadMemoryPools*>(OS_GetTLSValue(PoolIndex));
|
||||
if (pools)
|
||||
return;
|
||||
TPoolAllocator* threadPoolAllocator; // the current pool
|
||||
};
|
||||
|
||||
TPoolAllocator *threadPoolAllocator = new TPoolAllocator();
|
||||
|
||||
TThreadMemoryPools* threadData = new TThreadMemoryPools();
|
||||
|
||||
threadData->threadPoolAllocator = threadPoolAllocator;
|
||||
|
||||
OS_SetTLSValue(PoolIndex, threadData);
|
||||
// Return the thread-specific pool pointers.
|
||||
TThreadMemoryPools* GetThreadMemoryPools()
|
||||
{
|
||||
return static_cast<TThreadMemoryPools*>(OS_GetTLSValue(PoolIndex));
|
||||
}
|
||||
|
||||
void FreeGlobalPools()
|
||||
// Set the thread-specific pool pointers.
|
||||
void SetThreadMemoryPools(TThreadMemoryPools* pools)
|
||||
{
|
||||
// Release the allocated memory for this thread.
|
||||
TThreadMemoryPools* globalPools = static_cast<TThreadMemoryPools*>(OS_GetTLSValue(PoolIndex));
|
||||
if (! globalPools)
|
||||
return;
|
||||
|
||||
GetThreadPoolAllocator().popAll();
|
||||
delete &GetThreadPoolAllocator();
|
||||
delete globalPools;
|
||||
OS_SetTLSValue(PoolIndex, pools);
|
||||
}
|
||||
|
||||
// Return the thread-specific current pool.
|
||||
TPoolAllocator& GetThreadPoolAllocator()
|
||||
{
|
||||
return *GetThreadMemoryPools()->threadPoolAllocator;
|
||||
}
|
||||
|
||||
// Set the thread-specific current pool.
|
||||
void SetThreadPoolAllocator(TPoolAllocator* poolAllocator)
|
||||
{
|
||||
GetThreadMemoryPools()->threadPoolAllocator = poolAllocator;
|
||||
}
|
||||
|
||||
// Process-wide set up of the TLS pool storage.
|
||||
bool InitializePoolIndex()
|
||||
{
|
||||
// Allocate a TLS index.
|
||||
@ -78,24 +83,30 @@ bool InitializePoolIndex()
|
||||
return true;
|
||||
}
|
||||
|
||||
// Process-wide tear down of the TLS pool storage.
|
||||
void FreePoolIndex()
|
||||
{
|
||||
// Release the TLS index.
|
||||
OS_FreeTLSIndex(PoolIndex);
|
||||
}
|
||||
|
||||
TPoolAllocator& GetThreadPoolAllocator()
|
||||
// Per-thread set up of the memory pools.
|
||||
void InitializeMemoryPools()
|
||||
{
|
||||
TThreadMemoryPools* threadData = static_cast<TThreadMemoryPools*>(OS_GetTLSValue(PoolIndex));
|
||||
|
||||
return *threadData->threadPoolAllocator;
|
||||
if (GetThreadMemoryPools() == nullptr) {
|
||||
SetThreadMemoryPools(new TThreadMemoryPools());
|
||||
SetThreadPoolAllocator(new TPoolAllocator());
|
||||
}
|
||||
}
|
||||
|
||||
void SetThreadPoolAllocator(TPoolAllocator& poolAllocator)
|
||||
// Per-thread tear down of the memory pools.
|
||||
void FreeMemoryPools()
|
||||
{
|
||||
TThreadMemoryPools* threadData = static_cast<TThreadMemoryPools*>(OS_GetTLSValue(PoolIndex));
|
||||
|
||||
threadData->threadPoolAllocator = &poolAllocator;
|
||||
if (GetThreadMemoryPools() != nullptr) {
|
||||
GetThreadPoolAllocator().popAll();
|
||||
delete &GetThreadPoolAllocator();
|
||||
delete GetThreadMemoryPools();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -217,7 +217,7 @@ enum EPrecisionClass {
|
||||
TSymbolTable* CommonSymbolTable[VersionCount][SpvVersionCount][ProfileCount][SourceCount][EPcCount] = {};
|
||||
TSymbolTable* SharedSymbolTables[VersionCount][SpvVersionCount][ProfileCount][SourceCount][EShLangCount] = {};
|
||||
|
||||
TPoolAllocator* PerProcessGPA = 0;
|
||||
TPoolAllocator* PerProcessGPA = nullptr;
|
||||
|
||||
//
|
||||
// Parse and add to the given symbol table the content of the given shader string.
|
||||
@ -361,7 +361,7 @@ bool AddContextSpecificSymbols(const TBuiltInResource* resources, TInfoSink& inf
|
||||
// pool allocator intact, so:
|
||||
// - Switch to a new pool for parsing the built-ins
|
||||
// - Do the parsing, which builds the symbol table, using the new pool
|
||||
// - Switch to the process-global pool to save a copy the resulting symbol table
|
||||
// - Switch to the process-global pool to save a copy of the resulting symbol table
|
||||
// - Free up the new pool used to parse the built-ins
|
||||
// - Switch back to the original thread's pool
|
||||
//
|
||||
@ -388,8 +388,8 @@ void SetupBuiltinSymbolTable(int version, EProfile profile, const SpvVersion& sp
|
||||
|
||||
// Switch to a new pool
|
||||
TPoolAllocator& previousAllocator = GetThreadPoolAllocator();
|
||||
TPoolAllocator* builtInPoolAllocator = new TPoolAllocator();
|
||||
SetThreadPoolAllocator(*builtInPoolAllocator);
|
||||
TPoolAllocator* builtInPoolAllocator = new TPoolAllocator;
|
||||
SetThreadPoolAllocator(builtInPoolAllocator);
|
||||
|
||||
// Dynamically allocate the local symbol tables so we can control when they are deallocated WRT when the pool is popped.
|
||||
TSymbolTable* commonTable[EPcCount];
|
||||
@ -403,7 +403,7 @@ void SetupBuiltinSymbolTable(int version, EProfile profile, const SpvVersion& sp
|
||||
InitializeSymbolTables(infoSink, commonTable, stageTables, version, profile, spvVersion, source);
|
||||
|
||||
// Switch to the process-global pool
|
||||
SetThreadPoolAllocator(*PerProcessGPA);
|
||||
SetThreadPoolAllocator(PerProcessGPA);
|
||||
|
||||
// Copy the local symbol tables from the new pool to the global tables using the process-global pool
|
||||
for (int precClass = 0; precClass < EPcCount; ++precClass) {
|
||||
@ -430,7 +430,7 @@ void SetupBuiltinSymbolTable(int version, EProfile profile, const SpvVersion& sp
|
||||
delete stageTables[stage];
|
||||
|
||||
delete builtInPoolAllocator;
|
||||
SetThreadPoolAllocator(previousAllocator);
|
||||
SetThreadPoolAllocator(&previousAllocator);
|
||||
|
||||
glslang::ReleaseGlobalLock();
|
||||
}
|
||||
@ -1196,7 +1196,7 @@ int ShInitialize()
|
||||
if (! InitProcess())
|
||||
return 0;
|
||||
|
||||
if (! PerProcessGPA)
|
||||
if (PerProcessGPA == nullptr)
|
||||
PerProcessGPA = new TPoolAllocator();
|
||||
|
||||
glslang::TScanContext::fillInKeywordMap();
|
||||
@ -1288,10 +1288,10 @@ int __fastcall ShFinalize()
|
||||
}
|
||||
}
|
||||
|
||||
if (PerProcessGPA) {
|
||||
if (PerProcessGPA != nullptr) {
|
||||
PerProcessGPA->popAll();
|
||||
delete PerProcessGPA;
|
||||
PerProcessGPA = 0;
|
||||
PerProcessGPA = nullptr;
|
||||
}
|
||||
|
||||
glslang::TScanContext::deleteKeywordMap();
|
||||
@ -1708,7 +1708,7 @@ bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion
|
||||
return false;
|
||||
|
||||
pool = new TPoolAllocator();
|
||||
SetThreadPoolAllocator(*pool);
|
||||
SetThreadPoolAllocator(pool);
|
||||
if (! preamble)
|
||||
preamble = "";
|
||||
|
||||
@ -1732,7 +1732,7 @@ bool TShader::preprocess(const TBuiltInResource* builtInResources,
|
||||
return false;
|
||||
|
||||
pool = new TPoolAllocator();
|
||||
SetThreadPoolAllocator(*pool);
|
||||
SetThreadPoolAllocator(pool);
|
||||
if (! preamble)
|
||||
preamble = "";
|
||||
|
||||
@ -1789,7 +1789,7 @@ bool TProgram::link(EShMessages messages)
|
||||
bool error = false;
|
||||
|
||||
pool = new TPoolAllocator();
|
||||
SetThreadPoolAllocator(*pool);
|
||||
SetThreadPoolAllocator(pool);
|
||||
|
||||
for (int s = 0; s < EShLangCount; ++s) {
|
||||
if (! linkStage((EShLanguage)s, messages))
|
||||
|
@ -68,15 +68,14 @@
|
||||
#endif
|
||||
|
||||
//
|
||||
// Driver must call this first, once, before doing any other
|
||||
// compiler/linker operations.
|
||||
// Call before doing any other compiler/linker operations.
|
||||
//
|
||||
// (Call once per process, not once per thread.)
|
||||
//
|
||||
SH_IMPORT_EXPORT int ShInitialize();
|
||||
|
||||
//
|
||||
// Driver should call this at process shutdown.
|
||||
// Call this at process shutdown to clean up memory.
|
||||
//
|
||||
SH_IMPORT_EXPORT int __fastcall ShFinalize();
|
||||
|
||||
@ -290,7 +289,7 @@ SH_IMPORT_EXPORT int ShGetUniformLocation(const ShHandle uniformMap, const char*
|
||||
// Deferred-Lowering C++ Interface
|
||||
// -----------------------------------
|
||||
//
|
||||
// Below is a new alternate C++ interface that might potentially replace the above
|
||||
// Below is a new alternate C++ interface, which deprecates the above
|
||||
// opaque handle-based interface.
|
||||
//
|
||||
// The below is further designed to handle multiple compilation units per stage, where
|
||||
|
Loading…
Reference in New Issue
Block a user