10f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines/*
20f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines * Copyright (C) 2011-2012 The Android Open Source Project
30f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines *
40f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines * Licensed under the Apache License, Version 2.0 (the "License");
50f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines * you may not use this file except in compliance with the License.
60f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines * You may obtain a copy of the License at
70f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines *
80f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines *      http://www.apache.org/licenses/LICENSE-2.0
90f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines *
100f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines * Unless required by applicable law or agreed to in writing, software
110f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines * distributed under the License is distributed on an "AS IS" BASIS,
120f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines * See the License for the specific language governing permissions and
140f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines * limitations under the License.
150f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines */
160f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
170f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines#include "rsdCore.h"
180f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines#include "rsdAllocation.h"
190f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines#include "rsdBcc.h"
200f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines#include "rsdSampler.h"
21ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams#include "rsdScriptGroup.h"
220f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
230f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines#include <malloc.h>
240f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines#include "rsContext.h"
250f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
260f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines#include <sys/types.h>
270f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines#include <sys/resource.h>
280f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines#include <sched.h>
290f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines#include <cutils/properties.h>
300f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines#include <sys/syscall.h>
310f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines#include <string.h>
320f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
330f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesusing namespace android;
340f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesusing namespace android::renderscript;
350f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
360f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesstatic void Shutdown(Context *rsc);
370f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesstatic void SetPriority(const Context *rsc, int32_t priority);
380f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
390f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesstatic RsdHalFunctions FunctionTable = {
4033b0a9fe4f0fc7bd26378420af259d24036caa22Stephen Hines    NULL,
4133b0a9fe4f0fc7bd26378420af259d24036caa22Stephen Hines    NULL,
4233b0a9fe4f0fc7bd26378420af259d24036caa22Stephen Hines    NULL,
4333b0a9fe4f0fc7bd26378420af259d24036caa22Stephen Hines    NULL,
440f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
450f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    Shutdown,
460f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    NULL,
470f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    SetPriority,
480f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    {
490f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        rsdScriptInit,
50ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        rsdInitIntrinsic,
510f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        rsdScriptInvokeFunction,
520f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        rsdScriptInvokeRoot,
530f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        rsdScriptInvokeForEach,
540f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        rsdScriptInvokeInit,
550f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        rsdScriptInvokeFreeChildren,
560f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        rsdScriptSetGlobalVar,
570f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        rsdScriptSetGlobalVarWithElemDims,
580f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        rsdScriptSetGlobalBind,
590f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        rsdScriptSetGlobalObj,
600f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        rsdScriptDestroy
610f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    },
620f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
630f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    {
640f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        rsdAllocationInit,
650f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        rsdAllocationDestroy,
660f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        rsdAllocationResize,
670f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        rsdAllocationSyncAll,
680f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        rsdAllocationMarkDirty,
6933b0a9fe4f0fc7bd26378420af259d24036caa22Stephen Hines        NULL,
7033b0a9fe4f0fc7bd26378420af259d24036caa22Stephen Hines        NULL,
7133b0a9fe4f0fc7bd26378420af259d24036caa22Stephen Hines        NULL,
7233b0a9fe4f0fc7bd26378420af259d24036caa22Stephen Hines        NULL,
730f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        rsdAllocationData1D,
740f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        rsdAllocationData2D,
750f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        rsdAllocationData3D,
760f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        rsdAllocationRead1D,
770f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        rsdAllocationRead2D,
780f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        rsdAllocationRead3D,
790f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        rsdAllocationLock1D,
800f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        rsdAllocationUnlock1D,
810f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        rsdAllocationData1D_alloc,
820f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        rsdAllocationData2D_alloc,
830f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        rsdAllocationData3D_alloc,
840f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        rsdAllocationElementData1D,
850f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        rsdAllocationElementData2D,
860f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        rsdAllocationGenerateMipmaps
870f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    },
880f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
890f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
900f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    {
9133b0a9fe4f0fc7bd26378420af259d24036caa22Stephen Hines        NULL,
9233b0a9fe4f0fc7bd26378420af259d24036caa22Stephen Hines        NULL,
9333b0a9fe4f0fc7bd26378420af259d24036caa22Stephen Hines        NULL
940f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    },
950f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
960f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    {
9733b0a9fe4f0fc7bd26378420af259d24036caa22Stephen Hines        NULL,
9833b0a9fe4f0fc7bd26378420af259d24036caa22Stephen Hines        NULL,
9933b0a9fe4f0fc7bd26378420af259d24036caa22Stephen Hines        NULL
1000f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    },
1010f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
1020f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    {
10333b0a9fe4f0fc7bd26378420af259d24036caa22Stephen Hines        NULL,
10433b0a9fe4f0fc7bd26378420af259d24036caa22Stephen Hines        NULL,
10533b0a9fe4f0fc7bd26378420af259d24036caa22Stephen Hines        NULL
1060f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    },
1070f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
1080f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    {
10933b0a9fe4f0fc7bd26378420af259d24036caa22Stephen Hines        NULL,
11033b0a9fe4f0fc7bd26378420af259d24036caa22Stephen Hines        NULL,
11133b0a9fe4f0fc7bd26378420af259d24036caa22Stephen Hines        NULL
1120f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    },
1130f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
1140f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    {
11533b0a9fe4f0fc7bd26378420af259d24036caa22Stephen Hines        NULL,
11633b0a9fe4f0fc7bd26378420af259d24036caa22Stephen Hines        NULL,
11733b0a9fe4f0fc7bd26378420af259d24036caa22Stephen Hines        NULL
1180f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    },
1190f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
1200f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    {
12133b0a9fe4f0fc7bd26378420af259d24036caa22Stephen Hines        NULL,
12233b0a9fe4f0fc7bd26378420af259d24036caa22Stephen Hines        NULL,
12333b0a9fe4f0fc7bd26378420af259d24036caa22Stephen Hines        NULL,
12433b0a9fe4f0fc7bd26378420af259d24036caa22Stephen Hines        NULL
1250f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    },
1260f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
1270f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    {
1280f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        rsdSamplerInit,
1290f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        rsdSamplerDestroy
1300f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    },
1310f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
1320f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    {
13333b0a9fe4f0fc7bd26378420af259d24036caa22Stephen Hines        NULL,
13433b0a9fe4f0fc7bd26378420af259d24036caa22Stephen Hines        NULL,
13533b0a9fe4f0fc7bd26378420af259d24036caa22Stephen Hines        NULL
1360f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    },
1370f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
138ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    {
139ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        rsdScriptGroupInit,
140ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        rsdScriptGroupSetInput,
141ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        rsdScriptGroupSetOutput,
142ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        rsdScriptGroupExecute,
143ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams        rsdScriptGroupDestroy
144ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    }
145ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
146ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams
1470f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines};
1480f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
1490f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinespthread_key_t rsdgThreadTLSKey = 0;
1500f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesuint32_t rsdgThreadTLSKeyCount = 0;
1510f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinespthread_mutex_t rsdgInitMutex = PTHREAD_MUTEX_INITIALIZER;
1520f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
1530f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
1540f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesstatic void * HelperThreadProc(void *vrsc) {
1550f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    Context *rsc = static_cast<Context *>(vrsc);
1560f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
1570f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
1580f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
1590f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    uint32_t idx = (uint32_t)android_atomic_inc(&dc->mWorkers.mLaunchCount);
1600f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
1610f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    //ALOGV("RS helperThread starting %p idx=%i", rsc, idx);
1620f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
1630f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    dc->mWorkers.mLaunchSignals[idx].init();
1640f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    dc->mWorkers.mNativeThreadId[idx] = gettid();
1650f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
1660f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    int status = pthread_setspecific(rsdgThreadTLSKey, &dc->mTlsStruct);
1670f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    if (status) {
1680f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        ALOGE("pthread_setspecific %i", status);
1690f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    }
1700f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
1710f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines#if 0
1720f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    typedef struct {uint64_t bits[1024 / 64]; } cpu_set_t;
1730f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    cpu_set_t cpuset;
1740f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    memset(&cpuset, 0, sizeof(cpuset));
1750f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    cpuset.bits[idx / 64] |= 1ULL << (idx % 64);
1760f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    int ret = syscall(241, rsc->mWorkers.mNativeThreadId[idx],
1770f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines              sizeof(cpuset), &cpuset);
1780f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    ALOGE("SETAFFINITY ret = %i %s", ret, EGLUtils::strerror(ret));
1790f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines#endif
1800f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
1810f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    while (!dc->mExit) {
1820f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        dc->mWorkers.mLaunchSignals[idx].wait();
1830f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        if (dc->mWorkers.mLaunchCallback) {
1840f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines           dc->mWorkers.mLaunchCallback(dc->mWorkers.mLaunchData, idx);
1850f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        }
1860f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        android_atomic_dec(&dc->mWorkers.mRunningCount);
1870f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        dc->mWorkers.mCompleteSignal.set();
1880f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    }
1890f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
1900f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    //ALOGV("RS helperThread exited %p idx=%i", rsc, idx);
1910f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    return NULL;
1920f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines}
1930f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
1940f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesvoid rsdLaunchThreads(Context *rsc, WorkerCallback_t cbk, void *data) {
1950f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
1960f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
1970f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    dc->mWorkers.mLaunchData = data;
1980f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    dc->mWorkers.mLaunchCallback = cbk;
1990f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount);
2000f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) {
2010f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        dc->mWorkers.mLaunchSignals[ct].set();
2020f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    }
2030f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    while (android_atomic_acquire_load(&dc->mWorkers.mRunningCount) != 0) {
2040f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        dc->mWorkers.mCompleteSignal.wait();
2050f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    }
2060f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines}
2070f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
208ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Samsextern "C" bool rsdHalInit(RsContext c, uint32_t version_major,
209ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams                           uint32_t version_minor) {
210ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    Context *rsc = (Context*) c;
2110f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    rsc->mHal.funcs = FunctionTable;
2120f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
2130f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    RsdHal *dc = (RsdHal *)calloc(1, sizeof(RsdHal));
2140f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    if (!dc) {
2150f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        ALOGE("Calloc for driver hal failed.");
2160f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        return false;
2170f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    }
2180f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    rsc->mHal.drv = dc;
2190f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
2200f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    pthread_mutex_lock(&rsdgInitMutex);
2210f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    if (!rsdgThreadTLSKeyCount) {
2220f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        int status = pthread_key_create(&rsdgThreadTLSKey, NULL);
2230f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        if (status) {
2240f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines            ALOGE("Failed to init thread tls key.");
2250f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines            pthread_mutex_unlock(&rsdgInitMutex);
2260f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines            return false;
2270f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        }
2280f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    }
2290f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    rsdgThreadTLSKeyCount++;
2300f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    pthread_mutex_unlock(&rsdgInitMutex);
2310f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
2320f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    dc->mTlsStruct.mContext = rsc;
2330f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    dc->mTlsStruct.mScript = NULL;
2340f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    int status = pthread_setspecific(rsdgThreadTLSKey, &dc->mTlsStruct);
2350f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    if (status) {
2360f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        ALOGE("pthread_setspecific %i", status);
2370f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    }
2380f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
2390f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
2400f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    int cpu = sysconf(_SC_NPROCESSORS_ONLN);
241ca29b8caf56fa4866752f9cea4ec02b2a271dceeJason Sams    if(rsc->props.mDebugMaxThreads) {
2420f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        cpu = rsc->props.mDebugMaxThreads;
2430f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    }
2440f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    if (cpu < 2) {
2450f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        cpu = 0;
2460f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    }
2470f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    ALOGV("%p Launching thread(s), CPUs %i", rsc, cpu);
2480f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
2490f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    dc->mWorkers.mCount = (uint32_t)cpu;
2500f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    dc->mWorkers.mThreadId = (pthread_t *) calloc(dc->mWorkers.mCount, sizeof(pthread_t));
2510f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    dc->mWorkers.mNativeThreadId = (pid_t *) calloc(dc->mWorkers.mCount, sizeof(pid_t));
2520f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    dc->mWorkers.mLaunchSignals = new Signal[dc->mWorkers.mCount];
2530f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    dc->mWorkers.mLaunchCallback = NULL;
2540f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
2550f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    dc->mWorkers.mCompleteSignal.init();
2560f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
2570f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount);
2580f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    android_atomic_release_store(0, &dc->mWorkers.mLaunchCount);
2590f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
2600f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    pthread_attr_t threadAttr;
2610f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    status = pthread_attr_init(&threadAttr);
2620f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    if (status) {
2630f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        ALOGE("Failed to init thread attribute.");
2640f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        return false;
2650f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    }
2660f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
2670f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    for (uint32_t ct=0; ct < dc->mWorkers.mCount; ct++) {
2680f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        status = pthread_create(&dc->mWorkers.mThreadId[ct], &threadAttr, HelperThreadProc, rsc);
2690f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        if (status) {
2700f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines            dc->mWorkers.mCount = ct;
2710f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines            ALOGE("Created fewer than expected number of RS threads.");
2720f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines            break;
2730f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        }
2740f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    }
2750f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    while (android_atomic_acquire_load(&dc->mWorkers.mRunningCount) != 0) {
2760f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        usleep(100);
2770f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    }
2780f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
2790f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    pthread_attr_destroy(&threadAttr);
2800f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    return true;
2810f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines}
2820f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
2830f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
2840f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesvoid SetPriority(const Context *rsc, int32_t priority) {
2850f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
2860f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    for (uint32_t ct=0; ct < dc->mWorkers.mCount; ct++) {
2870f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        setpriority(PRIO_PROCESS, dc->mWorkers.mNativeThreadId[ct], priority);
2880f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    }
2890f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    if (dc->mHasGraphics) {
29033b0a9fe4f0fc7bd26378420af259d24036caa22Stephen Hines        //rsdGLSetPriority(rsc, priority);
2910f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    }
2920f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines}
2930f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
2940f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hinesvoid Shutdown(Context *rsc) {
2950f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
2960f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
2970f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    dc->mExit = true;
2980f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    dc->mWorkers.mLaunchData = NULL;
2990f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    dc->mWorkers.mLaunchCallback = NULL;
3000f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount);
3010f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) {
3020f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        dc->mWorkers.mLaunchSignals[ct].set();
3030f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    }
3040f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    void *res;
3050f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) {
3060f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        pthread_join(dc->mWorkers.mThreadId[ct], &res);
3070f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    }
3080f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    rsAssert(android_atomic_acquire_load(&dc->mWorkers.mRunningCount) == 0);
3090f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
3100f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    // Global structure cleanup.
3110f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    pthread_mutex_lock(&rsdgInitMutex);
3120f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    --rsdgThreadTLSKeyCount;
3130f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    if (!rsdgThreadTLSKeyCount) {
3140f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines        pthread_key_delete(rsdgThreadTLSKey);
3150f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    }
3160f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines    pthread_mutex_unlock(&rsdgInitMutex);
3170f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
3180f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines}
3190f6f72e19db852cc253fd2fc05459abdf8d5c3afStephen Hines
320