Example #1
0
File: opq.cpp Project: tweakoz/vrx
	void* OpqThreadImpl(void* arg_opaq)
	{
		OpqThreadData* opqthreaddata = (OpqThreadData*)arg_opaq;
		OpMultiQ* popq = opqthreaddata->mpOpQ;
		std::string opqn = popq->mName;
		SetCurrentThreadName(opqn.c_str());


		static int icounter = 0;
		int thid = opqthreaddata->miThreadID + 4;
		std::string channam = ork::FormatString("opqth%d", int(thid));

		////////////////////////////////////////////////
		// main opq loop
		////////////////////////////////////////////////

		popq->mThreadsRunning.fetch_add(1);
		while (false == popq->mbOkToExit)
		{
			popq->BlockingIterate(thid);
		}
		popq->mThreadsRunning.fetch_sub(1);

		////////////////////////////////////////////////

		//printf( "popq<%p> thread exiting...\n", popq );

		return (void*)0;

	}
void ResourceResidencyQueue::CleanThreadFunc() {
	SetCurrentThreadName("CommandList Clean Thread");

	std::vector<std::unique_ptr<Task>> workingSet;
	while (m_runThreads) {
		std::unique_lock<std::mutex> lk(m_cleanMutex);
		m_cleanCv.wait(lk, [this] {return !m_runThreads || !m_cleanQueue.empty(); });

		while (!m_cleanQueue.empty()) {
			std::unique_ptr<Task> task = std::move(m_cleanQueue.front());
			workingSet.push_back(std::move(task));
			m_cleanQueue.pop();
		}
		lk.unlock();

		for (auto& task : workingSet) {
			task->syncPoint.m_fence->Wait(task->syncPoint.m_value);
			for (const MemoryObject& res : task->resources) {
				// TODO...
			}
		}

		workingSet.clear();
	}
}
Example #3
0
void BasicThread::DoRun(std::shared_ptr<Object>&& refTracker) {
  assert(m_running);

  // Make our own session current before we do anything else:
  CurrentContextPusher pusher(GetContext());

  // Set the thread name no matter what:
  if(GetName())
    SetCurrentThreadName();

  // Now we wait for the thread to be good to go:
  try {
    Run();
  }
  catch(dispatch_aborted_exception&) {
    // Okay, this is fine, a dispatcher is terminating--this is a normal way to
    // end a dispatcher loop.
  }
  catch(...) {
    try {
      // Ask that the enclosing context filter this exception, if possible:
      GetContext()->FilterException();
    }
    catch(...) {
      // Generic exception, unhandled, we can't do anything about this
    }

    // Signal shutdown on the enclosing context--cannot wait, if we wait we WILL deadlock
    GetContext()->SignalShutdown(false);
  }

  // Run loop is over, time to clean up
  DoRunLoopCleanup(pusher.Pop(), std::move(refTracker));
}
Example #4
0
DWORD __stdcall CCPUFrequencyMonitor::StaticPerCPUSamplingThread(LPVOID param)
{
	SetCurrentThreadName("CPU frequency measuring thread");

	auto* pState = reinterpret_cast<CPUSamplerState*>(param);
	pState->pOwner->PerCPUSamplingThread(pState->cpuNumber);
	return 0;
}
Example #5
0
DWORD __stdcall CCPUFrequencyMonitor::StaticMonitorThread(LPVOID param)
{
	SetCurrentThreadName("CPU frequency monitor thread");

	auto* pThis = reinterpret_cast<CCPUFrequencyMonitor*>(param);
	pThis->MonitorThread();
	return 0;
}
Example #6
0
DWORD __stdcall CWorkingSetMonitor::StaticWSMonitorThread(LPVOID param)
{
	SetCurrentThreadName("Working set monitor thread");

	CWorkingSetMonitor* pThis = reinterpret_cast<CWorkingSetMonitor*>(param);
	pThis->WSMonitorThread();
	return 0;
}
Example #7
0
DWORD WINAPI Thread::entryPoint(LPVOID param) {
	
	SetCurrentThreadName(((Thread*)param)->threadName);
	
	CrashHandler::registerThreadCrashHandlers();
	((Thread*)param)->run();
	CrashHandler::unregisterThreadCrashHandlers();
	return 0;
}
Example #8
0
    void Thread::thread_func(void* arg)
    {
        Thread* thread = (Thread*)arg;
        ThreadTask* task = thread->_task;
        
        task->_stopRequested = false;
        SetCurrentThreadName(task->ToString());

        try
        {
            task->Run();
        }
        catch (const Exception& e)
        {
            CoreLib::OnUnhandledException(e, task->ToString());
        }
        catch (...)
        {
            Xli::Exception e("An unsupported C++ exception was thrown");
            CoreLib::OnUnhandledException(e, task->ToString());
        }

        thread->_state = ThreadStateStopped;
    }
