KiSetAffinityThread

VOID __fastcall KiSetAffinityThread(_ETHREAD *Thread, _SINGLE_LIST_ENTRY *ReadyList, _GROUP_AFFINITY *Affinity){
  int v3; 
  unsigned int v6; 
  __int64 v7; 
  unsigned int v8; 
  _KPRCB *v9; 
  _KNODE *v10; 
  unsigned __int16 v11; 
  UINT8 v12; 
  UINT8 v13; 
  _KPRCB *v14; 
  _KSHARED_READY_QUEUE *v15; 
  __int64 v16; 
  unsigned int v17; 
  UINT64 v18; 
  UINT64 SpinCount; 
  _KPRCB *v20; 
  _KSHARED_READY_QUEUE *ControlReadyQueue; 
  _SINGLE_LIST_ENTRY *v22; 
  _GROUP_AFFINITY Affinitya; 
  v20 = 0i64;
  v3 = 0;
  ControlReadyQueue = 0i64;
  LODWORD(SpinCount) = 0;
  v22 = ReadyList;
  Affinitya = 0i64;
  while( _interlockedbittestandset64((volatile signed __int32 *)Thread + 16, 0i64) )
  {
    do
      KeYieldProcessorEx(&SpinCount);
    while( *((_QWORD *)Thread + 8) );
  }
  v6 = *((_DWORD *)Thread + 49);
  HIDWORD(SpinCount) = *((_DWORD *)Thread + 147);
  *((_WORD *)Thread + 280) = Affinity->Group;
  *((_QWORD *)Thread + 69) = Affinity->Mask;
  v7 = *((unsigned int *)Thread + 49);
  v8 = *((_DWORD *)Thread + 49);
  v9 = *(&KiProcessorBlock + v7);
  if( !KiPrcbInGroupAffinity((__int64)v9, (__int64)Affinity) )
  {
    v10 = KeSelectNodeForAffinity(Affinity);
    Affinitya.Group = Affinity->Group;
    Affinitya.Mask = Affinity->Mask & v10->Affinity.Mask;
    v11 = KeSelectIdealProcessor(v10, &Affinitya, 0i64);
    LODWORD(v7) = v11;
    *((_DWORD *)Thread + 49) = v11;
    v8 = v11;
    v9 = *(&KiProcessorBlock + v11);
  }
  if( (*((_DWORD *)Thread + 29) & 8) != 0 )
  {
    v14 = v20;
  }
  else
  {
    KiAcquireThreadStateLock(Thread, &v20, &ControlReadyQueue);
    v13 = v12;
    *((_WORD *)Thread + 292) = Affinity->Group;
    *((_QWORD *)Thread + 72) = Affinity->Mask;
    if( (unsigned int)KiComputeThreadAffinity((_KTHREAD *)Thread) )
    {
      Affinity = &Affinitya;
      Affinitya.Group = *((_WORD *)Thread + 292);
      Affinitya.Mask = *((_QWORD *)Thread + 72);
    }
    else
    {
      *((_DWORD *)Thread + 147) = v7;
      KiUpdateNodeAffinitizedFlag((_KTHREAD *)Thread);
      KiUpdateSharedReadyQueueAffinityThread(v9, (_KTHREAD *)Thread);
    }
    v14 = v20;
    v15 = ControlReadyQueue;
    v3 = KiRescheduleThreadAfterAffinityChange((_KTHREAD *)Thread, Affinity, v13, v20, ControlReadyQueue, v22);
    KiReleaseThreadStateLock(v16, (__int64)v14, (volatile signed __int64 *)v15);
    v8 = *((_DWORD *)Thread + 49);
  }
  v17 = *((_DWORD *)Thread + 147);
  KiReleaseThreadLockSafe((INT64)Thread);
  if( v3 )
  {
    v18 = *((unsigned int *)v14 + 9);
    if( *((_DWORD *)KeGetPcr() + 105) != (_DWORD)v18 )
      KiSendSoftwareInterrupt(v18, 2u);
  }
  if( (*(_DWORD *)(&PerfGlobalGroupMask + 2) & 0x8000000) != 0 )
  {
    EtwTraceIdealProcessor((INT64)Thread, 0x546u, HIDWORD(SpinCount), v17);
    if( (*(_DWORD *)(&PerfGlobalGroupMask + 2) & 0x8000000) != 0 )
      EtwTraceIdealProcessor((INT64)Thread, 0x547u, v6, v8);
  }
}

Referenced by:

KeSetAffinityProcess
KeSetAffinityThread
KeSetLegacyAffinityThread