void TaskProcessor::processTilesOfWork()

in renderscript-toolkit/src/main/cpp/TaskProcessor.cpp [130:178]


void TaskProcessor::processTilesOfWork(int threadIndex, bool returnWhenNoWork) {
    if (threadIndex != 0) {
        // Set the name of the thread, except for thread 0, which is not part of the pool.
        // PR_SET_NAME takes a maximum of 16 characters, including the terminating null.
        char name[16]{"RenderScToolkit"};
        prctl(PR_SET_NAME, name, 0, 0, 0);
        // ALOGI("Starting thread%d", threadIndex);
    }

    std::unique_lock<std::mutex> lock(mQueueMutex);
    while (true) {
        mWorkAvailableOrStop.wait(lock, [this, returnWhenNoWork]() /*REQUIRES(mQueueMutex)*/ {
            return mStopThreads || (mTilesNotYetStarted > 0) ||
                   (returnWhenNoWork && (mTilesNotYetStarted == 0));
        });
        // ALOGI("Woke thread%d", threadIndex);

        // This ScopedLockAssertion is to help the compiler when it checks thread annotations
        // to realize that we have the lock. It's however not completely true; we don't
        // hold the lock while processing the tile.
        // TODO Figure out how to fix that.
        // android::base::ScopedLockAssertion lockAssert(mQueueMutex);
        if (mStopThreads || (returnWhenNoWork && mTilesNotYetStarted == 0)) {
            break;
        }

        while (mTilesNotYetStarted > 0 && !mStopThreads) {
            // This picks the tiles in decreasing order but that does not matter.
            int myTile = --mTilesNotYetStarted;
            mTilesInProcess++;
            lock.unlock();
            {
                // We won't be executing this code unless the main thread is
                // holding the mTaskMutex lock, which guards mCurrentTask.
                // The compiler can't figure this out.
                // android::base::ScopedLockAssertion lockAssert(mTaskMutex);
                mCurrentTask->processTile(threadIndex, myTile);
            }
            lock.lock();
            mTilesInProcess--;
            if (mTilesInProcess == 0 && mTilesNotYetStarted == 0) {
                mWorkIsFinished.notify_one();
            }
        }
    }
    // if (threadIndex != 0) {
    //     ALOGI("Ending thread%d", threadIndex);
    // }
}