KiUpdateCpuTargetByWeight

VOID __stdcall KiUpdateCpuTargetByWeight(_KSCHEDULING_GROUP *SchedulingGroup, UINT8 ResetHistory, _KPRCB *a3){
  UINT8 v3; 
  unsigned __int16 Weight; 
  unsigned __int16 MaxRate; 
  unsigned __int64 MaxQuotaCycleTarget; 
  unsigned __int64 v8; 
  __int64 v9; 
  char v10; 
  __int64 v11; 
  _KSCB *v12; 
  char v13; 
  _LIST_ENTRY *p_ChildList; 
  _KPRCB *v15; 
  _KSCB *Parent; 
  _KSCHEDULING_GROUP *v17; 
  unsigned __int64 v18; 
  __int64 v19; 
  _KPRCB *v20; 
  unsigned int v21; 
  bool v22; 
  UINT64 v24; 
  UINT64 SpinCount; 

  v3 = ResetHistory;
  Weight = SchedulingGroup->Policy.Weight;
  MaxRate = SchedulingGroup->Policy.MaxRate;
  if( SchedulingGroup->Parent )
  {
    LODWORD(v24) = 0;
    v15 = KiProcessorBlock;
    while( _interlockedbittestandset64((volatile signed __int32 *)&v15->PrcbLock, 0i64) )
    {
      do
        KeYieldProcessorEx(&v24);
      while( v15->PrcbLock );
    }
    Parent = SchedulingGroup->PerProcessor[0].Parent;
    v17 = SchedulingGroup->Parent;
    v18 = SchedulingGroup->Policy.Weight * Parent->MinQuotaCycleTarget / v17->ChildTotalWeight;
    v8 = v18;
    if( Weight == MaxRate )
      MaxQuotaCycleTarget = SchedulingGroup->Policy.Weight * Parent->MinQuotaCycleTarget / v17->ChildTotalWeight;
    else
      MaxQuotaCycleTarget = Parent->MaxQuotaCycleTarget;
    _InterlockedAnd64((volatile signed __int64 *)&v15->PrcbLock, 0i64);
    v3 = ResetHistory;
  }
  else
  {
    MaxQuotaCycleTarget = KiCyclesPerGeneration;
    v8 = KiCyclesPerGeneration
       * (unsigned __int64)SchedulingGroup->Policy.Weight
       / (unsigned int)KiGroupSchedulingTotalWeight;
    if( Weight == MaxRate )
      MaxQuotaCycleTarget = KiCyclesPerGeneration
                          * (unsigned __int64)SchedulingGroup->Policy.Weight
                          / (unsigned int)KiGroupSchedulingTotalWeight;
  }
  v21 = KeNumberProcessors_0;
  v9 = 0i64;
  v22 = MaxQuotaCycleTarget == KiCyclesPerGeneration;
  if( (_DWORD)KeMaximumProcessors )
  {
    v10 = 16 * (MaxQuotaCycleTarget == KiCyclesPerGeneration);
    do
    {
      v11 = (__int64)*(&KiProcessorBlock + v9);
      v12 = &SchedulingGroup->PerProcessor[(unsigned int)v9];
      if( v11 )
      {
        LODWORD(SpinCount) = 0;
        while( _interlockedbittestandset64((volatile signed __int32 *)(v11 + 48), 0i64) )
        {
          do
            KeYieldProcessorEx(&SpinCount);
          while( *(_QWORD *)(v11 + 48) );
        }
        if( !v22 && *(_BYTE *)(v11 + 33) )
        {
          v19 = MaxQuotaCycleTarget * v21;
          SchedulingGroup->MaxQuotaLimitCycles = v19;
          SchedulingGroup->MaxQuotaCyclesRemaining = v19;
        }
      }
      v3 = ResetHistory;
      v13 = v10 | *((_BYTE *)v12 + 112) & 0xEF;
      v12->MinQuotaCycleTarget = v8;
      v12->MaxQuotaCycleTarget = MaxQuotaCycleTarget;
      *((_BYTE *)v12 + 112) = v13;
      if( v11 )
      {
        if( ResetHistory )
        {
          v12->LongTermCycles = 0i64;
          v12->OverQuotaHistory = 0i64;
          if( (SchedulingGroup->Policy.AllFlags & 2) != 0 )
          {
            KiResetScb(v12);
            KiCheckForEffectivePriorityChange((_KPRCB *)v11, v12, v20);
          }
        }
        _InterlockedAnd64((volatile signed __int64 *)(v11 + 48), 0i64);
      }
      v9 = (unsigned int)(v9 + 1);
    }
    while( (unsigned int)v9 < (unsigned int)KeMaximumProcessors );
  }
  if( v3 )
    SchedulingGroup->QueryHistoryTimeStamp = KeQueryPerformanceCounter(0i64);
  p_ChildList = &SchedulingGroup->ChildList;
  if( p_ChildList->Flink != p_ChildList )
    KiUpdateChildrenCpuTarget(p_ChildList, v3);
}

Referenced by:

KiAssignSchedulingGroupWeights
KiUpdateChildrenCpuTarget