void Ext::DefaultCpuDispatcher::submitTask(PxBaseTask& task)
{
	if(!mNumThreads)
	{
		// no worker threads, run directly
		task.runProfiled();
		task.release();
		return;
	}

	Ps::Thread::Id currentThread = Ps::Thread::getId();

	// TODO: Could use TLS to make this more efficient
	for(PxU32 i = 0; i < mNumThreads; ++i)
	{
		if(mWorkerThreads[i].tryAcceptJobToLocalQueue(task, currentThread))
			return mWorkReady.set();
	}

	SharedQueueEntry* entry = mQueueEntryPool.getEntry(&task);
	if (entry)
	{
		mJobList.push(*entry);
		mWorkReady.set();
	}
}
void Ext::CpuWorkerThread::execute()
{
	mThreadId = getId();

	while (!quitIsSignalled())
    {
        mOwner->resetWakeSignal();

		PxBaseTask* task = TaskQueueHelper::fetchTask(mLocalJobList, mQueueEntryPool);

		if(!task)
			task = mOwner->fetchNextTask();
		
		if (task)
		{
			mOwner->runTask(*task);
			task->release();
		}
		else
		{
			mOwner->waitForWork();
		}
	}

	quit();
}
void CpuWorkerThread::execute()
{
	mThreadId = getId();

	while (!quitIsSignalled())
	{
		mOwner->resetWakeSignal();

		PxBaseTask* task = TaskQueueHelper::fetchTask(mLocalJobList, mQueueEntryPool);

		if (!task)
		{
			task = mOwner->getJob();
		}

		if (!task)
		{
			task = mOwner->stealJob();
		}

		if (task)
		{
#if PHYSX_PROFILE_SDK
			if (mPvdBinding!=NULL)
			{
				task->runProfiled();
			}
			else
			{
				task->run();
			}
#else
			task->run();
#endif
			task->release();
		}
		else
		{
			mOwner->waitForWork();
		}
	}

	quit();
};
void FPhysXCPUDispatcherSingleThread::submitTask( PxBaseTask& Task ) 
{
	SCOPE_CYCLE_COUNTER(STAT_PhysXSingleThread);
	check(IsInGameThread());

	TaskStack.Push(&Task);
	if (TaskStack.Num() > 1)
	{
		return;
	}
	Task.run();
	Task.release();
	while (TaskStack.Num() > 1)
	{
		PxBaseTask& ChildTask = *TaskStack.Pop();
		ChildTask.run();
		ChildTask.release();
	}
	verify(&Task == TaskStack.Pop() && !TaskStack.Num());
}