Move TLS behind hal.

Change-Id: I9e84acb3736bc98fa5fb0720bddb13a030285319
diff --git a/libs/rs/driver/rsdBcc.cpp b/libs/rs/driver/rsdBcc.cpp
index 2c6840b..8120864 100644
--- a/libs/rs/driver/rsdBcc.cpp
+++ b/libs/rs/driver/rsdBcc.cpp
@@ -56,8 +56,9 @@
 
 };
 
+
 static Script * setTLS(Script *sc) {
-    ScriptTLSStruct * tls = (ScriptTLSStruct *)pthread_getspecific(Context::gThreadTLSKey);
+    ScriptTLSStruct * tls = (ScriptTLSStruct *)pthread_getspecific(rsdgThreadTLSKey);
     rsAssert(tls);
     Script *old = tls->mScript;
     tls->mScript = sc;
@@ -133,12 +134,13 @@
                      uint32_t flags) {
     //LOGE("rsdScriptCreate %p %p %p %p %i %i %p", rsc, resName, cacheDir, bitcode, bitcodeSize, flags, lookupFunc);
 
+    pthread_mutex_lock(&rsdgInitMutex);
     char *cachePath = NULL;
     uint32_t objectSlotCount = 0;
 
     DrvScript *drv = (DrvScript *)calloc(1, sizeof(DrvScript));
     if (drv == NULL) {
-        return false;
+        goto error;
     }
     script->mHal.drv = drv;
 
@@ -159,20 +161,20 @@
                   (char const *)drv->mScriptText,
                   drv->mScriptTextLength, 0) != 0) {
         LOGE("bcc: FAILS to read bitcode");
-        return NULL;
+        goto error;
     }
 
 #if 1
     if (bccLinkFile(drv->mBccScript, "/system/lib/libclcore.bc", 0) != 0) {
         LOGE("bcc: FAILS to link bitcode");
-        return NULL;
+        goto error;
     }
 #endif
     cachePath = genCacheFileName(cacheDir, resName, ".oBCC");
 
     if (bccPrepareExecutable(drv->mBccScript, cachePath, 0) != 0) {
         LOGE("bcc: FAILS to prepare executable");
-        return NULL;
+        goto error;
     }
 
     free(cachePath);
@@ -234,10 +236,12 @@
     script->mHal.info.root = drv->mRoot;
 
 
+    pthread_mutex_unlock(&rsdgInitMutex);
     return true;
 
 error:
 
+    pthread_mutex_unlock(&rsdgInitMutex);
     free(drv);
     return false;
 
diff --git a/libs/rs/driver/rsdCore.cpp b/libs/rs/driver/rsdCore.cpp
index c01e5ab..5b80439 100644
--- a/libs/rs/driver/rsdCore.cpp
+++ b/libs/rs/driver/rsdCore.cpp
@@ -73,6 +73,9 @@
 
 };
 
+pthread_key_t rsdgThreadTLSKey = 0;
+uint32_t rsdgThreadTLSKeyCount = 0;
+pthread_mutex_t rsdgInitMutex = PTHREAD_MUTEX_INITIALIZER;
 
 
 static void * HelperThreadProc(void *vrsc) {
@@ -87,6 +90,11 @@
     dc->mWorkers.mLaunchSignals[idx].init();
     dc->mWorkers.mNativeThreadId[idx] = gettid();
 
+    int status = pthread_setspecific(rsdgThreadTLSKey, &dc->mTlsStruct);
+    if (status) {
+        LOGE("pthread_setspecific %i", status);
+    }
+
 #if 0
     typedef struct {uint64_t bits[1024 / 64]; } cpu_set_t;
     cpu_set_t cpuset;
@@ -97,11 +105,6 @@
     LOGE("SETAFFINITY ret = %i %s", ret, EGLUtils::strerror(ret));
 #endif
 
-    int status = pthread_setspecific(rsc->gThreadTLSKey, rsc->mTlsStruct);
-    if (status) {
-        LOGE("pthread_setspecific %i", status);
-    }
-
     while (!dc->mExit) {
         dc->mWorkers.mLaunchSignals[idx].wait();
         if (dc->mWorkers.mLaunchCallback) {
@@ -139,6 +142,25 @@
     }
     rsc->mHal.drv = dc;
 
+    pthread_mutex_lock(&rsdgInitMutex);
+    if (!rsdgThreadTLSKeyCount) {
+        int status = pthread_key_create(&rsdgThreadTLSKey, NULL);
+        if (status) {
+            LOGE("Failed to init thread tls key.");
+            pthread_mutex_unlock(&rsdgInitMutex);
+            return false;
+        }
+    }
+    rsdgThreadTLSKeyCount++;
+    pthread_mutex_unlock(&rsdgInitMutex);
+
+    dc->mTlsStruct.mContext = rsc;
+    dc->mTlsStruct.mScript = NULL;
+    int status = pthread_setspecific(rsdgThreadTLSKey, &dc->mTlsStruct);
+    if (status) {
+        LOGE("pthread_setspecific %i", status);
+    }
+
 
     int cpu = sysconf(_SC_NPROCESSORS_ONLN);
     LOGV("RS Launching thread(s), reported CPU count %i", cpu);
@@ -155,7 +177,6 @@
     android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount);
     android_atomic_release_store(0, &dc->mWorkers.mLaunchCount);
 
-    int status;
     pthread_attr_t threadAttr;
     status = pthread_attr_init(&threadAttr);
     if (status) {
@@ -203,6 +224,15 @@
         status = pthread_join(dc->mWorkers.mThreadId[ct], &res);
     }
     rsAssert(android_atomic_acquire_load(&dc->mWorkers.mRunningCount) == 0);
+
+    // Global structure cleanup.
+    pthread_mutex_lock(&rsdgInitMutex);
+    --rsdgThreadTLSKeyCount;
+    if (!rsdgThreadTLSKeyCount) {
+        pthread_key_delete(rsdgThreadTLSKey);
+    }
+    pthread_mutex_unlock(&rsdgInitMutex);
+
 }
 
 
