Commit 420b64d2 by Nicolas Capens

Fix TLS for platforms without library constructors.

Some platforms don't support constructors that get called when the shared library gets loaded. This results in the thread-local-storage key to never be allocated. Instead we can check if it was allocated on each use. Also prevent creating new 'current' state if it already exists, and avoid pthreads undefined behavior. Bug b/25629882 Change-Id: I5e2486f88185150b976d88d0144e4d13a349eb79 Reviewed-on: https://swiftshader-review.googlesource.com/10451Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <capn@google.com> Tested-by: 's avatarNicolas Capens <capn@google.com>
parent a781af7d
......@@ -135,7 +135,7 @@ namespace sw
return TlsAlloc();
#else
LocalStorageKey key;
pthread_key_create(&key, 0);
pthread_key_create(&key, NULL);
return key;
#endif
}
......@@ -145,7 +145,7 @@ namespace sw
#if defined(_WIN32)
TlsFree(key);
#else
pthread_key_delete(key);
pthread_key_delete(key); // Using an invalid key is an error but not undefined behavior.
#endif
}
......@@ -154,7 +154,10 @@ namespace sw
#if defined(_WIN32)
TlsSetValue(key, value);
#else
pthread_setspecific(key, value);
if(key != TLS_OUT_OF_INDEXES) // Avoid undefined behavior.
{
pthread_setspecific(key, value);
}
#endif
}
......@@ -163,6 +166,11 @@ namespace sw
#if defined(_WIN32)
return TlsGetValue(key);
#else
if(key == TLS_OUT_OF_INDEXES) // Avoid undefined behavior.
{
return nullptr;
}
return pthread_getspecific(key);
#endif
}
......
......@@ -39,22 +39,31 @@ static sw::Thread::LocalStorageKey currentTLS = TLS_OUT_OF_INDEXES;
namespace egl
{
void attachThread()
Current *attachThread()
{
TRACE("()");
Current *current = new Current;
if(currentTLS == TLS_OUT_OF_INDEXES)
{
currentTLS = sw::Thread::allocateLocalStorageKey();
}
Current *current = (Current*)sw::Thread::getLocalStorage(currentTLS);
if(current)
if(!current)
{
sw::Thread::setLocalStorage(currentTLS, current);
current = new Current;
current->error = EGL_SUCCESS;
current->API = EGL_OPENGL_ES_API;
current->context = nullptr;
current->drawSurface = nullptr;
current->readSurface = nullptr;
sw::Thread::setLocalStorage(currentTLS, current);
}
current->error = EGL_SUCCESS;
current->API = EGL_OPENGL_ES_API;
current->context = nullptr;
current->drawSurface = nullptr;
current->readSurface = nullptr;
return current;
}
void detachThread()
......@@ -82,13 +91,6 @@ CONSTRUCTOR void attachProcess()
}
#endif
currentTLS = sw::Thread::allocateLocalStorageKey();
if(currentTLS == TLS_OUT_OF_INDEXES)
{
return;
}
attachThread();
}
......@@ -176,10 +178,10 @@ static Current *getCurrent(void)
if(!current)
{
attachThread();
current = attachThread();
}
return (Current*)sw::Thread::getLocalStorage(currentTLS);
return current;
}
void setCurrentError(EGLint error)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment