• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright (C) 2002-2005  3Dlabs Inc. Ltd.
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions
7 // are met:
8 //
9 //    Redistributions of source code must retain the above copyright
10 //    notice, this list of conditions and the following disclaimer.
11 //
12 //    Redistributions in binary form must reproduce the above
13 //    copyright notice, this list of conditions and the following
14 //    disclaimer in the documentation and/or other materials provided
15 //    with the distribution.
16 //
17 //    Neither the name of 3Dlabs Inc. Ltd. nor the names of its
18 //    contributors may be used to endorse or promote products derived
19 //    from this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 // POSSIBILITY OF SUCH DAMAGE.
33 //
34 
35 #define SH_EXPORTING
36 
37 #include <cassert>
38 
39 #include "InitializeDll.h"
40 #include "../glslang/Include/InitializeGlobals.h"
41 #include "../glslang/Public/ShaderLang.h"
42 #include "../glslang/Include/PoolAlloc.h"
43 
44 namespace glslang {
45 
46 OS_TLSIndex ThreadInitializeIndex = OS_INVALID_TLS_INDEX;
47 
48 // Per-process initialization.
49 // Needs to be called at least once before parsing, etc. is done.
50 // Will also do thread initialization for the calling thread; other
51 // threads will need to do that explicitly.
InitProcess()52 bool InitProcess()
53 {
54     glslang::GetGlobalLock();
55 
56     if (ThreadInitializeIndex != OS_INVALID_TLS_INDEX) {
57         //
58         // Function is re-entrant.
59         //
60 
61         glslang::ReleaseGlobalLock();
62         return true;
63     }
64 
65     ThreadInitializeIndex = OS_AllocTLSIndex();
66 
67     if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX) {
68         assert(0 && "InitProcess(): Failed to allocate TLS area for init flag");
69 
70         glslang::ReleaseGlobalLock();
71         return false;
72     }
73 
74     if (! InitializePoolIndex()) {
75         assert(0 && "InitProcess(): Failed to initialize global pool");
76 
77         glslang::ReleaseGlobalLock();
78         return false;
79     }
80 
81     if (! InitThread()) {
82         assert(0 && "InitProcess(): Failed to initialize thread");
83 
84         glslang::ReleaseGlobalLock();
85         return false;
86     }
87 
88     glslang::ReleaseGlobalLock();
89     return true;
90 }
91 
92 // Per-thread scoped initialization.
93 // Must be called at least once by each new thread sharing the
94 // symbol tables, etc., needed to parse.
InitThread()95 bool InitThread()
96 {
97     //
98     // This function is re-entrant
99     //
100     if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX) {
101         assert(0 && "InitThread(): Process hasn't been initalised.");
102         return false;
103     }
104 
105     if (OS_GetTLSValue(ThreadInitializeIndex) != 0)
106         return true;
107 
108     if (! OS_SetTLSValue(ThreadInitializeIndex, (void *)1)) {
109         assert(0 && "InitThread(): Unable to set init flag.");
110         return false;
111     }
112 
113     glslang::SetThreadPoolAllocator(nullptr);
114 
115     return true;
116 }
117 
118 // Not necessary to call this: InitThread() is reentrant, and the need
119 // to do per thread tear down has been removed.
120 //
121 // This is kept, with memory management removed, to satisfy any exiting
122 // calls to it that rely on it.
DetachThread()123 bool DetachThread()
124 {
125     bool success = true;
126 
127     if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX)
128         return true;
129 
130     //
131     // Function is re-entrant and this thread may not have been initialized.
132     //
133     if (OS_GetTLSValue(ThreadInitializeIndex) != 0) {
134         if (!OS_SetTLSValue(ThreadInitializeIndex, (void *)0)) {
135             assert(0 && "DetachThread(): Unable to clear init flag.");
136             success = false;
137         }
138     }
139 
140     return success;
141 }
142 
143 // Not necessary to call this: InitProcess() is reentrant.
144 //
145 // This is kept, with memory management removed, to satisfy any exiting
146 // calls to it that rely on it.
147 //
148 // Users of glslang should call shFinalize() or glslang::FinalizeProcess() for
149 // process-scoped memory tear down.
DetachProcess()150 bool DetachProcess()
151 {
152     bool success = true;
153 
154     if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX)
155         return true;
156 
157     success = DetachThread();
158 
159     OS_FreeTLSIndex(ThreadInitializeIndex);
160     ThreadInitializeIndex = OS_INVALID_TLS_INDEX;
161 
162     return success;
163 }
164 
165 } // end namespace glslang
166