Ejemplo n.º 1
0
void PixelPipeline::worker_main(int core)
{
#if defined(WIN32) && defined(PROFILE_PIPELINE)
	SetThreadIdealProcessor(GetCurrentThread(), core);
	SetThreadAffinityMask(GetCurrentThread(), 1 << core);
	unsigned __int64 ticks_waiting = 0;
	unsigned __int64 ticks_working = 0;
#endif
	PixelThreadContext context(core, active_cores);
	while (true)
	{
#if defined(WIN32) && defined(PROFILE_PIPELINE)
		unsigned __int64 wait_start_time = __rdtsc();
#endif
		int wakeup_reason = Event::wait(event_more_commands[core], event_stop);
		if (wakeup_reason != 0)
			break;
		event_more_commands[core].reset();
#if defined(WIN32) && defined(PROFILE_PIPELINE)
		unsigned __int64 wait_end_time = __rdtsc();
		ticks_waiting += wait_end_time-wait_start_time;
#endif
		process_commands(&context);
#if defined(WIN32) && defined(PROFILE_PIPELINE)
		unsigned __int64 commands_end_time = __rdtsc();
		ticks_working += commands_end_time-wait_end_time;
#endif
	}
#if defined(WIN32) && defined(PROFILE_PIPELINE)
	MessageBoxA(
		0,
		cl_format("Pipeline core %1 spent %2 percent of its time waiting for commands",
		core,
		(int)(ticks_waiting*100/(ticks_working+ticks_waiting))).c_str(),
		"DEBUG", MB_OK);
#endif
}
Ejemplo n.º 2
0
  /*! set the affinity of a given thread */
  void setAffinity(HANDLE thread, ssize_t affinity)
  {
#if (_WIN32_WINNT >= 0x0601) // FIXME: use getProcAddress to activate this feature only if supported by Windows
    int groups = GetActiveProcessorGroupCount();
    int totalProcessors = 0, group = 0, number = 0;
    for (int i = 0; i<groups; i++) {
      int processors = GetActiveProcessorCount(i);
      if (totalProcessors + processors > affinity) {
        group = i;
        number = (int)affinity - totalProcessors;
        break;
      }
      totalProcessors += processors;
    }

    GROUP_AFFINITY groupAffinity;
    groupAffinity.Group = (WORD)group;
    groupAffinity.Mask = (KAFFINITY)(uint64(1) << number);
    groupAffinity.Reserved[0] = 0;
    groupAffinity.Reserved[1] = 0;
    groupAffinity.Reserved[2] = 0;
    if (!SetThreadGroupAffinity(thread, &groupAffinity, NULL))
      THROW_RUNTIME_ERROR("cannot set thread group affinity");

    PROCESSOR_NUMBER processorNumber;
    processorNumber.Group = group;
    processorNumber.Number = number;
    processorNumber.Reserved = 0;
    if (!SetThreadIdealProcessorEx(thread, &processorNumber, NULL))
      THROW_RUNTIME_ERROR("cannot set ideal processor");
#else
    if (!SetThreadAffinityMask(thread, DWORD_PTR(uint64(1) << affinity)))
      THROW_RUNTIME_ERROR("cannot set thread affinity mask");
    if (SetThreadIdealProcessor(thread, (DWORD)affinity) == (DWORD)-1)
      THROW_RUNTIME_ERROR("cannot set ideal processor");
#endif
  }
Ejemplo n.º 3
0
  /*! set the affinity of a given thread */
  void setAffinity(HANDLE thread, ssize_t affinity)
  {
#if (_WIN32_WINNT >= 0x0601)
    int groups = GetActiveProcessorGroupCount();
    int totalProcessors = 0, group = 0, number = 0;
    for (int i = 0; i<groups; i++) {
      int processors = GetActiveProcessorCount(i);
      if (totalProcessors + processors > affinity) {
        group = i;
        number = (int)affinity - totalProcessors;
        break;
      }
      totalProcessors += processors;
    }

    GROUP_AFFINITY groupAffinity;
    groupAffinity.Group = (WORD)group;
    groupAffinity.Mask = (KAFFINITY)(uint64(1) << number);
    groupAffinity.Reserved[0] = 0;
    groupAffinity.Reserved[1] = 0;
    groupAffinity.Reserved[2] = 0;
    if (!SetThreadGroupAffinity(thread, &groupAffinity, NULL))
      throw std::runtime_error("cannot set thread group affinity");

    PROCESSOR_NUMBER processorNumber;
    processorNumber.Group = group;
    processorNumber.Number = number;
    processorNumber.Reserved = 0;
    if (!SetThreadIdealProcessorEx(thread, &processorNumber, NULL))
      throw std::runtime_error("cannot set thread ideal processor");
#else
    if (!SetThreadAffinityMask(thread, DWORD_PTR(uint64(1) << affinity)))
      throw std::runtime_error("cannot set thread affinity mask");
    if (SetThreadIdealProcessor(thread, (DWORD)affinity) == (DWORD)-1)
      throw std::runtime_error("cannot set thread ideal processor");
#endif
  }
