KiAbProcessContextSwitch
VOID __stdcall KiAbProcessContextSwitch(_ETHREAD *Thread, UINT64 RequestInterrupt){
int i;
_AB_PRIORITY v3;
struct _KPRCB *CurrentPrcb;
char v5;
_SINGLE_LIST_ENTRY *p_AbSelfIoBoostsList;
_KLOCK_ENTRY *LockEntries;
int v8;
bool v9;
_KLOCK_ENTRY *v10;
_KLOCK_ENTRY *v11;
__int64 bf_0;
int AllPriorities;
_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;
INT8 v23;
char v24;
int v25;
char v26;
_ETHREAD *v27;
void(__fastcall **ExtensionTable)(_ETHREAD *);
_SINGLE_LIST_ENTRY *v29;
int v30[8];
_SINGLE_LIST_ENTRY ReadyList;
_SINGLE_LIST_ENTRY PropagateBoostsList;
_SINGLE_LIST_ENTRY *SelfBoostsList;
struct _KPRCB *v34;
_KLOCK_QUEUE_HANDLE HeadEntryLockQueue;
_AB_PRIORITY MaxPriority;
int v37;
UINT64 BoostOutstandingIOsRequired;
int v39;
v37 = RequestInterrupt;
i = RequestInterrupt;
if( ((char)Thread->Tcb.AbEntrySummary | (char)Thread->Tcb.AbOrphanedEntrySummary) == 63 )
return;
v3 = 0;
CurrentPrcb = KeGetCurrentPrcb();
v5 = Thread->Tcb.AbEntrySummary | Thread->Tcb.AbOrphanedEntrySummary;
ReadyList.Next = 0i64;
PropagateBoostsList.Next = 0i64;
p_AbSelfIoBoostsList = &CurrentPrcb->AbSelfIoBoostsList;
SelfBoostsList = &CurrentPrcb->AbSelfIoBoostsList;
v34 = CurrentPrcb;
v39 = 0;
if( v5 == 63 )
{
Next = ReadyList.Next;
goto LABEL_20;
}
LockEntries = Thread->Tcb.LockEntries;
v8 = ((char)Thread->Tcb.AbEntrySummary | (char)Thread->Tcb.AbOrphanedEntrySummary) ^ 0x3F;
v9 = !_BitScanForward((unsigned int *)&Thread, v8);
if( v9 )
goto LABEL_18;
v10 = LockEntries;
do
{
v8 &= v8 - 1;
v11 = &v10[(_QWORD)Thread];
bf_0 = v11->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0;
if( !bf_0 || (bf_0 & 2) != 0 || (bf_0 & 1) != 0 )
goto LABEL_15;
if( bf_0 >= 0 )
goto LABEL_9;
if( (v11->CrossThreadFlags & 1) != 0 )
goto LABEL_15;
if( (v11->ThreadLocalFlags & 1) == 0 )
{
if( KiAbOwnerComputeCpuPriorityKey(&v10[(_QWORD)Thread]) == v11->CpuPriorityKey )
goto LABEL_15;
LABEL_9:
MaxPriority = v3;
LODWORD(BoostOutstandingIOsRequired) = v3;
AllPriorities = v3.AllPriorities;
memset(&HeadEntryLockQueue, 0, sizeof(HeadEntryLockQueue));
LockedHeadEntry = KiAbEntryGetLockedHeadEntry(v11, 1ui64, &HeadEntryLockQueue);
v15 = LockedHeadEntry;
if( !LockedHeadEntry )
goto LABEL_15;
if( (v11->ThreadLocalFlags & 1) == 0 )
{
if( v11 != LockedHeadEntry )
KiAbEntryUpdateOwnerTreePosition(v11, LockedHeadEntry);
KiAbDetermineMaxWaiterPriority(v15, &MaxPriority);
if( !*(_DWORD *)&MaxPriority )
goto LABEL_14;
KiAbSetMinimumThreadPriority(
v11,
&MaxPriority,
&ReadyList,
&PropagateBoostsList,
p_AbSelfIoBoostsList,
&BoostOutstandingIOsRequired);
if( v25 && v11 != v15 )
KiAbEntryUpdateOwnerTreePosition(v11, v15);
AllPriorities = BoostOutstandingIOsRequired;
goto LABEL_37;
}
if( v11 != LockedHeadEntry )
KiAbEntryUpdateWaiterTreePosition(v11, LockedHeadEntry);
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(v11);
if( v20 < CpuPriorityKey )
{
if( !v21 )
{
p_AbSelfIoBoostsList = SelfBoostsList;
goto LABEL_36;
}
}
else if( !v21 )
{
p_AbSelfIoBoostsList = SelfBoostsList;
LABEL_14:
KeReleaseInStackQueuedSpinLockFromDpcLevel(&HeadEntryLockQueue);
goto LABEL_15;
}
p_AbSelfIoBoostsList = SelfBoostsList;
KiAbIoBoostOwners(v15, (_BYTE *)v21, &ReadyList, &PropagateBoostsList, SelfBoostsList);
LABEL_36:
KiAbCpuBoostOwners(v15, CpuPriorityKey, &ReadyList, &PropagateBoostsList, p_AbSelfIoBoostsList);
LABEL_37:
KeReleaseInStackQueuedSpinLockFromDpcLevel(&HeadEntryLockQueue);
if( AllPriorities )
{
v27 = (_ETHREAD *)((char *)v11 - 16 * v11->EntryOffset);
if( ObReferenceObjectSafeWithTag((INT64)v27, 1953261124i64) )
{
if( (AllPriorities & 1) != 0 )
IoBoostThreadIoPriority(v27, IoPriorityNormal, 0x80000000ui64);
if( (AllPriorities & 2) != 0 )
{
if( v27->IoQoSThrottleCount )
{
ExtensionTable = (void(__fastcall **)(_ETHREAD *))ExGetExtensionTable(*(&stru_140C452E0 + 122));
if( ExtensionTable )
{
ExtensionTable[2](v27);
ExReleaseRundownProtection((_EX_RUNDOWN_REF *)(*(&stru_140C452E0 + 122) + 64i64));
}
}
}
ObDereferenceObjectDeferDeleteWithTag((UINT64)v27, 1953261124i64);
}
}
goto LABEL_15;
}
v26 = BYTE3((&v11[2].FreeListEntry.Next)[-2 * v11->EntryOffset]);
if( v26 > 15 )
v26 = 15;
if( v26 != v11->CpuPriorityKey )
goto LABEL_9;
LABEL_15:
v9 = !_BitScanForward((unsigned int *)&Thread, v8);
v3 = 0;
v39 = (int)Thread;
}
while( !v9 );
v16 = PropagateBoostsList.Next;
for( i = v37; PropagateBoostsList.Next; v16 = PropagateBoostsList.Next )
{
v29 = v16 - 101;
PropagateBoostsList.Next = v16->Next;
v16->Next = (_SINGLE_LIST_ENTRY *)1;
_InterlockedOr(v30, 0);
if( BYTE1(v16[-2].Next) )
KiAbProcessThreadLocks(
(_KTHREAD *)&v16[-101],
0i64,
1ui64,
0i64,
&ReadyList,
&PropagateBoostsList,
p_AbSelfIoBoostsList);
_InterlockedDecrement16((volatile signed __int16 *)&v29[108].Next + 2);
}
CurrentPrcb = v34;
LABEL_18:
Next = ReadyList.Next;
if( ReadyList.Next )
ReadyList.Next = ReadyList.Next->Next;
LABEL_20:
if( Next )
{
while( 1 )
{
KiDeferredReadySingleThread((INT64)CurrentPrcb, (_DWORD)Next - 216, (INT64)&ReadyList);
LODWORD(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