void ThreadManager::pushMessage(uint8_t destthread, MessageQueueObject* msg) {

        {
                boost::lock_guard<boost::mutex> lLock(*mMutexes[destthread]);
                mPerThreadMessageQueue[destthread]->push_back(msg);
        } // release lock now

        mCondVars[destthread]->notify_one();

}
Exemple #2
0
/*!
 * \brief Finishes initializing all previously recorded objects
 *
 * Submits internal vulkan command buffer
 */
bool rSceneBase::endInitObject() {
   if ( !vInitializingObjects ) {
      eLOG( "beginInitObject was NOT called on secene ", vName_str );
      return false;
   }

   vkEndCommandBuffer( vInitBuff_vk );

   VkSubmitInfo lInfo         = {};
   lInfo.sType                = VK_STRUCTURE_TYPE_SUBMIT_INFO;
   lInfo.pNext                = nullptr;
   lInfo.waitSemaphoreCount   = 0;
   lInfo.pWaitSemaphores      = nullptr;
   lInfo.pWaitDstStageMask    = nullptr;
   lInfo.commandBufferCount   = 1;
   lInfo.pCommandBuffers      = &vInitBuff_vk;
   lInfo.signalSemaphoreCount = 0;
   lInfo.pSignalSemaphores    = nullptr;

   auto lFence = vWorldPtr->createFence();

   VkResult lRes;

   {
      std::lock_guard<std::mutex> lLock( vWorldPtr->getInitPtr()->getQueueMutex( vInitQueue_vk ) );
      lRes = vkQueueSubmit( vInitQueue_vk, 1, &lInfo, lFence );
   }

   if ( lRes ) {
      eLOG( "'vkQueueSubmit' returned ", uEnum2Str::toStr( lRes ) );
      vInitObjs.clear();
      vObjectsInit_MUT.unlock();
      return false;
   }

   lRes = vkWaitForFences( vWorldPtr->getDevice(), 1, &lFence, VK_TRUE, UINT64_MAX );
   if ( lRes ) {
      eLOG( "'vkQueueSubmit' returned ", uEnum2Str::toStr( lRes ) );
   }

   for ( auto &i : vInitObjs )
      i->finishData();

   vkDestroyFence( vWorldPtr->getDevice(), lFence, nullptr );
   vkFreeCommandBuffers( vWorldPtr->getDevice(), vInitPool_vk, 1, &vInitBuff_vk );

   vInitObjs.clear();
   vInitializingObjects = false;
   vObjectsInit_MUT.unlock();
   return true;
}
		long detachStepping(bool & pDetached)
		{
			MVTestsPortability::MutexP lLock(&mSteppingL);
			long const lResult = mStep;
			if (pDetached)
				return lResult;
			pDetached = true;
			mStepCntReset--;
			if (0 == --mStepCnt)
			{
				InterlockedIncrement(&mStep);
				mStepCnt = mStepCntReset;
			}
			return lResult;
		}
		void nextStep(long pWaitForStep = -1)
		{
			long lWaitForStep = pWaitForStep;
			{
				MVTestsPortability::MutexP lLock(&mSteppingL);
				if (0 == --mStepCnt)
				{
					InterlockedIncrement(&mStep);
					mStepCnt = mStepCntReset;
				}
				else
					lWaitForStep = mStep;
			}
			while (mStep <= lWaitForStep)
				MVTestsPortability::threadSleep(100);
		}
