KeSetSelectedCpuSetsThread
NTSTATUS __stdcall KeSetSelectedCpuSetsThread(_ETHREAD *Thread, UINT64 CpuSetCount, UINT64 *CpuSetMasks){
unsigned int v5;
NTSTATUS result;
INT64 *ThreadCpuSetMaskPointer;
unsigned __int8 CurrentIrql;
__int64 v9;
volatile LONG *v10;
unsigned int v11;
_KPRCB *updated;
unsigned int v13;
_KPRCB *v14;
UINT64 v15;
struct _KPRCB *CurrentPrcb;
ULONG_PTR v17;
__int64 v18;
__int64 v19;
bool v20;
UINT64 SpinCount;
_SINGLE_LIST_ENTRY ReadyList;
unsigned int a2;
a2 = 0;
v5 = CpuSetCount;
result = KiValidateCpuSetMasks(CpuSetMasks, CpuSetCount);
if( result >= 0 )
{
ReadyList.Next = 0i64;
ThreadCpuSetMaskPointer = (INT64 *)KiGetThreadCpuSetMaskPointer((INT64)Thread, &a2);
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
v10 = (volatile LONG *)(v9 + 64);
ExAcquireSpinLockSharedAtDpcLevel((PEX_SPIN_LOCK)(v9 + 64));
LODWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)Thread + 16, 0i64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( *((_QWORD *)Thread + 8) );
}
v11 = *((_DWORD *)Thread + 147);
KiWriteCpuSetMasks(ThreadCpuSetMaskPointer, a2, (INT64)CpuSetMasks, v5);
updated = KiUpdateThreadCpuSets((_KTHREAD *)Thread, &ReadyList);
v13 = *((_DWORD *)Thread + 147);
v14 = updated;
KiReleaseThreadLockSafe((INT64)Thread);
if( (*(_DWORD *)(&PerfGlobalGroupMask + 2) & 0x8000000) != 0 )
EtwTraceIdealProcessor((INT64)Thread, 0x546u, v11, v13);
ExReleaseSpinLockSharedFromDpcLevel(v10);
if( v14 )
{
v15 = *((unsigned int *)v14 + 9);
if( *((_DWORD *)KeGetPcr() + 105) != (_DWORD)v15 )
KiSendSoftwareInterrupt(v15, 2u);
}
CurrentPrcb = KeGetCurrentPrcb();
KiReadyDeferredReadyList(CurrentPrcb, &ReadyList);
if( CurrentIrql >= 2u )
{
if( *((_QWORD *)CurrentPrcb + 2) && !*((_BYTE *)CurrentPrcb + 12586) )
KiRequestSoftwareInterrupt(CurrentPrcb, 2);
}
else
{
v17 = *((_QWORD *)CurrentPrcb + 1);
if( *((_QWORD *)CurrentPrcb + 2) )
{
KiAbProcessContextSwitch(*((_KTHREAD **)CurrentPrcb + 1), 0i64);
HIDWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)CurrentPrcb + 12, 0i64) )
{
do
KeYieldProcessorEx((UINT64 *)((char *)&SpinCount + 4));
while( *((_QWORD *)CurrentPrcb + 6) );
}
v18 = *((_QWORD *)CurrentPrcb + 2);
*((_QWORD *)CurrentPrcb + 2) = 0i64;
_disable();
KiEndThreadCycleAccumulation(CurrentPrcb, (_KTHREAD *)v17, 0i64);
_enable();
*((_QWORD *)CurrentPrcb + 1) = v18;
if( *(_BYTE *)(v18 + 388) == 1 )
{
v19 = (unsigned int)(*(_DWORD *)(v18 + 132) - *(_DWORD *)(v18 + 436));
*(_DWORD *)(v18 + 132) = v19 + KUSER_SHARED_DATA.TickCount.LowPart;
}
*(_BYTE *)(v18 + 388) = 2;
*(_BYTE *)(v17 + 643) = 32;
*(_BYTE *)(v17 + 390) = CurrentIrql;
KiQueueReadyThread((__int64)CurrentPrcb, v17, v19);
v20 = !KiSwapContext((PKTHREAD)v17, (PKTHREAD)v18);
}
else
{
v20 = (*(_DWORD *)(v17 + 116) & 0x40) == 0;
}
if( !v20 )
{
__writecr8(1ui64);
*(_DWORD *)(v17 + 116) &= ~0x40u;
KiDeliverApc(0, 0i64, 0i64);
}
__writecr8(CurrentIrql);
}
return 0;
}
return result;
}Referenced by:
NtSetInformationThread