1e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams/*
2803626f61526c9271a1ffb27f3e3e0bfce767f41Jason Sams * Copyright (C) 2011 The Android Open Source Project
3e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams *
4e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams * Licensed under the Apache License, Version 2.0 (the "License");
5e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams * you may not use this file except in compliance with the License.
6e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams * You may obtain a copy of the License at
7e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams *
8e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams *      http://www.apache.org/licenses/LICENSE-2.0
9e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams *
10e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams * Unless required by applicable law or agreed to in writing, software
11e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams * distributed under the License is distributed on an "AS IS" BASIS,
12e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams * See the License for the specific language governing permissions and
14e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams * limitations under the License.
15e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams */
16e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams
17e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams#include "rsdCore.h"
187e8aae7f76f221905fba7ccbcb3442c6f96dfad2Jason Sams#include "rsdAllocation.h"
19e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams#include "rsdBcc.h"
20803626f61526c9271a1ffb27f3e3e0bfce767f41Jason Sams#include "rsdGL.h"
2148f505657adba4d9156856e7d5593f23af5d5d5aJason Sams#include "rsdProgramStore.h"
22331bf9b14b1c5c1e88f5c4092b6e24fae887fb3bJason Sams#include "rsdProgramRaster.h"
234a36b45c72b91045db49c54d33fd7a05fc5a7a3dAlex Sakhartchouk#include "rsdProgramVertex.h"
244a36b45c72b91045db49c54d33fd7a05fc5a7a3dAlex Sakhartchouk#include "rsdProgramFragment.h"
254a36b45c72b91045db49c54d33fd7a05fc5a7a3dAlex Sakhartchouk#include "rsdMesh.h"
26438505431c253fd891f3deda38033c30268913e8Alex Sakhartchouk#include "rsdSampler.h"
272f6964fc89bf69c8e37f096d37c8e224d598b8f8Alex Sakhartchouk#include "rsdFrameBuffer.h"
28e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams
29e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams#include <malloc.h>
30e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams#include "rsContext.h"
31e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams
3255d2a25402319380c62a97f3f84b57e2977448d1Jason Sams#include <sys/types.h>
3355d2a25402319380c62a97f3f84b57e2977448d1Jason Sams#include <sys/resource.h>
3455d2a25402319380c62a97f3f84b57e2977448d1Jason Sams#include <sched.h>
3555d2a25402319380c62a97f3f84b57e2977448d1Jason Sams#include <cutils/properties.h>
3655d2a25402319380c62a97f3f84b57e2977448d1Jason Sams#include <cutils/sched_policy.h>
3755d2a25402319380c62a97f3f84b57e2977448d1Jason Sams#include <sys/syscall.h>
3855d2a25402319380c62a97f3f84b57e2977448d1Jason Sams#include <string.h>
3917a8a1939d4cbc74de54954c67f3dd61882420aaAlex Sakhartchouk#include <bcc/bcc.h>
4055d2a25402319380c62a97f3f84b57e2977448d1Jason Sams
41e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Samsusing namespace android;
42e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Samsusing namespace android::renderscript;
43e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams
4455d2a25402319380c62a97f3f84b57e2977448d1Jason Samsstatic void Shutdown(Context *rsc);
4555d2a25402319380c62a97f3f84b57e2977448d1Jason Samsstatic void SetPriority(const Context *rsc, int32_t priority);
461222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hinesstatic void initForEach(outer_foreach_t* forEachLaunch);
4755d2a25402319380c62a97f3f84b57e2977448d1Jason Sams
48e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Samsstatic RsdHalFunctions FunctionTable = {
49803626f61526c9271a1ffb27f3e3e0bfce767f41Jason Sams    rsdGLInit,
50803626f61526c9271a1ffb27f3e3e0bfce767f41Jason Sams    rsdGLShutdown,
51803626f61526c9271a1ffb27f3e3e0bfce767f41Jason Sams    rsdGLSetSurface,
52803626f61526c9271a1ffb27f3e3e0bfce767f41Jason Sams    rsdGLSwap,
53803626f61526c9271a1ffb27f3e3e0bfce767f41Jason Sams
5455d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    Shutdown,
55e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams    NULL,
5655d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    SetPriority,
57e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams    {
58e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams        rsdScriptInit,
59e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams        rsdScriptInvokeFunction,
60e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams        rsdScriptInvokeRoot,
6155d2a25402319380c62a97f3f84b57e2977448d1Jason Sams        rsdScriptInvokeForEach,
62e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams        rsdScriptInvokeInit,
63514f9790fdf180ca3c58e508cbd36c520fa7be08Stephen Hines        rsdScriptInvokeFreeChildren,
64e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams        rsdScriptSetGlobalVar,
65e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams        rsdScriptSetGlobalBind,
66e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams        rsdScriptSetGlobalObj,
67e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams        rsdScriptDestroy
6848f505657adba4d9156856e7d5593f23af5d5d5aJason Sams    },
6948f505657adba4d9156856e7d5593f23af5d5d5aJason Sams
707e8aae7f76f221905fba7ccbcb3442c6f96dfad2Jason Sams    {
717e8aae7f76f221905fba7ccbcb3442c6f96dfad2Jason Sams        rsdAllocationInit,
727e8aae7f76f221905fba7ccbcb3442c6f96dfad2Jason Sams        rsdAllocationDestroy,
737e8aae7f76f221905fba7ccbcb3442c6f96dfad2Jason Sams        rsdAllocationResize,
747e8aae7f76f221905fba7ccbcb3442c6f96dfad2Jason Sams        rsdAllocationSyncAll,
757e8aae7f76f221905fba7ccbcb3442c6f96dfad2Jason Sams        rsdAllocationMarkDirty,
767e8aae7f76f221905fba7ccbcb3442c6f96dfad2Jason Sams        rsdAllocationData1D,
777e8aae7f76f221905fba7ccbcb3442c6f96dfad2Jason Sams        rsdAllocationData2D,
787e8aae7f76f221905fba7ccbcb3442c6f96dfad2Jason Sams        rsdAllocationData3D,
79304b1f5497155bcf91e7b855cfab7a675e80bf26Alex Sakhartchouk        rsdAllocationData1D_alloc,
80304b1f5497155bcf91e7b855cfab7a675e80bf26Alex Sakhartchouk        rsdAllocationData2D_alloc,
81304b1f5497155bcf91e7b855cfab7a675e80bf26Alex Sakhartchouk        rsdAllocationData3D_alloc,
827e8aae7f76f221905fba7ccbcb3442c6f96dfad2Jason Sams        rsdAllocationElementData1D,
837e8aae7f76f221905fba7ccbcb3442c6f96dfad2Jason Sams        rsdAllocationElementData2D
847e8aae7f76f221905fba7ccbcb3442c6f96dfad2Jason Sams    },
857e8aae7f76f221905fba7ccbcb3442c6f96dfad2Jason Sams
8648f505657adba4d9156856e7d5593f23af5d5d5aJason Sams
8748f505657adba4d9156856e7d5593f23af5d5d5aJason Sams    {
8848f505657adba4d9156856e7d5593f23af5d5d5aJason Sams        rsdProgramStoreInit,
8948f505657adba4d9156856e7d5593f23af5d5d5aJason Sams        rsdProgramStoreSetActive,
9048f505657adba4d9156856e7d5593f23af5d5d5aJason Sams        rsdProgramStoreDestroy
91331bf9b14b1c5c1e88f5c4092b6e24fae887fb3bJason Sams    },
92331bf9b14b1c5c1e88f5c4092b6e24fae887fb3bJason Sams
93331bf9b14b1c5c1e88f5c4092b6e24fae887fb3bJason Sams    {
94331bf9b14b1c5c1e88f5c4092b6e24fae887fb3bJason Sams        rsdProgramRasterInit,
95331bf9b14b1c5c1e88f5c4092b6e24fae887fb3bJason Sams        rsdProgramRasterSetActive,
96331bf9b14b1c5c1e88f5c4092b6e24fae887fb3bJason Sams        rsdProgramRasterDestroy
974a36b45c72b91045db49c54d33fd7a05fc5a7a3dAlex Sakhartchouk    },
984a36b45c72b91045db49c54d33fd7a05fc5a7a3dAlex Sakhartchouk
994a36b45c72b91045db49c54d33fd7a05fc5a7a3dAlex Sakhartchouk    {
1004a36b45c72b91045db49c54d33fd7a05fc5a7a3dAlex Sakhartchouk        rsdProgramVertexInit,
1014a36b45c72b91045db49c54d33fd7a05fc5a7a3dAlex Sakhartchouk        rsdProgramVertexSetActive,
1024a36b45c72b91045db49c54d33fd7a05fc5a7a3dAlex Sakhartchouk        rsdProgramVertexDestroy
1034a36b45c72b91045db49c54d33fd7a05fc5a7a3dAlex Sakhartchouk    },
1044a36b45c72b91045db49c54d33fd7a05fc5a7a3dAlex Sakhartchouk
1054a36b45c72b91045db49c54d33fd7a05fc5a7a3dAlex Sakhartchouk    {
1064a36b45c72b91045db49c54d33fd7a05fc5a7a3dAlex Sakhartchouk        rsdProgramFragmentInit,
1074a36b45c72b91045db49c54d33fd7a05fc5a7a3dAlex Sakhartchouk        rsdProgramFragmentSetActive,
1084a36b45c72b91045db49c54d33fd7a05fc5a7a3dAlex Sakhartchouk        rsdProgramFragmentDestroy
1094a36b45c72b91045db49c54d33fd7a05fc5a7a3dAlex Sakhartchouk    },
1104a36b45c72b91045db49c54d33fd7a05fc5a7a3dAlex Sakhartchouk
1114a36b45c72b91045db49c54d33fd7a05fc5a7a3dAlex Sakhartchouk    {
1124a36b45c72b91045db49c54d33fd7a05fc5a7a3dAlex Sakhartchouk        rsdMeshInit,
1134a36b45c72b91045db49c54d33fd7a05fc5a7a3dAlex Sakhartchouk        rsdMeshDraw,
1144a36b45c72b91045db49c54d33fd7a05fc5a7a3dAlex Sakhartchouk        rsdMeshDestroy
115438505431c253fd891f3deda38033c30268913e8Alex Sakhartchouk    },
116438505431c253fd891f3deda38033c30268913e8Alex Sakhartchouk
117438505431c253fd891f3deda38033c30268913e8Alex Sakhartchouk    {
118438505431c253fd891f3deda38033c30268913e8Alex Sakhartchouk        rsdSamplerInit,
119438505431c253fd891f3deda38033c30268913e8Alex Sakhartchouk        rsdSamplerDestroy
120438505431c253fd891f3deda38033c30268913e8Alex Sakhartchouk    },
12148f505657adba4d9156856e7d5593f23af5d5d5aJason Sams
1222f6964fc89bf69c8e37f096d37c8e224d598b8f8Alex Sakhartchouk    {
1232f6964fc89bf69c8e37f096d37c8e224d598b8f8Alex Sakhartchouk        rsdFrameBufferInit,
1242f6964fc89bf69c8e37f096d37c8e224d598b8f8Alex Sakhartchouk        rsdFrameBufferSetActive,
1252f6964fc89bf69c8e37f096d37c8e224d598b8f8Alex Sakhartchouk        rsdFrameBufferDestroy
1262f6964fc89bf69c8e37f096d37c8e224d598b8f8Alex Sakhartchouk    },
1272f6964fc89bf69c8e37f096d37c8e224d598b8f8Alex Sakhartchouk
128e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams};
129e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams
130be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Samspthread_key_t rsdgThreadTLSKey = 0;
131be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Samsuint32_t rsdgThreadTLSKeyCount = 0;
132be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Samspthread_mutex_t rsdgInitMutex = PTHREAD_MUTEX_INITIALIZER;
133e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams
13455d2a25402319380c62a97f3f84b57e2977448d1Jason Sams
13555d2a25402319380c62a97f3f84b57e2977448d1Jason Samsstatic void * HelperThreadProc(void *vrsc) {
13655d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    Context *rsc = static_cast<Context *>(vrsc);
137fcf7231249822ff4dae852f1de1f799756689f91Jason Sams    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
13855d2a25402319380c62a97f3f84b57e2977448d1Jason Sams
13955d2a25402319380c62a97f3f84b57e2977448d1Jason Sams
14055d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    uint32_t idx = (uint32_t)android_atomic_inc(&dc->mWorkers.mLaunchCount);
14155d2a25402319380c62a97f3f84b57e2977448d1Jason Sams
14255d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    //LOGV("RS helperThread starting %p idx=%i", rsc, idx);
14355d2a25402319380c62a97f3f84b57e2977448d1Jason Sams
14455d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    dc->mWorkers.mLaunchSignals[idx].init();
14555d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    dc->mWorkers.mNativeThreadId[idx] = gettid();
14655d2a25402319380c62a97f3f84b57e2977448d1Jason Sams
147be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams    int status = pthread_setspecific(rsdgThreadTLSKey, &dc->mTlsStruct);
148be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams    if (status) {
149be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams        LOGE("pthread_setspecific %i", status);
150be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams    }
151be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams
15255d2a25402319380c62a97f3f84b57e2977448d1Jason Sams#if 0
15355d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    typedef struct {uint64_t bits[1024 / 64]; } cpu_set_t;
15455d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    cpu_set_t cpuset;
15555d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    memset(&cpuset, 0, sizeof(cpuset));
15655d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    cpuset.bits[idx / 64] |= 1ULL << (idx % 64);
15755d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    int ret = syscall(241, rsc->mWorkers.mNativeThreadId[idx],
15855d2a25402319380c62a97f3f84b57e2977448d1Jason Sams              sizeof(cpuset), &cpuset);
15955d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    LOGE("SETAFFINITY ret = %i %s", ret, EGLUtils::strerror(ret));
16055d2a25402319380c62a97f3f84b57e2977448d1Jason Sams#endif
16155d2a25402319380c62a97f3f84b57e2977448d1Jason Sams
16255d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    while (!dc->mExit) {
16355d2a25402319380c62a97f3f84b57e2977448d1Jason Sams        dc->mWorkers.mLaunchSignals[idx].wait();
16455d2a25402319380c62a97f3f84b57e2977448d1Jason Sams        if (dc->mWorkers.mLaunchCallback) {
16555d2a25402319380c62a97f3f84b57e2977448d1Jason Sams           dc->mWorkers.mLaunchCallback(dc->mWorkers.mLaunchData, idx);
16655d2a25402319380c62a97f3f84b57e2977448d1Jason Sams        }
16755d2a25402319380c62a97f3f84b57e2977448d1Jason Sams        android_atomic_dec(&dc->mWorkers.mRunningCount);
16855d2a25402319380c62a97f3f84b57e2977448d1Jason Sams        dc->mWorkers.mCompleteSignal.set();
16955d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    }
17055d2a25402319380c62a97f3f84b57e2977448d1Jason Sams
17155d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    //LOGV("RS helperThread exited %p idx=%i", rsc, idx);
17255d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    return NULL;
17355d2a25402319380c62a97f3f84b57e2977448d1Jason Sams}
17455d2a25402319380c62a97f3f84b57e2977448d1Jason Sams
17555d2a25402319380c62a97f3f84b57e2977448d1Jason Samsvoid rsdLaunchThreads(Context *rsc, WorkerCallback_t cbk, void *data) {
176fcf7231249822ff4dae852f1de1f799756689f91Jason Sams    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
17755d2a25402319380c62a97f3f84b57e2977448d1Jason Sams
17855d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    dc->mWorkers.mLaunchData = data;
17955d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    dc->mWorkers.mLaunchCallback = cbk;
18055d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount);
18155d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) {
18255d2a25402319380c62a97f3f84b57e2977448d1Jason Sams        dc->mWorkers.mLaunchSignals[ct].set();
18355d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    }
18455d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    while (android_atomic_acquire_load(&dc->mWorkers.mRunningCount) != 0) {
18555d2a25402319380c62a97f3f84b57e2977448d1Jason Sams        dc->mWorkers.mCompleteSignal.wait();
18655d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    }
18755d2a25402319380c62a97f3f84b57e2977448d1Jason Sams}
18855d2a25402319380c62a97f3f84b57e2977448d1Jason Sams
189e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Samsbool rsdHalInit(Context *rsc, uint32_t version_major, uint32_t version_minor) {
190e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams    rsc->mHal.funcs = FunctionTable;
191e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams
192fcf7231249822ff4dae852f1de1f799756689f91Jason Sams    RsdHal *dc = (RsdHal *)calloc(1, sizeof(RsdHal));
19380e29cf5c45e378bd28a1b061bb70d8ce02846aeJason Sams    if (!dc) {
19480e29cf5c45e378bd28a1b061bb70d8ce02846aeJason Sams        LOGE("Calloc for driver hal failed.");
195e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams        return false;
196e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams    }
19755d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    rsc->mHal.drv = dc;
198e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams
199be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams    pthread_mutex_lock(&rsdgInitMutex);
200be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams    if (!rsdgThreadTLSKeyCount) {
201be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams        int status = pthread_key_create(&rsdgThreadTLSKey, NULL);
202be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams        if (status) {
203be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams            LOGE("Failed to init thread tls key.");
204be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams            pthread_mutex_unlock(&rsdgInitMutex);
205be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams            return false;
206be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams        }
207be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams    }
208be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams    rsdgThreadTLSKeyCount++;
209be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams    pthread_mutex_unlock(&rsdgInitMutex);
210be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams
2111222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    initForEach(dc->mForEachLaunch);
2121222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines
213be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams    dc->mTlsStruct.mContext = rsc;
214be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams    dc->mTlsStruct.mScript = NULL;
215be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams    int status = pthread_setspecific(rsdgThreadTLSKey, &dc->mTlsStruct);
216be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams    if (status) {
217be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams        LOGE("pthread_setspecific %i", status);
218be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams    }
219be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams
22055d2a25402319380c62a97f3f84b57e2977448d1Jason Sams
22155d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    int cpu = sysconf(_SC_NPROCESSORS_ONLN);
2228410b14c85b5a0c7fcaa095b61feca96fb36d528Jason Sams    LOGV("%p Launching thread(s), CPUs %i", rsc, cpu);
22355d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    if (cpu < 2) cpu = 0;
22455d2a25402319380c62a97f3f84b57e2977448d1Jason Sams
22555d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    dc->mWorkers.mCount = (uint32_t)cpu;
22655d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    dc->mWorkers.mThreadId = (pthread_t *) calloc(dc->mWorkers.mCount, sizeof(pthread_t));
22755d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    dc->mWorkers.mNativeThreadId = (pid_t *) calloc(dc->mWorkers.mCount, sizeof(pid_t));
22855d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    dc->mWorkers.mLaunchSignals = new Signal[dc->mWorkers.mCount];
22955d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    dc->mWorkers.mLaunchCallback = NULL;
23055d2a25402319380c62a97f3f84b57e2977448d1Jason Sams
23155d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    dc->mWorkers.mCompleteSignal.init();
23255d2a25402319380c62a97f3f84b57e2977448d1Jason Sams
23355d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount);
23455d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    android_atomic_release_store(0, &dc->mWorkers.mLaunchCount);
23555d2a25402319380c62a97f3f84b57e2977448d1Jason Sams
23655d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    pthread_attr_t threadAttr;
23755d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    status = pthread_attr_init(&threadAttr);
23855d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    if (status) {
23955d2a25402319380c62a97f3f84b57e2977448d1Jason Sams        LOGE("Failed to init thread attribute.");
24055d2a25402319380c62a97f3f84b57e2977448d1Jason Sams        return false;
24155d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    }
24255d2a25402319380c62a97f3f84b57e2977448d1Jason Sams
24355d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    for (uint32_t ct=0; ct < dc->mWorkers.mCount; ct++) {
24455d2a25402319380c62a97f3f84b57e2977448d1Jason Sams        status = pthread_create(&dc->mWorkers.mThreadId[ct], &threadAttr, HelperThreadProc, rsc);
24555d2a25402319380c62a97f3f84b57e2977448d1Jason Sams        if (status) {
24655d2a25402319380c62a97f3f84b57e2977448d1Jason Sams            dc->mWorkers.mCount = ct;
24755d2a25402319380c62a97f3f84b57e2977448d1Jason Sams            LOGE("Created fewer than expected number of RS threads.");
24855d2a25402319380c62a97f3f84b57e2977448d1Jason Sams            break;
24955d2a25402319380c62a97f3f84b57e2977448d1Jason Sams        }
25055d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    }
25155d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    while (android_atomic_acquire_load(&dc->mWorkers.mRunningCount) != 0) {
25255d2a25402319380c62a97f3f84b57e2977448d1Jason Sams        usleep(100);
25355d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    }
25455d2a25402319380c62a97f3f84b57e2977448d1Jason Sams
25555d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    pthread_attr_destroy(&threadAttr);
256e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams    return true;
257e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams}
258e4a06c5fc738bf219f2a495e12a637b2d0871651Jason Sams
25955d2a25402319380c62a97f3f84b57e2977448d1Jason Sams
26055d2a25402319380c62a97f3f84b57e2977448d1Jason Samsvoid SetPriority(const Context *rsc, int32_t priority) {
261fcf7231249822ff4dae852f1de1f799756689f91Jason Sams    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
26255d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    for (uint32_t ct=0; ct < dc->mWorkers.mCount; ct++) {
26355d2a25402319380c62a97f3f84b57e2977448d1Jason Sams        setpriority(PRIO_PROCESS, dc->mWorkers.mNativeThreadId[ct], priority);
26455d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    }
26555d2a25402319380c62a97f3f84b57e2977448d1Jason Sams}
26655d2a25402319380c62a97f3f84b57e2977448d1Jason Sams
26755d2a25402319380c62a97f3f84b57e2977448d1Jason Samsvoid Shutdown(Context *rsc) {
268fcf7231249822ff4dae852f1de1f799756689f91Jason Sams    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
26955d2a25402319380c62a97f3f84b57e2977448d1Jason Sams
27055d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    dc->mExit = true;
27155d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    dc->mWorkers.mLaunchData = NULL;
27255d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    dc->mWorkers.mLaunchCallback = NULL;
27355d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    android_atomic_release_store(dc->mWorkers.mCount, &dc->mWorkers.mRunningCount);
27455d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) {
27555d2a25402319380c62a97f3f84b57e2977448d1Jason Sams        dc->mWorkers.mLaunchSignals[ct].set();
27655d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    }
27755d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    int status;
27855d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    void *res;
27955d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    for (uint32_t ct = 0; ct < dc->mWorkers.mCount; ct++) {
28055d2a25402319380c62a97f3f84b57e2977448d1Jason Sams        status = pthread_join(dc->mWorkers.mThreadId[ct], &res);
28155d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    }
28255d2a25402319380c62a97f3f84b57e2977448d1Jason Sams    rsAssert(android_atomic_acquire_load(&dc->mWorkers.mRunningCount) == 0);
283be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams
284be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams    // Global structure cleanup.
285be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams    pthread_mutex_lock(&rsdgInitMutex);
286be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams    --rsdgThreadTLSKeyCount;
287be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams    if (!rsdgThreadTLSKeyCount) {
288be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams        pthread_key_delete(rsdgThreadTLSKey);
289be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams    }
290be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams    pthread_mutex_unlock(&rsdgInitMutex);
291be8ac6ace9036262942bc8c96baa36abeb2291f3Jason Sams
29255d2a25402319380c62a97f3f84b57e2977448d1Jason Sams}
29355d2a25402319380c62a97f3f84b57e2977448d1Jason Sams
2941222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hinesstatic void rsdForEach17(const void *vRoot,
295aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams        const android::renderscript::RsForEachStubParamStruct *p,
296aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams                                uint32_t x1, uint32_t x2,
297aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams                                uint32_t instep, uint32_t outstep) {
2981222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    typedef void (*fe)(const void *, uint32_t);
2991222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    (*(fe*)vRoot)(p->in, p->y);
3001222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines}
3011222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines
3021222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hinesstatic void rsdForEach18(const void *vRoot,
303aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams        const android::renderscript::RsForEachStubParamStruct *p,
304aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams                                uint32_t x1, uint32_t x2,
305aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams                                uint32_t instep, uint32_t outstep) {
3061222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    typedef void (*fe)(void *, uint32_t);
3071222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    (*(fe*)vRoot)(p->out, p->y);
3081222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines}
3091222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines
3101222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hinesstatic void rsdForEach19(const void *vRoot,
311aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams        const android::renderscript::RsForEachStubParamStruct *p,
312aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams                                uint32_t x1, uint32_t x2,
313aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams                                uint32_t instep, uint32_t outstep) {
3141222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    typedef void (*fe)(const void *, void *, uint32_t);
3151222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    (*(fe*)vRoot)(p->in, p->out, p->y);
3161222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines}
3171222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines
3181222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hinesstatic void rsdForEach21(const void *vRoot,
319aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams        const android::renderscript::RsForEachStubParamStruct *p,
320aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams                                uint32_t x1, uint32_t x2,
321aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams                                uint32_t instep, uint32_t outstep) {
3221222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    typedef void (*fe)(const void *, const void *, uint32_t);
3231222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    (*(fe*)vRoot)(p->in, p->usr, p->y);
3241222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines}
3251222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines
3261222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hinesstatic void rsdForEach22(const void *vRoot,
327aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams        const android::renderscript::RsForEachStubParamStruct *p,
328aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams                                uint32_t x1, uint32_t x2,
329aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams                                uint32_t instep, uint32_t outstep) {
3301222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    typedef void (*fe)(void *, const void *, uint32_t);
3311222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    (*(fe*)vRoot)(p->out, p->usr, p->y);
3321222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines}
3331222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines
3341222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hinesstatic void rsdForEach23(const void *vRoot,
335aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams        const android::renderscript::RsForEachStubParamStruct *p,
336aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams                                uint32_t x1, uint32_t x2,
337aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams                                uint32_t instep, uint32_t outstep) {
3381222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    typedef void (*fe)(const void *, void *, const void *, uint32_t);
3391222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    (*(fe*)vRoot)(p->in, p->out, p->usr, p->y);
3401222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines}
3411222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines
3421222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hinesstatic void rsdForEach25(const void *vRoot,
343aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams        const android::renderscript::RsForEachStubParamStruct *p,
344aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams                                uint32_t x1, uint32_t x2,
345aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams                                uint32_t instep, uint32_t outstep) {
3461222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    typedef void (*fe)(const void *, uint32_t, uint32_t);
347aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams    const uint8_t *pin = (const uint8_t *)p->in;
348aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams    uint32_t y = p->y;
349aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams    for (uint32_t x = x1; x < x2; x++) {
350aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams        (*(fe*)vRoot)(pin, x, y);
351aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams        pin += instep;
352aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams    }
3531222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines}
3541222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines
3551222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hinesstatic void rsdForEach26(const void *vRoot,
356aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams        const android::renderscript::RsForEachStubParamStruct *p,
357aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams                                uint32_t x1, uint32_t x2,
358aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams                                uint32_t instep, uint32_t outstep) {
3591222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    typedef void (*fe)(void *, uint32_t, uint32_t);
360aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams    uint8_t *pout = (uint8_t *)p->out;
361aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams    uint32_t y = p->y;
362aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams    for (uint32_t x = x1; x < x2; x++) {
363aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams        (*(fe*)vRoot)(pout, x, y);
364aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams        pout += outstep;
365aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams    }
3661222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines}
3671222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines
3681222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hinesstatic void rsdForEach27(const void *vRoot,
369aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams        const android::renderscript::RsForEachStubParamStruct *p,
370aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams                                uint32_t x1, uint32_t x2,
371aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams                                uint32_t instep, uint32_t outstep) {
3721222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    typedef void (*fe)(const void *, void *, uint32_t, uint32_t);
373aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams    uint8_t *pout = (uint8_t *)p->out;
374aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams    const uint8_t *pin = (const uint8_t *)p->in;
375aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams    uint32_t y = p->y;
376aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams    for (uint32_t x = x1; x < x2; x++) {
377aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams        (*(fe*)vRoot)(pin, pout, x, y);
378aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams        pin += instep;
379aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams        pout += outstep;
380aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams    }
3811222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines}
3821222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines
3831222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hinesstatic void rsdForEach29(const void *vRoot,
384aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams        const android::renderscript::RsForEachStubParamStruct *p,
385aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams                                uint32_t x1, uint32_t x2,
386aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams                                uint32_t instep, uint32_t outstep) {
3871222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    typedef void (*fe)(const void *, const void *, uint32_t, uint32_t);
388aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams    const uint8_t *pin = (const uint8_t *)p->in;
389aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams    const void *usr = p->usr;
390aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams    const uint32_t y = p->y;
391aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams    for (uint32_t x = x1; x < x2; x++) {
392aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams        (*(fe*)vRoot)(pin, usr, x, y);
393aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams        pin += instep;
394aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams    }
3951222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines}
3961222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines
3971222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hinesstatic void rsdForEach30(const void *vRoot,
398aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams        const android::renderscript::RsForEachStubParamStruct *p,
399aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams                                uint32_t x1, uint32_t x2,
400aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams                                uint32_t instep, uint32_t outstep) {
4011222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    typedef void (*fe)(void *, const void *, uint32_t, uint32_t);
402aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams    uint8_t *pout = (uint8_t *)p->out;
403aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams    const void *usr = p->usr;
404aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams    const uint32_t y = p->y;
405aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams    for (uint32_t x = x1; x < x2; x++) {
406aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams        (*(fe*)vRoot)(pout, usr, x, y);
407aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams        pout += outstep;
408aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams    }
4091222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines}
4101222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines
4111222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hinesstatic void rsdForEach31(const void *vRoot,
412aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams        const android::renderscript::RsForEachStubParamStruct *p,
413aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams                                uint32_t x1, uint32_t x2,
414aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams                                uint32_t instep, uint32_t outstep) {
4151222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    typedef void (*fe)(const void *, void *, const void *, uint32_t, uint32_t);
416aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams    uint8_t *pout = (uint8_t *)p->out;
417aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams    const uint8_t *pin = (const uint8_t *)p->in;
418aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams    const void *usr = p->usr;
419aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams    const uint32_t y = p->y;
420aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams    for (uint32_t x = x1; x < x2; x++) {
421aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams        (*(fe*)vRoot)(pin, pout, usr, x, y);
422aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams        pin += instep;
423aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams        pout += outstep;
424aac24a219aca5b2b529bde931fd403d04fff9e43Jason Sams    }
4251222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines}
4261222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines
4271222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines
4281222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hinesstatic void initForEach(outer_foreach_t* forEachLaunch) {
4291222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    rsAssert(forEachLaunch);
4301222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    forEachLaunch[0x00] = NULL;
4311222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    forEachLaunch[0x01] = rsdForEach31; // in
4321222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    forEachLaunch[0x02] = rsdForEach30; //     out
4331222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    forEachLaunch[0x03] = rsdForEach31; // in, out
4341222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    forEachLaunch[0x04] = NULL;
4351222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    forEachLaunch[0x05] = rsdForEach29;  // in,      usr
4361222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    forEachLaunch[0x06] = rsdForEach30; //     out, usr
4371222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    forEachLaunch[0x07] = rsdForEach31; // in, out, usr
4381222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    forEachLaunch[0x08] = NULL;
4391222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    forEachLaunch[0x09] = rsdForEach25; // in,           x
4401222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    forEachLaunch[0x0a] = rsdForEach26; //     out,      x
4411222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    forEachLaunch[0x0b] = rsdForEach27; // in, out,      x
4421222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    forEachLaunch[0x0c] = NULL;
4431222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    forEachLaunch[0x0d] = rsdForEach29; // in,      usr, x
4441222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    forEachLaunch[0x0e] = rsdForEach30; //     out, usr, x
4451222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    forEachLaunch[0x0f] = rsdForEach31; // in, out, usr, x
4461222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    forEachLaunch[0x10] = NULL;
4471222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    forEachLaunch[0x11] = rsdForEach17; // in               y
4481222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    forEachLaunch[0x12] = rsdForEach18; //     out,         y
4491222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    forEachLaunch[0x13] = rsdForEach19; // in, out,         y
4501222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    forEachLaunch[0x14] = NULL;
4511222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    forEachLaunch[0x15] = rsdForEach21; // in,      usr,    y
4521222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    forEachLaunch[0x16] = rsdForEach22; //     out, usr,    y
4531222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    forEachLaunch[0x17] = rsdForEach23; // in, out, usr,    y
4541222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    forEachLaunch[0x18] = NULL;
4551222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    forEachLaunch[0x19] = rsdForEach25; // in,           x, y
4561222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    forEachLaunch[0x1a] = rsdForEach26; //     out,      x, y
4571222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    forEachLaunch[0x1b] = rsdForEach27; // in, out,      x, y
4581222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    forEachLaunch[0x1c] = NULL;
4591222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    forEachLaunch[0x1d] = rsdForEach29; // in,      usr, x, y
4601222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    forEachLaunch[0x1e] = rsdForEach30; //     out, usr, x, y
4611222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines    forEachLaunch[0x1f] = rsdForEach31; // in, out, usr, x, y
4621222393e357e97a2218bae8a2a41b7d8031d1171Stephen Hines}
46355d2a25402319380c62a97f3f84b57e2977448d1Jason Sams
464