MessageQueueObject* ThreadManager::getNextMessage(bool block, uint8_t thisID) {

        MessageQueueObject* lRetVal = NULL;
        std::vector<MessageQueueObject*>::iterator lIter;

        boost::unique_lock<boost::mutex> lLock(*mMutexes[thisID]); // we only block here if somebody's sending our queue a message, and then not long.
        if(mPerThreadMessageQueue[thisID]->size() != 0) {
                lRetVal = mPerThreadMessageQueue[thisID]->front();
                lIter = mPerThreadMessageQueue[thisID]->begin();
                mPerThreadMessageQueue[thisID]->erase(lIter);
                return(lRetVal); // should release lock as it goes out of scope
        } else if(block) {
                while(mPerThreadMessageQueue[thisID]->size() == 0) {
                        mCondVars[thisID]->wait(lLock);
                }
                lRetVal = mPerThreadMessageQueue[thisID]->front();
                lIter = mPerThreadMessageQueue[thisID]->begin();
                mPerThreadMessageQueue[thisID]->erase(lIter);
                return(lRetVal);
        } else { // nothing to get, we're not waiting -- i.e. render thread
        return(NULL);
        }

}
Exemple #6
0
/** This is a main run cycle thread entry point
**/
void threadRunCycle( void * i_args)
{
   AFINFO("ThreadRun::run:")
   ThreadArgs * a = (ThreadArgs*)i_args;

while( AFRunning)
{
#ifdef _DEBUG
printf("...................................\n");
#endif
/**/
   {
//
// Lock containers:
//
AFINFO("ThreadRun::run: Locking containers...")
      AfContainerLock jLock( a->jobs,     AfContainerLock::WRITELOCK);
      AfContainerLock lLock( a->renders,  AfContainerLock::WRITELOCK);
      AfContainerLock mlock( a->monitors, AfContainerLock::WRITELOCK);
      AfContainerLock tlock( a->talks,    AfContainerLock::WRITELOCK);
      AfContainerLock ulock( a->users,    AfContainerLock::WRITELOCK);

//
// Messages reaction:
//
AFINFO("ThreadRun::run: React on incoming messages:")

   /*
      Process all messages in our message queue. We do it without
      waiting so that the job solving below can run just after.
      NOTE: I think this should be a waiting operation in a different
      thread. The job solving below should be put asleep using a
      semaphore and woke up when something changes. We need to avoid
      the Sleep() function below.
   */

   af::Msg *message;
   while( message = a->msgQueue->popMsg( af::AfQueue::e_no_wait) )
   {
      threadRunCycleCase( a, message );
   }

//
// Refresh data:
//
AFINFO("ThreadRun::run: Refreshing data:")
      a->talks    ->refresh( NULL,        a->monitors);
      a->monitors ->refresh( NULL,        a->monitors);
      a->jobs     ->refresh( a->renders,  a->monitors);
      a->renders  ->refresh( a->jobs,     a->monitors);
      a->users    ->refresh( NULL,        a->monitors);

//
// Jobs sloving:
//
		{
      AFINFO("ThreadRun::run: Solving jobs:")
      RenderContainerIt rendersIt( a->renders);
      std::list<int> rIds;
      {
         // ask every ready render to produce a task
         for( RenderAf *render = rendersIt.render(); render != NULL; rendersIt.next(), render = rendersIt.render())
         {
            if( render->isReady())
            {
               // store render Id if it produced a task
               if( a->users->solve( render, a->monitors))
               {
                  rIds.push_back( render->getId());
                  continue;
               }
            }
            // Render not solved, needed to update render status
            render->notSolved();
         }
      }

      // cycle on renders, which produced a task
		static const int renders_cycle_limit = 100000;
		int renders_cycle = 0;
		while( rIds.size())
		{
			renders_cycle++;
			if( renders_cycle > renders_cycle_limit )
			{
				AFERROR("Renders solve cycles limit reached.");
				break;
			}
         AFINFA("ThreadRun::run: Renders on cycle: %d", int(rIds.size()))
         std::list<int>::iterator rIt = rIds.begin();
         while( rIt != rIds.end())
         {
            RenderAf * render = rendersIt.getRender( *rIt);
            if( render->isReady())
            {
               if( a->users->solve( render, a->monitors))
               {
                  rIt++;
                  continue;
               }
            }
            // delete render id from list if it can't produce a task
            rIt = rIds.erase( rIt);
         }
      }
		}

//
// Wake-On-Lan:
//
		{
		AFINFO("ThreadRun::run: Wake-On-Lan:")
		RenderContainerIt rendersIt( a->renders);
		{
			for( RenderAf *render = rendersIt.render(); render != NULL; rendersIt.next(), render = rendersIt.render())
			{
				if( render->isWOLWakeAble())
				{
					if( a->users->solve( render, a->monitors))
					{
						render->wolWake( a->monitors, std::string("Automatic waking by a job."));
						continue;
					}
				}
			}
		}
		}

//
// Dispatch events to monitors:
//
AFINFO("ThreadRun::run: dispatching monitor events:")
      a->monitors->dispatch();

//
// Free Containers:
//
AFINFO("ThreadRun::run: deleting zombies:")
      a->talks    ->freeZombies();
      a->monitors ->freeZombies();
      a->renders  ->freeZombies();
      a->jobs     ->freeZombies();
      a->users    ->freeZombies();

   }

//
// Sleeping
//
AFINFO("ThreadRun::run: sleeping...")
   af::sleep_sec( 1);
}
}