Ejemplo n.º 1
0
void doneTiming()
{
  // terminate "stuck" thread
  SetEvent(endStuckEvent);
  Real_WaitForSingleObject(stuckThread,500);
  CloseHandle(stuckThread);
  CloseHandle(stuckTimer);

  // make sure all currently active waits are finished
  ResetEvent(resyncEvent);
  SetEvent(nextFrameEvent);
  if(waitCounter)
    ResetEvent(noOneWaiting);
  else
    SetEvent(noOneWaiting);

  while(Real_WaitForSingleObject(noOneWaiting,5) == WAIT_TIMEOUT)
    if(!waitCounter)
      break;

  // these functions depend on critical sections that we're about to delete.
  UnhookFunction(&Real_timeSetEvent);
  UnhookFunction(&Real_timeKillEvent);
  UnhookFunction(&Real_SetTimer);
  EnterCriticalSection(&TimerAllocLock);
  LeaveCriticalSection(&TimerAllocLock);
  DeleteCriticalSection(&TimerAllocLock);
  
  EnterCriticalSection(&TimerSeedLock);
  TimersSeeded = true;
  LeaveCriticalSection(&TimerSeedLock);
  DeleteCriticalSection(&TimerSeedLock);

  // we have to remove those, because code we call on deinitilization (especially directshow related)
  // might be using them.
  UnhookFunction(&Real_Sleep);
  UnhookFunction(&Real_WaitForSingleObject);
  UnhookFunction(&Real_WaitForMultipleObjects);
  UnhookFunction(&Real_MsgWaitForMultipleObjects);

  CloseHandle(nextFrameEvent);
  CloseHandle(resyncEvent);
  CloseHandle(noOneWaiting);
  CloseHandle(endStuckEvent);

  int runTime = Real_timeGetTime() - realStartTime;
  timeEndPeriod(1);

  if(runTime)
  {
    int rate = MulDiv(currentFrame,100*1000,runTime);
    printLog("timing: %d.%02d frames per second on average\n",rate/100,rate%100);
  }
}
Ejemplo n.º 2
0
DWORD __stdcall Mine_MsgWaitForMultipleObjects(DWORD nCount,CONST HANDLE *lpHandles,BOOL bWaitAll,DWORD dwMilliseconds,DWORD dwWakeMask)
{
  // infinite waits are always passed through
  if(dwMilliseconds >= 0x7fffffff)
    return Real_MsgWaitForMultipleObjects(nCount,lpHandles,bWaitAll,dwMilliseconds,dwWakeMask);
  else
  {
    // waitalls are harder to fake, so we just clamp them to timeout 0.
    if(bWaitAll)
      return Real_MsgWaitForMultipleObjects(nCount,lpHandles,TRUE,0,dwWakeMask);
    else
    {
      // we can't use new/delete, this might be called from a context
      // where they don't work (such as after clib deinit)
      HANDLE *handles = (HANDLE *) _alloca((nCount + 1) * sizeof(HANDLE));
      memcpy(handles,lpHandles,nCount*sizeof(HANDLE));
      handles[nCount] = nextFrameEvent;

      Real_WaitForSingleObject(resyncEvent,INFINITE);
      IncrementWaiting();
  
      DWORD result = Real_MsgWaitForMultipleObjects(nCount+1,handles,FALSE,dwMilliseconds,dwWakeMask);
      if(result == WAIT_OBJECT_0+nCount)
        result = WAIT_TIMEOUT;

      DecrementWaiting();
  
      return result;
    }
  }
}
Ejemplo n.º 3
0
VOID __stdcall Mine_Sleep(DWORD dwMilliseconds)
{
  if(dwMilliseconds)
  {
    Real_WaitForSingleObject(resyncEvent,INFINITE);

    IncrementWaiting();
    if(params.MakeSleepsLastOneFrame)
      Real_WaitForSingleObject(nextFrameEvent,dwMilliseconds);
    else
      Real_WaitForSingleObject(nextFrameEvent,params.SleepTimeout);
    DecrementWaiting();
  }
  else
    Real_Sleep(0);
}
Ejemplo n.º 4
0
DWORD __stdcall Mine_WaitForSingleObject(HANDLE hHandle,DWORD dwMilliseconds)
{
  if(dwMilliseconds <= 0x7fffffff)
  {
    Real_WaitForSingleObject(resyncEvent,INFINITE);
    IncrementWaiting();

    HANDLE handles[] = { hHandle, nextFrameEvent };
    DWORD result = Real_WaitForMultipleObjects(2,handles,FALSE,dwMilliseconds);

    DecrementWaiting();

    if(result == WAIT_OBJECT_0+1)
      result = WAIT_TIMEOUT;

    return result;
  }
  else
    return Real_WaitForSingleObject(hHandle,dwMilliseconds);
}
Ejemplo n.º 5
0
DWORD __stdcall My_WaitForSingleObject(HANDLE a0,DWORD a1)
{
   
   	if( calledFromSC() ){
		AddAddr( SCOffset() );	
		LogAPI("WaitForSingleObject(%x,%x)\n", a0, a1);
	}

    DWORD ret = 0;
    try {
        ret = Real_WaitForSingleObject(a0, a1);
    }
	catch(...){	} 

    return ret;
}
Ejemplo n.º 6
0
void nextFrameTiming()
{
  ResetEvent(resyncEvent);
  SetEvent(nextFrameEvent);
  if(waitCounter)
    ResetEvent(noOneWaiting);
  else
    SetEvent(noOneWaiting);

  while(Real_WaitForSingleObject(noOneWaiting,5) == WAIT_TIMEOUT)
    if(!waitCounter)
      break;

  ResetEvent(nextFrameEvent);
  SetEvent(resyncEvent);

  DWORD oldFrameTime = UMulDiv(currentFrame,1000*frameRateDenom,frameRateScaled);
  DWORD newFrameTime = UMulDiv(currentFrame+1,1000*frameRateDenom,frameRateScaled);
  ProcessEventTimers(newFrameTime - oldFrameTime);

  if(!currentFrame)
    realStartTime = Real_timeGetTime();

  if(params.EnableAutoSkip)
  {
    LARGE_INTEGER due;
    due.QuadPart = -10*1000*__int64(params.FrameTimeout);
    SetWaitableTimer(stuckTimer,&due,0,0,0,FALSE);
  }

  if(exitNextFrame)
  {
    printLog("main: clean exit requested, doing my best...\n");
    ExitProcess(0);
  }

  // make sure there's always a message in the queue for next frame
  // (some old hjb intros stop when there's no new messages)
  PostMessage(GetForegroundWindow(),WM_NULL,0,0);
  currentFrame++;
  timerHammeringCounter = 0;
}