diff --git a/libs/rs/driver/rsdCore.h b/libs/rs/driver/rsdCore.h
index c8df575..422bb1b 100644
--- a/libs/rs/driver/rsdCore.h
+++ b/libs/rs/driver/rsdCore.h
@@ -34,6 +34,11 @@
     bool threadable;
 } RsdSymbolTable;
 
+typedef struct ScriptTLSStructRec {
+    android::renderscript::Context * mContext;
+    android::renderscript::Script * mScript;
+} ScriptTLSStruct;
+
 typedef struct RsdHalRec {
     uint32_t version_major;
     uint32_t version_minor;
@@ -53,9 +58,14 @@
     Workers mWorkers;
     bool mExit;
 
+    ScriptTLSStruct mTlsStruct;
+
     RsdGL gl;
 } RsdHal;
 
+extern pthread_key_t rsdgThreadTLSKey;
+extern uint32_t rsdgThreadTLSKeyCount;
+extern pthread_mutex_t rsdgInitMutex;
 
 
 void rsdLaunchThreads(android::renderscript::Context *rsc, WorkerCallback_t cbk, void *data);
diff --git a/libs/rs/driver/rsdRuntimeStubs.cpp b/libs/rs/driver/rsdRuntimeStubs.cpp
index e384713..b70a123 100644
--- a/libs/rs/driver/rsdRuntimeStubs.cpp
+++ b/libs/rs/driver/rsdRuntimeStubs.cpp
@@ -32,7 +32,7 @@
 using namespace android::renderscript;
 
 #define GET_TLS()  ScriptTLSStruct * tls = \
-    (ScriptTLSStruct *)pthread_getspecific(Context::gThreadTLSKey); \
+    (ScriptTLSStruct *)pthread_getspecific(rsdgThreadTLSKey); \
     Context * rsc = tls->mContext; \
     ScriptC * sc = (ScriptC *) tls->mScript
 
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index 0f61789..20fa367 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -39,13 +39,9 @@
 using namespace android;
 using namespace android::renderscript;
 
-pthread_key_t Context::gThreadTLSKey = 0;
-uint32_t Context::gThreadTLSKeyCount = 0;
 pthread_mutex_t Context::gInitMutex = PTHREAD_MUTEX_INITIALIZER;
 pthread_mutex_t Context::gLibMutex = PTHREAD_MUTEX_INITIALIZER;
 
