KiSelectNextThread

VOID __stdcall KiSelectNextThread(_KPRCB *Prcb, _SINGLE_LIST_ENTRY *ReadyList){
  _ETHREAD *IdleThread; 
  _KPRCB *v5; 
  char Priority; 
  _BYTE *SchedulerAssist; 
  _ETHREAD *v8; 
  UINT8 IsThreadRankNonZero; 
  INT64 v10; 
  UINT64 Preempted; 

  while( 1 )
  {
    IdleThread = (_ETHREAD *)KiSelectReadyThread(1i64, Prcb);
    if( !IdleThread )
    {
      IdleThread = (_ETHREAD *)KiSelectLowestRankedThread(Prcb);
      if( !IdleThread )
        IdleThread = (_ETHREAD *)KiSelectReadyThread(0i64, Prcb);
    }
    if( !IdleThread )
      goto LABEL_5;
    if( (unsigned int)KiCheckThreadAffinity(&IdleThread->Tcb) )
      goto LABEL_15;
    if( !ReadyList )
      break;
    KiInsertDeferredReadyList((INT64)ReadyList, (INT64)IdleThread);
  }
  LODWORD(Preempted) = 1;
  KiAddThreadToReadyQueue(Prcb, 0i64, &IdleThread->Tcb, 1u, Preempted);
  IdleThread = 0i64;
LABEL_15:
  if( !IdleThread )
  {
LABEL_5:
    IdleThread = Prcb->IdleThread;
    KiSetProcessorIdle(Prcb, 1ui64, 1ui64);
  }
  if( (IdleThread->Tcb.gap0[2] & 4) == 0
    || (IsThreadRankNonZero = KiIsThreadRankNonZero(&IdleThread->Tcb, Prcb, v5), Priority = 1, !IsThreadRankNonZero) )
  {
    Priority = IdleThread->Tcb.Priority;
  }
  *Prcb->PriorityState = Priority;
  SchedulerAssist = Prcb->SchedulerAssist;
  if( SchedulerAssist )
  {
    v10 = (unsigned int)KiVpThreadSystemWorkPriority;
    if( IdleThread != Prcb->IdleThread )
      v10 = (unsigned int)Priority;
    KiSetSchedulerAssistPriority((INT32 *)Prcb->SchedulerAssist, v10, 0);
    SchedulerAssist = Prcb->SchedulerAssist;
  }
  v8 = Prcb->IdleThread;
  Prcb->NextThread = IdleThread;
  if( SchedulerAssist )
    SchedulerAssist[16] = IdleThread == v8;
  if( IdleThread->Tcb.WaitBlockFill6[68] == 1 )
    IdleThread->Tcb.ReadyTime = IdleThread->Tcb.ReadyTime
                              - IdleThread->Tcb.WaitBlock[2].SpareLong
                              + KUSER_SHARED_DATA.TickCount.LowPart;
  IdleThread->Tcb.WaitBlockFill6[68] = 3;
}

Referenced by:

KeWaitForMultipleObjects
KeWaitForSingleObject
KiExitThreadWait
KiGroupSchedulingQuantumEnd
KiQuantumEnd
KiRescheduleThreadAfterAffinityChange
KiSearchForNewThreadOnProcessor
KiSetHeteroPolicyThread
KiSetSystemAffinityThread
KiUpdateGlobalCpuSetConfiguration