KiHeteroChooseTargetProcessor

_KPRCB *__stdcall KiHeteroChooseTargetProcessor(
        _KPRCB *CurrentPrcb,
        _KTHREAD *Thread,
        _GROUP_AFFINITY *Affinity,
        UINT64 *Idle){
  _KHETERO_CPU_POLICY v4; 
  unsigned __int64 Mask; 
  bool v7; 
  INT64 v8; 
  _KNODE *v9; 
  int v10; 
  unsigned __int64 IdleNonParkedCpuSet; 
  INT64 v12; 
  INT64 v13; 
  unsigned __int64 v14; 
  unsigned __int64 IdleSmtSet; 
  char v16; 
  UINT64 v17; 
  _KPRCB *v18; 
  INT64 v19; 
  __int64 v20; 
  unsigned __int64 v21; 
  unsigned __int64 v22; 
  int v23; 
  UINT64 v24; 
  __int64 v25; 
  __int64 v26; 
  UINT64 v27; 
  bool v28; 
  unsigned int BiasedProcessorIndex; 
  char v30; 
  unsigned __int64 v31; 
  int v32; 
  __int64 v33; 
  unsigned __int8 v34; 
  int v35; 
  unsigned __int64 v36; 
  __int64 v37; 
  unsigned __int8 v38; 
  char v39; 
  UINT64 v40; 
  UINT64 v41; 
  _KPRCB *v42; 
  __int64 v43; 
  char v44; 
  int v45; 
  unsigned __int64 v46; 
  unsigned __int64 v47; 
  unsigned __int64 v48; 
  unsigned __int64 v50; 
  UINT64 Affinitya; 
  UINT64 PreferredSetOut; 
  UINT64 SpinCount; 
  int v54; 
  UINT64 v55; 
  char v56[12]; 
  INT64 v57; 
  bool CanSelectSoftParkedProcessor; 
  _KHETERO_CPU_POLICY v60; 
  v4 = *((unsigned __int8 *)Thread + 125);
  Mask = Affinity->Mask;
  Affinitya = 0i64;
  *(_QWORD *)&v56[4] = 0i64;
  PreferredSetOut = 0i64;
  v50 = Mask;
  v60 = v4;
  if( (unsigned int)v4 >= KHeteroCpuPolicyDynamic )
  {
    v4 = KiConvertDynamicHeteroPolicy((_KTHREAD *)Thread, (_KHETERO_CPU_POLICY)Thread, CurrentPrcb);
    v60 = v4;
  }
  v7 = 0;
  CanSelectSoftParkedProcessor = 0;
  v8 = (INT64)*(&KiProcessorBlock + *((unsigned int *)Thread + 147));
  v57 = v8;
  v9 = *(_KNODE **)(v8 + 192);
  do
  {
    while( 1 )
    {
      v10 = KiGenerateHeteroSets(v9, Mask, v4, (UINT64 *)&v56[4], &PreferredSetOut, &Affinitya);
      IdleNonParkedCpuSet = v9->IdleNonParkedCpuSet;
      v12 = 0i64;
      if( v7 && !IdleNonParkedCpuSet )
        IdleNonParkedCpuSet = v9->IdleCpuSet & v9->SoftParkedSet;
      v13 = Affinitya;
      if( (IdleNonParkedCpuSet & Affinitya) == 0 && !v10 )
      {
        v13 = Affinitya;
        if( (v9->NonParkedSet & Affinitya) == 0 )
        {
          v13 = Mask;
          PreferredSetOut = Mask;
          Affinitya = Mask;
          *(_QWORD *)&v56[4] = Mask;
        }
      }
      v14 = v13 & IdleNonParkedCpuSet;
      if( v7 && !v14 )
        v14 = Affinitya & v9->IdleCpuSet & v9->SoftParkedSet;
      IdleSmtSet = v9->IdleSmtSet;
      if( (KiVelocityFlags & 0x4000) == 0 || *((_BYTE *)Thread + 512) || (v16 = 1, (unsigned int)(v4 - 1) > 1) )
        v16 = 0;
      if( !v16 || (PreferredSetOut & IdleSmtSet) != 0 )
        break;
      v13 = PreferredSetOut & v9->NonParkedSet & v9->QosPreemptibleSet;
      v17 = v9->NonPairedSmtSet & v13;
      if( !v17 )
        v17 = PreferredSetOut & v9->NonParkedSet & v9->QosPreemptibleSet;
      if( !v17 )
        goto LABEL_43;
      v18 = KiSelectProcessorToPreempt((_KTHREAD *)Thread, (_KPRCB *)v8, v17, 0i64);
      v19 = (INT64)v18;
      if( (v17 & *((_QWORD *)v18 + 25)) == 0 )
        goto LABEL_41;
      LODWORD(SpinCount) = 0;
      while( _interlockedbittestandset64((volatile signed __int32 *)(v19 + 48), 0i64) )
      {
        do
        {
          KeYieldProcessorEx(&SpinCount);
          v18 = *(_KPRCB **)(v19 + 48);
        }
        while( v18 );
      }
      v8 = v57;
      if( (*(_BYTE *)(v19 + 35) & 2) != 0 )
      {
        v12 = 0i64;
LABEL_38:
        _InterlockedAnd64((volatile signed __int64 *)(v19 + 48), 0i64);
        v13 = (INT64)KeGetCurrentPrcb();
        if( *(_QWORD *)(v13 + 33976) && *(_BYTE *)(v13 + 32) <= 1u && !(_DWORD)v18 )
LABEL_41:
          v12 = 0i64;
        v4 = v60;
LABEL_43:
        v7 = CanSelectSoftParkedProcessor;
        break;
      }
      v12 = 0i64;
      LOBYTE(v18) = *((_BYTE *)Thread + 195);
      if( **(char **)(v19 + 56) >= (char)v18 )
        goto LABEL_38;
      v18 = *(_KPRCB **)(v19 + 16);
      if( !v18 )
        v18 = *(_KPRCB **)(v19 + 8);
      LODWORD(v18) = (unsigned __int8)*((_DWORD *)v18 + 128) - 1;
      LOBYTE(v18) = (unsigned int)v18 <= 1;
      if( !(_BYTE)v18 )
        goto LABEL_38;
      if( (v9->IdleSmtSet & PreferredSetOut) == 0
        && ((v9->NonPairedSmtSet & *(_QWORD *)(v19 + 200)) != 0
         || (PreferredSetOut & v9->NonParkedSet & v9->QosPreemptibleSet & v9->NonPairedSmtSet) == 0) )
      {
        *(_DWORD *)Idle = (*(_BYTE *)(v19 + 35) & 1) == 0;
        return(_KPRCB *)v19;
      }
      _InterlockedAnd64((volatile signed __int64 *)(v19 + 48), 0i64);
      v7 = CanSelectSoftParkedProcessor;
LABEL_36:
      v4 = v60;
      Mask = v50;
    }
    if( v14 )
    {
      if( (*(_BYTE *)&v9->Flags & 0x20) != 0 )
      {
        if( KiIsQosGroupingActive()
          && (v21 = v14 & v20) != 0
          && (unsigned int)(unsigned __int8)*((_DWORD *)Thread + 128) - 1 <= 1 )
        {
          v14 = v21 & ~IdleSmtSet;
          if( !v14 )
            v14 = v21;
        }
        else
        {
          v22 = v14 & IdleSmtSet;
          if( v22 )
            v14 = v22;
        }
      }
      v23 = v12;
      v24 = *(_QWORD *)&v56[4] & v14;
      if( (*(_QWORD *)&v56[4] & v14) == 0 )
      {
        v24 = v14 & PreferredSetOut;
        if( (v14 & PreferredSetOut) == 0 )
          goto LABEL_58;
        v23 = 1;
      }
      v14 = v24;
LABEL_58:
      if( KeHeteroSystemQos != (_DWORD)v12 )
      {
        v25 = (unsigned __int8)*((_DWORD *)Thread + 128);
        v26 = *((_QWORD *)CurrentPrcb + 24);
        if( (v14 & *(_QWORD *)(v26 + 8 * v25 + 304)) != 0 )
          v14 &= *(_QWORD *)(v26 + 8 * v25 + 304);
      }
      v19 = v8;
      if( (v14 & *(_QWORD *)(v8 + 200)) == 0 || v23 )
      {
        if( v23 )
        {
          v19 = v12;
          v34 = v12;
          if( v14 )
          {
            v35 = v9->Affinity.Group << 6;
            do
            {
              _BitScanForward64(&v36, v14);
              v54 = v36 & 0x3F;
              v37 = (__int64)*(&KiProcessorBlock + (unsigned int)KiProcessorNumberToIndexMappingTable[v35 + v54]);
              if( (unsigned int)(v60 - 3) <= 1 )
                v38 = *(_BYTE *)(v37 + 33210);
              else
                v38 = *(_BYTE *)(v37 + 33209);
              if( !v19 || v38 > v34 )
              {
                v19 = (INT64)*(&KiProcessorBlock + (unsigned int)KiProcessorNumberToIndexMappingTable[v35 + v54]);
                v34 = v38;
              }
              v14 &= ~*(_QWORD *)(v37 + 200);
            }
            while( v14 );
            v8 = v57;
          }
        }
        else
        {
          v27 = v14 & *(_QWORD *)(v8 + 33880);
          if( !v27 )
            v27 = v14;
          if( (KiHeteroSchedulerOptions & 1) != 0 )
            v28 = (KiHeteroSchedulerOptions & 4) == 0;
          else
            v28 = (((KiDynamicHeteroCpuPolicyMask & 0x10) != 0) & _bittest(&KiVelocityFlags, 0xCu)) == 0;
          if( v28 )
          {
            v30 = *(_BYTE *)(v8 + 209);
            _BitScanForward64(&v31, __ROR8__(v27, v30));
            v32 = ((_BYTE)v31 + v30) & 0x3F;
            v33 = v32 + (*(unsigned __int8 *)(v8 + 208) << 6);
            HIDWORD(SpinCount) = v32;
            BiasedProcessorIndex = KiProcessorNumberToIndexMappingTable[v33];
          }
          else
          {
            BiasedProcessorIndex = KiFindBiasedProcessorIndex(
                                     *(unsigned __int8 *)(v8 + 208),
                                     (*((_QWORD *)Thread + 9) >> KiFavoredCoreCycleTimeBits)
                                   + *(unsigned __int8 *)(v8 + 209),
                                     v27);
            LODWORD(v12) = 0;
          }
          v19 = (INT64)*(&KiProcessorBlock + BiasedProcessorIndex);
        }
      }
      LODWORD(v55) = v12;
      *(_DWORD *)Idle = 1;
      while( _interlockedbittestandset64((volatile signed __int32 *)(v19 + 48), 0i64) )
      {
        do
          KeYieldProcessorEx(&v55);
        while( *(_QWORD *)(v19 + 48) );
      }
      v39 = *(_BYTE *)(v19 + 35);
      v7 = CanSelectSoftParkedProcessor;
      if( !v39 || CanSelectSoftParkedProcessor && v39 == 6 )
        return(_KPRCB *)v19;
      _InterlockedAnd64((volatile signed __int64 *)(v19 + 48), 0i64);
      goto LABEL_36;
    }
    if( v7 )
      break;
    Mask = v50;
    CanSelectSoftParkedProcessor = KiCanSelectSoftParkedProcessor(v13, v8);
    v7 = CanSelectSoftParkedProcessor;
  }
  while( CanSelectSoftParkedProcessor );
  v40 = PreferredSetOut;
  v41 = Affinitya;
  if( PreferredSetOut == Affinitya )
    v40 = 0i64;
  v42 = KiSelectProcessorToPreempt((_KTHREAD *)Thread, (_KPRCB *)v8, Affinitya, v40);
  v43 = (__int64)v42;
  if( (v41 & *((_QWORD *)v42 + 25)) == 0 )
  {
    v44 = *((_BYTE *)v42 + 209);
    v45 = *((unsigned __int8 *)v42 + 208);
    _BitScanForward64(&v46, __ROR8__(v41, v44));
    HIDWORD(v55) = ((_BYTE)v46 + v44) & 0x3F;
    v43 = (__int64)*(&KiProcessorBlock + (unsigned int)KiProcessorNumberToIndexMappingTable[HIDWORD(v55) + (v45 << 6)]);
  }
  *(_DWORD *)v56 = 0;
  while( _interlockedbittestandset64((volatile signed __int32 *)(v43 + 48), 0i64) )
  {
    do
      KeYieldProcessorEx((UINT64 *)v56);
    while( *(_QWORD *)(v43 + 48) );
  }
  v47 = v9->IdleNonParkedCpuSet;
  if( v7 )
  {
    v48 = v9->IdleCpuSet & v9->SoftParkedSet;
    v47 |= v48;
  }
  if( (v47 & Affinitya) != 0 )
  {
    _InterlockedAnd64((volatile signed __int64 *)(v43 + 48), 0i64);
    goto LABEL_36;
  }
  v28 = (*(_BYTE *)(v43 + 35) & 2) == 0;
  *(_DWORD *)Idle = 0;
  if( !v28 )
  {
    _InterlockedAnd64((volatile signed __int64 *)(v43 + 48), 0i64);
    v43 = KiSelectCandidateProcessor(v43, (__int64)Thread, Affinitya);
    if( (*(_BYTE *)(v43 + 35) & 1) == 0 )
      *(_DWORD *)Idle = 1;
  }
  return(_KPRCB *)v43;
}

Referenced by:

KiDeferredReadySingleThread