KiSetAffinityThread

VOID __stdcall KiSetAffinityThread(_ETHREAD *Thread, _SINGLE_LIST_ENTRY *ReadyList, _GROUP_AFFINITY *Affinity){
  int v3; 
  int UserIdealProcessor; 
  __int64 v7; 
  int v8; 
  _KPRCB *v9; 
  _KNODE *v10; 
  unsigned __int16 v11; 
  UINT8 v12; 
  UINT8 v13; 
  _KPRCB *v14; 
  int v15; 
  _KPRCB *v16; 
  int IdealProcessor; 
  UINT64 Number; 
  UINT64 SpinCount; 
  _KPRCB *ControlPrcb; 
  _KSHARED_READY_QUEUE *ControlReadyQueue; 
  _SINGLE_LIST_ENTRY *v22; 
  _GROUP_AFFINITY Affinitya; 

  ControlPrcb = 0i64;
  v3 = 0;
  ControlReadyQueue = 0i64;
  LODWORD(SpinCount) = 0;
  v22 = ReadyList;
  Affinitya = 0i64;
  while( _interlockedbittestandset64((volatile signed __int32 *)&Thread->Tcb.ThreadLock, 0i64) )
  {
    do
      KeYieldProcessorEx(&SpinCount);
    while( Thread->Tcb.ThreadLock );
  }
  UserIdealProcessor = Thread->Tcb.UserIdealProcessor;
  HIDWORD(SpinCount) = Thread->Tcb.IdealProcessor;
  Thread->Tcb.UserAffinity.Group = Affinity->Group;
  Thread->Tcb.UserAffinity.Mask = Affinity->Mask;
  v7 = Thread->Tcb.UserIdealProcessor;
  v8 = Thread->Tcb.UserIdealProcessor;
  v9 = *(&KiProcessorBlock + v7);
  if( !(unsigned int)KiPrcbInGroupAffinity(v9, Affinity) )
  {
    v10 = KeSelectNodeForAffinity(Affinity);
    Affinitya.Group = Affinity->Group;
    Affinitya.Mask = Affinity->Mask & v10->Affinity.Mask;
    v11 = KeSelectIdealProcessor(v10, &Affinitya, 0i64);
    LODWORD(v7) = v11;
    Thread->Tcb.UserIdealProcessor = v11;
    v8 = v11;
    v9 = *(&KiProcessorBlock + v11);
  }
  if( (Thread->Tcb._bf_0 & 8) != 0 )
  {
    v14 = ControlPrcb;
  }
  else
  {
    KiAcquireThreadStateLock(Thread, &ControlPrcb, &ControlReadyQueue);
    v13 = v12;
    Thread->Tcb.Affinity.Group = Affinity->Group;
    Thread->Tcb.Affinity.Mask = Affinity->Mask;
    if( (unsigned int)KiComputeThreadAffinity(&Thread->Tcb) )
    {
      Affinity = &Affinitya;
      Affinitya.Group = Thread->Tcb.Affinity.Group;
      Affinitya.Mask = Thread->Tcb.Affinity.Mask;
    }
    else
    {
      Thread->Tcb.IdealProcessor = v7;
      KiUpdateNodeAffinitizedFlag(&Thread->Tcb);
      KiUpdateSharedReadyQueueAffinityThread(v9, &Thread->Tcb);
    }
    v14 = ControlPrcb;
    KiRescheduleThreadAfterAffinityChange(Thread, Affinity, v13, ControlPrcb, ControlReadyQueue, v22);
    v3 = v15;
    KiReleaseThreadStateLock(v16, (_KSHARED_READY_QUEUE *)v14);
    v8 = Thread->Tcb.UserIdealProcessor;
  }
  IdealProcessor = Thread->Tcb.IdealProcessor;
  KiReleaseThreadLockSafe((INT64)Thread);
  if( v3 )
  {
    Number = v14->Number;
    if( KeGetPcr()->Prcb.Number != (_DWORD)Number )
      KiSendSoftwareInterrupt(Number, 2u);
  }
  if( (xmmword_140CFB490 & 0x8000000) != 0 )
  {
    EtwTraceIdealProcessor((__int64)Thread, 0x546u, SHIDWORD(SpinCount), IdealProcessor);
    if( (xmmword_140CFB490 & 0x8000000) != 0 )
      EtwTraceIdealProcessor((__int64)Thread, 0x547u, UserIdealProcessor, v8);
  }
}

Referenced by:

KeSetAffinityProcess
KeSetAffinityThread
KeSetLegacyAffinityThread