KiSetHeteroPolicyThread

_KHETERO_CPU_POLICY __stdcall KiSetHeteroPolicyThread(
        _ETHREAD *Thread,
        _KHETERO_CPU_POLICY NewPolicy,
        UINT64 SetUserPolicy,
        UINT64 Set){
  int v4; 
  int v5; 
  unsigned __int8 CurrentIrql; 
  __int64 IdealProcessor; 
  unsigned int UserIdealProcessor; 
  int SystemHeteroCpuPolicy; 
  char v12; 
  bool v13; 
  NTSTATUS v14; 
  __int64 v15; 
  char v16; 
  unsigned __int64 v17; 
  char v18; 
  unsigned int v19; 
  int v20; 
  unsigned __int8 v21; 
  _KPRCB *v22; 
  _KPRCB *v23; 
  int v24; 
  int v25; 
  UINT64 Number; 
  struct _KPRCB *CurrentPrcb; 
  _ETHREAD *CurrentThread; 
  INT64 v29; 
  _ETHREAD *NextThread; 
  char v31; 
  bool v32; 
  UINT64 *PreferredSetOut; 
  UINT64 *AvailableSetOut; 
  _KPRCB *ControlPrcb; 
  _SINGLE_LIST_ENTRY ReadyList; 
  int v38; 
  int v39; 
  UINT64 v40; 
  UINT64 v41; 
  _KSHARED_READY_QUEUE *ControlReadyQueue; 
  UINT64 IdealSetOut; 
  UINT64 v44; 
  UINT64 SpinCount; 

  v41 = 0i64;
  v4 = Set;
  IdealSetOut = 0i64;
  v5 = SetUserPolicy;
  ControlPrcb = 0i64;
  v44 = 0i64;
  ReadyList.Next = 0i64;
  ControlReadyQueue = 0i64;
  CurrentIrql = KeGetCurrentIrql();
  __writecr8(2ui64);
  LODWORD(SpinCount) = 0;
  while( _interlockedbittestandset64((volatile signed __int32 *)&Thread->Tcb.ThreadLock, 0i64) )
  {
    do
      KeYieldProcessorEx(&SpinCount);
    while( Thread->Tcb.ThreadLock );
  }
  IdealProcessor = Thread->Tcb.IdealProcessor;
  UserIdealProcessor = Thread->Tcb.UserIdealProcessor;
  v38 = Thread->Tcb.IdealProcessor;
  v39 = UserIdealProcessor;
  if( v5 )
  {
    SystemHeteroCpuPolicy = Thread->Tcb.SystemHeteroCpuPolicy;
    v12 = (Thread->Tcb._bf_0 ^ NewPolicy) & 0x7F;
    v13 = ((v12 ^ Thread->Tcb._bf_0) & 0x80u) != 0;
    Thread->Tcb._bf_0 ^= v12;
    if( v13 )
      goto LABEL_8;
    goto LABEL_7;
  }
  if( v4 )
  {
LABEL_7:
    SystemHeteroCpuPolicy = NewPolicy;
    goto LABEL_8;
  }
  SystemHeteroCpuPolicy = Thread->Tcb._bf_0 & 0x7F;
  Thread->Tcb._bf_0 &= ~0x80u;
LABEL_8:
  if( SystemHeteroCpuPolicy == 8 )
    SystemHeteroCpuPolicy = KiDefaultHeteroCpuPolicy;
  if( !KeHeteroSystem )
  {
    SystemHeteroCpuPolicy = 0;
    Thread->Tcb._bf_0 &= ~0x80u;
  }
  if( Thread->Tcb.SystemHeteroCpuPolicy == SystemHeteroCpuPolicy )
  {
    KiReleaseThreadLockSafe((INT64)Thread);
    __writecr8(CurrentIrql);
  }
  else
  {
    v14 = SystemHeteroCpuPolicy;
    v15 = (__int64)*(&KiProcessorBlock + IdealProcessor);
    if( SystemHeteroCpuPolicy >= 5 )
      v14 = KiConvertDynamicHeteroPolicy(Thread, NewPolicy, *(&KiProcessorBlock + IdealProcessor));
    KiGenerateHeteroSets(
      *(_KNODE **)(v15 + 192),
      Thread->Tcb.Affinity.Mask,
      (_KHETERO_CPU_POLICY)v14,
      &IdealSetOut,
      &v44,
      &v41);
    if( (IdealSetOut & *(_QWORD *)(v15 + 200)) == 0 )
    {
      v16 = *(_BYTE *)(v15 + 209);
      _BitScanForward64(&v17, __ROR8__(IdealSetOut, v16));
      v18 = v17 + v16;
      LODWORD(v17) = Thread->Tcb._bf_0;
      v19 = KiProcessorNumberToIndexMappingTable[64 * *(unsigned __int8 *)(v15 + 208) + (v18 & 0x3F)];
      Thread->Tcb.IdealProcessor = v19;
      if( (v17 & 8) == 0 )
        Thread->Tcb.UserIdealProcessor = v19;
    }
    v20 = 0;
    KiAcquireThreadStateLock(Thread, &ControlPrcb, &ControlReadyQueue);
    v22 = ControlPrcb;
    Thread->Tcb.SystemHeteroCpuPolicy = SystemHeteroCpuPolicy;
    if( v21 == 1 )
    {
      KiRemoveThreadFromAnyReadyQueue(v22, ControlReadyQueue, (__int64)Thread, (unsigned int)Thread->Tcb.Priority);
      KiPrepareReadyThreadForRescheduling(&Thread->Tcb, (unsigned int)Thread->Tcb.Priority, &ReadyList);
    }
    else
    {
      v23 = (_KPRCB *)((unsigned int)v21 - 2);
      if( v21 == 2 )
      {
        if( (v22->GroupSetMember & v41) == 0 )
        {
          if( Thread->Tcb.WaitBlockFill6[68] == 2 )
          {
            _interlockedbittestandset((volatile signed __int32 *)&Thread->Tcb.116 + 1, 0xCu);
            v22 = ControlPrcb;
            if( !ControlPrcb->NextThread )
            {
              KiSelectNextThread(ControlPrcb, &ReadyList);
              v20 = 1;
            }
          }
          else
          {
            Thread->Tcb.WaitRegister.Flags |= 8u;
            v22 = ControlPrcb;
          }
        }
      }
      else if( v21 == 3 && (v22->GroupSetMember & v41) == 0 )
      {
        KiSelectNextThread(v22, &ReadyList);
        KiInsertDeferredReadyList((INT64)&ReadyList, (INT64)Thread);
      }
    }
    v24 = Thread->Tcb.IdealProcessor;
    v25 = Thread->Tcb.UserIdealProcessor;
    KiReleaseThreadStateLock(v23, (_KSHARED_READY_QUEUE *)v22);
    KiReleaseThreadLockSafe((INT64)Thread);
    if( v20 )
    {
      Number = ControlPrcb->Number;
      if( KeGetPcr()->Prcb.Number != (_DWORD)Number )
        KiSendSoftwareInterrupt(Number, 2u);
    }
    if( (xmmword_140CFB490 & 0x8000000) != 0 )
    {
      EtwTraceIdealProcessor((__int64)Thread, 0x546u, v38, v24);
      if( (xmmword_140CFB490 & 0x8000000) != 0 )
        EtwTraceIdealProcessor((__int64)Thread, 0x547u, v39, v25);
    }
    CurrentPrcb = KeGetCurrentPrcb();
    KiReadyDeferredReadyList(CurrentPrcb, &ReadyList);
    if( CurrentIrql >= 2u )
    {
      if( CurrentPrcb->NextThread && !CurrentPrcb->DpcRoutineActive )
        KiRequestSoftwareInterrupt(CurrentPrcb, 2);
    }
    else
    {
      CurrentThread = CurrentPrcb->CurrentThread;
      if( CurrentPrcb->NextThread )
      {
        KiAbProcessContextSwitch(&CurrentPrcb->CurrentThread->Tcb, 0i64);
        LODWORD(v40) = 0;
        while( _interlockedbittestandset64((volatile signed __int32 *)&CurrentPrcb->PrcbLock, 0i64) )
        {
          do
            KeYieldProcessorEx(&v40);
          while( CurrentPrcb->PrcbLock );
        }
        NextThread = CurrentPrcb->NextThread;
        CurrentPrcb->NextThread = 0i64;
        _disable();
        KiEndThreadCycleAccumulation(
          (INT64)CurrentPrcb,
          (INT64)CurrentThread,
          0i64,
          v29,
          (INT64)PreferredSetOut,
          (INT64)AvailableSetOut,
          (INT64)ControlPrcb);
        _enable();
        CurrentPrcb->CurrentThread = NextThread;
        if( NextThread->Tcb.WaitBlockFill6[68] == 1 )
          NextThread->Tcb.ReadyTime = NextThread->Tcb.ReadyTime
                                    - NextThread->Tcb.WaitBlock[2].SpareLong
                                    + KUSER_SHARED_DATA.TickCount.LowPart;
        NextThread->Tcb.WaitBlockFill6[68] = 2;
        CurrentThread->Tcb.WaitReason = 32;
        CurrentThread->Tcb.WaitIrql = CurrentIrql;
        KiQueueReadyThread(CurrentPrcb, &CurrentThread->Tcb);
        KiSwapContext();
        v32 = v31 == 0;
      }
      else
      {
        v32 = (CurrentThread->Tcb._bf_0 & 0x40) == 0;
      }
      if( !v32 )
      {
        __writecr8(1ui64);
        CurrentThread->Tcb._bf_0 &= ~0x40u;
        KiDeliverApc(0, 0i64, 0i64);
      }
      __writecr8(CurrentIrql);
    }
  }
  return SystemHeteroCpuPolicy;
}

Referenced by:

KeSetHeteroCpuPolicyThread
KeSetUserHeteroCpuPolicyThread
PopUpdateSingleThreadHeteroPolicies