From 7b54f43fb1b123f451460edb0add218a0428fe95 Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Mon, 7 Aug 2017 14:54:55 -0700 Subject: Remove uses of global variables There were two main places where global variables were used in the Slang implementation: 1. The "standard library" code was generated as a string at run-time, and stored in a global variable so that it could be amortized across compiles. 2. The representation of types uses some globals (well, class `static` members) to store common types (e.g., `void`) and to deal with memory lifetime for things like canonicalized types. In each case the "simple" fix is to move the relevant state into the `Session` type that controlled their lifetime already (the `Session` destructor was already cleaning up these globals to avoid leaks). For the standard library stuff this really was easy, but for the types it required threading through the `Session` a bit carefully. One more case that I found: there was a function-`static` variable used to generate a unique ID for files output when dumping of intermediates is enabled (this is almost strictly a debugging option). Rather than make this counter per-session (which would lead to different sessions on different threads clobbering the same few files), I went ahead and used an atomic in this case. Note that the remaining case I had been worried about was any function-`static` counter that might be used in generating unique names. It turns out that right now the parser doesn't use such a counter (even in cases where it probably should), and the lowering pass already uses a counter local to the pass (again, whether or not this is a good idea). This change should be a major step toward allowing an application to use Slang in multiple threads, so long as each thread uses a distinct `SlangSession`. The case of using a single session across multiple threads is harder to support, and will require more careful implementation work. --- source/slang/slang.cpp | 75 ++++++++++++++------------------------------------ 1 file changed, 20 insertions(+), 55 deletions(-) (limited to 'source/slang/slang.cpp') diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp index bb83eb8af..03bb6a09b 100644 --- a/source/slang/slang.cpp +++ b/source/slang/slang.cpp @@ -1,7 +1,6 @@ #include "../../slang.h" #include "../core/slang-io.h" -#include "../slang/slang-stdlib.h" #include "parameter-binding.h" #include "../slang/parser.h" #include "../slang/preprocessor.h" @@ -19,65 +18,31 @@ namespace Slang { -class Session +Session::Session() { -public: - bool useCache = false; - String cacheDir; + // Initialize representations of some very basic types: + initializeTypes(); - RefPtr coreLanguageScope; - RefPtr hlslLanguageScope; - RefPtr slangLanguageScope; - RefPtr glslLanguageScope; - - List> loadedModuleCode; - - - Session(bool /*pUseCache*/, String /*pCacheDir*/) - { - // Initialize global state - // TODO: move this into the session instead - BasicExpressionType::Init(); - - // Create scopes for various language builtins. - // - // TODO: load these on-demand to avoid parsing - // stdlib code for languages the user won't use. - - coreLanguageScope = new Scope(); - - hlslLanguageScope = new Scope(); - hlslLanguageScope->nextSibling = coreLanguageScope; - - slangLanguageScope = new Scope(); - slangLanguageScope->nextSibling = hlslLanguageScope; - - glslLanguageScope = new Scope(); - glslLanguageScope->nextSibling = coreLanguageScope; - - addBuiltinSource(coreLanguageScope, "core", getCoreLibraryCode()); - addBuiltinSource(hlslLanguageScope, "hlsl", getHLSLLibraryCode()); - addBuiltinSource(glslLanguageScope, "glsl", getGLSLLibraryCode()); - } + // Create scopes for various language builtins. + // + // TODO: load these on-demand to avoid parsing + // stdlib code for languages the user won't use. - ~Session() - { - // We need to clean up the strings for the standard library - // code that we might have allocated and loaded into static - // variables (TODO: don't use `static` variables for this stuff) + coreLanguageScope = new Scope(); - finalizeShaderLibrary(); + hlslLanguageScope = new Scope(); + hlslLanguageScope->nextSibling = coreLanguageScope; - // Ditto for our type represnetation stuff + slangLanguageScope = new Scope(); + slangLanguageScope->nextSibling = hlslLanguageScope; - ExpressionType::Finalize(); - } + glslLanguageScope = new Scope(); + glslLanguageScope->nextSibling = coreLanguageScope; - void addBuiltinSource( - RefPtr const& scope, - String const& path, - String const& source); -}; + addBuiltinSource(coreLanguageScope, "core", getCoreLibraryCode()); + addBuiltinSource(hlslLanguageScope, "hlsl", getHLSLLibraryCode()); + addBuiltinSource(glslLanguageScope, "glsl", getGLSLLibraryCode()); +} struct IncludeHandlerImpl : IncludeHandler { @@ -614,9 +579,9 @@ void Session::addBuiltinSource( #define SESSION(x) reinterpret_cast(x) #define REQ(x) reinterpret_cast(x) -SLANG_API SlangSession* spCreateSession(const char * cacheDir) +SLANG_API SlangSession* spCreateSession(const char*) { - return reinterpret_cast(new Slang::Session((cacheDir ? true : false), cacheDir)); + return reinterpret_cast(new Slang::Session()); } SLANG_API void spDestroySession( -- cgit v1.2.3