KiBeginThreadWait

VOID __stdcall KiBeginThreadWait(_ETHREAD *Thread, CHAR WaitMode, _KWAIT_REASON WaitReason, UINT8 Alertable){
  UINT8 v4; 
  __int64 v6; 
  struct _KPRCB *CurrentPrcb; 
  char v9; 
  __int64 v10; 
  UINT64 SpinCount; 
  _KWAIT_REASON v12; 
  v12 = WaitReason;
  v4 = *((_BYTE *)Thread + 390);
  v6 = WaitMode;
  while( 1 )
  {
    *((_DWORD *)Thread + 29) &= ~0x10u;
    *((_BYTE *)Thread + 112) = 0;
    *((_BYTE *)Thread + 391) = v6;
    if( Alertable )
      *((_DWORD *)Thread + 29) |= 0x10u;
    CurrentPrcb = KeGetCurrentPrcb();
    LODWORD(SpinCount) = 0;
    while( _interlockedbittestandset64((volatile signed __int32 *)Thread + 16, 0i64) )
    {
      do
        KeYieldProcessorEx(&SpinCount);
      while( *((_QWORD *)Thread + 8) );
      v10 = *((_QWORD *)CurrentPrcb + 4247);
      if( v10 && *((_BYTE *)CurrentPrcb + 32) <= 1u )
        ++*(_DWORD *)(v10 + 24);
    }
    if( !*((_BYTE *)Thread + 193) || *((_WORD *)Thread + 243) || v4 )
      break;
    KiReleaseThreadLockSafe((INT64)Thread);
    __writecr8(1ui64);
    KiDeliverApc(0, 0i64, 0i64);
    KeGetCurrentIrql();
    __writecr8(2ui64);
    *((_BYTE *)Thread + 390) = 0;
  }
  v9 = v12;
  if( Alertable )
  {
    if( *((_BYTE *)Thread + v6 + 114) )
    {
      *((_BYTE *)Thread + v6 + 114) = 0;
    }
    else if( (_BYTE)v6 && *((_ETHREAD **)Thread + 21) != (_ETHREAD *)((char *)Thread + 168) )
    {
      *((_BYTE *)Thread + 194) |= 2u;
    }
    else
    {
      if( !*((_BYTE *)Thread + 114) )
      {
LABEL_9:
        *((_BYTE *)Thread + 388) = 5;
        *((_BYTE *)Thread + 643) = v9;
        *((_DWORD *)Thread + 109) = KUSER_SHARED_DATA.TickCount.LowPart;
        *((_QWORD *)Thread + 8) = 0i64;
        return;
      }
      *((_BYTE *)Thread + 114) = 0;
    }
  }
  else if( (*((_BYTE *)Thread + 194) & 2) == 0 || !(_BYTE)v6 )
  {
    goto LABEL_9;
  }
  KiReleaseThreadLockSafe((INT64)Thread);
  KiCheckForThreadDispatch(KeGetCurrentPrcb(), v4);
}

Referenced by:

KeDelayExecutionThread
KeRemovePriQueue
KeWaitForAlertByThreadId
KeWaitForGate
KiWaitForAllObjects