Ejemplo n.º 4
0
Application::Application(void): main_frame(),
				ec(),
				ecm(),
				fc(),
				evc(),
				evcm(),
				fcm(),
				navigator_manager(),
				graphic_factory(), 
				layer_tree(),
				plugin_map(),
				three_dimension_camera_controller(NULL),
				two_dimension_camera_controller(NULL),
				dc(NULL),
				plugin_running(false),
				srs()
{


  //for being able to load all type of images
  wxInitAllImageHandlers();

#ifdef WIN32
  //This is to activate memory-leaks detection
  _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif

  wmsInitialize();
  application_time = ApplicationTime::GetInstance();
  application_time->Off();
  cpw::IdGenerator::SetNamespace(GetMACaddress());

#ifdef WIN32
  SetThreadAffinityMask(GetCurrentThread(), 0);
#endif

}
Ejemplo n.º 5
0
vm_status vm_affinity_thread_get(vm_thread *pthr, vm_affinity_mask *mptr)
{
    DWORD processmask = 0;

    if(!mptr)
        return VM_NULL_PTR;

    if(mptr[0].msklen)
    {
        /* only one way to obtain thread affinity mask - set it again */
        if (pthr[0].preset_affinity_mask)
        {
            mptr[0].mskbits[0] = (unsigned long)SetThreadAffinityMask(pthr[0].handle, pthr[0].preset_affinity_mask);
            return VM_OK;
        }
        else
        {
            if(GetProcessAffinityMask(pthr[0].handle, (PDWORD_PTR)&processmask, (PDWORD_PTR)mptr[0].mskbits))
                return VM_OK;
        }
    }

    return VM_OPERATION_FAILED;
}
Ejemplo n.º 6
0
/*
==============
Sys_StartAsyncThread

Start the thread that will call idCommon::Async()
==============
*/
void Sys_StartAsyncThread(void)
{
	// create an auto-reset event that happens 60 times a second
	hTimer = CreateWaitableTimer(NULL, false, NULL);

	if (!hTimer) {
		common->Error("idPacketServer::Spawn: CreateWaitableTimer failed");
	}

	LARGE_INTEGER	t;
	t.HighPart = t.LowPart = 0;
	SetWaitableTimer(hTimer, &t, USERCMD_MSEC, NULL, NULL, TRUE);

	Sys_CreateThread((xthread_t)Sys_AsyncThread, NULL, THREAD_ABOVE_NORMAL, threadInfo, "Async", g_threads,  &g_thread_count);

#ifdef SET_THREAD_AFFINITY
	// give the async thread an affinity for the second cpu
	SetThreadAffinityMask((HANDLE)threadInfo.threadHandle, 2);
#endif

	if (!threadInfo.threadHandle) {
		common->Error("Sys_StartAsyncThread: failed");
	}
}
Ejemplo n.º 7
0
// We don't call this directly from DLL_PROCESS_ATTACH because if we do things
// can break when we're loaded via LoadLibrary
// Instead this is called by LunaDLLInitHook, which is set up by
// SetupLunaDLLInitHook that runs from DLL_PROCESS_ATTACH
void LunaDLLInit()
{
    InitGlobals();
#if PATCHIT
    TrySkipPatch();
#endif // PATCHIT

    // Test OpenGL support
    if (!gStartupSettings.noGL && LunaDLLTestGLFeatures()) {
        g_GLEngine.Enable();
    } else {
        g_GLEngine.Disable();
    }

    // Set processor affinity for the main thread. Switching cores is bad for stable frame rate
    DWORD curProcessor = GetCurrentProcessorNumberXP();
    SetThreadAffinityMask(GetCurrentThread(), 1 << curProcessor);
    SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL);

    // Initialize GDI+ so we can make use of it
    ULONG_PTR m_gdiplusToken;   // class member
    Gdiplus::GdiplusStartupInput gdiplusStartupInput;
    Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);
}
bool CAdvThread::setAffinity()
{
#ifdef Q_OS_LINUX
    if(threadHandle != 0)
    {
        int j;
        for (j = 0; j < coreQuantity; j++)
            if(affinityData.coreMask & (1<<j))
                CPU_SET(j, &cpuset);
        pthread_setaffinity_np(threadHandle, sizeof(cpu_set_t), &cpuset);
    }
#else
    if(threadHandle != 0)
    {
        DWORD_PTR res = SetThreadAffinityMask(threadHandle, affinityData.coreMask);
        if (0 == res)
        {
         // failure
        }
    }
#endif

     affinityData.coreChanged = 0;
}
Ejemplo n.º 9
0
RakNetTimeNS RakNet::GetTimeNS( void )
{
#if defined(_PS3)
    uint64_t curTime;
    if ( initialized == false)
    {
        ticksPerSecond = _PS3_GetTicksPerSecond();
        // Use the function to get elapsed ticks, this is a macro.
        _PS3_GetElapsedTicks(curTime);
        uint64_t quotient, remainder;
        quotient=(curTime / ticksPerSecond);
        remainder=(curTime % ticksPerSecond);
        initialTime = (RakNetTimeNS) quotient*(RakNetTimeNS)1000000 + (remainder*(RakNetTimeNS)1000000 / ticksPerSecond);
        initialized = true;
    }
#elif defined(_WIN32)
    // Win32
    if ( initialized == false)
    {
        initialized = true;

#if !defined(_WIN32_WCE)
        // Save the current process
        HANDLE mProc = GetCurrentProcess();

        // Get the current Affinity
#if _MSC_VER >= 1400 && defined (_M_X64)
        GetProcessAffinityMask(mProc, (PDWORD_PTR)&mProcMask, (PDWORD_PTR)&mSysMask);
#else
        GetProcessAffinityMask(mProc, &mProcMask, &mSysMask);
#endif

        mThread = GetCurrentThread();

#endif // !defined(_WIN32_WCE)

        QueryPerformanceFrequency( &yo );
    }
    // 01/12/08 - According to the docs "The frequency cannot change while the system is running." so this shouldn't be necessary
    /*
    if (++queryCount==200)
    {
    	// Set affinity to the first core
    	SetThreadAffinityMask(mThread, 1);

    	QueryPerformanceFrequency( &yo );

    	// Reset affinity
    	SetThreadAffinityMask(mThread, mProcMask);

    	queryCount=0;
    }
    */

#elif (defined(__GNUC__)  || defined(__GCCXML__))
    if ( initialized == false)
    {
        gettimeofday( &tp, 0 );
        initialized=true;
        // I do this because otherwise RakNetTime in milliseconds won't work as it will underflow when dividing by 1000 to do the conversion
        initialTime = ( tp.tv_sec ) * (RakNetTimeNS) 1000000 + ( tp.tv_usec );
    }
#endif

#if defined(_PS3)
    // Use the function to get elapsed ticks, this is a macro.
    _PS3_GetElapsedTicks(curTime);
    uint64_t quotient, remainder;
    quotient=(curTime / ticksPerSecond);
    remainder=(curTime % ticksPerSecond);
    curTime = (RakNetTimeNS) quotient*(RakNetTimeNS)1000000 + (remainder*(RakNetTimeNS)1000000 / ticksPerSecond);
    // Subtract from initialTime so the millisecond conversion does not underflow
    return curTime - initialTime;
#elif defined(_WIN32)

    RakNetTimeNS curTime;
    static RakNetTimeNS lastQueryVal=(RakNetTimeNS)0;
//	static unsigned long lastTickCountVal = GetTickCount();

    LARGE_INTEGER PerfVal;

#if !defined(_WIN32_WCE)
    // Set affinity to the first core
    SetThreadAffinityMask(mThread, 1);
#endif // !defined(_WIN32_WCE)

    // Docs: On a multiprocessor computer, it should not matter which processor is called.
    // However, you can get different results on different processors due to bugs in the basic input/output system (BIOS) or the hardware abstraction layer (HAL). To specify processor affinity for a thread, use the SetThreadAffinityMask function.
    // Query the timer
    QueryPerformanceCounter( &PerfVal );

#if !defined(_WIN32_WCE)
    // Reset affinity
    SetThreadAffinityMask(mThread, mProcMask);
#endif // !defined(_WIN32_WCE)

    __int64 quotient, remainder;
    quotient=((PerfVal.QuadPart) / yo.QuadPart);
    remainder=((PerfVal.QuadPart) % yo.QuadPart);
    curTime = (RakNetTimeNS) quotient*(RakNetTimeNS)1000000 + (remainder*(RakNetTimeNS)1000000 / yo.QuadPart);

    // 08/26/08 - With the below workaround, the time seems to jump forward regardless.
    // Just make sure the time doesn't go backwards
    if (curTime < lastQueryVal)
        return lastQueryVal;
    lastQueryVal=curTime;

    /*
#if !defined(_WIN32_WCE)
    if (lastQueryVal==0)
    {
    	// First call
    	lastQueryVal=curTime;
    	return curTime;
    }

    // To workaround http://support.microsoft.com/kb/274323 where the timer can sometimes jump forward by hours or days
    unsigned long curTickCount = GetTickCount();
    unsigned long elapsedTickCount = curTickCount - lastTickCountVal;
    RakNetTimeNS elapsedQueryVal = curTime - lastQueryVal;
    if (elapsedQueryVal/1000 > elapsedTickCount+100)
    {
    	curTime=(RakNetTimeNS)lastQueryVal+(RakNetTimeNS)elapsedTickCount*(RakNetTimeNS)1000;
    }

    lastTickCountVal=curTickCount;
    lastQueryVal=curTime;
#endif
    */

    return curTime;

#elif (defined(__GNUC__)  || defined(__GCCXML__))
    // GCC
    RakNetTimeNS curTime;
    gettimeofday( &tp, 0 );

    curTime = ( tp.tv_sec ) * (RakNetTimeNS) 1000000 + ( tp.tv_usec );
    // Subtract from initialTime so the millisecond conversion does not underflow
    return curTime - initialTime;
#endif
}
Ejemplo n.º 10
0
void b3Win32ThreadSupport::startThreads(const Win32ThreadConstructionInfo& threadConstructionInfo)
{
	static int uniqueId = 0;
	uniqueId++;
	m_activeThreadStatus.resize(threadConstructionInfo.m_numThreads);
	m_completeHandles.resize(threadConstructionInfo.m_numThreads);

	m_maxNumTasks = threadConstructionInfo.m_numThreads;

	for (int i=0;i<threadConstructionInfo.m_numThreads;i++)
	{
		printf("starting thread %d\n",i);

		b3ThreadStatus&	threadStatus = m_activeThreadStatus[i];

		LPSECURITY_ATTRIBUTES lpThreadAttributes=NULL;
		SIZE_T dwStackSize=threadConstructionInfo.m_threadStackSize;
		LPTHREAD_START_ROUTINE lpStartAddress=&Thread_no_1;
		LPVOID lpParameter=&threadStatus;
		DWORD dwCreationFlags=0;
		LPDWORD lpThreadId=0;

		threadStatus.m_userPtr=0;

		sprintf(threadStatus.m_eventStartHandleName,"es%.8s%d%d",threadConstructionInfo.m_uniqueName,uniqueId,i);
		threadStatus.m_eventStartHandle = CreateEventA (0,false,false,threadStatus.m_eventStartHandleName);

		sprintf(threadStatus.m_eventCompletetHandleName,"ec%.8s%d%d",threadConstructionInfo.m_uniqueName,uniqueId,i);
		threadStatus.m_eventCompletetHandle = CreateEventA (0,false,false,threadStatus.m_eventCompletetHandleName);

		m_completeHandles[i] = threadStatus.m_eventCompletetHandle;

		HANDLE handle = CreateThread(lpThreadAttributes,dwStackSize,lpStartAddress,lpParameter,	dwCreationFlags,lpThreadId);
		switch(threadConstructionInfo.m_priority)
		{
		case 0:
		{
			SetThreadPriority(handle,THREAD_PRIORITY_HIGHEST);
			break;
		}
		case 1:
		{
			SetThreadPriority(handle,THREAD_PRIORITY_TIME_CRITICAL);
			break;
		}
		case 2:
		{
			SetThreadPriority(handle,THREAD_PRIORITY_BELOW_NORMAL);
			break;
		}
		
		default:
		{
			
		}

		}
		
		DWORD mask = 1;
		mask = 1<<mask;
		SetThreadAffinityMask(handle, mask);

		threadStatus.m_taskId = i;
		threadStatus.m_commandId = 0;
		threadStatus.m_status = 0;
		threadStatus.m_threadHandle = handle;
		threadStatus.m_lsMemory = threadConstructionInfo.m_lsMemoryFunc();
		threadStatus.m_userThreadFunc = threadConstructionInfo.m_userThreadFunc;

		printf("started %s thread %d with threadHandle %p\n",threadConstructionInfo.m_uniqueName,i,handle);
		
	}

}
Ejemplo n.º 11
0
int wthread_set_affinity_mask( wthread_t h, 
                               CPU_AFFINITY_SET* dwThreadAffinityMask)
{
    return (int) SetThreadAffinityMask( ((threadContext*) h)->mThread, 
                                        (DWORD_PTR) dwThreadAffinityMask );
}
Ejemplo n.º 12
0
void Thread::setCurrentThreadAffinityMask (const uint32 affinityMask)
{
    SetThreadAffinityMask (GetCurrentThread(), affinityMask);
}
Ejemplo n.º 13
0
void jsInit()
{
#ifdef DEBUG_OUTPUT
	g_pDebugLog = fopen("JS_DEBUG.log", "w");
#endif 

	//find number of cores
	SYSTEM_INFO sysInfo = { 0 };
	GetSystemInfo(&sysInfo);
	g_numProcessors = sysInfo.dwNumberOfProcessors;


	//spawn fibers
	for (int i = 0; i < NUM_FIBERS; ++i)
	{
		g_fibers[i].fiber = CreateFiber(FIBER_STACK_SIZE, fiberRoutine, g_fibers + i);
		g_fibers[i].pNextInWaitList = NULL;
		g_fibers[i].status = UNUSED;
		g_pFiberPool[NUM_FIBERS - 1 - i] = g_fibers + i;
	}


	//init waiting fibers
	memset(g_waitingFibers, 0, sizeof(g_waitingFibers));
	g_waitingFiberHead = 0;
	g_waitListTail.pFiber = NULL;
	g_waitListTail.pNextWaitingFiber = NULL;
	g_waitListTail.time = 0;

	//get performance frequency
	QueryPerformanceFrequency((LARGE_INTEGER*)&g_performanceFrequency);

	//init jobs
	for (int i = 2; i < MAX_JOBS; ++i)
	{
		g_jobs[i - 1].pNextJob = g_jobs + i;
	}
	g_pFreeJob = g_jobs + 1;
	g_pJobQueueHead = g_jobs;
	g_dummyJob.threadId = 0x0;
	g_dummyJob.pNextJob = g_pJobQueueHead;
	g_dummyJob.pName = "__dummy";

	//spawn threads
	g_threadData = TlsAlloc();

	for (int i = 0; i < g_numProcessors; ++i)
	{
		//create thread
		if (i == 0)
		{
			g_threads[0].handle = GetCurrentThread();
		}
		else
		{
			g_threads[i].handle = CreateThread(NULL, 0, threadStart, g_threads + i, 0, NULL);
		}

		g_threads[i].id = 0x1 << i;
		g_threads[i].ppJobQueueTail = &(g_dummyJob.pNextJob);



		//lock thread to specific cpu
		SetThreadAffinityMask(g_threads[i].handle, 1 << i);
	}
	TlsSetValue(g_threadData, g_threads + 0);

	initCounterAllocator();

#ifdef DEBUG_OUTPUT
	fprintf(g_pDebugLog, "%lld \t jobsystem started\n", time(NULL));
#endif

}
Ejemplo n.º 14
0
	bool MScheduler::Init( uint32 numThreads )
	{
		static const uint32 cProcessors = GetCPUThreadCount();
		AX_ASSERT( cProcessors > 0 );

		const uint32 cDesiredThreads = numThreads > 0 ? numThreads : cProcessors;
		const uint32 cThreads = cDesiredThreads >= kMaxWorkers ? kMaxWorkers : cDesiredThreads;

		for( uint32 i = 0; i < cThreads; ++i ) {
#ifdef _MSC_VER
# pragma warning( push )
# pragma warning( disable:4316 ) //object allocated on the heap may not be aligned 64
#endif
			m_pWorkers[ i ] = new LWorker( *this, i );
#ifdef _MSC_VER
# pragma warning( pop )
#endif
			if( !AX_VERIFY_NOT_NULL( m_pWorkers[ i ] ) ) {
				while( i > 0 ) {
					delete m_pWorkers[ i - 1 ];
					--i;
				}

				return false;
			}
		}

#ifdef _WIN32
		// Peg the main thread to one specific processor core for QueryPerformanceCounter() improvement
		SetThreadAffinityMask( GetCurrentThread(), 1<<0 );
#endif

		m_pThreads[ 0 ] = nullptr;
		for( uint32 i = 1; i < cThreads; ++i ) {
			m_pThreads[ i ] = new LWorkerThread( *m_pWorkers[ i ] );
			if( !AX_VERIFY_NOT_NULL( m_pThreads[ i ] ) ) {
				while( i > 0 ) {
					delete m_pThreads[ i - 1 ];
					--i;
				}

				for( i = 0; i < cThreads; ++i ) {
					delete m_pWorkers[ i ];
				}

				return false;
			}

#if AX_THREAD_MODEL == AX_THREAD_MODEL_WINDOWS
			const HANDLE hThread = m_pThreads[ i ]->GetNative_MSWin();
			SetThreadAffinityMask( hThread, DWORD_PTR( 1 )<<i );
#endif
		}

		m_cWorkers = cThreads;

		m_cSleepingWorkers = 0;
		m_bIsQuitting = false;
		m_cFrameChains = 0;
		m_cFrameTasks = 0;
#if !AX_ASYNC_LOCAL_WORK_ENABLED
		m_cSubmittedChains = 0;
#endif
#if !AX_ASYNC_PER_WORKER_IDLE_FLAG_ENABLED
		m_cIdleWorkers = m_cWorkers;
#endif

		AX_MEMORY_BARRIER(); //must be set before threads start (this is just paranoia)

		for( uint32 i = 1; i < cThreads; ++i ) {
			m_pThreads[ i ]->Start();
		}

		return true;
	}
