rsdCore.cpp revision b81a0eb8180791e4eaab1253b59fa8bd562b046b
1bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams/*
24b3de47071d875faaa7d419d050a464b09538797Jason Sams * Copyright (C) 2011 The Android Open Source Project
3bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams *
4bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams * Licensed under the Apache License, Version 2.0 (the "License");
5bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams * you may not use this file except in compliance with the License.
6bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams * You may obtain a copy of the License at
7bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams *
8bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams *      http://www.apache.org/licenses/LICENSE-2.0
9bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams *
10bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams * Unless required by applicable law or agreed to in writing, software
11bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams * distributed under the License is distributed on an "AS IS" BASIS,
12bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams * See the License for the specific language governing permissions and
14bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams * limitations under the License.
15bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams */
16bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
17bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams#include "rsdCore.h"
18eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams#include "rsdAllocation.h"
19bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams#include "rsdBcc.h"
204b3de47071d875faaa7d419d050a464b09538797Jason Sams#include "rsdGL.h"
218feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams#include "rsdProgramStore.h"
22721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams#include "rsdProgramRaster.h"
23a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk#include "rsdProgramVertex.h"
24a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk#include "rsdProgramFragment.h"
25a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk#include "rsdMesh.h"
267f126c78a107257090c6675ea40ffac41516a9dcAlex Sakhartchouk#include "rsdSampler.h"
27da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk#include "rsdFrameBuffer.h"
28bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
29bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams#include <malloc.h>
30bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams#include "rsContext.h"
31bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
32cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#include <sys/types.h>
33cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#include <sys/resource.h>
34cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#include <sched.h>
35cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#include <cutils/properties.h>
36cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#include <cutils/sched_policy.h>
37cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#include <sys/syscall.h>
38cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#include <string.h>
39b81a0eb8180791e4eaab1253b59fa8bd562b046bAlex Sakhartchouk#include <bcc/bcc.h>
40cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
41bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Samsusing namespace android;
42bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Samsusing namespace android::renderscript;
43bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
44cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsstatic void Shutdown(Context *rsc);
45cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsstatic void SetPriority(const Context *rsc, int32_t priority);
46cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
47bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Samsstatic RsdHalFunctions FunctionTable = {
484b3de47071d875faaa7d419d050a464b09538797Jason Sams    rsdGLInit,
494b3de47071d875faaa7d419d050a464b09538797Jason Sams    rsdGLShutdown,
504b3de47071d875faaa7d419d050a464b09538797Jason Sams    rsdGLSetSurface,
514b3de47071d875faaa7d419d050a464b09538797Jason Sams    rsdGLSwap,
524b3de47071d875faaa7d419d050a464b09538797Jason Sams
53cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    Shutdown,
54bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    NULL,
55cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    SetPriority,
56bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    {
57bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptInit,
58bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptInvokeFunction,
59bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptInvokeRoot,
60cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        rsdScriptInvokeForEach,
61bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptInvokeInit,
62bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptSetGlobalVar,
63bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptSetGlobalBind,
64bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptSetGlobalObj,
65bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptDestroy
668feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams    },
678feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams
68eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    {
69eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationInit,
70eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationDestroy,
71eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationResize,
72eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationSyncAll,
73eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationMarkDirty,
74eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationData1D,
75eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationData2D,
76eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationData3D,
77eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationElementData1D,
78eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams        rsdAllocationElementData2D
79eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams    },
80eb4fe18dd88634330f9566cbb9e785d8c7ec5813Jason Sams
818feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams
828feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams    {
838feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams        rsdProgramStoreInit,
848feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams        rsdProgramStoreSetActive,
858feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams        rsdProgramStoreDestroy
86721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams    },
87721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams
88721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams    {
89721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams        rsdProgramRasterInit,
90721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams        rsdProgramRasterSetActive,
91721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams        rsdProgramRasterDestroy
92a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    },
93a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
94a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    {
95a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdProgramVertexInit,
96a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdProgramVertexSetActive,
97a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdProgramVertexDestroy
98a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    },
99a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
100a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    {
101a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdProgramFragmentInit,
102a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdProgramFragmentSetActive,
103a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdProgramFragmentDestroy
104a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    },
105a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
106a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    {
107a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdMeshInit,
108a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdMeshDraw,
109a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdMeshDestroy
1107f126c78a107257090c6675ea40ffac41516a9dcAlex Sakhartchouk    },
1117f126c78a107257090c6675ea40ffac41516a9dcAlex Sakhartchouk
1127f126c78a107257090c6675ea40ffac41516a9dcAlex Sakhartchouk    {
1137f126c78a107257090c6675ea40ffac41516a9dcAlex Sakhartchouk        rsdSamplerInit,
1147f126c78a107257090c6675ea40ffac41516a9dcAlex Sakhartchouk        rsdSamplerDestroy
1157f126c78a107257090c6675ea40ffac41516a9dcAlex Sakhartchouk    },
1168feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams
117da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk    {
118da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk        rsdFrameBufferInit,
119da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk        rsdFrameBufferSetActive,
120da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk        rsdFrameBufferDestroy
121da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk    },
122da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk
123bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams};
124bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
12583c451a4ef4388e002482e383d488ca9b7b7600dJason Samspthread_key_t rsdgThreadTLSKey = 0;
12683c451a4ef4388e002482e383d488ca9b7b7600dJason Samsuint32_t rsdgThreadTLSKeyCount = 0;
12783c451a4ef4388e002482e383d488ca9b7b7600dJason Samspthread_mutex_t rsdgInitMutex = PTHREAD_MUTEX_INITIALIZER;
128bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
129cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
130cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsstatic void * HelperThreadProc(void *vrsc) {
131cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    Context *rsc = static_cast<Context *>(vrsc);
13287fe59a2f4d4c74539bfa0bff5f9a7e320e99415Jason Sams    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
133cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
134cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
135cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    uint32_t idx = (uint32_t)android_atomic_inc(&dc->mWorkers.mLaunchCount);
136cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
137cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    //LOGV("RS helperThread starting %p idx=%i", rsc, idx);
138cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
139cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchSignals[idx].init();
140cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mNativeThreadId[idx] = gettid();
141cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
14283c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    int status = pthread_setspecific(rsdgThreadTLSKey, &dc->mTlsStruct);
14383c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    if (status) {
14483c451a4ef4388e002482e383d488ca9b7b7600dJason Sams        LOGE("pthread_setspecific %i", status);
14583c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    }
14683c451a4ef4388e002482e383d488ca9b7b7600dJason Sams
147cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#if 0
148cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    typedef struct {uint64_t bits[1024 / 64]; } cpu_set_t;
149cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    cpu_set_t cpuset;
150cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    memset(&cpuset, 0, sizeof(cpuset));
151cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    cpuset.bits[idx / 64] |= 1ULL << (idx % 64);
152cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    int ret = syscall(241, rsc->mWorkers.mNativeThreadId[idx],
153cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams              sizeof(cpuset), &cpuset);
154cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    LOGE("SETAFFINITY ret = %i %s", ret, EGLUtils::strerror(ret));
155cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#endif
156cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
157cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    while (!dc->mExit) {
158cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        dc->mWorkers.mLaunchSignals[idx].wait();
159cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        if (dc->mWorkers.mLaunchCallback) {
160cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams           dc->mWorkers.mLaunchCallback(dc->mWorkers.mLaunchData, idx);
161cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        }
162cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        android_atomic_dec(&dc->mWorkers.mRunningCount);
163cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        dc->mWorkers.mCompleteSignal.set();
164cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
165cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
166cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    //LOGV("RS helperThread exited %p idx=%i", rsc, idx);
167cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    return NULL;
168cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams}
169cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
170cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsvoid rsdLaunchThreads(Context *rsc, WorkerCallback_t cbk, void *data) {
17187fe59a2f4d4c74539bfa0bff5f9a7e320e99415Jason Sams    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
172cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
173cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchData = data;
174cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchCallback = cbk;
175cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount);
176cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) {
177cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        dc->mWorkers.mLaunchSignals[ct].set();
178cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
179cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    while (android_atomic_acquire_load(&dc->mWorkers.mRunningCount) != 0) {
180cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        dc->mWorkers.mCompleteSignal.wait();
181cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
182cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams}
183cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
184bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Samsbool rsdHalInit(Context *rsc, uint32_t version_major, uint32_t version_minor) {
185bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    rsc->mHal.funcs = FunctionTable;
186bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
18787fe59a2f4d4c74539bfa0bff5f9a7e320e99415Jason Sams    RsdHal *dc = (RsdHal *)calloc(1, sizeof(RsdHal));
1882cfe51e7a9eef3dec091ce7c15d2a5a2216e9d3eJason Sams    if (!dc) {
1892cfe51e7a9eef3dec091ce7c15d2a5a2216e9d3eJason Sams        LOGE("Calloc for driver hal failed.");
190bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        return false;
191bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    }
192cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    rsc->mHal.drv = dc;
193bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
19483c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    pthread_mutex_lock(&rsdgInitMutex);
19583c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    if (!rsdgThreadTLSKeyCount) {
19683c451a4ef4388e002482e383d488ca9b7b7600dJason Sams        int status = pthread_key_create(&rsdgThreadTLSKey, NULL);
19783c451a4ef4388e002482e383d488ca9b7b7600dJason Sams        if (status) {
19883c451a4ef4388e002482e383d488ca9b7b7600dJason Sams            LOGE("Failed to init thread tls key.");
19983c451a4ef4388e002482e383d488ca9b7b7600dJason Sams            pthread_mutex_unlock(&rsdgInitMutex);
20083c451a4ef4388e002482e383d488ca9b7b7600dJason Sams            return false;
20183c451a4ef4388e002482e383d488ca9b7b7600dJason Sams        }
20283c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    }
20383c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    rsdgThreadTLSKeyCount++;
20483c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    pthread_mutex_unlock(&rsdgInitMutex);
20583c451a4ef4388e002482e383d488ca9b7b7600dJason Sams
20683c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    dc->mTlsStruct.mContext = rsc;
20783c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    dc->mTlsStruct.mScript = NULL;
20883c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    int status = pthread_setspecific(rsdgThreadTLSKey, &dc->mTlsStruct);
20983c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    if (status) {
21083c451a4ef4388e002482e383d488ca9b7b7600dJason Sams        LOGE("pthread_setspecific %i", status);
21183c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    }
21283c451a4ef4388e002482e383d488ca9b7b7600dJason Sams
213cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
214cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    int cpu = sysconf(_SC_NPROCESSORS_ONLN);
215cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    LOGV("RS Launching thread(s), reported CPU count %i", cpu);
216cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    if (cpu < 2) cpu = 0;
217cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
218cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mCount = (uint32_t)cpu;
219cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mThreadId = (pthread_t *) calloc(dc->mWorkers.mCount, sizeof(pthread_t));
220cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mNativeThreadId = (pid_t *) calloc(dc->mWorkers.mCount, sizeof(pid_t));
221cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchSignals = new Signal[dc->mWorkers.mCount];
222cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchCallback = NULL;
223cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
224cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mCompleteSignal.init();
225cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
226cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount);
227cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    android_atomic_release_store(0, &dc->mWorkers.mLaunchCount);
228cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
229cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    pthread_attr_t threadAttr;
230cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    status = pthread_attr_init(&threadAttr);
231cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    if (status) {
232cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        LOGE("Failed to init thread attribute.");
233cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        return false;
234cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
235cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
236cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    for (uint32_t ct=0; ct < dc->mWorkers.mCount; ct++) {
237cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        status = pthread_create(&dc->mWorkers.mThreadId[ct], &threadAttr, HelperThreadProc, rsc);
238cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        if (status) {
239cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams            dc->mWorkers.mCount = ct;
240cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams            LOGE("Created fewer than expected number of RS threads.");
241cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams            break;
242cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        }
243cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
244cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    while (android_atomic_acquire_load(&dc->mWorkers.mRunningCount) != 0) {
245cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        usleep(100);
246cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
247cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
248cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    pthread_attr_destroy(&threadAttr);
249bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    return true;
250bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams}
251bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
252cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
253cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsvoid SetPriority(const Context *rsc, int32_t priority) {
25487fe59a2f4d4c74539bfa0bff5f9a7e320e99415Jason Sams    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
255cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    for (uint32_t ct=0; ct < dc->mWorkers.mCount; ct++) {
256cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        setpriority(PRIO_PROCESS, dc->mWorkers.mNativeThreadId[ct], priority);
257cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
258cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams}
259cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
260cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsvoid Shutdown(Context *rsc) {
26187fe59a2f4d4c74539bfa0bff5f9a7e320e99415Jason Sams    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
262cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
263cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mExit = true;
264cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchData = NULL;
265cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchCallback = NULL;
266cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount);
267cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) {
268cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        dc->mWorkers.mLaunchSignals[ct].set();
269cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
270cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    int status;
271cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    void *res;
272cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) {
273cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        status = pthread_join(dc->mWorkers.mThreadId[ct], &res);
274cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
275cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    rsAssert(android_atomic_acquire_load(&dc->mWorkers.mRunningCount) == 0);
27683c451a4ef4388e002482e383d488ca9b7b7600dJason Sams
27783c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    // Global structure cleanup.
27883c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    pthread_mutex_lock(&rsdgInitMutex);
27983c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    --rsdgThreadTLSKeyCount;
28083c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    if (!rsdgThreadTLSKeyCount) {
28183c451a4ef4388e002482e383d488ca9b7b7600dJason Sams        pthread_key_delete(rsdgThreadTLSKey);
28283c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    }
28383c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    pthread_mutex_unlock(&rsdgInitMutex);
28483c451a4ef4388e002482e383d488ca9b7b7600dJason Sams
285cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams}
286cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
287cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
288