-
-
 bool Context::initGLThread() {
     pthread_mutex_lock(&gInitMutex);
     LOGV("initGLThread start %p", this);
@@ -263,94 +259,86 @@
 }
 
 void * Context::threadProc(void *vrsc) {
-     Context *rsc = static_cast<Context *>(vrsc);
-     rsc->mNativeThreadId = gettid();
+    Context *rsc = static_cast<Context *>(vrsc);
+    rsc->mNativeThreadId = gettid();
 
-     setpriority(PRIO_PROCESS, rsc->mNativeThreadId, ANDROID_PRIORITY_DISPLAY);
-     rsc->mThreadPriority = ANDROID_PRIORITY_DISPLAY;
+    setpriority(PRIO_PROCESS, rsc->mNativeThreadId, ANDROID_PRIORITY_DISPLAY);
+    rsc->mThreadPriority = ANDROID_PRIORITY_DISPLAY;
 
-     rsc->props.mLogTimes = getProp("debug.rs.profile");
-     rsc->props.mLogScripts = getProp("debug.rs.script");
-     rsc->props.mLogObjects = getProp("debug.rs.object");
-     rsc->props.mLogShaders = getProp("debug.rs.shader");
-     rsc->props.mLogShadersAttr = getProp("debug.rs.shader.attributes");
-     rsc->props.mLogShadersUniforms = getProp("debug.rs.shader.uniforms");
-     rsc->props.mLogVisual = getProp("debug.rs.visual");
+    rsc->props.mLogTimes = getProp("debug.rs.profile");
+    rsc->props.mLogScripts = getProp("debug.rs.script");
+    rsc->props.mLogObjects = getProp("debug.rs.object");
+    rsc->props.mLogShaders = getProp("debug.rs.shader");
+    rsc->props.mLogShadersAttr = getProp("debug.rs.shader.attributes");
+    rsc->props.mLogShadersUniforms = getProp("debug.rs.shader.uniforms");
+    rsc->props.mLogVisual = getProp("debug.rs.visual");
 
-     rsc->mTlsStruct = new ScriptTLSStruct;
-     if (!rsc->mTlsStruct) {
-         LOGE("Error allocating tls storage");
-         rsc->setError(RS_ERROR_OUT_OF_MEMORY, "Failed allocation for TLS");
-         return NULL;
-     }
-     rsc->mTlsStruct->mContext = rsc;
-     rsc->mTlsStruct->mScript = NULL;
-     int status = pthread_setspecific(rsc->gThreadTLSKey, rsc->mTlsStruct);
-     if (status) {
-         LOGE("pthread_setspecific %i", status);
-     }
+    if (!rsdHalInit(rsc, 0, 0)) {
+        LOGE("Hal init failed");
+        return NULL;
+    }
+    rsc->mHal.funcs.setPriority(rsc, rsc->mThreadPriority);
 
-     if (!rsc->initGLThread()) {
-         rsc->setError(RS_ERROR_OUT_OF_MEMORY, "Failed initializing GL");
-         return NULL;
-     }
+    if (!rsc->initGLThread()) {
+        rsc->setError(RS_ERROR_OUT_OF_MEMORY, "Failed initializing GL");
+        return NULL;
+    }
 
-     if (rsc->mIsGraphicsContext) {
-         rsc->mStateRaster.init(rsc);
-         rsc->setProgramRaster(NULL);
-         rsc->mStateVertex.init(rsc);
-         rsc->setProgramVertex(NULL);
-         rsc->mStateFragment.init(rsc);
-         rsc->setProgramFragment(NULL);
-         rsc->mStateFragmentStore.init(rsc);
-         rsc->setProgramStore(NULL);
-         rsc->mStateFont.init(rsc);
-         rsc->setFont(NULL);
-         rsc->mStateVertexArray.init(rsc);
-     }
+    if (rsc->mIsGraphicsContext) {
+        rsc->mStateRaster.init(rsc);
+        rsc->setProgramRaster(NULL);
+        rsc->mStateVertex.init(rsc);
+        rsc->setProgramVertex(NULL);
+        rsc->mStateFragment.init(rsc);
+        rsc->setProgramFragment(NULL);
+        rsc->mStateFragmentStore.init(rsc);
+        rsc->setProgramStore(NULL);
+        rsc->mStateFont.init(rsc);
+        rsc->setFont(NULL);
+        rsc->mStateVertexArray.init(rsc);
+    }
 
-     rsc->mRunning = true;
-     bool mDraw = true;
-     while (!rsc->mExit) {
-         mDraw |= rsc->mIO.playCoreCommands(rsc, !mDraw);
-         mDraw &= (rsc->mRootScript.get() != NULL);
-         mDraw &= (rsc->mWndSurface != NULL);
+    rsc->mRunning = true;
+    bool mDraw = true;
+    while (!rsc->mExit) {
+        mDraw |= rsc->mIO.playCoreCommands(rsc, !mDraw);
+        mDraw &= (rsc->mRootScript.get() != NULL);
+        mDraw &= (rsc->mWndSurface != NULL);
 
-         uint32_t targetTime = 0;
-         if (mDraw && rsc->mIsGraphicsContext) {
-             targetTime = rsc->runRootScript();
+        uint32_t targetTime = 0;
+        if (mDraw && rsc->mIsGraphicsContext) {
+            targetTime = rsc->runRootScript();
 
-             if (rsc->props.mLogVisual) {
-                 rsc->displayDebugStats();
-             }
+            if (rsc->props.mLogVisual) {
+                rsc->displayDebugStats();
+            }
 
-             mDraw = targetTime && !rsc->mPaused;
-             rsc->timerSet(RS_TIMER_CLEAR_SWAP);
-             rsc->mHal.funcs.swap(rsc);
-             rsc->timerFrame();
-             rsc->timerSet(RS_TIMER_INTERNAL);
-             rsc->timerPrint();
-             rsc->timerReset();
-         }
-         if (targetTime > 1) {
-             int32_t t = (targetTime - (int32_t)(rsc->mTimeMSLastScript + rsc->mTimeMSLastSwap)) * 1000;
-             if (t > 0) {
-                 usleep(t);
-             }
-         }
-     }
+            mDraw = targetTime && !rsc->mPaused;
+            rsc->timerSet(RS_TIMER_CLEAR_SWAP);
+            rsc->mHal.funcs.swap(rsc);
+            rsc->timerFrame();
+            rsc->timerSet(RS_TIMER_INTERNAL);
+            rsc->timerPrint();
+            rsc->timerReset();
+        }
+        if (targetTime > 1) {
+            int32_t t = (targetTime - (int32_t)(rsc->mTimeMSLastScript + rsc->mTimeMSLastSwap)) * 1000;
+            if (t > 0) {
+                usleep(t);
+            }
+        }
+    }
 
-     LOGV("%p, RS Thread exiting", rsc);
+    LOGV("%p, RS Thread exiting", rsc);
 
-     if (rsc->mIsGraphicsContext) {
-         pthread_mutex_lock(&gInitMutex);
-         rsc->deinitEGL();
-         pthread_mutex_unlock(&gInitMutex);
-     }
-     delete rsc->mTlsStruct;
+    if (rsc->mIsGraphicsContext) {
+        pthread_mutex_lock(&gInitMutex);
+        rsc->deinitEGL();
+        pthread_mutex_unlock(&gInitMutex);
+    }
 
-     LOGV("%p, RS Thread exited", rsc);
-     return NULL;
+    LOGV("%p, RS Thread exited", rsc);
+    return NULL;
 }
 
 void Context::destroyWorkerThreadResources() {
@@ -429,16 +417,6 @@
     int status;
     pthread_attr_t threadAttr;
 
-    if (!gThreadTLSKeyCount) {
-        status = pthread_key_create(&gThreadTLSKey, NULL);
-        if (status) {
-            LOGE("Failed to init thread tls key.");
-            pthread_mutex_unlock(&gInitMutex);
-            return false;
-        }
-    }
-    gThreadTLSKeyCount++;
-
     pthread_mutex_unlock(&gInitMutex);
 
     // Global init done at this point.
@@ -454,12 +432,6 @@
     timerInit();
     timerSet(RS_TIMER_INTERNAL);
 
-    if (!rsdHalInit(this, 0, 0)) {
-        LOGE("Hal init failed");
-        return false;
-    }
-    mHal.funcs.setPriority(this, mThreadPriority);
-
     status = pthread_create(&mThreadId, &threadAttr, threadProc, this);
     if (status) {
         LOGE("Failed to start rs context thread.");
@@ -499,10 +471,6 @@
     pthread_mutex_lock(&gInitMutex);
     if (mDev) {
         mDev->removeContext(this);
-        --gThreadTLSKeyCount;
-        if (!gThreadTLSKeyCount) {
-            pthread_key_delete(gThreadTLSKey);
-        }
         mDev = NULL;
     }
     pthread_mutex_unlock(&gInitMutex);
diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h
index 0a0f3e0..df85a6b 100644
--- a/libs/rs/rsContext.h
+++ b/libs/rs/rsContext.h
@@ -84,9 +84,6 @@
     static Context * createContext(Device *, const RsSurfaceConfig *sc);
     ~Context();
 
-    static pthread_key_t gThreadTLSKey;
-    static uint32_t gThreadTLSKeyCount;
-    static uint32_t gGLContextCount;
     static pthread_mutex_t gInitMutex;
     // Library mutex (for providing thread-safe calls from the runtime)
     static pthread_mutex_t gLibMutex;
@@ -105,7 +102,6 @@
         Context *mRsc;
     };
 
-    ScriptTLSStruct *mTlsStruct;
     RsSurfaceConfig mUserSurfaceConfig;
 
     ElementState mStateElement;
diff --git a/libs/rs/rs_hal.h b/libs/rs/rs_hal.h
index 90abd85..4283d4a 100644
--- a/libs/rs/rs_hal.h
+++ b/libs/rs/rs_hal.h
@@ -35,12 +35,6 @@
 
 typedef void *(*RsHalSymbolLookupFunc)(void *usrptr, char const *symbolName);
 
-typedef struct ScriptTLSStructRec {
-    Context * mContext;
-    Script * mScript;
-} ScriptTLSStruct;
-
-
 /**
  * Script management functions
  */