KiResumeThread

VOID __stdcall KiResumeThread(_ETHREAD *Thread, _KPRCB *Prcb, UINT8 ForceResume){
  _ETHREAD *v6; 
  _ETHREAD *v7; 
  unsigned __int8 WaitBlockCount; 
  unsigned __int8 i; 
  _KWAIT_BLOCK *v10; 
  _BYTE *Object; 
  char v12; 
  _LIST_ENTRY *v13; 
  int v14; 
  __int32 v15; 
  char v16; 
  _KWAIT_BLOCK *v17; 
  unsigned __int8 WaitType; 
  INT64 WaitKey; 
  _ULARGE_INTEGER DueTime; 
  _ETHREAD *v21; 
  _QWORD *v22; 
  struct _KPRCB *CurrentPrcb; 
  _ETHREAD *CurrentThread; 
  char v25; 
  int v26; 
  _KWAIT_BLOCK **QuantumTarget; 
  UINT64 SpinCount; 
  UINT64 Hand; 
  UINT64 v30; 

  LODWORD(Hand) = 0;
  *(_DWORD *)&Thread->Tcb.gap2E0[4] = 1;
  LODWORD(SpinCount) = 0;
  while( _interlockedbittestandset64((volatile signed __int32 *)&Thread->Tcb.ThreadLock, 0i64) )
  {
    do
      KeYieldProcessorEx(&SpinCount);
    while( Thread->Tcb.ThreadLock );
  }
  if( Thread->Tcb.WaitBlockFill6[68] == 5 && (Thread->Tcb.WaitRegister.Flags & 7) == 4 )
  {
    if( !ForceResume )
    {
      Thread->Tcb.WaitRegister.Flags = Thread->Tcb.WaitRegister.Flags & 0xF8 | 5;
      KiReleaseThreadLockSafe((INT64)Thread);
      WaitBlockCount = Thread->Tcb.WaitBlockCount;
      for( i = 0; i < WaitBlockCount; ++i )
      {
        v10 = &Thread->Tcb.WaitBlockList[i];
        if( v10->BlockState == 6 )
        {
          Object = v10->Object;
          v10->BlockState = 4;
          KiAcquireKobjectLockSafe(Object);
          if( *((int *)Object + 1) > 0 || (v12 = *Object & 0x7F, v12 == 2) )
          {
            _InterlockedAnd((volatile signed __int32 *)Object, 0xFFFFFF7F);
            v10->BlockState = 5;
            ForceResume = 1;
            break;
          }
          v13 = (_LIST_ENTRY *)*((_QWORD *)Object + 2);
          if( v13->Flink != (_LIST_ENTRY *)(Object + 8) )
LABEL_60:
            __fastfail(3u);
          v10->WaitListEntry.Flink = (_LIST_ENTRY *)(Object + 8);
          v10->WaitListEntry.Blink = v13;
          v13->Flink = &v10->WaitListEntry;
          *((_QWORD *)Object + 2) = v10;
          _InterlockedAnd((volatile signed __int32 *)Object, 0xFFFFFF7F);
        }
      }
      v14 = 0;
      if( (Thread->Tcb._bf_0 & 0x20000) != 0 && !ForceResume )
      {
        DueTime = Thread->Tcb.Timer.DueTime;
        *(_DWORD *)Thread->Tcb.Timer.gap0 |= 0x40000080u;
        if( (unsigned int)KiComputeDueTime(&Thread->Tcb.Timer, (_LARGE_INTEGER)DueTime.QuadPart, 0, &Hand) )
        {
          if( KiInsertTimerTable(Prcb, &Thread->Tcb.Timer, 0i64, (unsigned int)Hand, 0i64) )
            _InterlockedAnd((volatile signed __int32 *)&Thread->Tcb.Timer, 0xFFFFFF7F);
          else
            KiTimerWaitTest(Prcb, &Thread->Tcb.Timer, 0i64);
          v14 = 1;
        }
        else
        {
          ForceResume = 1;
          v14 = 0;
        }
      }
      LODWORD(v30) = 0;
      while( _interlockedbittestandset64((volatile signed __int32 *)&Thread->Tcb.ThreadLock, 0i64) )
      {
        do
          KeYieldProcessorEx(&v30);
        while( Thread->Tcb.ThreadLock );
      }
      v15 = Thread->Tcb._bf_0 & 0xFFFDFDFF | (v14 << 9) & 0xFFFDFFFF;
      v16 = Thread->Tcb.WaitRegister.Flags & 0xE7;
      Thread->Tcb._bf_0 = v15;
      if( v16 != 5 || KiTestForAlertPending(&Thread->Tcb, (v15 & 0x10) != 0, Thread->Tcb.WaitMode, 0i64) )
      {
        ForceResume = 1;
      }
      else if( Thread->Tcb.WaitReason == 37 && (Thread->Tcb._bf_4 & 0x10) != 0 )
      {
        ForceResume = 1;
      }
    }
    Thread->Tcb.WaitRegister.Flags = Thread->Tcb.WaitRegister.Flags & 0xF8 | 1;
  }
  if( ForceResume )
  {
    if( (*(&Thread->Tcb.MiscFlags + 1) & 0x8000) != 0 )
    {
      if( Thread->Tcb.WaitBlockFill6[68] == 5 )
        KiSignalThread(Prcb, Thread, 256i64, 0i64);
    }
    else
    {
      KiSignalThreadForApc(Prcb, &Thread->Tcb.SchedulerApc, 2u);
    }
  }
  KiReleaseThreadLockSafe((INT64)Thread);
  v6 = (_ETHREAD *)&Thread->Tcb.gap2E0[8];
  v7 = *(_ETHREAD **)&Thread->Tcb.gap2E0[8];
  if( v7 != (_ETHREAD *)&Thread->Tcb.gap2E0[8] )
  {
    while( 1 )
    {
      v17 = (_KWAIT_BLOCK *)v7;
      v7 = *(_ETHREAD **)v7->Tcb.gap0;
      WaitType = v17->WaitType;
      if( WaitType == 1 )
        break;
      if( WaitType != 2 )
      {
        WaitKey = 256i64;
        goto LABEL_29;
      }
      v17->BlockState = 5;
      v21 = v17->Thread;
      v17->WaitListEntry.Flink = 0i64;
      v22 = &v21->Tcb.gap0[8];
      KeGetCurrentIrql();
      __writecr8(2ui64);
      CurrentPrcb = KeGetCurrentPrcb();
      CurrentThread = CurrentPrcb->CurrentThread;
      KiAcquireKobjectLockSafe(v21);
      if( (_QWORD *)*v22 == v22
        || LODWORD(v21->Tcb.InitialStack) >= HIDWORD(v21->Tcb.InitialStack)
        || (_ETHREAD *)CurrentThread->Tcb.Queue == v21 && CurrentThread->Tcb.WaitReason == 15
        || (KiWakeQueueWaiter(CurrentPrcb, (_KQUEUE *)v21, (INT64)v17), !v25) )
      {
        v26 = *(_DWORD *)&v21->Tcb.gap0[4];
        *(_DWORD *)&v21->Tcb.gap0[4] = v26 + 1;
        QuantumTarget = (_KWAIT_BLOCK **)v21->Tcb.QuantumTarget;
        if( *QuantumTarget != (_KWAIT_BLOCK *)&v21->Tcb.SListFaultAddress )
          goto LABEL_60;
        v17->WaitListEntry.Flink = (_LIST_ENTRY *)&v21->Tcb.SListFaultAddress;
        v17->WaitListEntry.Blink = (_LIST_ENTRY *)QuantumTarget;
        *QuantumTarget = v17;
        v21->Tcb.QuantumTarget = (unsigned __int64)v17;
        if( !v26 && (_QWORD *)*v22 != v22 )
          KiWakeOtherQueueWaiters(CurrentPrcb, (_KQUEUE *)v21);
      }
      _InterlockedAnd((volatile signed __int32 *)v21, 0xFFFFFF7F);
LABEL_30:
      if( v7 == v6 )
        goto LABEL_8;
    }
    WaitKey = v17->WaitKey;
LABEL_29:
    KiTryUnwaitThread(Prcb, v17, WaitKey, 0i64);
    goto LABEL_30;
  }
LABEL_8:
  *(_QWORD *)&v6->Tcb.gap0[8] = v6;
  *(_QWORD *)v6->Tcb.gap0 = v6;
}

Referenced by:

KeForceResumeThread
KeResumeThread
KiAdjustThreadTimer
KiThawSingleThread