Example #9
0
DWORD workerThreadMain(LPVOID pData)
{
    THREAD_DATA *pThreadData = (THREAD_DATA*)pData;
    SWR_CONTEXT *pContext = pThreadData->pContext;
    uint32_t threadId = pThreadData->threadId;
    uint32_t workerId = pThreadData->workerId;

    bindThread(pContext, threadId, pThreadData->procGroupId, pThreadData->forceBindProcGroup);

    {
        char threadName[64];
        sprintf_s(threadName,
#if defined(_WIN32)
                  "SWRWorker_%02d_NUMA%d_Core%02d_T%d",
#else
                  // linux pthread name limited to 16 chars (including \0)
                  "w%03d-n%d-c%03d-t%d",
#endif
            workerId, pThreadData->numaId, pThreadData->coreId, pThreadData->htId);
        SetCurrentThreadName(threadName);
    }

    RDTSC_INIT(threadId);

    // Only need offset numa index from base for correct masking
    uint32_t numaNode = pThreadData->numaId - pContext->threadInfo.BASE_NUMA_NODE;
    uint32_t numaMask = pContext->threadPool.numaMask;

    // flush denormals to 0
    _mm_setcsr(_mm_getcsr() | _MM_FLUSH_ZERO_ON | _MM_DENORMALS_ZERO_ON);

    // Track tiles locked by other threads. If we try to lock a macrotile and find its already
    // locked then we'll add it to this list so that we don't try and lock it again.
    TileSet lockedTiles;

    // each worker has the ability to work on any of the queued draws as long as certain
    // conditions are met. the data associated
    // with a draw is guaranteed to be active as long as a worker hasn't signaled that he 
    // has moved on to the next draw when he determines there is no more work to do. The api
    // thread will not increment the head of the dc ring until all workers have moved past the
    // current head.
    // the logic to determine what to work on is:
    // 1- try to work on the FE any draw that is queued. For now there are no dependencies
    //    on the FE work, so any worker can grab any FE and process in parallel.  Eventually
    //    we'll need dependency tracking to force serialization on FEs.  The worker will try
    //    to pick an FE by atomically incrementing a counter in the swr context.  he'll keep
    //    trying until he reaches the tail.
    // 2- BE work must be done in strict order. we accomplish this today by pulling work off
    //    the oldest draw (ie the head) of the dcRing. the worker can determine if there is
    //    any work left by comparing the total # of binned work items and the total # of completed
    //    work items. If they are equal, then there is no more work to do for this draw, and
    //    the worker can safely increment its oldestDraw counter and move on to the next draw.
    std::unique_lock<std::mutex> lock(pContext->WaitLock, std::defer_lock);

    auto threadHasWork = [&](uint32_t curDraw) { return curDraw != pContext->dcRing.GetHead(); };

    uint32_t curDrawBE = 0;
    uint32_t curDrawFE = 0;

    bool bShutdown = false;

    while (true)
    {
        if (bShutdown && !threadHasWork(curDrawBE))
        {
            break;
        }

        uint32_t loop = 0;
        while (loop++ < KNOB_WORKER_SPIN_LOOP_COUNT && !threadHasWork(curDrawBE))
        {
            _mm_pause();
        }

        if (!threadHasWork(curDrawBE))
        {
            lock.lock();

            // check for thread idle condition again under lock
            if (threadHasWork(curDrawBE))
            {
                lock.unlock();
                continue;
            }

            pContext->FifosNotEmpty.wait(lock);
            lock.unlock();
        }

        if (IsBEThread)
        {
            RDTSC_BEGIN(WorkerWorkOnFifoBE, 0);
            bShutdown |= WorkOnFifoBE(pContext, workerId, curDrawBE, lockedTiles, numaNode, numaMask);
            RDTSC_END(WorkerWorkOnFifoBE, 0);

            WorkOnCompute(pContext, workerId, curDrawBE);
        }

        if (IsFEThread)
        {
            WorkOnFifoFE(pContext, workerId, curDrawFE);

            if (!IsBEThread)
            {
                curDrawBE = curDrawFE;
            }
        }
    }

    return 0;
}
Example #10
0
void UpdateThread::run() // virtual
{
	SetCurrentThreadName( "UpdateRunLoop" );

	ork::Timer timr;
	timr.Start();
	int icounter = 0;

	OpqTest opqtest(&UpdateSerialOpQ());

	while( false==mbEXITING )
	{	icounter++;
		float fsecs = timr.SecsSinceStart();
		if( fsecs > 10.0f )
		{
			printf( "ups<%f>\n", float(icounter)/fsecs );
			timr.Start();
			icounter=0;
		}
		////////////////////////////////////////////////
		// process serial update opQ 
		////////////////////////////////////////////////
		while(UpdateSerialOpQ().Process());
		////////////////////////////////////////////////
		// update scene
		////////////////////////////////////////////////
		switch( gUpdateStatus.meStatus )
		{
			case EUPD_START:
				mpVP->NotInDrawSync();
				gUpdateStatus.SetState(EUPD_RUNNING);
				break;
			case EUPD_RUNNING:
			{
				//ork::PerfMarkerPush( "ork.begin_update" );
				ent::DrawableBuffer* dbuf = ork::ent::DrawableBuffer::LockWriteBuffer(7);
				{
					OrkAssert(dbuf);

					auto psi = (ent::SceneInst*) mpVP->GetSceneInst();
					if( psi )
					{
						auto cmci = psi->GetCMCI();
						float frame_rate = cmci ? cmci->GetCurrentFrameRate() : 0.0f;
						bool externally_fixed_rate = (frame_rate!=0.0f);

						if( externally_fixed_rate )
						{
							RenderSyncToken syntok;
							if( DrawableBuffer::mOfflineUpdateSynchro.try_pop(syntok) )
							{
								syntok.mFrameIndex++;
								psi->Update();
								DrawableBuffer::mOfflineRenderSynchro.push(syntok);
							}
						}
						else
							psi->Update();
					}
					mpVP->QueueSceneInstToDb(dbuf);
				}
				ork::ent::DrawableBuffer::UnLockWriteBuffer(dbuf);
				//ork::PerfMarkerPush( "ork.end_update" );
				break;
			}
			case EUPD_STOP:
				mpVP->NotInDrawSync();
				gUpdateStatus.SetState(EUPD_STOPPED);
				break;
			case EUPD_STOPPED:
				mpVP->NotInDrawSync();
				break;
			default:
				assert(false);
				break;
		}
		////////////////////////////////////////////////
		ork::msleep(1);
	}
}
Example #11
0
void* ix_kb_thread( void* pctx )
{
	SetCurrentThreadName( "IxKeyboardThread" );

	for(int i=0; i<256; i++)
		ix_kb_state[i] = false;

	//int fd = open("/dev/input/event10", O_RDONLY );
	int fd = open("/dev/input/by-path/platform-i8042-serio-0-event-kbd", O_RDONLY );

	if( fd<0 )
		while(1) usleep(1<<20);
	
	struct input_event ev[64];
	
	std::queue<U8> byte_queue;
	while(1)
	{
		int rd = read(fd,ev,sizeof(input_event)*64);
		if( rd>0 )
		{
			U8* psrc = (U8*) ev;
			for( int i=0; i<rd; i++ )
			{
				byte_queue.push(psrc[i]);
			}
		}
		while(byte_queue.size()>=sizeof(input_event))
		{
			input_event oev;
			u8* pdest = (U8*) & oev;
			for( int i=0; i<sizeof(input_event); i++ )
			{
				pdest[i]=byte_queue.front();
				byte_queue.pop();
			}
			if( oev.type == 1 )
			{
				bool bkdown = (oev.value == 1);
				bool bkup = (oev.value == 0);
				bool bksta = (0!=oev.value);
				printf( "ev typ<%d> cod<%d> val<%d>\n", oev.type, oev.code, oev.value );

				switch(oev.code)
				{

					case 17: // w
						ix_kb_state['W'] = bksta;
						break;
					case 30: // a
						ix_kb_state['A'] = bksta;
						break;
					case 31: // s
						ix_kb_state['S'] = bksta;
						break;
					case 32: // d
						ix_kb_state['D'] = bksta;
						break;
					case 24: // o
						ix_kb_state['O'] = bksta;
						break;
					case 25: // p
						ix_kb_state['P'] = bksta;
						break;
					case 33: // f
						ix_kb_state['F'] = bksta;
						break;
					//case 105: // L
					//	ix_kb_state[ork::lev2::ETRIG_RAW_KEY_LEFT] = bksta;
					//	break;
					//case 106: // R
					//	ix_kb_state[ork::lev2::ETRIG_RAW_KEY_RIGHT] = bksta;
					//	break;
					//case 103: // U
					//	ix_kb_state[ork::lev2::ETRIG_RAW_KEY_UP] = bksta;
					//	break;
					//case 108: // D
					//	ix_kb_state[ork::lev2::ETRIG_RAW_KEY_DOWN] = bksta;
					//	break;
					//case 42: // lshift
					//	ix_kb_state[ork::lev2::ETRIG_RAW_KEY_LSHIFT] = bksta;
					//	break;
					//case 29: // lctrl
					//	ix_kb_state[ork::lev2::ETRIG_RAW_KEY_LCTRL] = bksta;
					//	break;
					//case 56: // lalt
					//	ix_kb_state[ork::lev2::ETRIG_RAW_KEY_LALT] = bksta;
					//	break;
//					case 28: // return
//						ix_kb_state[ork::lev2::ETRIG_RAW_KEY_ENTER] = bksta;
//						break;
					// 0 11
					// 9 10
					// [ 26
					default:
						break;
				}
			}
		}
//		printf( "rd<%d>\n", rd );
	}
}