rsdCore.cpp revision da6d34a5a6ece8c30d20673b9b6ff07d8c91768b
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"
18bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams#include "rsdBcc.h"
194b3de47071d875faaa7d419d050a464b09538797Jason Sams#include "rsdGL.h"
208feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams#include "rsdProgramStore.h"
21721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams#include "rsdProgramRaster.h"
22a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk#include "rsdProgramVertex.h"
23a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk#include "rsdProgramFragment.h"
24a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk#include "rsdMesh.h"
257f126c78a107257090c6675ea40ffac41516a9dcAlex Sakhartchouk#include "rsdSampler.h"
26da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk#include "rsdFrameBuffer.h"
27bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
28bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams#include <malloc.h>
29bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams#include "rsContext.h"
30bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
31cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#include <sys/types.h>
32cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#include <sys/resource.h>
33cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#include <sched.h>
34cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#include <cutils/properties.h>
35cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#include <cutils/sched_policy.h>
36cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#include <sys/syscall.h>
37cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#include <string.h>
38cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
39bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Samsusing namespace android;
40bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Samsusing namespace android::renderscript;
41bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
42cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsstatic void Shutdown(Context *rsc);
43cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsstatic void SetPriority(const Context *rsc, int32_t priority);
44cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
45bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Samsstatic RsdHalFunctions FunctionTable = {
464b3de47071d875faaa7d419d050a464b09538797Jason Sams    rsdGLInit,
474b3de47071d875faaa7d419d050a464b09538797Jason Sams    rsdGLShutdown,
484b3de47071d875faaa7d419d050a464b09538797Jason Sams    rsdGLSetSurface,
494b3de47071d875faaa7d419d050a464b09538797Jason Sams    rsdGLSwap,
504b3de47071d875faaa7d419d050a464b09538797Jason Sams
51cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    Shutdown,
52bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    NULL,
53cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    SetPriority,
54bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    {
55bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptInit,
56bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptInvokeFunction,
57bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptInvokeRoot,
58cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        rsdScriptInvokeForEach,
59bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptInvokeInit,
60bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptSetGlobalVar,
61bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptSetGlobalBind,
62bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptSetGlobalObj,
63bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptDestroy
648feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams    },
658feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams
668feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams
678feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams    {
688feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams        rsdProgramStoreInit,
698feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams        rsdProgramStoreSetActive,
708feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams        rsdProgramStoreDestroy
71721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams    },
72721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams
73721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams    {
74721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams        rsdProgramRasterInit,
75721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams        rsdProgramRasterSetActive,
76721acc495b859c6d884725a4f9b5523583dd11c7Jason Sams        rsdProgramRasterDestroy
77a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    },
78a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
79a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    {
80a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdProgramVertexInit,
81a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdProgramVertexSetActive,
82a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdProgramVertexDestroy
83a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    },
84a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
85a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    {
86a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdProgramFragmentInit,
87a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdProgramFragmentSetActive,
88a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdProgramFragmentDestroy
89a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    },
90a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk
91a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk    {
92a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdMeshInit,
93a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdMeshDraw,
94a04e30dbb5ab11592b03666bb3d102070759c58eAlex Sakhartchouk        rsdMeshDestroy
957f126c78a107257090c6675ea40ffac41516a9dcAlex Sakhartchouk    },
967f126c78a107257090c6675ea40ffac41516a9dcAlex Sakhartchouk
977f126c78a107257090c6675ea40ffac41516a9dcAlex Sakhartchouk    {
987f126c78a107257090c6675ea40ffac41516a9dcAlex Sakhartchouk        rsdSamplerInit,
997f126c78a107257090c6675ea40ffac41516a9dcAlex Sakhartchouk        rsdSamplerDestroy
1007f126c78a107257090c6675ea40ffac41516a9dcAlex Sakhartchouk    },
1018feea4e0dec48ea03bd6d32706d058b86dddc5baJason Sams
102da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk    {
103da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk        rsdFrameBufferInit,
104da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk        rsdFrameBufferSetActive,
105da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk        rsdFrameBufferDestroy
106da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk    },
107da6d34a5a6ece8c30d20673b9b6ff07d8c91768bAlex Sakhartchouk
108bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams};
109bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
11083c451a4ef4388e002482e383d488ca9b7b7600dJason Samspthread_key_t rsdgThreadTLSKey = 0;
11183c451a4ef4388e002482e383d488ca9b7b7600dJason Samsuint32_t rsdgThreadTLSKeyCount = 0;
11283c451a4ef4388e002482e383d488ca9b7b7600dJason Samspthread_mutex_t rsdgInitMutex = PTHREAD_MUTEX_INITIALIZER;
113bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
114cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
115cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsstatic void * HelperThreadProc(void *vrsc) {
116cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    Context *rsc = static_cast<Context *>(vrsc);
11787fe59a2f4d4c74539bfa0bff5f9a7e320e99415Jason Sams    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
118cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
119cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
120cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    uint32_t idx = (uint32_t)android_atomic_inc(&dc->mWorkers.mLaunchCount);
121cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
122cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    //LOGV("RS helperThread starting %p idx=%i", rsc, idx);
123cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
124cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchSignals[idx].init();
125cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mNativeThreadId[idx] = gettid();
126cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
12783c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    int status = pthread_setspecific(rsdgThreadTLSKey, &dc->mTlsStruct);
12883c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    if (status) {
12983c451a4ef4388e002482e383d488ca9b7b7600dJason Sams        LOGE("pthread_setspecific %i", status);
13083c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    }
13183c451a4ef4388e002482e383d488ca9b7b7600dJason Sams
132cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#if 0
133cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    typedef struct {uint64_t bits[1024 / 64]; } cpu_set_t;
134cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    cpu_set_t cpuset;
135cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    memset(&cpuset, 0, sizeof(cpuset));
136cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    cpuset.bits[idx / 64] |= 1ULL << (idx % 64);
137cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    int ret = syscall(241, rsc->mWorkers.mNativeThreadId[idx],
138cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams              sizeof(cpuset), &cpuset);
139cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    LOGE("SETAFFINITY ret = %i %s", ret, EGLUtils::strerror(ret));
140cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#endif
141cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
142cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    while (!dc->mExit) {
143cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        dc->mWorkers.mLaunchSignals[idx].wait();
144cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        if (dc->mWorkers.mLaunchCallback) {
145cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams           dc->mWorkers.mLaunchCallback(dc->mWorkers.mLaunchData, idx);
146cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        }
147cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        android_atomic_dec(&dc->mWorkers.mRunningCount);
148cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        dc->mWorkers.mCompleteSignal.set();
149cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
150cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
151cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    //LOGV("RS helperThread exited %p idx=%i", rsc, idx);
152cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    return NULL;
153cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams}
154cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
155cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsvoid rsdLaunchThreads(Context *rsc, WorkerCallback_t cbk, void *data) {
15687fe59a2f4d4c74539bfa0bff5f9a7e320e99415Jason Sams    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
157cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
158cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchData = data;
159cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchCallback = cbk;
160cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount);
161cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) {
162cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        dc->mWorkers.mLaunchSignals[ct].set();
163cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
164cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    while (android_atomic_acquire_load(&dc->mWorkers.mRunningCount) != 0) {
165cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        dc->mWorkers.mCompleteSignal.wait();
166cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
167cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams}
168cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
169bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Samsbool rsdHalInit(Context *rsc, uint32_t version_major, uint32_t version_minor) {
170bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    rsc->mHal.funcs = FunctionTable;
171bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
17287fe59a2f4d4c74539bfa0bff5f9a7e320e99415Jason Sams    RsdHal *dc = (RsdHal *)calloc(1, sizeof(RsdHal));
1732cfe51e7a9eef3dec091ce7c15d2a5a2216e9d3eJason Sams    if (!dc) {
1742cfe51e7a9eef3dec091ce7c15d2a5a2216e9d3eJason Sams        LOGE("Calloc for driver hal failed.");
175bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        return false;
176bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    }
177cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    rsc->mHal.drv = dc;
178bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
17983c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    pthread_mutex_lock(&rsdgInitMutex);
18083c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    if (!rsdgThreadTLSKeyCount) {
18183c451a4ef4388e002482e383d488ca9b7b7600dJason Sams        int status = pthread_key_create(&rsdgThreadTLSKey, NULL);
18283c451a4ef4388e002482e383d488ca9b7b7600dJason Sams        if (status) {
18383c451a4ef4388e002482e383d488ca9b7b7600dJason Sams            LOGE("Failed to init thread tls key.");
18483c451a4ef4388e002482e383d488ca9b7b7600dJason Sams            pthread_mutex_unlock(&rsdgInitMutex);
18583c451a4ef4388e002482e383d488ca9b7b7600dJason Sams            return false;
18683c451a4ef4388e002482e383d488ca9b7b7600dJason Sams        }
18783c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    }
18883c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    rsdgThreadTLSKeyCount++;
18983c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    pthread_mutex_unlock(&rsdgInitMutex);
19083c451a4ef4388e002482e383d488ca9b7b7600dJason Sams
19183c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    dc->mTlsStruct.mContext = rsc;
19283c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    dc->mTlsStruct.mScript = NULL;
19383c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    int status = pthread_setspecific(rsdgThreadTLSKey, &dc->mTlsStruct);
19483c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    if (status) {
19583c451a4ef4388e002482e383d488ca9b7b7600dJason Sams        LOGE("pthread_setspecific %i", status);
19683c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    }
19783c451a4ef4388e002482e383d488ca9b7b7600dJason Sams
198cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
199cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    int cpu = sysconf(_SC_NPROCESSORS_ONLN);
200cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    LOGV("RS Launching thread(s), reported CPU count %i", cpu);
201cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    if (cpu < 2) cpu = 0;
202cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
203cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mCount = (uint32_t)cpu;
204cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mThreadId = (pthread_t *) calloc(dc->mWorkers.mCount, sizeof(pthread_t));
205cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mNativeThreadId = (pid_t *) calloc(dc->mWorkers.mCount, sizeof(pid_t));
206cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchSignals = new Signal[dc->mWorkers.mCount];
207cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchCallback = NULL;
208cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
209cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mCompleteSignal.init();
210cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
211cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount);
212cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    android_atomic_release_store(0, &dc->mWorkers.mLaunchCount);
213cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
214cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    pthread_attr_t threadAttr;
215cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    status = pthread_attr_init(&threadAttr);
216cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    if (status) {
217cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        LOGE("Failed to init thread attribute.");
218cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        return false;
219cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
220cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
221cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    for (uint32_t ct=0; ct < dc->mWorkers.mCount; ct++) {
222cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        status = pthread_create(&dc->mWorkers.mThreadId[ct], &threadAttr, HelperThreadProc, rsc);
223cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        if (status) {
224cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams            dc->mWorkers.mCount = ct;
225cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams            LOGE("Created fewer than expected number of RS threads.");
226cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams            break;
227cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        }
228cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
229cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    while (android_atomic_acquire_load(&dc->mWorkers.mRunningCount) != 0) {
230cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        usleep(100);
231cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
232cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
233cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    pthread_attr_destroy(&threadAttr);
234bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    return true;
235bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams}
236bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
237cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
238cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsvoid SetPriority(const Context *rsc, int32_t priority) {
23987fe59a2f4d4c74539bfa0bff5f9a7e320e99415Jason Sams    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
240cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    for (uint32_t ct=0; ct < dc->mWorkers.mCount; ct++) {
241cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        setpriority(PRIO_PROCESS, dc->mWorkers.mNativeThreadId[ct], priority);
242cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
243cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams}
244cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
245cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsvoid Shutdown(Context *rsc) {
24687fe59a2f4d4c74539bfa0bff5f9a7e320e99415Jason Sams    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
247cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
248cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mExit = true;
249cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchData = NULL;
250cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchCallback = NULL;
251cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount);
252cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) {
253cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        dc->mWorkers.mLaunchSignals[ct].set();
254cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
255cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    int status;
256cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    void *res;
257cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) {
258cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        status = pthread_join(dc->mWorkers.mThreadId[ct], &res);
259cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
260cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    rsAssert(android_atomic_acquire_load(&dc->mWorkers.mRunningCount) == 0);
26183c451a4ef4388e002482e383d488ca9b7b7600dJason Sams
26283c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    // Global structure cleanup.
26383c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    pthread_mutex_lock(&rsdgInitMutex);
26483c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    --rsdgThreadTLSKeyCount;
26583c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    if (!rsdgThreadTLSKeyCount) {
26683c451a4ef4388e002482e383d488ca9b7b7600dJason Sams        pthread_key_delete(rsdgThreadTLSKey);
26783c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    }
26883c451a4ef4388e002482e383d488ca9b7b7600dJason Sams    pthread_mutex_unlock(&rsdgInitMutex);
26983c451a4ef4388e002482e383d488ca9b7b7600dJason Sams
270cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams}
271cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
272cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
273