KiQuantumEnd
VOID __stdcall KiQuantumEnd(){
unsigned __int64 v0;
INT64 v1;
_KPRCB *v2;
INT64 v3;
UINT8 v4;
INT64 CurrentThread;
unsigned __int64 v6;
int v7;
char v8;
unsigned int LowPart;
int v10;
bool v11;
struct _KPRCB *v12;
_ETHREAD *NextThread;
struct _KPRCB *v14;
INT8 v15;
struct _KPRCB *v16;
unsigned int v17;
int v18;
unsigned __int64 v19;
_KPRCB *v20;
char v21;
BOOL IsUserVaAccessAllowed;
INT64 SharedReadyQueue;
char v24;
INT64 v25;
int v26;
char v27;
INT64 v28;
int v29;
unsigned int v30;
unsigned int v31;
_QWORD **v32;
_QWORD *v33;
_ETHREAD *v34;
bool v35;
bool v36;
UINT64 *v37;
char v38;
unsigned int ReadySummary;
int v40;
_LIST_ENTRY *DispatcherReadyListHead;
unsigned int QueueIndex;
unsigned int v43;
unsigned int v44;
unsigned int v45;
_QWORD *p_Flink;
_QWORD *v47;
INT64 v48;
bool v49;
int v50;
_QWORD *v51;
unsigned int v52;
_KNODE *ParentNode;
_DWORD *v54;
UINT8 v55;
_DWORD *v56;
INT64 v57;
UINT64 v58;
struct _KPRCB *v59;
INT64 v60;
INT64 v61;
UINT64 v62;
_DWORD *SchedulerAssist;
NTSTATUS GuestSchedulerAssistPriority;
_DWORD *v65;
int v66;
NTSTATUS v67;
_DWORD *v68;
int v69;
UINT8 IsThreadRankNonZero;
char v71;
INT64 v72;
UINT8 v73;
char Priority;
INT32 *v75;
INT64 v76;
_ETHREAD *IdleThread;
INT64 v78;
_SINGLE_LIST_ENTRY ReadyList;
INT64 v80;
UINT64 CycleTime;
UINT64 v82;
UINT64 v83;
UINT64 v84;
UINT64 v85;
_QWORD *v86;
unsigned int v87;
unsigned int v88;
UINT64 SpinCount;
UINT64 v90;
UINT64 v91;
INT64 v92;
_KPRCB *CurrentPrcb;
INT64 v94;
INT64 v95;
_SINGLE_LIST_ENTRY v96;
_SINGLE_LIST_ENTRY v97;
char v98;
unsigned int v99;
unsigned int v100;
char OldPriority;
INT64 OldPrioritya;
int OldPriorityb;
INT64 OldPriorityc;
_ETHREAD *v105;
int v106;
int v107;
v2 = KeGetCurrentPrcb();
LODWORD(v3) = 0;
v4 = 0;
ReadyList.Next = 0i64;
v98 = 0;
CurrentPrcb = v2;
CurrentThread = (INT64)v2->CurrentThread;
v92 = CurrentThread;
if( (_ETHREAD *)CurrentThread != v2->IdleThread )
{
v6 = *(_QWORD *)(CurrentThread + 72);
if( v6 >= *(_QWORD *)(CurrentThread + 32) || *(_BYTE *)(CurrentThread + 125) )
{
v14 = KeGetCurrentPrcb();
LODWORD(v82) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)(CurrentThread + 64), 0i64) )
{
do
KeYieldProcessorEx(&v82);
while( *(_QWORD *)(CurrentThread + 64) );
SchedulerAssist = v14->SchedulerAssist;
if( SchedulerAssist && v14->NestingLevel <= 1u )
++SchedulerAssist[6];
}
if( v6 >= *(_QWORD *)(CurrentThread + 32) )
{
if( (*(_DWORD *)(CurrentThread + 120) & 0x100) != 0 && *(char *)(CurrentThread + 195) >= 16 )
{
v18 = 127;
}
else
{
v15 = KiComputeNewPriority((_KTHREAD *)CurrentThread, 1);
v16 = KeGetCurrentPrcb();
v17 = v15;
HIDWORD(v82) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&v2->PrcbLock, 0i64) )
{
do
KeYieldProcessorEx((UINT64 *)((char *)&v82 + 4));
while( v2->PrcbLock );
v56 = v16->SchedulerAssist;
if( v56 && v16->NestingLevel <= 1u )
++v56[6];
}
if( !(unsigned __int8)KiUpdateVPBackingThreadPriority((PVOID)CurrentThread) )
KiUpdateThreadPriority(v2, (_KTHREAD *)CurrentThread, v17, v2->NextThread == 0i64);
_InterlockedAnd64((volatile signed __int64 *)&v2->PrcbLock, 0i64);
v18 = *(unsigned __int8 *)(CurrentThread + 651);
v4 = 1;
v98 = 1;
KiTryScheduleNextForegroundBoost((_KTHREAD *)CurrentThread);
}
v19 = v6 + (unsigned int)(v18 * KiCyclesPerClockQuantum);
if( (*(_DWORD *)(CurrentThread + 120) & 0x20) != 0 )
_interlockedbittestandreset((volatile signed __int32 *)(CurrentThread + 120), 5u);
*(_QWORD *)(CurrentThread + 32) = v19;
if( v2->GroupSetMember != v2->CoreProcessorSet
&& !_bittestandreset((signed __int32 *)(CurrentThread + 116), 7u)
&& (v2->CoreProcessorSet & (v2->GroupSetMember | v2->ParentNode->IdleCpuSet)) != v2->CoreProcessorSet )
{
ParentNode = (*(&KiProcessorBlock + *(unsigned int *)(CurrentThread + 588)))->ParentNode;
if( (ParentNode->IdleSmtSet & ParentNode->NonParkedSet & *(_QWORD *)(CurrentThread + 576)) != 0 )
{
*(_DWORD *)(CurrentThread + 116) |= 0x80u;
_interlockedbittestandset((volatile signed __int32 *)(CurrentThread + 120), 0xCu);
}
}
}
if( (unsigned int)KiCheckPreferredHeteroProcessor((_KTHREAD *)CurrentThread, v2) )
_interlockedbittestandset((volatile signed __int32 *)(CurrentThread + 120), 0xCu);
KiReleaseThreadLockSafe(CurrentThread);
LODWORD(v3) = 0;
}
}
v7 = 10;
v8 = 0;
LowPart = KUSER_SHARED_DATA.TickCount.LowPart;
v10 = 16;
v11 = (signed int)(v2->ReadyScanTick - KUSER_SHARED_DATA.TickCount.LowPart) < 0;
v88 = KUSER_SHARED_DATA.TickCount.LowPart;
if( !v11 )
goto LABEL_5;
v8 = 1;
if( !(unsigned int)KiShouldScanSharedReadyQueue(v2) )
goto LABEL_5;
SharedReadyQueue = (INT64)v2->SharedReadyQueue;
v80 = SharedReadyQueue;
if( (*(_DWORD *)(SharedReadyQueue + 8) & 0x7FFE) == 0 )
goto LABEL_5;
v24 = *(_BYTE *)(SharedReadyQueue + 594);
v94 = v3;
OldPriority = v24;
LODWORD(v83) = v3;
v25 = v80;
while( _interlockedbittestandset64((volatile signed __int32 *)v80, 0i64) )
{
do
KeYieldProcessorEx(&v83);
while( *(_QWORD *)v80 );
}
v0 = *(_DWORD *)(v80 + 8) & 0x7FFE;
if( (*(_DWORD *)(v80 + 8) & 0x7FFE) != 0 )
{
v26 = 10;
v27 = OldPriority;
v28 = v80 + 16;
v29 = 16;
LODWORD(v0) = __ROR4__(v0, OldPriority);
v1 = KUSER_SHARED_DATA.TickCount.LowPart - 300;
v99 = KUSER_SHARED_DATA.TickCount.LowPart - 300;
do
{
_BitScanForward(&v30, v0);
HIDWORD(v83) = v30;
LODWORD(v84) = v0 ^ (1 << v30);
v31 = ((_BYTE)v30 + v27) & 0x1F;
v87 = v31;
v32 = (_QWORD **)(v28 + 16i64 * (((_BYTE)v30 + v27) & 0x1F));
v33 = *v32;
do
{
v34 = (_ETHREAD *)(v33 - 27);
v35 = 0;
v36 = (*(_DWORD *)(v33 - 12) & 0x400000) == 0;
v33 = (_QWORD *)*v33;
v86 = v33;
v105 = v34;
if( !v36 )
{
GuestSchedulerAssistPriority = KiReadGuestSchedulerAssistPriority((INT64)v34);
v34 = v105;
v33 = v86;
v1 = v99;
if( GuestSchedulerAssistPriority >= 16 )
GuestSchedulerAssistPriority = 15;
v35 = GuestSchedulerAssistPriority != v105->Tcb.SchedulerAssistPriorityFloor;
}
v106 = v1 - v34->Tcb.WaitBlock[2].SpareLong;
if( v106 > 0 || v35 )
{
KiRemoveThreadFromSharedReadyQueue((_KSHARED_READY_QUEUE *)v80, &v34->Tcb, v31);
KiInsertDeferredReadyList((INT64)&v94, v60);
v1 = v99;
if( v106 > 0 )
--v26;
}
--v29;
}
while( v33 != v32 && v26 && v29 );
v0 = (unsigned int)v84;
v28 = v80 + 16;
v107 = v26;
LODWORD(v86) = v29;
if( !(_DWORD)v84 )
break;
if( !v26 )
break;
v27 = OldPriority;
}
while( v29 );
_InterlockedAnd64((volatile signed __int64 *)v80, 0i64);
v7 = 10;
v2 = CurrentPrcb;
v4 = v98;
v10 = 16;
v37 = (UINT64 *)v94;
if( v94 )
{
do
{
v61 = (INT64)(v37 - 27);
v62 = *(v37 - 18);
OldPriorityc = (INT64)(v37 - 27);
CycleTime = *v37;
v84 = v62;
CurrentPrcb = KeGetCurrentPrcb();
LODWORD(v85) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)(v61 + 64), 0i64) )
{
do
KeYieldProcessorEx(&v85);
while( *(_QWORD *)(OldPriorityc + 64) );
v61 = OldPriorityc;
v65 = CurrentPrcb->SchedulerAssist;
if( v65 && CurrentPrcb->NestingLevel <= 1u )
{
v66 = v65[6] + 1;
v65[6] = v66;
}
}
if( (int)(v99 - *(_DWORD *)(v61 + 436)) > 0 && *(char *)(v61 + 195) < 15 )
KiSetPriorityBoost(0i64, (_KTHREAD *)v61, 15, v84);
KiReleaseThreadLockSafe(v61);
*(_QWORD *)(v61 + 216) = 0i64;
v96.Next = (_SINGLE_LIST_ENTRY *)(v61 + 216);
KiReadyDeferredReadyList(v2, &v96);
v37 = (UINT64 *)CycleTime;
}
while( CycleTime );
v4 = v98;
v25 = v80;
v29 = (int)v86;
}
if( !v29 || !v107 )
{
v38 = v87 + 1;
if( v87 + 1 <= 0xE )
goto LABEL_71;
}
}
else
{
_InterlockedAnd64((volatile signed __int64 *)v80, 0i64);
}
v38 = 1;
LABEL_71:
CurrentThread = v92;
LODWORD(v3) = 0;
*(_BYTE *)(v25 + 594) = v38;
LowPart = v88;
LABEL_5:
if( KiGroupSchedulingEnabled )
{
KiGroupSchedulingQuantumEnd(v2, (_KTHREAD *)CurrentThread, v4, &ReadyList);
}
else
{
v12 = KeGetCurrentPrcb();
LODWORD(SpinCount) = v3;
while( _interlockedbittestandset64((volatile signed __int32 *)&v2->PrcbLock, 0i64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( v2->PrcbLock );
v54 = v12->SchedulerAssist;
if( v54 && v12->NestingLevel <= 1u )
++v54[6];
}
v7 = 10;
}
if( v8 )
{
ReadySummary = v2->ReadySummary;
v2->ReadyScanTick = LowPart + 75;
v40 = ReadySummary & 0x7FFE;
if( v40 )
{
DispatcherReadyListHead = v2->DispatcherReadyListHead;
QueueIndex = v2->QueueIndex;
v95 = 0i64;
v43 = __ROR4__(v40, QueueIndex);
v0 = KUSER_SHARED_DATA.TickCount.LowPart - 300;
v100 = KUSER_SHARED_DATA.TickCount.LowPart - 300;
do
{
_BitScanForward(&v44, v43);
v43 ^= 1 << v44;
HIDWORD(SpinCount) = v44;
v45 = ((_BYTE)v44 + (_BYTE)QueueIndex) & 0x1F;
p_Flink = &DispatcherReadyListHead[((_BYTE)v44 + (_BYTE)QueueIndex) & 0x1F].Flink;
CycleTime = (UINT64)p_Flink;
v47 = (_QWORD *)*p_Flink;
do
{
v48 = (INT64)(v47 - 27);
v49 = 0;
v36 = (*(_DWORD *)(v47 - 12) & 0x400000) == 0;
v47 = (_QWORD *)*v47;
OldPrioritya = (INT64)v47;
v80 = v48;
if( !v36 )
{
v67 = KiReadGuestSchedulerAssistPriority(v48);
v48 = v80;
p_Flink = (_QWORD *)CycleTime;
v47 = (_QWORD *)OldPrioritya;
if( v67 >= 16 )
v67 = 15;
v0 = v100;
v49 = v67 != *(_DWORD *)(v80 + 1024);
}
v50 = v0 - *(_DWORD *)(v48 + 436);
OldPriorityb = v50;
if( v50 > 0 || v49 )
{
KiRemoveThreadFromReadyQueue(v2, (_LIST_ENTRY *)(v48 + 216), v45);
KiInsertDeferredReadyList((INT64)&v95, v80);
v0 = v100;
if( OldPriorityb > 0 )
--v7;
}
--v10;
}
while( v47 != p_Flink && v7 && v10 );
DispatcherReadyListHead = v2->DispatcherReadyListHead;
}
while( v43 && v7 && v10 );
v51 = (_QWORD *)v95;
CurrentThread = v92;
v4 = v98;
if( v95 )
{
_InterlockedAnd64((volatile signed __int64 *)&v2->PrcbLock, 0i64);
do
{
v57 = (INT64)(v51 - 27);
v58 = *(v51 - 18);
v51 = (_QWORD *)*v51;
CycleTime = v58;
LODWORD(v90) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)(v57 + 64), 0i64) )
{
do
KeYieldProcessorEx(&v90);
while( *(_QWORD *)(v57 + 64) );
}
if( (int)(v100 - *(_DWORD *)(v57 + 436)) > 0 && *(char *)(v57 + 195) < 15 )
KiSetPriorityBoost(0i64, (_KTHREAD *)v57, 15, CycleTime);
KiReleaseThreadLockSafe(v57);
v97.Next = (_SINGLE_LIST_ENTRY *)(v57 + 216);
*(_QWORD *)(v57 + 216) = 0i64;
KiReadyDeferredReadyList(v2, &v97);
}
while( v51 );
v59 = KeGetCurrentPrcb();
HIDWORD(v90) = 0;
CurrentThread = v92;
while( _interlockedbittestandset64((volatile signed __int32 *)&v2->PrcbLock, 0i64) )
{
do
KeYieldProcessorEx((UINT64 *)((char *)&v90 + 4));
while( v2->PrcbLock );
v68 = v59->SchedulerAssist;
if( v68 && v59->NestingLevel <= 1u )
{
v69 = v68[6] + 1;
v68[6] = v69;
}
}
}
if( v10 && v7 || (v52 = v45 + 1, v52 > 0xE) )
v52 = 1;
v2->QueueIndex = v52;
}
}
while( 1 )
{
NextThread = v2->NextThread;
if( NextThread )
{
if( v4 )
*(_BYTE *)(CurrentThread + 565) = 0;
LABEL_49:
if( !NextThread )
goto LABEL_13;
goto LABEL_50;
}
if( !v4 || (NextThread = (_ETHREAD *)KiSelectReadyThread((unsigned int)*(char *)(CurrentThread + 195), v2)) == 0i64 )
{
if( (*(_DWORD *)(CurrentThread + 120) & 0x1000) == 0 )
goto LABEL_13;
if( (_ETHREAD *)CurrentThread == v2->IdleThread )
{
_interlockedbittestandreset((volatile signed __int32 *)(CurrentThread + 120), 0xCu);
goto LABEL_13;
}
KiSelectNextThread(v2, &ReadyList);
NextThread = v2->NextThread;
goto LABEL_49;
}
LABEL_50:
if( NextThread != v2->IdleThread && !(unsigned int)KiCheckThreadAffinity(&NextThread->Tcb) )
{
if( (*(_BYTE *)(CurrentThread + 2) & 4) == 0
|| (IsThreadRankNonZero = KiIsThreadRankNonZero((_KTHREAD *)CurrentThread, v2, (_KPRCB *)v0),
v71 = 1,
!IsThreadRankNonZero) )
{
v71 = *(_BYTE *)(CurrentThread + 195);
}
*v2->PriorityState = v71;
if( v2->SchedulerAssist )
{
v72 = (unsigned int)KiVpThreadSystemWorkPriority;
if( (_ETHREAD *)CurrentThread != v2->IdleThread )
v72 = (unsigned int)v71;
KiSetSchedulerAssistPriority((INT32 *)v2->SchedulerAssist, v72, 0);
}
if( v2->NextThread == NextThread )
KiSelectNextThread(v2, &ReadyList);
KiInsertDeferredReadyList((INT64)&ReadyList, (INT64)NextThread);
NextThread = 0i64;
}
LABEL_13:
if( !ReadyList.Next )
break;
if( NextThread && NextThread != v2->IdleThread && v2->NextThread != NextThread )
{
if( (NextThread->Tcb.gap0[2] & 4) == 0
|| (v73 = KiIsThreadRankNonZero(&NextThread->Tcb, v2, (_KPRCB *)v0), Priority = 1, !v73) )
{
Priority = NextThread->Tcb.Priority;
}
*v2->PriorityState = Priority;
v75 = (INT32 *)v2->SchedulerAssist;
if( v75 )
{
if( NextThread == v2->IdleThread )
v76 = (unsigned int)KiVpThreadSystemWorkPriority;
else
v76 = (unsigned int)Priority;
KiSetSchedulerAssistPriority(v75, v76, 0);
v75 = (INT32 *)v2->SchedulerAssist;
}
IdleThread = v2->IdleThread;
v2->NextThread = NextThread;
if( v75 )
*((_BYTE *)v75 + 16) = NextThread == IdleThread;
if( NextThread->Tcb.WaitBlockFill6[68] == 1 )
NextThread->Tcb.ReadyTime = NextThread->Tcb.ReadyTime
- NextThread->Tcb.WaitBlock[2].SpareLong
+ KUSER_SHARED_DATA.TickCount.LowPart;
NextThread->Tcb.WaitBlockFill6[68] = 3;
}
_InterlockedAnd64((volatile signed __int64 *)&v2->PrcbLock, 0i64);
KiSetVpThreadSpinLockCount();
KiReadyDeferredReadyList(v2, &ReadyList);
LODWORD(v91) = 0;
ReadyList.Next = 0i64;
while( 1 )
{
KiSetVpThreadSpinLockCount();
if( !_interlockedbittestandset64((volatile signed __int32 *)&v2->PrcbLock, 0i64) )
break;
KiSetVpThreadSpinLockCount();
do
KeYieldProcessorEx(&v91);
while( v2->PrcbLock );
}
}
if( !NextThread || (_ETHREAD *)CurrentThread == v2->IdleThread )
{
_InterlockedAnd64((volatile signed __int64 *)&v2->PrcbLock, 0i64);
KiSetVpThreadSpinLockCount();
}
else
{
v2->NextThread = 0i64;
_disable();
KiEndThreadCycleAccumulation((INT64)v2, CurrentThread, 0i64, v1, (INT64)ReadyList.Next, v80, CycleTime);
_enable();
if( (NextThread->Tcb.gap0[2] & 4) == 0 || (v55 = KiIsThreadRankNonZero(&NextThread->Tcb, v2, v20), v21 = 1, !v55) )
v21 = NextThread->Tcb.Priority;
*v2->PriorityState = v21;
if( v2->SchedulerAssist )
{
v78 = (unsigned int)KiVpThreadSystemWorkPriority;
if( NextThread != v2->IdleThread )
v78 = (unsigned int)v21;
KiSetSchedulerAssistPriority((INT32 *)v2->SchedulerAssist, v78, 0);
}
v2->CurrentThread = NextThread;
if( NextThread->Tcb.WaitBlockFill6[68] == 1 )
NextThread->Tcb.ReadyTime = NextThread->Tcb.ReadyTime
- NextThread->Tcb.WaitBlock[2].SpareLong
+ KUSER_SHARED_DATA.TickCount.LowPart;
NextThread->Tcb.WaitBlockFill6[68] = 2;
*(_BYTE *)(CurrentThread + 643) = 30;
KiQueueReadyThread(v2, (_KTHREAD *)CurrentThread);
KiAbProcessContextSwitch((_KTHREAD *)CurrentThread, 1ui64);
IsUserVaAccessAllowed = KeIsUserVaAccessAllowed(0i64);
if( KeSmapEnabled )
__stac();
KiSwapContext();
if( !IsUserVaAccessAllowed )
{
if( KeSmapEnabled )
__clac();
}
}
}Referenced by:
KiDispatchInterrupt
KiIdleLoop