2 // Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
7 // tls.cpp: Simple cross-platform interface for thread local storage.
9 #include "common/tls.h"
13 #ifdef ANGLE_ENABLE_WINDOWS_STORE
19 #include <wrl/client.h>
20 #include <wrl/async.h>
21 #include <Windows.System.Threading.h>
24 using namespace Windows::Foundation;
25 using namespace ABI::Windows::System::Threading;
27 // Thread local storage for Windows Store support
28 typedef vector<void*> ThreadLocalData;
30 static __declspec(thread) ThreadLocalData* currentThreadData = nullptr;
31 static set<ThreadLocalData*> allThreadData;
32 static DWORD nextTlsIndex = 0;
33 static vector<DWORD> freeTlsIndices;
37 TLSIndex CreateTLSIndex()
41 #ifdef ANGLE_PLATFORM_WINDOWS
42 #ifdef ANGLE_ENABLE_WINDOWS_STORE
43 if (!freeTlsIndices.empty())
45 DWORD result = freeTlsIndices.back();
46 freeTlsIndices.pop_back();
51 index = nextTlsIndex++;
57 #elif defined(ANGLE_PLATFORM_POSIX)
58 // Create global pool key
59 if ((pthread_key_create(&index, NULL)) != 0)
61 index = TLS_INVALID_INDEX;
65 assert(index != TLS_INVALID_INDEX && "CreateTLSIndex(): Unable to allocate Thread Local Storage");
69 bool DestroyTLSIndex(TLSIndex index)
71 assert(index != TLS_INVALID_INDEX && "DestroyTLSIndex(): Invalid TLS Index");
72 if (index == TLS_INVALID_INDEX)
77 #ifdef ANGLE_PLATFORM_WINDOWS
78 #ifdef ANGLE_ENABLE_WINDOWS_STORE
79 assert(index < nextTlsIndex);
80 assert(find(freeTlsIndices.begin(), freeTlsIndices.end(), index) == freeTlsIndices.end());
82 freeTlsIndices.push_back(index);
83 for (auto threadData : allThreadData)
85 if (threadData->size() > index)
87 threadData->at(index) = nullptr;
92 return (TlsFree(index) == TRUE);
94 #elif defined(ANGLE_PLATFORM_POSIX)
95 return (pthread_key_delete(index) == 0);
99 bool SetTLSValue(TLSIndex index, void *value)
101 assert(index != TLS_INVALID_INDEX && "SetTLSValue(): Invalid TLS Index");
102 if (index == TLS_INVALID_INDEX)
107 #ifdef ANGLE_PLATFORM_WINDOWS
108 #ifdef ANGLE_ENABLE_WINDOWS_STORE
109 ThreadLocalData* threadData = currentThreadData;
112 threadData = new ThreadLocalData(index + 1, nullptr);
113 allThreadData.insert(threadData);
114 currentThreadData = threadData;
116 else if (threadData->size() <= index)
118 threadData->resize(index + 1, nullptr);
121 threadData->at(index) = value;
124 return (TlsSetValue(index, value) == TRUE);
126 #elif defined(ANGLE_PLATFORM_POSIX)
127 return (pthread_setspecific(index, value) == 0);
131 void *GetTLSValue(TLSIndex index)
133 assert(index != TLS_INVALID_INDEX && "GetTLSValue(): Invalid TLS Index");
134 if (index == TLS_INVALID_INDEX)
139 #ifdef ANGLE_PLATFORM_WINDOWS
140 #ifdef ANGLE_ENABLE_WINDOWS_STORE
141 ThreadLocalData* threadData = currentThreadData;
142 if (threadData && threadData->size() > index)
144 return threadData->at(index);
151 return TlsGetValue(index);
153 #elif defined(ANGLE_PLATFORM_POSIX)
154 return pthread_getspecific(index);