KiAbProcessContextSwitch
VOID __stdcall KiAbProcessContextSwitch(_ETHREAD *Thread, UINT64 RequestInterrupt){
int i;
void *v3;
struct _KPRCB *CurrentPrcb;
char v5;
_SINGLE_LIST_ENTRY *v6;
__int64 v7;
int v8;
bool v9;
__int64 v10;
_KLOCK_ENTRY *v11;
__int64 LockState;
int v13;
_KLOCK_ENTRY *LockedHeadEntry;
_KLOCK_ENTRY *v15;
_SINGLE_LIST_ENTRY *v16;
_SINGLE_LIST_ENTRY *Next;
_RTL_BALANCED_NODE *Min;
char v19;
char v20;
unsigned int v21;
CHAR CpuPriorityKey;
CHAR v23;
char v24;
char v25;
KSPIN_LOCK *v26;
UINT64 ExtensionTable;
_SINGLE_LIST_ENTRY *v28;
int v29[8];
_SINGLE_LIST_ENTRY ReadyList;
_SINGLE_LIST_ENTRY PropagateBoostsList;
_SINGLE_LIST_ENTRY *SelfBoostsList;
struct _KPRCB *v33;
struct _KLOCK_QUEUE_HANDLE LockHandle;
INT64 v35;
int v36;
int v37;
int v38;
v36 = RequestInterrupt;
i = RequestInterrupt;
if( (*((char *)Thread + 792) | *((char *)Thread + 870)) == 63 )
return;
v3 = 0i64;
CurrentPrcb = KeGetCurrentPrcb();
v5 = *((_BYTE *)Thread + 792) | *((_BYTE *)Thread + 870);
ReadyList.Next = 0i64;
PropagateBoostsList.Next = 0i64;
v6 = (_SINGLE_LIST_ENTRY *)((char *)CurrentPrcb + 34672);
SelfBoostsList = (_SINGLE_LIST_ENTRY *)((char *)CurrentPrcb + 34672);
v33 = CurrentPrcb;
v38 = 0;
if( v5 == 63 )
{
Next = ReadyList.Next;
goto LABEL_20;
}
v7 = *((_QWORD *)Thread + 100);
v8 = (*((char *)Thread + 792) | *((char *)Thread + 870)) ^ 0x3F;
v9 = !_BitScanForward((unsigned int *)&Thread, v8);
if( v9 )
goto LABEL_18;
v10 = v7;
do
{
v8 &= v8 - 1;
v11 = (_KLOCK_ENTRY *)(v10 + 96i64 * (_QWORD)Thread);
LockState = (__int64)v11->LockState.LockState;
if( !LockState || (LockState & 2) != 0 || (LockState & 1) != 0 )
goto LABEL_15;
if( LockState >= 0 )
goto LABEL_9;
if( (v11->CrossThreadFlags & 1) != 0 )
goto LABEL_15;
if( (v11->ThreadLocalFlags & 1) == 0 )
{
if( KiAbOwnerComputeCpuPriorityKey((_KLOCK_ENTRY *)(v10 + 96i64 * (_QWORD)Thread)) == v11->CpuPriorityKey )
goto LABEL_15;
LABEL_9:
LODWORD(v35) = (_DWORD)v3;
v37 = (int)v3;
v13 = (int)v3;
memset(&LockHandle, 0, sizeof(LockHandle));
LockedHeadEntry = (_KLOCK_ENTRY *)KiAbEntryGetLockedHeadEntry((unsigned __int64)v11, 1, &LockHandle, v3);
v15 = LockedHeadEntry;
if( !LockedHeadEntry )
goto LABEL_15;
if( (v11->ThreadLocalFlags & 1) == 0 )
{
if( v11 != LockedHeadEntry )
KiAbEntryUpdateOwnerTreePosition(v11, LockedHeadEntry);
KiAbDetermineMaxWaiterPriority((INT64)v15, (INT64)&v35);
if( !(_DWORD)v35 )
goto LABEL_14;
if( (unsigned int)KiAbSetMinimumThreadPriority(
(__int64)v11,
(__int64)&v35,
(__int64)&ReadyList,
&PropagateBoostsList,
v6,
&v37)
&& v11 != v15 )
{
KiAbEntryUpdateOwnerTreePosition(v11, v15);
}
v13 = v37;
goto LABEL_37;
}
if( v11 != LockedHeadEntry )
KiAbEntryUpdateWaiterTreePosition((SLIST_ENTRY *)v11);
Min = v15->OwnerTree.Min;
if( Min )
v19 = (char)Min[2].Children[0];
else
v19 = 15;
v20 = v19;
if( (v15->ThreadLocalFlags & 1) == 0 )
{
v23 = KiAbOwnerComputeCpuPriorityKey(v15);
if( v23 < v24 )
v20 = v23;
}
KiAbTryIncrementIoWaiterCounts(v11, v15);
CpuPriorityKey = KiAbEntryGetCpuPriorityKey((unsigned __int8 *)v11);
if( v20 < CpuPriorityKey )
{
if( !v21 )
{
v6 = SelfBoostsList;
goto LABEL_36;
}
}
else if( !v21 )
{
v6 = SelfBoostsList;
LABEL_14:
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
goto LABEL_15;
}
v6 = SelfBoostsList;
KiAbIoBoostOwners(v15, v21, &ReadyList, &PropagateBoostsList, SelfBoostsList);
LABEL_36:
KiAbCpuBoostOwners(v15, CpuPriorityKey, &ReadyList, &PropagateBoostsList, v6);
LABEL_37:
KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
if( v13 )
{
v26 = (KSPIN_LOCK *)((char *)v11 - 16 * v11->EntryOffset);
if( ObReferenceObjectSafeWithTag(v26, 0x746C6644ui64) )
{
if( (v13 & 1) != 0 )
IoBoostThreadIoPriority(v26, 2, 0x80000000);
if( (v13 & 2) != 0 )
{
if( *((_DWORD *)v26 + 342) )
{
ExtensionTable = ExGetExtensionTable(IopIoRateExtensionHost);
if( ExtensionTable )
{
(*(void(__fastcall **)(KSPIN_LOCK *))(ExtensionTable + 16))(v26);
ExReleaseRundownProtection(IopIoRateExtensionHost + 8);
}
}
}
ObDereferenceObjectDeferDeleteWithTag(v26, 0x746C6644ui64);
}
}
goto LABEL_15;
}
v25 = BYTE3((&v11[2].FreeListEntry.Next)[-2 * v11->EntryOffset]);
if( v25 > 15 )
v25 = 15;
if( v25 != v11->CpuPriorityKey )
goto LABEL_9;
LABEL_15:
v9 = !_BitScanForward((unsigned int *)&Thread, v8);
v3 = 0i64;
v38 = (int)Thread;
}
while( !v9 );
v16 = PropagateBoostsList.Next;
for( i = v36; PropagateBoostsList.Next; v16 = PropagateBoostsList.Next )
{
v28 = v16 - 101;
PropagateBoostsList.Next = v16->Next;
v16->Next = (_SINGLE_LIST_ENTRY *)1;
_InterlockedOr(v29, 0);
if( BYTE1(v16[-2].Next) )
KiAbProcessThreadLocks((_KTHREAD *)&v16[-101], 0i64, 1ui64, 0i64, &ReadyList, &PropagateBoostsList, v6);
_InterlockedDecrement16((volatile signed __int16 *)&v28[108].Next + 2);
}
CurrentPrcb = v33;
LABEL_18:
Next = ReadyList.Next;
if( ReadyList.Next )
ReadyList.Next = ReadyList.Next->Next;
LABEL_20:
if( Next )
{
while( 1 )
{
KiDeferredReadySingleThread((INT64)CurrentPrcb, (INT64)&Next[-27], (INT64)&ReadyList);
Next = ReadyList.Next;
if( !ReadyList.Next )
break;
ReadyList.Next = ReadyList.Next->Next;
}
}
if( i )
KiCheckForThreadDispatch(CurrentPrcb, 2u);
}Referenced by:
KeBoostPriorityThread
KeCpuSetReportParkedProcessors
KeDelayExecutionThread
KeRecomputeCpuSetAffinityProcess
KeRemoveQueueEx
KeSetAffinityThread
KeSetBasePriorityThread
KeSetCpuSetsProcess
KeSetLegacyAffinityThread
KeSetSchedulingGroupRankBias
KeSetSelectedCpuSetsThread
KeSetThreadSchedulerAssist
KeUpdateThreadCpuSets
KeYieldExecution
KiAbForceProcessLockEntry
KiAbThreadUnboostCpuPriority
KiCheckForThreadDispatch
KiExitDispatcher
KiProcessDeferredReadyList
KiQuantumEnd
KiReadyOutSwappedThreads
KiSchedulerApc
KiSetHeteroPolicyThread
KiSwapThread
KxDispatchInterrupt
PsImpersonateContainerOfThread