diff options
Diffstat (limited to 'src/3rdparty/angle/src/common/tls.cpp')
-rw-r--r-- | src/3rdparty/angle/src/common/tls.cpp | 107 |
1 files changed, 80 insertions, 27 deletions
diff --git a/src/3rdparty/angle/src/common/tls.cpp b/src/3rdparty/angle/src/common/tls.cpp index c46fab5303..cb1b32d325 100644 --- a/src/3rdparty/angle/src/common/tls.cpp +++ b/src/3rdparty/angle/src/common/tls.cpp @@ -10,29 +10,50 @@ #include <assert.h> -#if defined(ANGLE_PLATFORM_WINRT) +#ifdef ANGLE_ENABLE_WINDOWS_STORE #include <vector> -std::vector<void *> *tls = nullptr; -std::vector<TLSIndex> *freeIndices = nullptr; +#include <set> +#include <map> +#include <mutex> + +#include <wrl/client.h> +#include <wrl/async.h> +#include <Windows.System.Threading.h> + +using namespace std; +using namespace Windows::Foundation; +using namespace ABI::Windows::System::Threading; + +// Thread local storage for Windows Store support +typedef vector<void*> ThreadLocalData; + +static __declspec(thread) ThreadLocalData* currentThreadData = nullptr; +static set<ThreadLocalData*> allThreadData; +static DWORD nextTlsIndex = 0; +static vector<DWORD> freeTlsIndices; + #endif TLSIndex CreateTLSIndex() { TLSIndex index; -#if defined(ANGLE_PLATFORM_WINRT) - if (!tls) - tls = new std::vector<void *>; - if (freeIndices && !freeIndices->empty()) { - index = freeIndices->back(); - freeIndices->pop_back(); - return index; - } else { - tls->push_back(nullptr); - return tls->size() - 1; +#ifdef ANGLE_PLATFORM_WINDOWS +#ifdef ANGLE_ENABLE_WINDOWS_STORE + if (!freeTlsIndices.empty()) + { + DWORD result = freeTlsIndices.back(); + freeTlsIndices.pop_back(); + index = result; } -#elif defined(ANGLE_PLATFORM_WINDOWS) + else + { + index = nextTlsIndex++; + } +#else index = TlsAlloc(); +#endif + #elif defined(ANGLE_PLATFORM_POSIX) // Create global pool key if ((pthread_key_create(&index, NULL)) != 0) @@ -53,13 +74,23 @@ bool DestroyTLSIndex(TLSIndex index) return false; } -#if defined(ANGLE_PLATFORM_WINRT) - if (!freeIndices) - freeIndices = new std::vector<TLSIndex>; - freeIndices->push_back(index); +#ifdef ANGLE_PLATFORM_WINDOWS +#ifdef ANGLE_ENABLE_WINDOWS_STORE + assert(index < nextTlsIndex); + assert(find(freeTlsIndices.begin(), freeTlsIndices.end(), index) == freeTlsIndices.end()); + + freeTlsIndices.push_back(index); + for (auto threadData : allThreadData) + { + if (threadData->size() > index) + { + threadData->at(index) = nullptr; + } + } return true; -#elif ANGLE_PLATFORM_WINDOWS +#else return (TlsFree(index) == TRUE); +#endif #elif defined(ANGLE_PLATFORM_POSIX) return (pthread_key_delete(index) == 0); #endif @@ -73,11 +104,25 @@ bool SetTLSValue(TLSIndex index, void *value) return false; } -#if defined(ANGLE_PLATFORM_WINRT) - tls->at(index) = value; +#ifdef ANGLE_PLATFORM_WINDOWS +#ifdef ANGLE_ENABLE_WINDOWS_STORE + ThreadLocalData* threadData = currentThreadData; + if (!threadData) + { + threadData = new ThreadLocalData(index + 1, nullptr); + allThreadData.insert(threadData); + currentThreadData = threadData; + } + else if (threadData->size() <= index) + { + threadData->resize(index + 1, nullptr); + } + + threadData->at(index) = value; return true; -#elif defined(ANGLE_PLATFORM_WINDOWS) +#else return (TlsSetValue(index, value) == TRUE); +#endif #elif defined(ANGLE_PLATFORM_POSIX) return (pthread_setspecific(index, value) == 0); #endif @@ -85,18 +130,26 @@ bool SetTLSValue(TLSIndex index, void *value) void *GetTLSValue(TLSIndex index) { -#if !defined(ANGLE_PLATFORM_WINRT) // Valid on WinRT, as Alloc handles the index creation assert(index != TLS_INVALID_INDEX && "GetTLSValue(): Invalid TLS Index"); -#endif if (index == TLS_INVALID_INDEX) { return NULL; } -#if defined(ANGLE_PLATFORM_WINRT) - return tls->at(index); -#elif defined(ANGLE_PLATFORM_WINDOWS) +#ifdef ANGLE_PLATFORM_WINDOWS +#ifdef ANGLE_ENABLE_WINDOWS_STORE + ThreadLocalData* threadData = currentThreadData; + if (threadData && threadData->size() > index) + { + return threadData->at(index); + } + else + { + return nullptr; + } +#else return TlsGetValue(index); +#endif #elif defined(ANGLE_PLATFORM_POSIX) return pthread_getspecific(index); #endif |