KiCheckForTimerExpiration

VOID __stdcall KiCheckForTimerExpiration(_KPRCB *Prcb){
  char v1; 
  char *v2; 
  _KPRCB *v4; 
  _KTIMER_TABLE *p_TimerTable; 
  bool v6; 
  bool v7; 
  unsigned int v8; 
  __int64 v9; 
  __int64 v10; 
  int v11; 
  unsigned int *LastTimerHand; 
  int v13; 
  unsigned int v14; 
  unsigned int v15; 
  unsigned __int64 QuadPart; 
  UINT64 v17; 
  char *v18; 
  UINT64 v19; 
  unsigned __int8 CurrentIrql; 
  unsigned int ClockIntervalOneShot; 
  unsigned __int16 v22; 
  UINT64 v23; 
  bool v24; 
  unsigned int v25; 
  __int128 v26; 

  v26 = 0i64;
  v1 = 0;
  v2 = *(char **)&KUSER_SHARED_DATA.InterruptTime.LowPart;
  if( (Prcb->DpcRequestSummary & 8) == 0 )
  {
    if( KiSerializeTimerExpiration )
    {
      if( !Prcb->ClockOwner )
        goto LABEL_4;
      v4 = KiProcessorBlock;
    }
    else
    {
      v4 = Prcb;
    }
    p_TimerTable = &v4->TimerTable;
    if( v4 != (_KPRCB *)-14656i64 )
    {
      v6 = v4->TimerTable.TableState.LastTimerExpiration[0] != KiLastPseudoHrTimerExpiration;
      v7 = v6;
      if( (KiVelocityFlags & 0x2000) != 0 )
        v7 = v4->TimerTable.TableState.LastTimerExpiration[1] != (_QWORD)KiLastNonHrTimerExpiration;
      v24 = v4->TimerTable.TableState.LastTimerExpiration[0] != KiLastPseudoHrTimerExpiration;
      if( v7 || v4->TimerTable.TableState.LastTimerExpiration[0] != KiLastPseudoHrTimerExpiration )
      {
        v8 = 0;
        v9 = *(_QWORD *)&KUSER_SHARED_DATA.InterruptTime.LowPart >> 18;
        v10 = 0i64;
        v11 = -1;
        LastTimerHand = v4->TimerTable.TableState.LastTimerHand;
        while( 1 )
        {
          v13 = *LastTimerHand + 255;
          if( (unsigned int)v9 - *LastTimerHand < 0x100 )
            v13 = v9;
          v14 = *LastTimerHand - 1;
          while( 1 )
          {
            ++v14;
            v15 = v11;
            QuadPart = p_TimerTable->TimerEntries[v10][(unsigned __int8)v14].Time.QuadPart;
            if( v8 != 1 || v7 )
              break;
            if( (unsigned __int64)v2 >= QuadPart )
            {
              v11 = v14;
              if( v15 < v14 )
                v11 = v15;
              if( (unsigned __int64)&v2[KePseudoHrTimeIncrement] > (unsigned int)KeNonHrTimeIncrement + QuadPart )
              {
                v1 = 1;
                KiLastNonHrTimerExpiration = v2;
                v7 = 1;
                v14 = v11;
                goto LABEL_22;
              }
            }
LABEL_19:
            if( v14 == v13 )
              goto LABEL_20;
          }
          if( (unsigned __int64)v2 < QuadPart )
            goto LABEL_19;
          v1 = 1;
LABEL_20:
          if( !v8 || v7 )
LABEL_22:
            p_TimerTable->TableState.LastTimerHand[v8] = v14;
          ++v8;
          ++LastTimerHand;
          ++v10;
          LODWORD(v9) = v13;
          if( v8 >= 2 )
          {
            v6 = v24;
            break;
          }
        }
      }
      if( !Prcb->ClockOwner )
        goto LABEL_5;
      if( !v7
        && v6
        && (unsigned __int64)v2 >= qword_140C31A98
        && (unsigned __int64)&v2[KePseudoHrTimeIncrement] > (unsigned __int64)(unsigned int)KeNonHrTimeIncrement
                                                          + qword_140C31A98 )
      {
        KiLastNonHrTimerExpiration = v2;
LABEL_59:
        v1 = 1;
        goto LABEL_4;
      }
      if( v1 )
        goto LABEL_4;
      if( v7 )
      {
        if( KiNextTimer2DueTime <= (unsigned __int64)v2 )
          v1 = 1;
      }
      else if( v6 && qword_140C31A80 <= (unsigned __int64)v2 || DueTime <= (unsigned __int64)v2 )
      {
        goto LABEL_59;
      }
    }
  }
LABEL_4:
  if( !Prcb->ClockOwner )
    goto LABEL_5;
  v17 = DueTime;
  v18 = &v2[(unsigned int)KeMaximumIncrement];
  if( DueTime > (unsigned __int64)v2 )
  {
    v19 = KiClockOwnerOneShotRequest;
    if( !KiClockOwnerOneShotRequest )
      v19 = -1i64;
    if( v19 != DueTime )
    {
      CurrentIrql = KeGetCurrentIrql();
      __writecr8(0xFui64);
      if( (unsigned __int64)v18 <= v17 )
      {
        if( KiClockOwnerOneShotRequest )
        {
          PoTraceSystemTimerResolutionKernel(0i64, 0x534F5248ui64);
          KiClockOwnerOneShotRequest = 0i64;
          KiSetClockIntervalToMinimumRequested();
        }
      }
      else
      {
        KiClockOwnerOneShotRequest = v17;
        KiSetClockIntervalToMinimumRequested();
        ClockIntervalOneShot = KiGetClockIntervalOneShot(v17, (INT64)v2);
        PoTraceSystemTimerResolutionKernel(ClockIntervalOneShot, 0x534F5248ui64);
      }
      __writecr8(CurrentIrql);
    }
LABEL_5:
    if( !v1 )
      return;
  }
  v25 = 0;
  _m_prefetchw(&Prcb->12588);
  v22 = Prcb->DpcRequestSlot[0];
  v23 = v22;
  for( BYTE1(v23) = HIBYTE(v22);
        v22 != _InterlockedCompareExchange16((volatile signed __int16 *)&Prcb->12588, v22 | 8, v22);
        BYTE1(v23) = HIBYTE(v22) )
  {
    RtlBackoff(&v25);
    _m_prefetchw(&Prcb->12588);
    v22 = Prcb->DpcRequestSlot[0];
    v23 = v22;
  }
  if( (v22 & 0x29) == 0 )
  {
    if( Prcb->NestingLevel )
    {
      Prcb->InterruptRequest = 1;
    }
    else
    {
      LOBYTE(v23) = 2;
      HalRequestSoftwareInterrupt(v23);
    }
  }
}

Referenced by:

KeAccumulateTicks