KiGroupSchedulingGenerationEnd

VOID __stdcall KiGroupSchedulingGenerationEnd(_KPRCB *Prcb, UINT64 CurrentTick, UINT8 Parking){
  INT64 v3; 
  _ETHREAD *CurrentThread; 
  _ETHREAD *IdleThread; 
  _KPRCB *v9; 
  _ETHREAD *NextThread; 
  int v11; 
  INT64 v12; 
  _ETHREAD *v13; 
  _KPRCB *v14; 
  _ETHREAD *v15; 
  _ETHREAD *v16; 
  char Priority; 
  INT64 v18; 
  char v19; 
  _BYTE *SchedulerAssist; 
  bool v21; 
  UINT64 v22; 
  UINT64 v23; 
  UINT8 v24; 
  UINT8 IsThreadRankNonZero; 
  INT64 v26; 
  INT64 v27; 
  INT64 ShareRankNonZero; 
  INT64 v29; 
  INT64 v30; 

  CurrentThread = Prcb->CurrentThread;
  IdleThread = Prcb->IdleThread;
  if( !Parking )
  {
    _disable();
    KiEndThreadCycleAccumulation((INT64)Prcb, (INT64)Prcb->CurrentThread, 0i64, v3, ShareRankNonZero, v29, v30);
    _enable();
  }
  KiTransitionSchedulingGroupGeneration(Prcb, CurrentTick, Parking);
  if( !Parking )
  {
    NextThread = Prcb->NextThread;
    v11 = 0;
    if( NextThread )
    {
      if( NextThread == Prcb->IdleThread )
        goto LABEL_9;
      Prcb->NextThread = 0i64;
      if( (CurrentThread->Tcb.gap0[2] & 4) == 0
        || (IsThreadRankNonZero = KiIsThreadRankNonZero(&CurrentThread->Tcb, Prcb, v9),
            Priority = 1,
            !IsThreadRankNonZero) )
      {
        Priority = CurrentThread->Tcb.Priority;
      }
      *Prcb->PriorityState = Priority;
      if( Prcb->SchedulerAssist )
      {
        v26 = (unsigned int)KiVpThreadSystemWorkPriority;
        if( CurrentThread != Prcb->IdleThread )
          v26 = (unsigned int)Priority;
        KiSetSchedulerAssistPriority((INT32 *)Prcb->SchedulerAssist, v26, 0);
      }
      NextThread->Tcb.WaitBlockFill6[68] = 1;
      v18 = (unsigned int)NextThread->Tcb.Priority;
      NextThread->Tcb.WaitBlock[2].SpareLong = KUSER_SHARED_DATA.TickCount.LowPart;
      KiAddThreadToPrcbQueue(Prcb, &NextThread->Tcb, v18, 1ui64, 0);
      v11 = 1;
    }
    if( NextThread == Prcb->IdleThread )
      goto LABEL_9;
    if( CurrentThread == IdleThread )
    {
      v12 = 0i64;
    }
    else
    {
      v12 = (unsigned int)(CurrentThread->Tcb.Priority + 1);
      if( (int)v12 > 31 )
        goto LABEL_9;
    }
    v13 = (_ETHREAD *)KiSelectReadyThread(v12, Prcb);
    v15 = v13;
    if( v13 )
    {
      if( (v13->Tcb.gap0[2] & 4) != 0 )
      {
        v24 = KiIsThreadRankNonZero(&v13->Tcb, Prcb, v14);
        v19 = 1;
        if( !v24 )
          v19 = v15->Tcb.Priority;
      }
      else
      {
        v19 = v13->Tcb.Priority;
      }
      *Prcb->PriorityState = v19;
      SchedulerAssist = Prcb->SchedulerAssist;
      if( SchedulerAssist )
      {
        v27 = (unsigned int)KiVpThreadSystemWorkPriority;
        if( v15 != Prcb->IdleThread )
          v27 = (unsigned int)v19;
        KiSetSchedulerAssistPriority((INT32 *)Prcb->SchedulerAssist, v27, 0);
        SchedulerAssist = Prcb->SchedulerAssist;
      }
      v21 = v15 == Prcb->IdleThread;
      Prcb->NextThread = v15;
      if( SchedulerAssist )
        SchedulerAssist[16] = v21;
      if( v15->Tcb.WaitBlockFill6[68] == 1 )
        v15->Tcb.ReadyTime = v15->Tcb.ReadyTime - v15->Tcb.WaitBlock[2].SpareLong + KUSER_SHARED_DATA.TickCount.LowPart;
      v15->Tcb.WaitBlockFill6[68] = 3;
      --v11;
    }
LABEL_9:
    if( CurrentThread != IdleThread )
    {
LABEL_10:
      _disable();
      KiStartThreadCycleAccumulation(Prcb, &CurrentThread->Tcb, CurrentThread == IdleThread);
      _enable();
      return;
    }
    if( v11 > 0 )
    {
      if( (Prcb->IdleState & 1) != 0 )
      {
        v22 = 1i64;
        v23 = 1i64;
LABEL_36:
        KiSetProcessorIdle(Prcb, v23, v22);
      }
    }
    else if( v11 < 0 && (Prcb->IdleState & 1) == 0 )
    {
      v22 = 0i64;
      v23 = 0i64;
      goto LABEL_36;
    }
    v16 = Prcb->NextThread;
    if( !v16 || v16 == Prcb->IdleThread )
    {
      if( (Prcb->IdleState & 1) == 0 )
        goto LABEL_10;
    }
    else if( (Prcb->IdleState & 1) != 0 )
    {
      goto LABEL_10;
    }
    __fastfail(0x1Eu);
  }
}

Referenced by:

KeTransitionProcessorParkState
KiGroupSchedulingQuantumEnd