rsdCore.cpp revision cdfdb8f2cdf4668c476cac842212892b2505ff3f
1bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams/*
2bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams * Copyright (C) 2009 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"
19bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
20bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams#include <malloc.h>
21bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams#include "rsContext.h"
22bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
23cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#include <sys/types.h>
24cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#include <sys/resource.h>
25cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#include <sched.h>
26cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#include <cutils/properties.h>
27cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#include <cutils/sched_policy.h>
28cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#include <sys/syscall.h>
29cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#include <string.h>
30cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
31bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Samsusing namespace android;
32bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Samsusing namespace android::renderscript;
33bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
34cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsstatic void Shutdown(Context *rsc);
35cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsstatic void SetPriority(const Context *rsc, int32_t priority);
36cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
37bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Samsstatic RsdHalFunctions FunctionTable = {
38cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    Shutdown,
39bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    NULL,
40cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    SetPriority,
41bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    {
42bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptInit,
43bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptInvokeFunction,
44bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptInvokeRoot,
45cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        rsdScriptInvokeForEach,
46bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptInvokeInit,
47bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptSetGlobalVar,
48bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptSetGlobalBind,
49bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptSetGlobalObj,
50bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        rsdScriptDestroy
51bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    }
52bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams};
53bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
54bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
55cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
56cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsstatic void * HelperThreadProc(void *vrsc) {
57cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    Context *rsc = static_cast<Context *>(vrsc);
58cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    RsHal *dc = (RsHal *)rsc->mHal.drv;
59cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
60cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
61cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    uint32_t idx = (uint32_t)android_atomic_inc(&dc->mWorkers.mLaunchCount);
62cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
63cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    //LOGV("RS helperThread starting %p idx=%i", rsc, idx);
64cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
65cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchSignals[idx].init();
66cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mNativeThreadId[idx] = gettid();
67cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
68cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#if 0
69cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    typedef struct {uint64_t bits[1024 / 64]; } cpu_set_t;
70cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    cpu_set_t cpuset;
71cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    memset(&cpuset, 0, sizeof(cpuset));
72cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    cpuset.bits[idx / 64] |= 1ULL << (idx % 64);
73cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    int ret = syscall(241, rsc->mWorkers.mNativeThreadId[idx],
74cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams              sizeof(cpuset), &cpuset);
75cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    LOGE("SETAFFINITY ret = %i %s", ret, EGLUtils::strerror(ret));
76cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams#endif
77cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
78cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    int status = pthread_setspecific(rsc->gThreadTLSKey, rsc->mTlsStruct);
79cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    if (status) {
80cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        LOGE("pthread_setspecific %i", status);
81cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
82cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
83cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    while (!dc->mExit) {
84cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        dc->mWorkers.mLaunchSignals[idx].wait();
85cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        if (dc->mWorkers.mLaunchCallback) {
86cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams           dc->mWorkers.mLaunchCallback(dc->mWorkers.mLaunchData, idx);
87cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        }
88cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        android_atomic_dec(&dc->mWorkers.mRunningCount);
89cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        dc->mWorkers.mCompleteSignal.set();
90cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
91cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
92cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    //LOGV("RS helperThread exited %p idx=%i", rsc, idx);
93cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    return NULL;
94cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams}
95cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
96cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsvoid rsdLaunchThreads(Context *rsc, WorkerCallback_t cbk, void *data) {
97cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    RsHal *dc = (RsHal *)rsc->mHal.drv;
98cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
99cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchData = data;
100cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchCallback = cbk;
101cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount);
102cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) {
103cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        dc->mWorkers.mLaunchSignals[ct].set();
104cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
105cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    while (android_atomic_acquire_load(&dc->mWorkers.mRunningCount) != 0) {
106cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        dc->mWorkers.mCompleteSignal.wait();
107cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
108cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams}
109cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
110bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Samsbool rsdHalInit(Context *rsc, uint32_t version_major, uint32_t version_minor) {
111bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    rsc->mHal.funcs = FunctionTable;
112bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
113cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    RsHal *dc = (RsHal *)calloc(1, sizeof(RsHal));
114bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    if (!rsc->mHal.drv) {
115bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams        return false;
116bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    }
117cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    rsc->mHal.drv = dc;
118bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
119cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
120cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    int cpu = sysconf(_SC_NPROCESSORS_ONLN);
121cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    LOGV("RS Launching thread(s), reported CPU count %i", cpu);
122cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    if (cpu < 2) cpu = 0;
123cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
124cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mCount = (uint32_t)cpu;
125cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mThreadId = (pthread_t *) calloc(dc->mWorkers.mCount, sizeof(pthread_t));
126cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mNativeThreadId = (pid_t *) calloc(dc->mWorkers.mCount, sizeof(pid_t));
127cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchSignals = new Signal[dc->mWorkers.mCount];
128cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchCallback = NULL;
129cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
130cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mCompleteSignal.init();
131cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
132cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount);
133cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    android_atomic_release_store(0, &dc->mWorkers.mLaunchCount);
134cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
135cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    int status;
136cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    pthread_attr_t threadAttr;
137cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    status = pthread_attr_init(&threadAttr);
138cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    if (status) {
139cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        LOGE("Failed to init thread attribute.");
140cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        return false;
141cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
142cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
143cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    for (uint32_t ct=0; ct < dc->mWorkers.mCount; ct++) {
144cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        status = pthread_create(&dc->mWorkers.mThreadId[ct], &threadAttr, HelperThreadProc, rsc);
145cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        if (status) {
146cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams            dc->mWorkers.mCount = ct;
147cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams            LOGE("Created fewer than expected number of RS threads.");
148cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams            break;
149cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        }
150cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
151cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    while (android_atomic_acquire_load(&dc->mWorkers.mRunningCount) != 0) {
152cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        usleep(100);
153cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
154cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
155cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    pthread_attr_destroy(&threadAttr);
156bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams    return true;
157bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams}
158bad807405b2b9764372af1ad24bcfd4fb1f33d8eJason Sams
159cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
160cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsvoid SetPriority(const Context *rsc, int32_t priority) {
161cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    RsHal *dc = (RsHal *)rsc->mHal.drv;
162cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    for (uint32_t ct=0; ct < dc->mWorkers.mCount; ct++) {
163cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        setpriority(PRIO_PROCESS, dc->mWorkers.mNativeThreadId[ct], priority);
164cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
165cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams}
166cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
167cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Samsvoid Shutdown(Context *rsc) {
168cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    RsHal *dc = (RsHal *)rsc->mHal.drv;
169cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
170cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mExit = true;
171cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchData = NULL;
172cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    dc->mWorkers.mLaunchCallback = NULL;
173cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount);
174cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) {
175cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        dc->mWorkers.mLaunchSignals[ct].set();
176cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
177cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    int status;
178cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    void *res;
179cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) {
180cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams        status = pthread_join(dc->mWorkers.mThreadId[ct], &res);
181cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    }
182cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams    rsAssert(android_atomic_acquire_load(&dc->mWorkers.mRunningCount) == 0);
183cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams}
184cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
185cdfdb8f2cdf4668c476cac842212892b2505ff3fJason Sams
186