void LockStepTaskScheduler4ThreadsLocalCore::dispatchTaskMainLoop(const size_t localThreadID, const size_t globalThreadID) { while (true) { bool dispatch = dispatchTask(localThreadID,globalThreadID); if (dispatch == true) break; } }
void LockStepTaskScheduler::dispatchTaskMainLoop(const size_t threadID, const size_t numThreads) { while (true) { bool dispatch = dispatchTask(threadID,numThreads); if (dispatch == true) break; } }
void LockStepTaskScheduler::releaseThreads(const size_t numThreads) { taskPtr = nullptr; taskPtr2 = nullptr; data = nullptr; numTasks = 0; dispatchTask(0,numThreads); }
//2.5 void YKDispatcher(TCBptr next) { /* Begins or resumes execution of the next task */ void* sp; // printString("Dispatcher\n\r"); runningTask = next; sp = next->sp; // printString("Stack: "); // printInt((int)sp); // printNewLine(); next->state = RUNNING; //YKEnterMutex(); dispatchTask(sp); //YKExitMutex(); }
/* * Remove one reference count from a task. Intended for use by the * GPU dispatcher, to remove reference counts when CUDA events are * resolved. Must be done here to make it thread safe. */ void PxTaskMgr::decrReference( PxTaskID taskID ) { LOCK(); #if DOT_LOG debugGraphEdge(currentTask, 0, 0, mTaskTable[ taskID ].mTask, 0, 0, 1); #endif if( !shdfnd::atomicDecrement( &mTaskTable[ taskID ].mRefCount ) ) { if( dispatchTask( taskID, false ) ) { mGpuDispatcher->finishGroup(); } } }
/* * A task has completed, decrement all dependencies and submit tasks * that are ready to run. Signal simulation end if ther are no more * pending tasks. */ bool PxTaskMgr::resolveRow( PxTaskID taskID, bool gpuGroupStart ) { int depRow = mTaskTable[ taskID ].mStartDep; uint32_t streamIndex = 0; bool syncRequired = false; if( mTaskTable[ taskID ].mTask ) { streamIndex = mTaskTable[ taskID ].mTask->mStreamIndex; } while( depRow != EOL ) { PxTaskDepTableRow& row = mDepTable[ uint32_t(depRow) ]; PxTaskTableRow& dtt = mTaskTable[ row.mTaskID ]; // pass stream index to (up to one) dependent GPU task if( dtt.mTask && dtt.mType == PxTaskType::TT_GPU && streamIndex ) { if( dtt.mTask->mStreamIndex ) { PX_ASSERT( dtt.mTask->mStreamIndex != streamIndex ); dtt.mTask->mPreSyncRequired = true; } else if( syncRequired ) { dtt.mTask->mPreSyncRequired = true; } else { dtt.mTask->mStreamIndex = streamIndex; /* only one forward task gets to use this stream */ syncRequired = true; } } if( !shdfnd::atomicDecrement( &dtt.mRefCount ) ) { gpuGroupStart |= dispatchTask( row.mTaskID, gpuGroupStart ); } depRow = row.mNextDep; } shdfnd::atomicDecrement( &mPendingTasks ); return gpuGroupStart; }
/* * Called by the owner (Scene) to start simulating the task graph. * Dispatch all tasks with refCount == 1 */ void PxTaskMgr::startSimulation() { PX_ASSERT( mCpuDispatcher ); if( mGpuDispatcher ) { mGpuDispatcher->startSimulation(); } /* Handle empty task graph */ if( mPendingTasks == 0 ) { return; } bool gpuDispatch = false; for( PxTaskID i = 0 ; i < mTaskTable.size() ; i++ ) { if( mTaskTable[ i ].mType == PxTaskType::TT_COMPLETED ) { continue; } if( !shdfnd::atomicDecrement( &mTaskTable[ i ].mRefCount ) ) { mStartDispatch.pushBack(i); } } for( uint32_t i=0; i<mStartDispatch.size(); ++i) { gpuDispatch |= dispatchTask( mStartDispatch[i], gpuDispatch ); } //mStartDispatch.resize(0); mStartDispatch.forceSize_Unsafe(0); if( mGpuDispatcher && gpuDispatch ) { mGpuDispatcher->finishGroup(); } }
void LockStepTaskScheduler4ThreadsLocalCore::releaseThreads(const size_t localThreadID, const size_t globalThreadID) { taskPtr = nullptr; data = nullptr; dispatchTask(localThreadID,globalThreadID); }
void LockStepTaskScheduler::releaseThreads(const size_t numThreads) { taskPtr = NULL; data = NULL; dispatchTask(0,numThreads); }