KiQueueReadyThread

VOID __stdcall KiQueueReadyThread(_KPRCB *Prcb, _ETHREAD *Thread){
  _KPRCB *v2; 
  unsigned __int64 CycleTime; 
  unsigned int Preempted; 
  _KSCHEDULING_GROUP *volatile SchedulingGroup; 
  _KSCHEDULING_GROUP *v8; 
  unsigned __int64 v9; 
  _KSCHEDULING_GROUP *volatile v10; 
  _KSCB *v11; 
  _BYTE *SchedulerAssist; 
  __int64 Priority; 
  unsigned __int64 SharedReadyQueueMask; 
  struct _KPRCB *CurrentPrcb; 
  _KSHARED_READY_QUEUE *SharedReadyQueue; 
  _LIST_ENTRY *v17; 
  _LIST_ENTRY *v18; 
  _LIST_ENTRY *v19; 
  __int64 v20; 
  _LIST_ENTRY *v21; 
  _KSCB *v22; 
  int v23; 
  __int16 v24; 
  _KSCB *v25; 
  _ETHREAD *NextThread; 
  _KSCB *v27; 
  int v28; 
  _LIST_ENTRY *v29; 
  _LIST_ENTRY *v30; 
  _LIST_ENTRY *Flink; 
  unsigned int ReadySummary; 
  __int64 ExpectedRunTime; 
  int IdealProcessor; 
  unsigned int v35; 
  unsigned __int64 v36; 
  _ETHREAD *v37; 
  int v38; 
  _DWORD *v39; 
  _LIST_ENTRY *Blink; 
  bool v41; 
  NTSTATUS GuestSchedulerAssistPriority; 
  _BYTE *v43; 
  _QWORD *v44; 
  _SINGLE_LIST_ENTRY ReadyList; 
  UINT8 ShareRankNonZero; 
  UINT64 SpinCount; 
  _KSCHEDULING_GROUP *volatile v48; 

  CycleTime = Thread->Tcb.CycleTime;
  Preempted = Thread->Tcb.Preempted;
  if( Thread->Tcb.AffinityVersion != KiCpuSetSequence && (Thread->Tcb._bf_0 & 8) == 0
    || CycleTime >= Thread->Tcb.QuantumTarget )
  {
    if( KiTryToAcquireThreadLock(&Thread->Tcb, 0i64) )
    {
      IdealProcessor = Thread->Tcb.IdealProcessor;
      if( CycleTime >= Thread->Tcb.QuantumTarget )
      {
        v35 = KiComputeNewPriority(&Thread->Tcb, 1);
        if( !(unsigned __int8)KiUpdateVPBackingThreadPriority(Thread) )
          KiUpdateThreadPriority(0i64, &Thread->Tcb, v35, 0);
        v36 = CycleTime + (unsigned int)Thread->Tcb.SchedulerApc.SpareByte1 * KiCyclesPerClockQuantum;
        if( (*(&Thread->Tcb.MiscFlags + 1) & 0x20) != 0 )
          _interlockedbittestandreset((volatile signed __int32 *)&Thread->Tcb.116 + 1, 5u);
        Thread->Tcb.QuantumTarget = v36;
        KiTryScheduleNextForegroundBoost(&Thread->Tcb);
        Preempted = 0;
      }
      if( !(unsigned int)KiCheckThreadAffinity(&Thread->Tcb)
        && (unsigned int)KiComputeThreadAffinity(&v37->Tcb)
        && !(unsigned int)KiPrcbInGroupAffinity(Prcb, &Thread->Tcb.Affinity) )
      {
        _interlockedbittestandset((volatile signed __int32 *)&Thread->Tcb.116 + 1, 0xCu);
      }
      v38 = Thread->Tcb.IdealProcessor;
      KiReleaseThreadLockSafe((INT64)Thread);
      if( (xmmword_140CFB490 & 0x8000000) != 0 )
        EtwTraceIdealProcessor((__int64)Thread, 0x546u, IdealProcessor, v38);
    }
    else
    {
      _interlockedbittestandset((volatile signed __int32 *)&Thread->Tcb.116 + 1, 0xCu);
    }
  }
  SchedulingGroup = Thread->Tcb.SchedulingGroup;
  v48 = SchedulingGroup;
  v8 = SchedulingGroup;
  if( SchedulingGroup )
  {
    v22 = (_KSCB *)((char *)SchedulingGroup + Prcb->ScbOffset);
    if( v22 )
    {
      v23 = 0;
      while( 1 )
      {
        if( (*((_BYTE *)v22 + 112) & 4) != 0 )
        {
          if( KiCheckMaxOverQuotaTransition(v22, v8) )
          {
            if( (*((_BYTE *)v22 + 112) & 1) != 0 )
              KiRemoveSchedulingGroupQueue(Prcb, v22, 1u);
          }
          else if( v22->GenerationCycles >= v22->RankCycleTarget && (*((_BYTE *)v22 + 112) & 2) == 0 )
          {
            KiRecomputeGroupSchedulingRank(v8, v22, Prcb);
          }
        }
        else
        {
          KiComputeGroupSchedulingRank(v8, Prcb, v22);
        }
        v23 += v22->Rank;
        v22 = v22->Parent;
        if( !v22 )
          break;
        v8 = (_KSCHEDULING_GROUP *)((char *)v22 - Prcb->ScbOffset);
        v48 = v8;
      }
      if( (*(&Thread->Tcb.MiscFlags + 1) & 0x200) == 0
        && Thread->Tcb.Priority < 16
        && KiShouldPreemptionBeDeferred(&Thread->Tcb)
        && v23
        && (v24 & 0xC00) == 0 )
      {
        _interlockedbittestandset((volatile signed __int32 *)&Thread->Tcb.116 + 1, 0xBu);
      }
    }
  }
  v9 = 0i64;
  if( Thread->Tcb.Priority >= KiRebalanceMinPriority || (Prcb->IdleState & 2) != 0 )
  {
    v10 = Thread->Tcb.SchedulingGroup;
    if( !v10 || (v25 = (_KSCB *)((char *)v10 + Prcb->ScbOffset)) == 0i64 || !KiCheckForMaxOverQuotaScb(v25) )
      v9 = Thread->Tcb.Affinity.Mask & Prcb->ParentNode->IdleNonParkedCpuSet;
  }
  if( (*(&Thread->Tcb.MiscFlags + 1) & 0x1000) == 0 && !v9 )
  {
    Thread->Tcb.Preempted = 0;
    Thread->Tcb.WaitBlock[2].SpareLong = KUSER_SHARED_DATA.TickCount.LowPart;
    v11 = (_KSCB *)Thread->Tcb.SchedulingGroup;
    if( v11 )
      v11 = (_KSCB *)((char *)v11 + Prcb->ScbOffset);
    SchedulerAssist = Prcb->SchedulerAssist;
    if( SchedulerAssist )
      SchedulerAssist[16] = 0;
    Thread->Tcb.WaitBlockFill6[68] = 1;
    ShareRankNonZero = 0;
    if( v11 )
    {
      if( (*(&Thread->Tcb.MiscFlags + 1) & 0xC00) == 0 )
      {
        KiGetThreadEffectiveRankNonZero(Thread, v11, v2, 0, &ShareRankNonZero);
        if( v28 )
        {
          KiAddThreadToScbQueue(Prcb, v27, &Thread->Tcb, Preempted);
          goto LABEL_25;
        }
      }
    }
    Priority = Thread->Tcb.Priority;
    if( (*(&Thread->Tcb.MiscFlags + 1) & 0x400000) != 0 )
    {
      _InterlockedOr((volatile signed __int32 *)Thread->Tcb.SchedulerAssist, 0x40000u);
      if( (*(&Thread->Tcb.MiscFlags + 1) & 0x400000) != 0 )
      {
        v41 = 0;
        GuestSchedulerAssistPriority = KiReadGuestSchedulerAssistPriority((INT64)Thread);
        if( GuestSchedulerAssistPriority >= 16 )
          GuestSchedulerAssistPriority = 15;
        if( GuestSchedulerAssistPriority != Thread->Tcb.SchedulerAssistPriorityFloor )
        {
          KxAcquireSpinLock(&KiUpdateVpThreadPriorityLock);
          v43 = Thread->Tcb.gap3F0;
          if( *(_QWORD *)Thread->Tcb.gap3F0 == 1i64 )
          {
            v44 = (_QWORD *)qword_140C31CE8;
            v41 = KiUpdateVpThreadPriorityListHead == (_QWORD)&KiUpdateVpThreadPriorityListHead;
            if( *(__int64 **)qword_140C31CE8 != &KiUpdateVpThreadPriorityListHead )
              goto LABEL_95;
            *(_QWORD *)v43 = &KiUpdateVpThreadPriorityListHead;
            *(_QWORD *)&Thread->Tcb.gap3F0[8] = v44;
            *v44 = v43;
            qword_140C31CE8 = (__int64)Thread->Tcb.gap3F0;
          }
          KxReleaseSpinLock(&KiUpdateVpThreadPriorityLock);
          if( v41 )
            KeInsertQueueDpc((UINT64)&KiUpdateVpThreadPriorityDpc, 0i64, 0i64);
        }
      }
    }
    SharedReadyQueueMask = Prcb->SharedReadyQueueMask;
    if( (*(&Thread->Tcb.MiscFlags + 1) & 0x2000) == 0
      || !SharedReadyQueueMask
      || (SharedReadyQueueMask & Thread->Tcb.Affinity.Mask) != SharedReadyQueueMask
      || ShareRankNonZero )
    {
      v29 = (_LIST_ENTRY *)Thread->Tcb.gapD8;
      v30 = &Prcb->DispatcherReadyListHead[Priority];
      if( Preempted )
      {
        Flink = v30->Flink;
        if( v30->Flink->Blink != v30 )
          goto LABEL_95;
        v29->Flink = Flink;
        *(_QWORD *)&Thread->Tcb.gapD8[8] = v30;
        Flink->Blink = v29;
        v30->Flink = v29;
        _bittestandset(&Prcb->AffinitizedSelectionMask, Priority);
      }
      else
      {
        Blink = v30->Blink;
        if( Blink->Flink != v30 )
          goto LABEL_95;
        v29->Flink = v30;
        *(_QWORD *)&Thread->Tcb.gapD8[8] = Blink;
        Blink->Flink = v29;
        v30->Blink = v29;
      }
      ReadySummary = Prcb->ReadySummary;
      ++Prcb->ReadyThreadCount;
      Prcb->ReadySummary = ReadySummary | (1 << Priority);
      ExpectedRunTime = Thread->Tcb.ExpectedRunTime;
      Thread->LastExpectedRunTime = ExpectedRunTime;
      Prcb->ReadyQueueExpectedRunTime += ExpectedRunTime;
      goto LABEL_25;
    }
    CurrentPrcb = KeGetCurrentPrcb();
    SharedReadyQueue = Prcb->SharedReadyQueue;
    v17 = &SharedReadyQueue->ReadyListHead[Priority];
    LODWORD(SpinCount) = 0;
    while( _interlockedbittestandset64((volatile signed __int32 *)SharedReadyQueue, 0i64) )
    {
      do
        KeYieldProcessorEx(&SpinCount);
      while( SharedReadyQueue->Lock );
      v39 = CurrentPrcb->SchedulerAssist;
      if( v39 )
      {
        if( CurrentPrcb->NestingLevel <= 1u )
          ++v39[6];
      }
    }
    v18 = (_LIST_ENTRY *)Thread->Tcb.gapD8;
    if( Preempted )
    {
      v19 = v17->Flink;
      if( v17->Flink->Blink == v17 )
      {
        v18->Flink = v19;
        *(_QWORD *)&Thread->Tcb.gapD8[8] = v17;
        v19->Blink = v18;
        v17->Flink = v18;
        _bittestandreset(&Prcb->AffinitizedSelectionMask, Priority);
LABEL_24:
        SharedReadyQueue->ReadySummary |= 1 << Priority;
        Thread->Tcb._bf_0 |= 0x80000000;
        ++SharedReadyQueue->ReadyThreadCount;
        v20 = Thread->Tcb.ExpectedRunTime;
        Thread->LastExpectedRunTime = v20;
        SharedReadyQueue->ReadyQueueExpectedRunTime += v20;
        _InterlockedAnd64((volatile signed __int64 *)SharedReadyQueue, 0i64);
LABEL_25:
        _InterlockedAnd64((volatile signed __int64 *)&Prcb->PrcbLock, 0i64);
        return;
      }
    }
    else
    {
      v21 = v17->Blink;
      if( v21->Flink == v17 )
      {
        v18->Flink = v17;
        *(_QWORD *)&Thread->Tcb.gapD8[8] = v21;
        v21->Flink = v18;
        v17->Blink = v18;
        goto LABEL_24;
      }
    }
LABEL_95:
    __fastfail(3u);
  }
  NextThread = Prcb->NextThread;
  KiEnterDeferredReadyState((INT64)Thread);
  _InterlockedAnd64((volatile signed __int64 *)&Prcb->PrcbLock, 0i64);
  _interlockedbittestandreset((volatile signed __int32 *)&Thread->Tcb.116 + 1, 0xCu);
  Thread->Tcb.Preempted = Preempted;
  ReadyList.Next = (_SINGLE_LIST_ENTRY *)Thread->Tcb.gapD8;
  *(_QWORD *)Thread->Tcb.gapD8 = 0i64;
  KiReadyDeferredReadyList(Prcb, &ReadyList);
  if( !NextThread && Prcb->CurrentThread != Prcb->IdleThread && Prcb->NextThread )
    KiRequestSoftwareInterrupt(Prcb, 2);
}

Referenced by:

KeBoostPriorityThread
KeCpuSetReportParkedProcessors
KeDelayExecutionThread
KeRecomputeCpuSetAffinityProcess
KeRemoveQueueEx
KeSetAffinityThread
KeSetBasePriorityThread
KeSetCpuSetsProcess
KeSetLegacyAffinityThread
KeSetSchedulingGroupRankBias
KeSetSelectedCpuSetsThread
KeSetThreadSchedulerAssist
KeUpdateThreadCpuSets
KeYieldExecution
KiAbForceProcessLockEntry
KiAbThreadUnboostCpuPriority
KiCheckForThreadDispatch
KiExitDispatcher
KiProcessDeferredReadyList
KiQuantumEnd
KiReadyOutSwappedThreads
KiSchedulerApc
KiSetHeteroPolicyThread
KxDispatchInterrupt
PsImpersonateContainerOfThread