KiGroupSchedulingQuantumEnd

VOID __stdcall KiGroupSchedulingQuantumEnd(
        _KPRCB *Prcb,
        _ETHREAD *Thread,
        UINT8 RoundRobin,
        _SINGLE_LIST_ENTRY *ReadyList){
  _KPRCB *v4; 
  unsigned __int64 TickCountQuad; 
  char v8; 
  struct _KPRCB *CurrentPrcb; 
  char v10; 
  _ETHREAD *NextThread; 
  _KSCB *SchedulingGroup; 
  _KSCHEDULING_GROUP *volatile v13; 
  _KSCHEDULING_GROUP *v14; 
  _KSCB *v15; 
  char v16; 
  char v17; 
  _KSCB *v18; 
  _ETHREAD *v19; 
  INT64 v20; 
  int v21; 
  _ETHREAD *v22; 
  _KPRCB *v23; 
  _ETHREAD *v24; 
  struct _KPRCB *v25; 
  _DWORD *v26; 
  _ETHREAD *v27; 
  _KPRCB *v28; 
  _DWORD *SchedulerAssist; 
  char v30; 
  _BYTE *v31; 
  UINT8 v32; 
  INT64 v33; 
  UINT8 IsThreadRankNonZero; 
  char Priority; 
  _BYTE *v36; 
  INT64 v37; 
  bool v38; 
  _KSCB *v39; 
  _KSCB *v40; 
  int v41; 
  char ShareRankNonZero[4]; 
  UINT64 SpinCount; 
  _KSCHEDULING_GROUP *volatile v44; 
  _ETHREAD *Threada; 
  char v46; 

  v4 = 0i64;
  v44 = 0i64;
  ShareRankNonZero[0] = 0;
  v46 = 0;
  TickCountQuad = KUSER_SHARED_DATA.TickCountQuad;
  v8 = 0;
  CurrentPrcb = KeGetCurrentPrcb();
  v10 = 0;
  LODWORD(SpinCount) = 0;
  while( _interlockedbittestandset64((volatile signed __int32 *)&Prcb->PrcbLock, 0i64) )
  {
    do
      KeYieldProcessorEx(&SpinCount);
    while( Prcb->PrcbLock );
    SchedulerAssist = CurrentPrcb->SchedulerAssist;
    if( SchedulerAssist && CurrentPrcb->NestingLevel <= 1u )
      ++SchedulerAssist[6];
  }
  NextThread = Prcb->NextThread;
  SchedulingGroup = 0i64;
  Threada = NextThread;
  if( NextThread )
  {
    SchedulingGroup = (_KSCB *)NextThread->Tcb.SchedulingGroup;
    if( SchedulingGroup )
      SchedulingGroup = (_KSCB *)((char *)SchedulingGroup + Prcb->ScbOffset);
  }
  if( TickCountQuad > Prcb->GenerationTarget )
  {
    KiGroupSchedulingGenerationEnd(Prcb, TickCountQuad, 0);
    return;
  }
  v13 = Thread->Tcb.SchedulingGroup;
  v14 = v13;
  v44 = v13;
  if( v13 )
  {
    v15 = (_KSCB *)((char *)v13 + Prcb->ScbOffset);
    if( v15 )
    {
      while( 1 )
      {
        v16 = *((_BYTE *)v15 + 112);
        if( (v16 & 4) != 0 )
          break;
        KiComputeGroupSchedulingRank(v14, Prcb, v15);
        if( (*((_BYTE *)v15 + 112) & 4) == 0 )
          goto LABEL_16;
        v10 = 1;
        v8 = 1;
        if( SchedulingGroup != v15 )
          goto LABEL_16;
        v17 = 1;
        v46 = 1;
LABEL_17:
        v15 = v15->Parent;
        if( !v15 )
        {
          v18 = (_KSCB *)Thread->Tcb.SchedulingGroup;
          v19 = Threada;
          if( v18 )
            v18 = (_KSCB *)((char *)v18 + Prcb->ScbOffset);
          if( !v10 || Threada )
          {
            if( v8 && Threada && SchedulingGroup )
            {
              if( SchedulingGroup == v18 )
                goto LABEL_39;
              while( SchedulingGroup )
              {
                SchedulingGroup = SchedulingGroup->Parent;
                if( SchedulingGroup == v18 )
                  goto LABEL_39;
              }
              if( !v18 || v17 )
              {
LABEL_39:
                v27 = (_ETHREAD *)KiChooseLowestRankedThread(
                                    Prcb,
                                    &Threada->Tcb,
                                    (unsigned int)(Threada->Tcb.Priority + 1));
                if( v27 )
                {
                  v19->Tcb.WaitBlockFill6[68] = 1;
                  v19->Tcb.WaitBlock[2].SpareLong = KUSER_SHARED_DATA.TickCount.LowPart;
                  if( (v27->Tcb.gap0[2] & 4) == 0
                    || (IsThreadRankNonZero = KiIsThreadRankNonZero(&v27->Tcb, Prcb, v28),
                        Priority = 1,
                        !IsThreadRankNonZero) )
                  {
                    Priority = v27->Tcb.Priority;
                  }
                  *Prcb->PriorityState = Priority;
                  v36 = Prcb->SchedulerAssist;
                  if( v36 )
                  {
                    v37 = (unsigned int)KiVpThreadSystemWorkPriority;
                    if( v27 != Prcb->IdleThread )
                      v37 = (unsigned int)Priority;
                    KiSetSchedulerAssistPriority((INT32 *)Prcb->SchedulerAssist, v37, 0);
                    v36 = Prcb->SchedulerAssist;
                  }
                  v38 = v27 == Prcb->IdleThread;
                  Prcb->NextThread = v27;
                  if( v36 )
                    v36[16] = v38;
                  if( v27->Tcb.WaitBlockFill6[68] == 1 )
                    v27->Tcb.ReadyTime = v27->Tcb.ReadyTime
                                       - v27->Tcb.WaitBlock[2].SpareLong
                                       + KUSER_SHARED_DATA.TickCount.LowPart;
                  v27->Tcb.WaitBlockFill6[68] = 3;
                  v39 = (_KSCB *)v19->Tcb.SchedulingGroup;
                  if( v39 )
                    v39 = (_KSCB *)((char *)v39 + Prcb->ScbOffset);
                  KiGetThreadEffectiveRankNonZero(v19, v39, v28, 1u, (UINT8 *)ShareRankNonZero);
                  if( v41 )
                    KiAddThreadToScbQueue(Prcb, v40, &v19->Tcb, 1ui64);
                  else
                    KiAddThreadToPrcbQueue(Prcb, &v19->Tcb, (unsigned int)v19->Tcb.Priority, 1ui64, ShareRankNonZero[0]);
                }
              }
            }
          }
          else
          {
            KiGetThreadEffectiveRankNonZero(Thread, v18, v4, 1u, 0i64);
            v20 = (unsigned int)Thread->Tcb.Priority;
            if( v21 )
              v22 = (_ETHREAD *)KiChooseLowestRankedThread(Prcb, &Thread->Tcb, (unsigned int)v20);
            else
              v22 = (_ETHREAD *)KiSelectReadyThread(v20, Prcb);
            v24 = v22;
            if( v22 )
            {
              if( (v22->Tcb.gap0[2] & 4) == 0 || (v32 = KiIsThreadRankNonZero(&v22->Tcb, Prcb, v23), v30 = 1, !v32) )
                v30 = v24->Tcb.Priority;
              *Prcb->PriorityState = v30;
              v31 = Prcb->SchedulerAssist;
              if( v31 )
              {
                v33 = (unsigned int)KiVpThreadSystemWorkPriority;
                if( v24 != Prcb->IdleThread )
                  v33 = (unsigned int)v30;
                KiSetSchedulerAssistPriority((INT32 *)Prcb->SchedulerAssist, v33, 0);
                v31 = Prcb->SchedulerAssist;
              }
              Prcb->NextThread = v24;
              if( v31 )
                v31[16] = v24 == Prcb->IdleThread;
              if( v24->Tcb.WaitBlockFill6[68] == 1 )
                v24->Tcb.ReadyTime = v24->Tcb.ReadyTime
                                   - v24->Tcb.WaitBlock[2].SpareLong
                                   + KUSER_SHARED_DATA.TickCount.LowPart;
              v24->Tcb.WaitBlockFill6[68] = 3;
            }
          }
          if( v18 )
          {
            if( KiShouldPreemptionBeDeferred(&Thread->Tcb) )
            {
              if( (*(&Thread->Tcb.MiscFlags + 1) & 0xC00) == 0 )
              {
                _InterlockedAnd64((volatile signed __int64 *)&Prcb->PrcbLock, 0i64);
                KiInsertDeferredPreemptionApc(Prcb, &Thread->Tcb, 0);
                v25 = KeGetCurrentPrcb();
                HIDWORD(SpinCount) = 0;
                while( _interlockedbittestandset64((volatile signed __int32 *)&Prcb->PrcbLock, 0i64) )
                {
                  do
                    KeYieldProcessorEx((UINT64 *)((char *)&SpinCount + 4));
                  while( Prcb->PrcbLock );
                  v26 = v25->SchedulerAssist;
                  if( v26 )
                  {
                    if( v25->NestingLevel <= 1u )
                      ++v26[6];
                  }
                }
              }
            }
            else if( KiCheckForMaxOverQuotaScb(v18) && !Prcb->NextThread )
            {
              KiSelectNextThread(Prcb, ReadyList);
            }
          }
          return;
        }
        v14 = (_KSCHEDULING_GROUP *)((char *)v15 - Prcb->ScbOffset);
        v44 = v14;
      }
      if( (v16 & 2) == 0 )
      {
        if( KiCheckMaxOverQuotaTransition(v15, v14) )
        {
          if( (*((_BYTE *)v15 + 112) & 1) != 0 )
            KiRemoveSchedulingGroupQueue(Prcb, v15, 1u);
        }
        else
        {
          if( v15->GenerationCycles < v15->RankCycleTarget )
          {
            if( RoundRobin )
              v10 = 1;
            goto LABEL_16;
          }
          KiRecomputeGroupSchedulingRank(v14, v15, Prcb);
          if( SchedulingGroup == v15 )
          {
            v10 = 1;
            v46 = 1;
            v8 = 1;
            goto LABEL_16;
          }
        }
      }
      v10 = 1;
      v8 = 1;
LABEL_16:
      v17 = v46;
      goto LABEL_17;
    }
  }
}

Referenced by:

KiQuantumEnd