KiSetHeteroPolicyThread

_KHETERO_CPU_POLICY __stdcall KiSetHeteroPolicyThread(
        _ETHREAD *Thread,
        _KHETERO_CPU_POLICY NewPolicy,
        UINT64 SetUserPolicy,
        UINT64 Set){
  int v4; 
  int v5; 
  unsigned __int8 CurrentIrql; 
  __int64 v9; 
  unsigned int v10; 
  _KHETERO_CPU_POLICY v11; 
  char v12; 
  bool v13; 
  _KHETERO_CPU_POLICY v14; 
  __int64 v15; 
  char v16; 
  unsigned __int64 v17; 
  char v18; 
  int v19; 
  int v20; 
  unsigned __int8 v21; 
  _KPRCB *v22; 
  __int64 v23; 
  unsigned int v24; 
  unsigned int v25; 
  UINT64 v26; 
  struct _KPRCB *CurrentPrcb; 
  ULONG_PTR v28; 
  __int64 v29; 
  __int64 v30; 
  bool v31; 
  _KPRCB *ControlPrcb; 
  _SINGLE_LIST_ENTRY ReadyList; 
  unsigned int a3; 
  unsigned int a3_4; 
  UINT64 v37; 
  UINT64 AvailableSetOut; 
  _KSHARED_READY_QUEUE *ControlReadyQueue; 
  UINT64 IdealSetOut; 
  UINT64 PreferredSetOut; 
  UINT64 SpinCount; 
  AvailableSetOut = 0i64;
  v4 = Set;
  IdealSetOut = 0i64;
  v5 = SetUserPolicy;
  ControlPrcb = 0i64;
  PreferredSetOut = 0i64;
  ReadyList.Next = 0i64;
  ControlReadyQueue = 0i64;
  CurrentIrql = KeGetCurrentIrql();
  __writecr8(2ui64);
  LODWORD(SpinCount) = 0;
  while( _interlockedbittestandset64((volatile signed __int32 *)Thread + 16, 0i64) )
  {
    do
      KeYieldProcessorEx(&SpinCount);
    while( *((_QWORD *)Thread + 8) );
  }
  v9 = *((unsigned int *)Thread + 147);
  v10 = *((_DWORD *)Thread + 49);
  a3 = *((_DWORD *)Thread + 147);
  a3_4 = v10;
  if( v5 )
  {
    v11 = *((unsigned __int8 *)Thread + 125);
    v12 = (*((_BYTE *)Thread + 126) ^ NewPolicy) & 0x7F;
    v13 = ((v12 ^ *((_BYTE *)Thread + 126)) & 0x80u) != 0;
    *((_BYTE *)Thread + 126) ^= v12;
    if( v13 )
      goto LABEL_8;
    goto LABEL_7;
  }
  if( v4 )
  {
LABEL_7:
    v11 = NewPolicy;
    goto LABEL_8;
  }
  v11 = *((_BYTE *)Thread + 126) & 0x7F;
  *((_BYTE *)Thread + 126) &= ~0x80u;
LABEL_8:
  if( v11 == KHeteroCpuPolicyDefault )
    v11 = KiDefaultHeteroCpuPolicy;
  if( !KeHeteroSystem )
  {
    v11 = KHeteroCpuPolicyAll;
    *((_BYTE *)Thread + 126) &= ~0x80u;
  }
  if( *((unsigned __int8 *)Thread + 125) == v11 )
  {
    KiReleaseThreadLockSafe((INT64)Thread);
    __writecr8(CurrentIrql);
  }
  else
  {
    v14 = v11;
    v15 = (__int64)*(&KiProcessorBlock + v9);
    if( v11 >= KHeteroCpuPolicyDynamic )
      v14 = KiConvertDynamicHeteroPolicy((_KTHREAD *)Thread, NewPolicy, *(&KiProcessorBlock + v9));
    KiGenerateHeteroSets(
      *(_KNODE **)(v15 + 192),
      *((_QWORD *)Thread + 72),
      v14,
      &IdealSetOut,
      &PreferredSetOut,
      &AvailableSetOut);
    if( (IdealSetOut & *(_QWORD *)(v15 + 200)) == 0 )
    {
      v16 = *(_BYTE *)(v15 + 209);
      _BitScanForward64(&v17, __ROR8__(IdealSetOut, v16));
      v18 = v17 + v16;
      LODWORD(v17) = *((_DWORD *)Thread + 29);
      v19 = KiProcessorNumberToIndexMappingTable[64 * *(unsigned __int8 *)(v15 + 208) + (v18 & 0x3F)];
      *((_DWORD *)Thread + 147) = v19;
      if( (v17 & 8) == 0 )
        *((_DWORD *)Thread + 49) = v19;
    }
    v20 = 0;
    KiAcquireThreadStateLock(Thread, &ControlPrcb, &ControlReadyQueue);
    v22 = ControlPrcb;
    *((_BYTE *)Thread + 125) = v11;
    if( v21 == 1 )
    {
      KiRemoveThreadFromAnyReadyQueue(v22, ControlReadyQueue, (_KTHREAD *)Thread, (unsigned int)*((char *)Thread + 195));
      KiPrepareReadyThreadForRescheduling((_KTHREAD *)Thread, (unsigned int)*((char *)Thread + 195), &ReadyList);
    }
    else
    {
      v23 = (unsigned int)v21 - 2;
      if( v21 == 2 )
      {
        if( (*((_QWORD *)v22 + 25) & AvailableSetOut) == 0 )
        {
          if( *((_BYTE *)Thread + 388) == 2 )
          {
            _interlockedbittestandset((volatile signed __int32 *)Thread + 30, 0xCu);
            v22 = ControlPrcb;
            if( !*((_QWORD *)ControlPrcb + 2) )
            {
              KiSelectNextThread(ControlPrcb, &ReadyList);
              v20 = 1;
            }
          }
          else
          {
            *((_BYTE *)Thread + 112) |= 8u;
            v22 = ControlPrcb;
          }
        }
      }
      else if( v21 == 3 && (*((_QWORD *)v22 + 25) & AvailableSetOut) == 0 )
      {
        KiSelectNextThread(v22, &ReadyList);
        KiInsertDeferredReadyList((INT64)&ReadyList, (INT64)Thread);
      }
    }
    v24 = *((_DWORD *)Thread + 147);
    v25 = *((_DWORD *)Thread + 49);
    KiReleaseThreadStateLock(v23, (__int64)v22, (volatile signed __int64 *)ControlReadyQueue);
    KiReleaseThreadLockSafe((INT64)Thread);
    if( v20 )
    {
      v26 = *((unsigned int *)ControlPrcb + 9);
      if( *((_DWORD *)KeGetPcr() + 105) != (_DWORD)v26 )
        KiSendSoftwareInterrupt(v26, 2u);
    }
    if( (*(_DWORD *)(&PerfGlobalGroupMask + 2) & 0x8000000) != 0 )
    {
      EtwTraceIdealProcessor((INT64)Thread, 0x546u, a3, v24);
      if( (*(_DWORD *)(&PerfGlobalGroupMask + 2) & 0x8000000) != 0 )
        EtwTraceIdealProcessor((INT64)Thread, 0x547u, a3_4, v25);
    }
    CurrentPrcb = KeGetCurrentPrcb();
    KiReadyDeferredReadyList(CurrentPrcb, &ReadyList);
    if( CurrentIrql >= 2u )
    {
      if( *((_QWORD *)CurrentPrcb + 2) && !*((_BYTE *)CurrentPrcb + 12586) )
        KiRequestSoftwareInterrupt(CurrentPrcb, 2);
    }
    else
    {
      v28 = *((_QWORD *)CurrentPrcb + 1);
      if( *((_QWORD *)CurrentPrcb + 2) )
      {
        KiAbProcessContextSwitch(*((_KTHREAD **)CurrentPrcb + 1), 0i64);
        LODWORD(v37) = 0;
        while( _interlockedbittestandset64((volatile signed __int32 *)CurrentPrcb + 12, 0i64) )
        {
          do
            KeYieldProcessorEx(&v37);
          while( *((_QWORD *)CurrentPrcb + 6) );
        }
        v29 = *((_QWORD *)CurrentPrcb + 2);
        *((_QWORD *)CurrentPrcb + 2) = 0i64;
        _disable();
        KiEndThreadCycleAccumulation(CurrentPrcb, (_KTHREAD *)v28, 0i64);
        _enable();
        *((_QWORD *)CurrentPrcb + 1) = v29;
        if( *(_BYTE *)(v29 + 388) == 1 )
        {
          v30 = (unsigned int)(*(_DWORD *)(v29 + 132) - *(_DWORD *)(v29 + 436));
          *(_DWORD *)(v29 + 132) = v30 + KUSER_SHARED_DATA.TickCount.LowPart;
        }
        *(_BYTE *)(v29 + 388) = 2;
        *(_BYTE *)(v28 + 643) = 32;
        *(_BYTE *)(v28 + 390) = CurrentIrql;
        KiQueueReadyThread((__int64)CurrentPrcb, v28, v30);
        v31 = !KiSwapContext((PKTHREAD)v28, (PKTHREAD)v29);
      }
      else
      {
        v31 = (*(_DWORD *)(v28 + 116) & 0x40) == 0;
      }
      if( !v31 )
      {
        __writecr8(1ui64);
        *(_DWORD *)(v28 + 116) &= ~0x40u;
        KiDeliverApc(0, 0i64, 0i64);
      }
      __writecr8(CurrentIrql);
    }
  }
  return v11;
}

Referenced by:

KeSetHeteroCpuPolicyThread
KeSetUserHeteroCpuPolicyThread
PopUpdateSingleThreadHeteroPolicies