Ejemplo n.º 15
0
void JUCE_CALLTYPE Thread::setCurrentThreadAffinityMask (const uint32 affinityMask)
{
    SetThreadAffinityMask (GetCurrentThread(), affinityMask);
}
Ejemplo n.º 16
0
Archivo: main.cpp Proyecto: CCJY/coliru
DWORD get_affinity() {
  DWORD mask = SetThreadAffinityMask(GetCurrentThread(), 1);
  SetThreadAffinityMask(GetCurrentThread(), mask);
  return mask != 0 ? mask : -1;
}
Ejemplo n.º 17
0
/*
==================
WinMain
==================
*/
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) {

	const HCURSOR hcurSave = ::SetCursor( LoadCursor( 0, IDC_WAIT ) );

	Sys_SetPhysicalWorkMemory( 192 << 20, 1024 << 20 );

	Sys_GetCurrentMemoryStatus( exeLaunchMemoryStats );

#if 0
    DWORD handler = (DWORD)_except_handler;
    __asm
    {                           // Build EXCEPTION_REGISTRATION record:
        push    handler         // Address of handler function
        push    FS:[0]          // Address of previous handler
        mov     FS:[0],ESP      // Install new EXECEPTION_REGISTRATION
    }
#endif

	win32.hInstance = hInstance;
	idStr::Copynz( sys_cmdline, lpCmdLine, sizeof( sys_cmdline ) );

	// done before Com/Sys_Init since we need this for error output
	Sys_CreateConsole();

	// no abort/retry/fail errors
	SetErrorMode( SEM_FAILCRITICALERRORS );

	for ( int i = 0; i < MAX_CRITICAL_SECTIONS; i++ ) {
		InitializeCriticalSection( &win32.criticalSections[i] );
	}

	// make sure the timer is high precision, otherwise
	// NT gets 18ms resolution
	timeBeginPeriod( 1 );

	// get the initial time base
	Sys_Milliseconds();

#ifdef DEBUG
	// disable the painfully slow MS heap check every 1024 allocs
	_CrtSetDbgFlag( 0 );
#endif

//	Sys_FPU_EnableExceptions( TEST_FPU_EXCEPTIONS );
	Sys_FPU_SetPrecision( FPU_PRECISION_DOUBLE_EXTENDED );

	common->Init( 0, NULL, lpCmdLine );

#if TEST_FPU_EXCEPTIONS != 0
	common->Printf( Sys_FPU_GetState() );
#endif

	if ( win32.win_notaskkeys.GetInteger() ) {
		DisableTaskKeys( TRUE, FALSE, /*( win32.win_notaskkeys.GetInteger() == 2 )*/ FALSE );
	}

	// hide or show the early console as necessary
	if ( win32.win_viewlog.GetInteger() ) {
		Sys_ShowConsole( 1, true );
	} else {
		Sys_ShowConsole( 0, false );
	}

#ifdef SET_THREAD_AFFINITY 
	// give the main thread an affinity for the first cpu
	SetThreadAffinityMask( GetCurrentThread(), 1 );
#endif

	::SetCursor( hcurSave );

	::SetFocus( win32.hWnd );

    // main game loop
	while( 1 ) {

		Win_Frame();

#ifdef DEBUG
		Sys_MemFrame();
#endif

		// set exceptions, even if some crappy syscall changes them!
		Sys_FPU_EnableExceptions( TEST_FPU_EXCEPTIONS );

		// run the game
		common->Frame();
	}

	// never gets here
	return 0;
}
Ejemplo n.º 18
0
Application::Application(const std::vector<CL_String> &args, lua_State *luaState)
    : mUpdated(false), mCompanyName(""), mApplicationName("bmgui"), mApplicationVersion(""), mQuit(false)
{
    GAME_ASSERT(!args.empty());

#ifdef WIN32
    // bind main thread to the first core for correct timings on some multicore systems
    SetThreadAffinityMask(GetCurrentThread(), 0x01);
#endif

    // parse the command line arguments
    std::vector<char *> argv;
    for (std::vector<CL_String>::const_iterator it = args.begin(); it != args.end(); ++it)
        argv.push_back(const_cast<char *>(it->c_str()));

    CL_CommandLine commandLine;
    commandLine.set_help_indent(40);
    commandLine.add_doc("Graphical interface for Sibek balance machines");
    commandLine.add_usage("[OPTION...]\n");

    commandLine.add_option('g', "gateway", "ADDR", "Default gateway address");
    commandLine.add_option('a', "local_addr", "ADDR", "Local address");
    commandLine.add_option('m', "netmask", "ADDR", "Subnet mask");
    commandLine.add_option('d', "dns", "ADDR", "DNS server address");
    commandLine.add_option('i', "input_dev", "TYPE", "Input device type");
    commandLine.add_option('s', "server_status", "FLAG", "Server status");
    commandLine.add_option('u', "available_update_version", "VERSION", "Available update version");
    commandLine.add_option('U', "updated", "FLAG", "Software update flag");
    commandLine.add_option('W', "updatedfw", "FLAG", "Firmware update flag");
    commandLine.add_option('D', "datadir", "PATH", "Path to the data directory");
    commandLine.add_option('h', "help", "", "Show this help");
    commandLine.parse_args(argv.size(), &argv[0]);

#if defined(WIN32) || defined(__APPLE__)
    mDataDirectory = CL_Directory::get_resourcedata("bmgui", "data");
#else
    mDataDirectory = CL_PathHelp::add_trailing_slash(GAME_DATA_DIR);
#endif
    while (commandLine.next())
    {
        switch (commandLine.get_key())
        {
        case 'g':
            mGateway = commandLine.get_argument();
            break;
        case 'a':
            mLocalAddr = commandLine.get_argument();
            break;
        case 'm':
            mNetmask = commandLine.get_argument();
            break;
        case 'd':
            mDNS = commandLine.get_argument();
            break;
        case 'i':
            mInputDev = commandLine.get_argument();
            break;
        case 's':
            mServerStatus = commandLine.get_argument();
            break;
        case 'u':
            mAvailableUpdateVersion = commandLine.get_argument();
            break;
        case 'U':
            mUpdated = CL_StringHelp::text_to_bool(commandLine.get_argument());
            break;
        case 'W':
            mFirmwareUpdated = commandLine.get_argument();
            break;
        case 'D':
            mDataDirectory = CL_PathHelp::add_trailing_slash(commandLine.get_argument());
            break;
        case 'h':
            commandLine.print_help();
            quit();
            return;
        }
    }

    /*CL_Console::write_line(cl_format("mGateway = %1", mGateway));
    CL_Console::write_line(cl_format("mLocalAddr = %1", mLocalAddr));
    CL_Console::write_line(cl_format("mNetmask = %1", mNetmask));
    CL_Console::write_line(cl_format("mDNS = %1", mDNS));
    CL_Console::write_line(cl_format("mInputDev = %1", mInputDev));
    CL_Console::write_line(cl_format("mServerStatus = %1", mServerStatus));
    CL_Console::write_line(cl_format("mAvailableUpdateVersion = %1", mAvailableUpdateVersion));
    CL_Console::write_line(cl_format("mDataDirectory = %1", mDataDirectory));*/

    // load the system profile
    Profile profile("");

    CL_Console::write_line(cl_format("gateway = %1", profile.getString("gateway")));
    CL_Console::write_line(cl_format("local_addr = %1", profile.getString("local_addr")));
    CL_Console::write_line(cl_format("netmask = %1", profile.getString("netmask")));
    CL_Console::write_line(cl_format("dns = %1", profile.getString("dns")));
    CL_Console::write_line(cl_format("input_dev = %1", profile.getInt("input_dev")));
    CL_Console::write_line(cl_format("server_status = %1", profile.getBool("server_status")));
    CL_Console::write_line(cl_format("available_update_version = %1", profile.getString("available_update_version")));
    CL_Console::write_line(cl_format("server_addr = %1", profile.getString("server_addr")));
    CL_Console::write_line(cl_format("remote_control = %1", profile.getBool("remote_control")));
    CL_Console::write_line(cl_format("ignored_update_version = %1", profile.getString("ignored_update_version")));
    CL_Console::write_line(cl_format("cal_command = %1", profile.getString("cal_command")));
    CL_Console::write_line(cl_format("language = %1", profile.getInt("language")));
    CL_Console::write_line(cl_format("fullscreen = %1", profile.getBool("fullscreen")));
    CL_Console::write_line(cl_format("width = %1", profile.getInt("width")));
    CL_Console::write_line(cl_format("height = %1", profile.getInt("height")));
    CL_Console::write_line(cl_format("sound_level = %1", profile.getInt("sound_level")));

    // initialize all game subsystems
    mBalance = CL_SharedPtr<Balance>(new Balance(profile));
    mDatabase = CL_SharedPtr<Database>(new Database(getConfigDirectory() + getApplicationName() + ".db"));
    mResourceManager = CL_SharedPtr<ResourceManager>(new ResourceManager());
    mResourceQueue = CL_SharedPtr<ResourceQueue>(new ResourceQueue());
    mGraphics = CL_SharedPtr<Graphics>(new Graphics(profile));
    mKeyboard = CL_SharedPtr<Keyboard>(new Keyboard());
    mMouse = CL_SharedPtr<Mouse>(new Mouse());
    mSoundOutput = CL_SoundOutput(44100);
    mLuaScript = CL_SharedPtr<LuaScript>(new LuaScript("main.lua", luaState));
}
Ejemplo n.º 19
0
void CLIENT_STATE::start_cpu_benchmarks() {
    int i;

    if (benchmarks_running) {
        msg_printf(0, MSG_INFO,
            "Can't start benchmarks - they're already running"
        );
        return;
    }

    if (config.skip_cpu_benchmarks) {
        if (log_flags.benchmark_debug) {
            msg_printf(0, MSG_INFO,
                "[benchmark] start_cpu_benchmarks(): Skipping CPU benchmarks"
            );
        }
        cpu_benchmarks_set_defaults();
        return;
    }
    msg_printf(NULL, MSG_INFO, "Running CPU benchmarks");

    cpu_benchmarks_pending = false;

    bm_state = BM_FP_INIT;
    remove_benchmark_file(BM_TYPE_FP);
    remove_benchmark_file(BM_TYPE_INT);
    cpu_benchmarks_start = dtime();

    if (benchmark_descs) {
        free(benchmark_descs);
    }
    bm_ncpus = ncpus;
    benchmark_descs = (BENCHMARK_DESC*)calloc(bm_ncpus, sizeof(BENCHMARK_DESC));
    benchmarks_running = true;

    for (i=0; i<bm_ncpus; i++) {
        benchmark_descs[i].ordinal = i;
        benchmark_descs[i].done = false;
        benchmark_descs[i].error = false;
#ifdef _WIN32
        benchmark_descs[i].handle = CreateThread(
            NULL, 0, win_cpu_benchmarks, benchmark_descs+i, 0,
            &benchmark_descs[i].pid
        );
        SetThreadAffinityMask(benchmark_descs[i].handle, 1<<i);
        SetThreadPriority(benchmark_descs[i].handle, THREAD_PRIORITY_IDLE);
#else
        sprintf(benchmark_descs[i].filename, "%s_%d.xml", CPU_BENCHMARKS_FILE_NAME, i);
        PROCESS_ID pid = fork();
        if (pid == 0) {
#if HAVE_SETPRIORITY
            if (setpriority(PRIO_PROCESS, 0, PROCESS_IDLE_PRIORITY)) {
                perror("setpriority");
            }
#endif
            int retval = cpu_benchmarks(benchmark_descs+i);
            fflush(NULL);
            _exit(retval);
        } else {
            benchmark_descs[i].pid = pid;
        }
#endif
    }
}
void CannBallNetworkManager::EstablishPeerConnection(int playerNum)
{
    UDPBroadcast broadcast;
    broadcast.SetMessage(to_string(CONNECT_MAGIC_NUM) + (playerNum == 1 ? "-PLAY1" : "-PLAY2"));
    broadcast.SetBroadcastPort(playerNum == 1 ? BROADCAST_PORT_P1 : BROADCAST_PORT_P2);
    
    SocketStream& peer = (playerNum == 1 ? m_player1 : m_player2);
    // TODO: REFACTOR THIS SHIT!
    broadcast.start();
    while(true) // Not needed? Just call broadcast.waitForFinish()???
    {
        if(!broadcast.isRunning())
        {
            broadcast.waitForFinish();

            cout << "OffworldNetManager P" << playerNum << ": Broadcast finished." << endl;
            SocketAddr peerAddr;
            if(!broadcast.GetPeerAddr(peerAddr))
            {
                cout << "OffworldNetManager P" << playerNum << ": Broadcast failed to find peer."
                     << endl;
                break;
            }

            cout << "OffworldNetManager P" << playerNum 
                 << ": Broadcast found peer. Attempting to connect" << endl;

            SocketAddr peerAddrStreamPort(peerAddr.GetIpAddr(), STREAM_PORT);
            Sleep(20); // Sleep gives peer time to setup their end.
            SetThreadAffinityMask(GetHandle(), 2);

            if(peer.Open(peerAddrStreamPort, 0))
            {
                // managed to connect.
                cout << "Connection to peer [" << peer.GetPeerAddr().ToString() << "]" 
                     << endl;

                char recvBuffer[100000];
                memset(recvBuffer, 0, 100000);
                if (peer.Recv(recvBuffer, 100000, 0) > 0)
                {
                    std::stringstream ssBuffer(recvBuffer);
                    std::string head;
                    ssBuffer >> head;
                    if(!head.compare("INIT"))
                    {
                        // Now read in entities.
                        while(!ssBuffer.eof())
                        {
                            std::string entityId;
                            ssBuffer >> head;
                            if(!head.compare("ENT"))
                            {                                
                                // Load in entity data.
                                ssBuffer >> entityId;
                                 
                                entityId =/* "P" + to_string(playerNum) + */entityId;
                                // What is it? Circle, Square?
                                std::string entityType;
                                ssBuffer >> entityType;
                                if(!entityType.compare("CIRC"))
                                {
                                    LoadCircle(ssBuffer, entityId);

                                    // Update circle to follow if it matches the player we're following.
                                    if (playerNum == m_playerNum)
                                    {
                                        m_followBallStr = entityId;
                                    }
                                       // m_followBall = m_scene->GetEntitySafe(entityId);
                                }
                                else if(!entityType.compare("SQR"))
                                {
                                    LoadSquare(ssBuffer, entityId);
                                }    
                                else if (!entityType.compare("CAN"))
                                {
                                    LoadCannon(ssBuffer, entityId);
                                }
                            }
                        }  
                        
                        int sentBytes = 0;
                        //while(sentBytes < 3)
                        //{ // Keep trying until sent all the data. Should send straight away without issues though.
                            // NOTE: Probably best to put something like this within the Send buffer.
                            sentBytes = peer.Send("ACK", 3, 0);
                        //}

                    }
                }
Ejemplo n.º 21
0
/*
==================
WinMain
==================
*/
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{

	const HCURSOR hcurSave = ::SetCursor(LoadCursor(0, IDC_WAIT));

	Sys_SetPhysicalWorkMemory(192 << 20, 1024 << 20);

	Sys_GetCurrentMemoryStatus(exeLaunchMemoryStats);

#if 0
	DWORD handler = (DWORD)_except_handler;
	__asm {
		// Build EXCEPTION_REGISTRATION record:
		push    handler         // Address of handler function
		push    FS:[0]          // Address of previous handler
		mov     FS:[0],ESP      // Install new EXECEPTION_REGISTRATION
	}
#endif

	win32.hInstance = hInstance;
	idStr::Copynz(sys_cmdline, lpCmdLine, sizeof(sys_cmdline));

	// done before Com/Sys_Init since we need this for error output
	Sys_CreateConsole();

	// no abort/retry/fail errors
	SetErrorMode(SEM_FAILCRITICALERRORS);

	for (int i = 0; i < MAX_CRITICAL_SECTIONS; i++) {
		InitializeCriticalSection(&win32.criticalSections[i]);
	}

	// get the initial time base
	Sys_Milliseconds();

#ifdef DEBUG
	// disable the painfully slow MS heap check every 1024 allocs
	_CrtSetDbgFlag(0);
#endif

//	Sys_FPU_EnableExceptions( TEST_FPU_EXCEPTIONS );
	Sys_FPU_SetPrecision(FPU_PRECISION_DOUBLE_EXTENDED);

	common->Init(0, NULL, lpCmdLine);

#if TEST_FPU_EXCEPTIONS != 0
	common->Printf(Sys_FPU_GetState());
#endif

#ifndef	ID_DEDICATED

	if (win32.win_notaskkeys.GetInteger()) {
		DisableTaskKeys(TRUE, FALSE, /*( win32.win_notaskkeys.GetInteger() == 2 )*/ FALSE);
	}

#endif

	Sys_StartAsyncThread();

	// hide or show the early console as necessary
	if (win32.win_viewlog.GetInteger() || com_skipRenderer.GetBool() || idAsyncNetwork::serverDedicated.GetInteger()) {
		Sys_ShowConsole(1, true);
	} else {
		Sys_ShowConsole(0, false);
	}

#ifdef SET_THREAD_AFFINITY
	// give the main thread an affinity for the first cpu
	SetThreadAffinityMask(GetCurrentThread(), 1);
#endif

	::SetCursor(hcurSave);

	// Launch the script debugger
	if (strstr(lpCmdLine, "+debugger")) {
		// DebuggerClientInit( lpCmdLine );
		return 0;
	}

	::SetFocus(win32.hWnd);

	// main game loop
	while (1) {

		Win_Frame();

#ifdef DEBUG
		Sys_MemFrame();
#endif

		// set exceptions, even if some crappy syscall changes them!
		Sys_FPU_EnableExceptions(TEST_FPU_EXCEPTIONS);

#ifdef ID_ALLOW_TOOLS

		if (com_editors) {
			if (com_editors & EDITOR_GUI) {
				// GUI editor
				GUIEditorRun();
			} else if (com_editors & EDITOR_RADIANT) {
				// Level Editor
				RadiantRun();
			} else if (com_editors & EDITOR_MATERIAL) {
				//BSM Nerve: Add support for the material editor
				MaterialEditorRun();
			} else {
				if (com_editors & EDITOR_LIGHT) {
					// in-game Light Editor
					LightEditorRun();
				}

				if (com_editors & EDITOR_SOUND) {
					// in-game Sound Editor
					SoundEditorRun();
				}

				if (com_editors & EDITOR_DECL) {
					// in-game Declaration Browser
					DeclBrowserRun();
				}

				if (com_editors & EDITOR_AF) {
					// in-game Articulated Figure Editor
					AFEditorRun();
				}

				if (com_editors & EDITOR_PARTICLE) {
					// in-game Particle Editor
					ParticleEditorRun();
				}

				if (com_editors & EDITOR_SCRIPT) {
					// in-game Script Editor
					ScriptEditorRun();
				}

				if (com_editors & EDITOR_PDA) {
					// in-game PDA Editor
					PDAEditorRun();
				}
			}
		}

#endif
		// run the game
		common->Frame();
	}

	// never gets here
	return 0;
}
Ejemplo n.º 22
0
int thread_bind_native(__unused_variable struct cpuid_state_t *state, __unused_variable uint32_t id)
{
#ifdef TARGET_OS_WINDOWS

	BOOL ret;
	HANDLE hThread = GetCurrentThread();
#if _WIN32_WINNT >= 0x0601
	GROUP_AFFINITY affinity;

	ZeroMemory(&affinity, sizeof(GROUP_AFFINITY));

	affinity.Group = id / 64;
	affinity.Mask = 1 << (id % 64);

	ret = SetThreadGroupAffinity(hThread, &affinity, NULL);
#else
	DWORD mask;

	if (id > 32)
		return 1;

	mask = (1 << id);

	ret = SetThreadAffinityMask(hThread, mask);
#endif

	return (ret != FALSE) ? 0 : 1;

#elif defined(TARGET_OS_LINUX) || defined(TARGET_OS_FREEBSD)

	int ret;

#ifdef CPU_SET_S
	size_t setsize = CPU_ALLOC_SIZE(MAX_CPUS);
	CPUSET_T *set = CPU_ALLOC(MAX_CPUS);
	pthread_t pth;

	pth = pthread_self();

	CPU_ZERO_S(setsize, set);
	CPU_SET_S(id, setsize, set);
	ret = pthread_setaffinity_np(pth, setsize, set);
	CPU_FREE(set);
#else
	size_t bits_per_set = sizeof(CPUSET_T) * 8;
	size_t bits_per_subset = sizeof(CPUSET_MASK_T) * 8;
	size_t setsize = sizeof(CPUSET_T) * (MAX_CPUS / bits_per_set);
	size_t set_id, subset_id;
	unsigned long long mask;
	CPUSET_T *set = malloc(setsize);
	pthread_t pth;

	pth = pthread_self();

	for (set_id = 0; set_id < (MAX_CPUS / bits_per_set); set_id++)
		CPU_ZERO(&set[set_id]);

	set_id = id / bits_per_set;
	id %= bits_per_set;

	subset_id = id / bits_per_subset;
	id %= bits_per_subset;

	mask = 1ULL << (unsigned long long)id;

	((unsigned long *)set[set_id].__bits)[subset_id] |= mask;
	ret = pthread_setaffinity_np(pth, setsize, set);
	free(set);
#endif

	return (ret == 0) ? 0 : 1;

#elif defined(TARGET_OS_MACOSX)

#ifdef USE_CHUD
	return (utilBindThreadToCPU(id) == 0) ? 0 : 1;
#else
	return 1;
#endif

#else
#error "thread_bind_native() not defined for this platform"
#endif
}
Ejemplo n.º 23
0
static void
bind_to_processor(int child_num)
{
  /* This routine will bind the calling process to a particular */
  /* processor. We are not choosy as to which processor, so it will be */
  /* the process id mod the number of processors - shifted by one for */
  /* those systems which name processor starting from one instead of */
  /* zero. on those systems where I do not yet know how to bind a */
  /* process to a processor, this routine will be a no-op raj 10/95 */

  /* just as a reminder, this is *only* for the looper processes, not */
  /* the actual measurement processes. those will, should, MUST float */
  /* or not float from CPU to CPU as controlled by the operating */
  /* system defaults. raj 12/95 */

#ifdef __hpux
#include <sys/syscall.h>
#include <sys/mp.h>

  int old_cpu = -2;

  if (debug) {
    fprintf(where,
            "child %d asking for CPU %d as pid %d with %d CPUs\n",
            child_num,
            (child_num % lib_num_loc_cpus),
            getpid(),
            lib_num_loc_cpus);
    fflush(where);
  }

  SETPROCESS((child_num % lib_num_loc_cpus), getpid());
  return;

#else
#if defined(__sun) && defined(__SVR4)
 /* should only be Solaris */
#include <sys/processor.h>
#include <sys/procset.h>

  int old_binding;

  if (debug) {
    fprintf(where,
            "bind_to_processor: child %d asking for CPU %d as pid %d with %d CPUs\n",
            child_num,
            (child_num % lib_num_loc_cpus),
            getpid(),
            lib_num_loc_cpus);
    fflush(where);
  }

  if (processor_bind(P_PID,
                     getpid(),
                     (child_num % lib_num_loc_cpus), 
                      &old_binding) != 0) {
    fprintf(where,"bind_to_processor: unable to perform processor binding\n");
    fprintf(where,"                   errno %d\n",errno);
    fflush(where);
  }
  return;
#else
#ifdef WIN32

  if (!SetThreadAffinityMask(GetCurrentThread(), (ULONG_PTR)1 << (child_num % lib_num_loc_cpus))) {
    perror("SetThreadAffinityMask failed");
    fflush(stderr);
  }

  if (debug) {
    fprintf(where,
            "bind_to_processor: child %d asking for CPU %d of %d CPUs\n",
            child_num,
            (child_num % lib_num_loc_cpus),
            lib_num_loc_cpus);
    fflush(where);
  }

#endif
  return;
#endif /* __sun && _SVR4 */
#endif /* __hpux */
}
Ejemplo n.º 24
0
void* LqThreadBase::BeginThreadHelper(void* ProcData)
#endif
{
    LqThreadBase* This = (LqThreadBase*)ProcData;

    This->IsStarted = true;
    This->StartThreadLocker.LockWrite();
    
    //
#if defined(LQPLATFORM_WINDOWS)
    pthread_setname_np(This->ThreadId(), This->Name);
#elif defined(LQPLATFORM_LINUX) || defined(LQPLATFORM_ANDROID)
    pthread_setname_np(pthread_self(), This->Name);
#elif defined(LQPLATFORM_FREEBSD)
    pthread_setname_np(pthread_self(), This->Name, nullptr);
#elif defined(LQPLATFORM_APPLE)
    pthread_setname_np(This->Name);
#endif

    if(This->Priority == LQTHREAD_PRIOR_NONE) {
#if defined(LQPLATFORM_WINDOWS)
        This->Priority = __GetPrior(GetThreadPriority(GetCurrentThread()));
#else
        sched_param schedparams;
        pthread_getschedparam(pthread_self(), LqDfltPtr(), &schedparams);
        This->Priority = __GetPrior(schedparams.sched_priority);
#endif
    } else {
#if defined(LQPLATFORM_WINDOWS)
        SetThreadPriority(GetCurrentThread(), __GetRealPrior(This->Priority));
#else
        sched_param schedparams;
        schedparams.sched_priority = __GetRealPrior(This->Priority);
        pthread_setschedparam(pthread_self(), SCHED_OTHER, &schedparams);
#endif
    }


    if(This->AffinMask == 0) {
#if defined(LQPLATFORM_WINDOWS)
        GROUP_AFFINITY ga = {0};
        GetThreadGroupAffinity(GetCurrentThread(), &ga);
        This->AffinMask = ga.Mask;
#elif !defined(LQPLATFORM_ANDROID)
        pthread_getaffinity_np(pthread_self(), sizeof(This->AffinMask), (cpu_set_t*)&This->AffinMask);
#endif
    } else {
#if defined(LQPLATFORM_WINDOWS)
        SetThreadAffinityMask(GetCurrentThread(), This->AffinMask);
#elif !defined(LQPLATFORM_ANDROID)
        pthread_setaffinity_np(pthread_self(), sizeof(This->AffinMask), (const cpu_set_t*)&This->AffinMask);
#endif
    }
    This->StartThreadLocker.UnlockWrite();

    This->EnterHandler(This->UserData); //Call user defined handler

    //Enter main func
    This->BeginThread();


#ifdef LQPLATFORM_WINDOWS
    if(NameThread != nullptr) {
        free(NameThread);
        NameThread = nullptr;
    }
#endif

    This->ExitHandler(This->UserData);

    This->StartThreadLocker.LockWrite();
#ifdef LQPLATFORM_WINDOWS
    CloseHandle((HANDLE)This->ThreadHandler);
#endif
    This->CurThreadId = -((intptr_t)1);
    This->ThreadHandler = 0;
    This->StartThreadLocker.UnlockWrite();
#ifdef LQPLATFORM_WINDOWS
    return 0;
#else
    return NULL;
#endif
}
Ejemplo n.º 25
0
	virtual void Run()
	{
		SetName("ZLibCompressor");

#if defined (DURANGO)
		SetThreadAffinityMask(GetCurrentThread(), BIT(3));
#endif

		while(!m_bCancelled || !m_files.empty())
		{
			m_event.Wait();

			uint8* pZLibCompressedBuffer = AllocateBlock();

			while(!m_files.empty())
			{
				CFile* pFile = m_files.pop();
				assert(pFile);
				PREFAST_ASSUME(pFile);

				while(!pFile->Closed() || !pFile->m_blocks.empty())
				{
					if( pFile->m_blocks.empty() )
					{ 
						CrySleep(1); // yield to give other threads a chance to do some work        
					}

					while(!pFile->m_blocks.empty())
					{
						SZLibBlock* block = pFile->m_blocks.pop();
						assert(block);
						PREFAST_ASSUME(block);

						if(pFile->m_pCompressor->m_bUseZLibCompression)
						{
							size_t compressedLength = XMLCPB_ZLIB_BUFFER_SIZE;
							bool compressionOk = gEnv->pSystem->CompressDataBlock( block->m_pZLibBuffer, block->m_ZLibBufferSizeUsed, pZLibCompressedBuffer, compressedLength );

							SZLibBlockHeader zlibHeader;
							zlibHeader.m_compressedSize = compressionOk ? compressedLength : SZLibBlockHeader::NO_ZLIB_USED;
							zlibHeader.m_uncompressedSize = block->m_ZLibBufferSizeUsed;
							pFile->m_bytesWrittenIntoFileUncompressed += block->m_ZLibBufferSizeUsed;

							pFile->Write( &zlibHeader, sizeof(SZLibBlockHeader) );
							if (compressionOk)
								pFile->Write( pZLibCompressedBuffer, compressedLength );
							else
								pFile->Write( block->m_pZLibBuffer, block->m_ZLibBufferSizeUsed );
						}
						else
						{
							pFile->Write(block->m_pZLibBuffer, block->m_ZLibBufferSizeUsed);
						}

						delete block;
					}
				}

				pFile->Finish();
				delete pFile;
			}

			FreeBlock(pZLibCompressedBuffer);
		}
	}
Ejemplo n.º 26
0
void PsychGetPrecisionTimerSeconds(double *secs)
{
  double					ss, ticks, diff;
  static LARGE_INTEGER		counterFreq;
  LARGE_INTEGER				count;
  static double				oss;
  static double				oldticks;
  static double				lastSlowcheckTimeSecs;
  static double				lastSlowcheckTimeTicks;
  psych_uint32				tick1, tick2, hangcount;
  psych_uint64				curRawticks;
  
	// First time init of timeglue: Set up system for high precision timing,
	// and enable workarounds for broken systems:
  if (firstTime) {

		// Init state to defaults:
		oss=0.0;
		oldticks=0.0;
		lastSlowcheckTimeSecs = -1;
		lastSlowcheckTimeTicks = -1;
		
		// Switch the system into high resolution timing mode, i.e.,
		// 1 khZ timer interrupts aka 1 msec timer resolution, for both,
		// the Sleep() command and TimeGetTime() queries. This way, our hybrid
		// sleep-waiting algorithm for PsychWaitUntilSeconds() can work with
		// tight busy-wait transition thresholds and doesn't burn too much
		// CPU time. The timeGetTime() function then gets sufficient granularity -
		// 1 msecs - to be a good reference for our correctness/consistency
		// checks on the high precision timer, and it is a sufficient fallback
		// in case of broken timers.
		// The drawback is increased general interrupt load due to the 1 kHZ IRQ's...
    	if ((timeBeginPeriod(1)!=TIMERR_NOERROR) && (schedulingtrouble == FALSE)) {
		  	// High precision mode failed! Output warning on first failed invocation...
		  	schedulingtrouble = TRUE;
        	printf("PTBCRITICAL -ERROR: PsychTimeGlue - Win32 syscall timeBeginPeriod(1) failed!!! Timing will be inaccurate.\n");
        	printf("PTBCRITICAL -ERROR: Time measurement may be highly unreliable - or even false!!!\n");
        	printf("PTBCRITICAL -ERROR: FIX YOUR SYSTEM! In its current state its not useable for conduction of studies!!!\n");
        	printf("PTBCRITICAL -ERROR: Check the FAQ section of the Psychtoolbox Wiki for more information.\n");

		  	// Increase switching threshold to 10 msecs to take low timer resolution into account:
		  	sleepwait_threshold = 0.010;
    	}    

	 	// This command timeEndPeriod(1); should be used when flushing the MEX file, but
		// we don't do it. Once a PsychTimeGlue function was called, we leave Matlab at
		// high timing precision mode and rely on the OS to revert to standard Windoze
		// behaviour, once the Matlab application is quit/terminated.

		// Next step for broken systems: Bind our Matlab interpreter/PTB main thread to the
		// first cpu core in the system. The only known way to make sure we don't get time
		// readings from different TSCs due to our thread jumping between cpu's. TSC's on
		// a multi-core system are not guaranteed to be synchronized, so if TSC is our timebase,
		// this could lead to time inconsistencies - even time going backwards between queries!!!
		// Drawback: We may not make optimal use of a multi-core system. On Vista and later, we assume
		// everything will be fine, but still perform consistency checks at each call to PsychGetPrecisionTimerSeconds():
		if (!PsychIsMSVista()) {
			if (SetThreadAffinityMask(GetCurrentThread(), 1)==0) {
				// Binding failed! Output warning on first failed invocation...
				schedulingtrouble = TRUE;
				printf("PTBCRITICAL -ERROR: PsychTimeGlue - Win32 syscall SetThreadAffinityMask() failed!!! Timing could be inaccurate.\n");
				printf("PTBCRITICAL -ERROR: Time measurement may be highly unreliable - or even false!!!\n");
				printf("PTBCRITICAL -ERROR: FIX YOUR SYSTEM! In its current state its not useable for conduction of studies!!!\n");
				printf("PTBCRITICAL -ERROR: Check the FAQ section of the Psychtoolbox Wiki for more information.\n");
			}
		}
		
		// Sleep us at least 10 msecs, so the system will reschedule us, with the
		// thread affinity mask above applied. Don't know if this is needed, but
		// better safe than sorry:
		Sleep(10);
		
		// Spin-Wait until timeGetTime() has switched to 1 msec resolution:
		hangcount = 0;
		while(hangcount < 100) {
			tick1 = (psych_uint32) timeGetTime();
			while((tick2=(psych_uint32) timeGetTime()) == tick1);
			if ((tick2 > tick1) && (tick2 - tick1 == 1)) break;
			hangcount++;
		}

		if (hangcount >= 100) {
			// Totally foobared system! Output another warning but try to go on. Checks further below in code
			// will trigger and provide counter measures - as far as this is possible with such a screwed system :-(
			printf("PTB-CRITICAL WARNING! Timing code detected problems with the low precision TIMER in your system hardware!\n");
			printf("PTB-CRITICAL WARNING! It doesn't run at the requested rate of 1 tick per millisecond. Interrupt problems?!?\n");
			printf("PTB-CRITICAL WARNING! Your system is somewhat screwed up wrt. timing!\n");
			printf("PTB-CRITICAL WARNING! It is NOT RECOMMENDED to continue using this machine for studies that require high\n");
			printf("PTB-CRITICAL WARNING! timing precision in stimulus onset or response collection. No guarantees can be made\n");
			printf("PTB-CRITICAL WARNING! wrt. to timing or correctness of any timestamps or stimulus onsets!\n");
			printf("PTB-CRITICAL WARNING! Check the FAQ section of the Psychtoolbox Wiki for more information.\n\n");
		}

		// Ok, now timeGetTime() should have the requested 1 msec increment rate.

		// Ok, this is a dumb solution, but at least sort of robust. The
		// proper solution will have to wait for the next 'beta' release cycle.
		// We don't allow to use any timing function on a Windoze system that
		// has more than 48 days of uptime. Rationale: At 49.8 days, the 32 bit
		// tick counter will wrap around and leave our fallback- and reference
		// timebase in an undefined state. Implementing proper wraparound handling
		// for inifinite uptimes is not simple, due to PTB's modular nature and
		// some special flaws of Windoze. Anyway, 48 days uptime is unlikely
		// anyway, unless the user doesn't perform regular system updates...
		if (((double) timeGetTime() * 0.001) > (3600 * 24 * 48)) {
			// Uptime exceeds 48 days. Say user this is a no no:
			printf("PTB-ERROR: Your system is running since over 48 days without a reboot. Due to some\n");
			printf("PTB-ERROR: pretty disgusting design flaws in the Windows operating system, timing\n");
			printf("PTB-ERROR: will become unreliable or wrong at uptimes of more than 49 days.\n");
			printf("PTB-ERROR: Therefore PTB will not continue executing any time related function unless\n");
			printf("PTB-ERROR: you reboot your machine now.\n\n");
			PsychErrorExitMsg(PsychError_user, "Maximum allowable uptime for Windows exceeded. Please reboot your system.");
		} 

		// Is the high-precision timer supported?
    	counterExists = QueryPerformanceFrequency(&counterFreq);
		if (counterExists) {
			// Initialize old counter values to now:
			if (0 == QueryPerformanceCounter(&count)) {
				Timertrouble = TRUE;
				counterExists = FALSE;
				oss = 0;
				
				printf("PTB-CRITICAL WARNING! Timing code detected problems with the high precision TIMER in your system hardware!\n");
				printf("PTB-CRITICAL WARNING! Initial call to QueryPerformanceCounter() failed!\n");
				printf("PTB-CRITICAL WARNING! Will switch back to lower precision/resolution timer (only +/-1 millisecond accuracy at best).\n");				
				printf("PTB-CRITICAL WARNING! This can cause a cascade of errors, failures and problems in any timing related functions!!\n\n");				
				printf("PTB-CRITICAL WARNING! It is NOT RECOMMENDED to continue using this machine for studies that require any\n");
				printf("PTB-CRITICAL WARNING! timing precision in stimulus onset or response collection. No guarantees can be made\n");
				printf("PTB-CRITICAL WARNING! wrt. to timing or correctness of any timestamps or stimulus onsets!\n");
				printf("PTB-CRITICAL WARNING! Read 'help GetSecsTest' and run GetSecsTest for further diagnosis and troubleshooting.\n");
				printf("PTB-CRITICAL WARNING! It may also help to restart the machine to see if the problem is transient.\n");
				printf("PTB-CRITICAL WARNING! Also check the FAQ section of the Psychtoolbox Wiki for more information.\n\n");
			}
			else {
				oss = ((double)count.QuadPart)/((double)counterFreq.QuadPart);
			}
		}
		
		// Sleep us another 10 msecs to make sure there is a significant difference between
		// first invocation and successive invocations:
		Sleep(10);
  }
  
	// Need to acquire our timelock before we continue, for atomic timestamping and as we will soon access shared data structures:
	EnterCriticalSection(&time_lock);

	// Query system time of low resolution counter:
	curRawticks = timeGetTime();

	// Query Performance counter if it is supported:
	if ((counterExists) && (0 == QueryPerformanceCounter(&count))) {
			Timertrouble = TRUE;
			printf("PTB-CRITICAL WARNING! Timing code detected problems with the high precision TIMER in your system hardware!\n");
			printf("PTB-CRITICAL WARNING! A call to QueryPerformanceCounter() failed!\n");
			printf("PTB-CRITICAL WARNING! Will switch back to lower precision/resolution timer (only +/-1 millisecond accuracy at best).\n");
			printf("PTB-CRITICAL WARNING! It is NOT RECOMMENDED to continue using this machine for studies that require high\n");
			printf("PTB-CRITICAL WARNING! timing precision in stimulus onset or response collection. No guarantees can be made\n");
			printf("PTB-CRITICAL WARNING! wrt. to timing or correctness of any timestamps or stimulus onsets!\n");
			printf("PTB-CRITICAL WARNING! Read 'help GetSecsTest' and run GetSecsTest for further diagnosis and troubleshooting.\n");
			printf("PTB-CRITICAL WARNING! It may also help to restart the machine to see if the problem is transient.\n");
			printf("PTB-CRITICAL WARNING! Also check the FAQ section of the Psychtoolbox Wiki for more information.\n\n");
	}

	// Convert to ticks in seconds for further processing:
	ticks = ((double) (psych_int64) curRawticks) * 0.001;
	tickInSecsAtLastQuery = ticks;
	
  // Start actual processing of result of QueryPerformanceCounter(). We do this here,
  // deferred under protection of the time_lock lock. The Query has been done above,
  // outside of the critical section, so multiple threads can't collide on a contended
  // time_lock and get delayed needlessly:
  if (counterExists) {

   ss = ((double)count.QuadPart)/((double)counterFreq.QuadPart);
   timeInSecsAtLastQuery = ss;

	// Initialize base time for slow consistency checks at first invocation:
	if (firstTime) {
		lastSlowcheckTimeSecs = ss;
		lastSlowcheckTimeTicks = ticks;
	}

	// Compute difference (disagreement over elapsed time since last call) between high-precision
	// timer and low-precision timer:
	diff = ((ss - oss) - (ticks - oldticks));

	// We don't perform the inter-timer agreement check at first invokation - Thread scheduling etc. needs to settle,
	// as well as the timeBeginPeriod(1) call above...
	if (!Timertrouble && !firstTime) {
		// No timer problems yet. Perform checks:

		// Time running backwards?
        // We allow for a slack of 10 nanoseconds. Not sure if this is a good idea, as it weakens the test
        // to avoid aggressive fallback on flaky but sort of still useable hardware. Some modern cpu's showed
        // this effect, but the fallback would have been worse...
		if (ss < (oss - 1e-8)) {
			Timertrouble = TRUE;
			printf("PTB-CRITICAL WARNING! Timing code detected problems with the high precision TIMER in your system hardware!\n");
			printf("PTB-CRITICAL WARNING! Apparently time is reported as RUNNING BACKWARDS. (Timewarp Delta: %0.30f secs.)\n", ss - oss);
			printf("PTB-CRITICAL WARNING! One reason could be a multi-core system with unsynchronized TSC's and buggy platform drivers.\n");
			printf("PTB-CRITICAL WARNING! Will switch back to lower precision/resolution timer (only +/-1 millisecond accuracy at best).\n");
		}
		
		// The old and new high res. timer should not
		// disagree in their increment since last call by more than 250 msecs. If they do,
		// this means that the high precision timer leaped forward, which indicates a faulty
		// Southbridge controller in the machines host chipset - Not a good basis for high precision timing.
		// See Microsoft Knowledge base article Nr. 274323 for further explanation and a list of known bad
		// chipsets.
		// We actually allow for an additional slack of 0.000200 seconds or 200 ppm for each
		// elapsed second of the test interval. This to account for clock drift of up to 200 ppm
		// between both clocks. According to some docs, 200 ppm drift are possible under MS-Windows!
		if ( diff > ( 0.25 + ((ticks - oldticks) * 0.000200 ) ) ) {
			// Mismatch between performance counter and tick counter detected!
			// Performance counter is faulty! Report this to user, then continue
			// by use of the older tick counter as a band-aid.
			Timertrouble = TRUE;
			printf("PTB-CRITICAL WARNING! Timing code detected a FAULTY high precision TIMER in your system hardware!(Delta %0.30f secs).\n", diff);
			printf("PTB-CRITICAL WARNING! Seems the timer sometimes randomly jumps forward in time by over 250 msecs!");
			printf("PTB-CRITICAL WARNING! Will switch back to lower precision/resolution timer (only +/-1 millisecond accuracy at best).\n");
			printf("PTB-CRITICAL WARNING! For more information see Microsoft knowledge base article Nr. 274323.\n");
			printf("PTB-CRITICAL WARNING! http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q274323&\n\n");
		}

		// We check for lags of QPC() wrt. to tick count at intervals of greater than 1 second, ie. only if
		// this query and the last one are at least 1 second spaced apart in time. This is kind of a low-pass
		// filter to account for the fact that the tick counter itself can sometimes lose a bit of time due
		// to lost timer interrupts, and then jump forward in time by a couple of milliseconds when some
		// system service detects the lost interrupts and accounts for them by incrementing time by multiple
		// ticks at a single IRQ. Here we check over a longer period to make it less likely that such transients
		// show up. We apply a much more generous lag threshold as well, so we can compensate for transient timer
		// jumps of up to 50 msecs.
		if ((ticks - lastSlowcheckTimeTicks) >= 1.0) {
			// Check for lags: A lag of multiple msec is normal and expected due to the measurement method.
			diff = ((ss - lastSlowcheckTimeSecs) - (ticks - lastSlowcheckTimeTicks));
						
			// Let's check for a lag exceeding 5% of the duration of the check interval, so we have a bit of headroom to the expected lag:
			if (diff < -0.05 * (ticks - lastSlowcheckTimeTicks)) {
				// Mismatch between performance counter and tick counter detected!
				// Performance counter is lagging behind realtime! Report this to user, then continue
				// by use of the older tick counter as a band-aid.
				Timertrouble = TRUE;
				printf("PTB-CRITICAL WARNING! Timing code detected a LAGGING high precision TIMER in your system hardware! (Delta %0.30f secs).\n", diff);
				printf("PTB-CRITICAL WARNING! Seems that the timer sometimes stops or slows down! This can happen on systems with\n");
				printf("PTB-CRITICAL WARNING! processor power management (cpu throttling) and defective platform drivers.\n");				
				printf("PTB-CRITICAL WARNING! Will switch back to lower precision/resolution timer (only +/-1 millisecond accuracy at best).\n");
				printf("PTB-CRITICAL WARNING! Please try if disabling all power management features of your system helps...\n");
			}
			
			// Update timestamps of last check:
			lastSlowcheckTimeSecs = ss;
			lastSlowcheckTimeTicks = ticks;
		}
		
		if (Timertrouble) {
            // Faulty high precision clock detected. We switch to the low-res clock for the rest of the session, in the hope that
            // the low-res clock is less broken than the high-res clock.
            //
            // We need to make the switch as seamless as possible. As the low-res and high-res clocks have different "zero seconds"
            // reference points, we need to compute the absolute offset between both and then apply that offset to the reported low
            // res clock time to compensate for it. This should reduce any jumps or jerks in the monotonic system time as perceived
            // by clients of this function, especially the PsychWaitUntilSeconds() and PsychWaitIntervalSeconds() functions, which
            // could hang for a very long time if the switch between high-res and low-res clock happens at the wrong moment.
            lowToHiBiasSecs = ss - ticks;

			// More info for user at first detection of trouble:
			printf("PTB-CRITICAL WARNING! It is NOT RECOMMENDED to continue using this machine for studies that require high\n");
			printf("PTB-CRITICAL WARNING! timing precision in stimulus onset or response collection. No guarantees can be made\n");
			printf("PTB-CRITICAL WARNING! wrt. to timing or correctness of any timestamps or stimulus onsets!\n");
			printf("PTB-CRITICAL WARNING! Read 'help GetSecsTest' and run GetSecsTest for further diagnosis and troubleshooting.\n");
			printf("PTB-CRITICAL WARNING! It may also help to restart the machine to see if the problem is transient.\n");
			printf("PTB-CRITICAL WARNING! Also check the FAQ section of the Psychtoolbox Wiki for more information.\n\n");			
		}
	}

	// All checks done: Prepare old values for new iteration:
	oss = ss;
	oldticks = ticks;
	
	// Ok, is the timer finally considered safe to use?
	if (!Timertrouble) {
		// All checks passed: ss is the valid return value:
		ss = ss;
	}
	else {
		// Performance counter works unreliably: Fall back to result of timeGetTime().
		// This only has 1 msec resolution at best, but at least it works (somewhat...).
        //
        // Correct for time bias between low-res clock and high-res clock to fake a time
        // that looks to clients as if it comes from the high-res clock, albeit with a lower
        // resolution of only 1 msec at best:
		ss = ticks + lowToHiBiasSecs;
	}	

	//  ========= End of high precision timestamping. =========
  }
  else {
	//  ========= Low precision fallback path for ancient machines: 1 khz tick counter: =========
	ss = ticks;
	timeInSecsAtLastQuery = -1;
  }

  // Finally assign time value:  
  *secs= ss;  

  // Clear the firstTime flag - this was the first time, maybe.
  firstTime = FALSE;

  // Need to release our timelock - Done with access to shared data:
  LeaveCriticalSection(&time_lock);

  return;
}
Ejemplo n.º 27
0
Archivo: main.cpp Proyecto: CCJY/coliru
bool set_affinity(DWORD mask) {
  return SetThreadAffinityMask(GetCurrentThread(), mask) != 0;
}
Ejemplo n.º 28
0
void TBag::run()
{
	for (int i = 0; i < _num_proc; ++i)
	{
		_events[i]._offset=i;

		_tasks[i] = createTask();
		_tasks[i]->offset=i;
		_bids.push(_tasks[i]);
	}

	Evt *e;
	Task *task;
	double duration;

	_busy=false;
	_curr_time = 0.0;
	_user_time=0.0;
	_event._type = MASTER;
	plan(&_event, 0.0);

	///////// установка привязки
	if(!SetThreadAffinityMask(GetCurrentThread(),0x1)){
		printf("\nSetThreadAffinityMask FAILED\n");return;
	}

	///////// установка приоритета
	if(!SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_HIGHEST)){
		printf("\nTHREAD_PRIORITY_ABOVE_NORMAL FAILED\n");return;
	}

	LARGE_INTEGER frequency;
	LARGE_INTEGER t1,t2;

	QueryPerformanceFrequency(&frequency);
	QueryPerformanceCounter(&t1);

	while(!_calendar.empty())
	{
		e=_calendar.top();
		_calendar.pop();
		
		assert(_curr_time <= e->_plan_time);

		_curr_time=e->_plan_time;
		e->_planed=false;

		switch(e->_type)
		{
			case MASTER:
				if (!_results.empty())
				{
					_busy=true;

					task = _results.front();
					_results.pop();

					put(task,duration);
					_user_time+=duration;

					_events[task->offset]._type=PUT;
					plan(&_events[task->offset],duration);
				}
				else if(!_bids.empty())
				{
					_busy=true;

					task = _bids.front();
					_bids.pop();

					_events[task->offset]._if_job=if_job(duration);
					_user_time+=duration;

					_events[task->offset]._type=IF_JOB;
					plan(&_events[task->offset],duration);
				}
				
				e->_type=DEFAULT;
				break;
			
			case IF_JOB:
				if(e->_if_job){
					get(_tasks[e->_offset],duration);
					_user_time+=duration;

					e->_type=GET;
					plan(e,duration);
				}
				else{
					_bids.push(_tasks[e->_offset]);
					e->_type=DEFAULT;

					_busy=false;
				}
				break;

			case PUT:
				e->_if_job=if_job(duration);
				_user_time+=duration;

				e->_type=IF_JOB;
				plan(e,duration);
				break;

			case GET:
				proc(_tasks[e->_offset],duration);
				_user_time+=duration;
				
				e->_type=PROC;
				plan(e,duration);

				_event._type=MASTER;
				plan(&_event,0);

				_busy=false;
				break;
				
			case PROC:
				_results.push(_tasks[e->_offset]);
				e->_type=DEFAULT;
				
				if(!_busy && _event._type==DEFAULT){
					_event._type=MASTER;
					plan(&_event,0);
				}
				break;

			case DEFAULT: 
				assert(0);
				break;
		}
	}
	
	QueryPerformanceCounter(&t2);
	_duration=(double)(t2.QuadPart-t1.QuadPart)/frequency.QuadPart;

	for (int i = 0; i < _num_proc; ++i)	delete _tasks[i];
}
portBASE_TYPE xPortStartScheduler( void )
{
void *pvHandle;
long lSuccess = pdPASS;
xThreadState *pxThreadState;

	/* Install the interrupt handlers used by the scheduler itself. */
	vPortSetInterruptHandler( portINTERRUPT_YIELD, prvProcessYieldInterrupt );
	vPortSetInterruptHandler( portINTERRUPT_TICK, prvProcessTickInterrupt );
	vPortSetInterruptHandler( portINTERRUPT_DELETE_THREAD, prvProcessDeleteThreadInterrupt );

	/* Create the events and mutexes that are used to synchronise all the
	threads. */
	pvInterruptEventMutex = CreateMutex( NULL, FALSE, NULL );
	pvInterruptEvent = CreateEvent( NULL, FALSE, FALSE, NULL );

	if( ( pvInterruptEventMutex == NULL ) || ( pvInterruptEvent == NULL ) )
	{
		lSuccess = pdFAIL;
	}

	/* Set the priority of this thread such that it is above the priority of 
	the threads that run tasks.  This higher priority is required to ensure
	simulated interrupts take priority over tasks. */
	pvHandle = GetCurrentThread();
	if( pvHandle == NULL )
	{
		lSuccess = pdFAIL;
	}
	
	if( lSuccess == pdPASS )
	{
		if( SetThreadPriority( pvHandle, THREAD_PRIORITY_NORMAL ) == 0 )
		{
			lSuccess = pdFAIL;
		}
		SetThreadPriorityBoost( pvHandle, TRUE );
		SetThreadAffinityMask( pvHandle, 0x01 );
	}

	if( lSuccess == pdPASS )
	{
		/* Start the thread that simulates the timer peripheral to generate
		tick interrupts.  The priority is set below that of the simulated 
		interrupt handler so the interrupt event mutex is used for the
		handshake / overrun protection. */
		pvHandle = CreateThread( NULL, 0, prvSimulatedPeripheralTimer, NULL, 0, NULL );
		if( pvHandle != NULL )
		{
			SetThreadPriority( pvHandle, THREAD_PRIORITY_BELOW_NORMAL );
			SetThreadPriorityBoost( pvHandle, TRUE );
			SetThreadAffinityMask( pvHandle, 0x01 );
		}
		
		/* Start the highest priority task by obtaining its associated thread 
		state structure, in which is stored the thread handle. */
		pxThreadState = ( xThreadState * ) *( ( unsigned long * ) pxCurrentTCB );
		ulCriticalNesting = portNO_CRITICAL_NESTING;

		/* Bump up the priority of the thread that is going to run, in the
		hope that this will asist in getting the Windows thread scheduler to
		behave as an embedded engineer might expect. */
		ResumeThread( pxThreadState->pvThread );

		/* Handle all simulated interrupts - including yield requests and 
		simulated ticks. */
		prvProcessSimulatedInterrupts();
	}	
	
	/* Would not expect to return from prvProcessSimulatedInterrupts(), so should 
	not get here. */
	return 0;
}
Ejemplo n.º 30
0
/*
==================
WinMain
==================
*/
int main(int argc, char *argv[]) {
	const HCURSOR hcurSave = ::SetCursor( LoadCursor( 0, IDC_WAIT ) );

	Sys_SetPhysicalWorkMemory( 192 << 20, 1024 << 20 );

	win32.hInstance = GetModuleHandle(NULL);

	// done before Com/Sys_Init since we need this for error output
	Sys_CreateConsole();

	// no abort/retry/fail errors
	SetErrorMode( SEM_FAILCRITICALERRORS );

#ifdef DEBUG
	// disable the painfully slow MS heap check every 1024 allocs
	_CrtSetDbgFlag( 0 );
#endif

	if ( argc > 1 ) {
		common->Init( argc-1, &argv[1] );
	} else {
		common->Init( 0, NULL );
	}

	// hide or show the early console as necessary
	if ( win32.win_viewlog.GetInteger() || com_skipRenderer.GetBool() || idAsyncNetwork::serverDedicated.GetInteger() ) {
		Sys_ShowConsole( 1, true );
	} else {
		Sys_ShowConsole( 0, false );
	}

#ifdef SET_THREAD_AFFINITY
	// give the main thread an affinity for the first cpu
	SetThreadAffinityMask( GetCurrentThread(), 1 );
#endif

	::SetCursor( hcurSave );

	// Launch the script debugger
	if ( strstr( GetCommandLine(), "+debugger" ) ) {
		// DebuggerClientInit( lpCmdLine );
		return 0;
	}

	::SetFocus( win32.hWnd );

	// main game loop
	while( 1 ) {

		Win_Frame();

#ifdef ID_ALLOW_TOOLS
		if ( com_editors ) {
			if ( com_editors & EDITOR_GUI ) {
				// GUI editor
				GUIEditorRun();
			} else if ( com_editors & EDITOR_RADIANT ) {
				// Level Editor
				RadiantRun();
			}
			else if (com_editors & EDITOR_MATERIAL ) {
				//BSM Nerve: Add support for the material editor
				MaterialEditorRun();
			}
			else {
				if ( com_editors & EDITOR_LIGHT ) {
					// in-game Light Editor
					LightEditorRun();
				}
				if ( com_editors & EDITOR_SOUND ) {
					// in-game Sound Editor
					SoundEditorRun();
				}
				if ( com_editors & EDITOR_DECL ) {
					// in-game Declaration Browser
					DeclBrowserRun();
				}
				if ( com_editors & EDITOR_AF ) {
					// in-game Articulated Figure Editor
					AFEditorRun();
				}
				if ( com_editors & EDITOR_PARTICLE ) {
					// in-game Particle Editor
					ParticleEditorRun();
				}
				if ( com_editors & EDITOR_SCRIPT ) {
					// in-game Script Editor
					ScriptEditorRun();
				}
				if ( com_editors & EDITOR_PDA ) {
					// in-game PDA Editor
					PDAEditorRun();
				}
			}
		}
#endif
		// run the game
		common->Frame();
	}

	// never gets here
	return 0;
}