KiQuantumEnd
VOID __stdcall KiQuantumEnd(){
struct _KPRCB *CurrentPrcb;
INT64 v1;
UINT8 v2;
ULONG_PTR v3;
unsigned __int64 v4;
int v5;
char v6;
unsigned int LowPart;
int v8;
bool v9;
struct _KPRCB *v10;
_KTHREAD *v11;
struct _KPRCB *v12;
char v13;
struct _KPRCB *v14;
unsigned int v15;
int v16;
unsigned __int64 v17;
__int64 v18;
char v19;
bool IsUserVaAccessAllowed;
INT64 v21;
char v22;
INT64 v23;
int v24;
char v25;
INT64 v26;
int v27;
unsigned int v28;
unsigned int v29;
unsigned int v30;
unsigned __int8 v31;
_QWORD **v32;
_QWORD *v33;
INT64 v34;
bool v35;
bool v36;
UINT64 *v37;
char v38;
int v39;
int v40;
char *v41;
int v42;
unsigned int v43;
unsigned int v44;
unsigned int v45;
int v46;
char *v47;
char *v48;
INT64 v49;
bool v50;
int v51;
_QWORD *v52;
unsigned int v53;
__int64 v54;
__int64 v55;
char v56;
__int64 v57;
INT64 v58;
UINT64 v59;
struct _KPRCB *v60;
INT64 v61;
INT64 v62;
UINT64 v63;
__int64 v64;
int GuestSchedulerAssistPriority;
__int64 v66;
int v67;
int v68;
__int64 v69;
int v70;
char v71;
char v72;
INT64 v73;
char v74;
char v75;
__int64 v76;
INT64 v77;
_ETHREAD *v78;
INT64 v79;
_SINGLE_LIST_ENTRY ReadyList;
INT64 v81;
UINT64 CycleTime;
UINT64 v83;
UINT64 v84;
UINT64 v85;
UINT64 v86;
_QWORD *v87;
int v88;
unsigned int v89;
UINT64 SpinCount;
UINT64 v91;
UINT64 v92;
ULONG_PTR v93;
struct _KPRCB *v94;
INT64 v95;
INT64 v96;
INT64 v97;
__int64 v98[9];
char v99;
unsigned int v100;
unsigned int v101;
char v102;
INT64 v103;
int v104;
INT64 v105;
INT64 v106;
int v107;
int v108;
CurrentPrcb = KeGetCurrentPrcb();
LODWORD(v1) = 0;
v2 = 0;
ReadyList.Next = 0i64;
v99 = 0;
v94 = CurrentPrcb;
v3 = *((_QWORD *)CurrentPrcb + 1);
v93 = v3;
if( v3 != *((_QWORD *)CurrentPrcb + 3) )
{
v4 = *(_QWORD *)(v3 + 72);
if( v4 >= *(_QWORD *)(v3 + 32) || *(_BYTE *)(v3 + 125) )
{
v12 = KeGetCurrentPrcb();
LODWORD(v83) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)(v3 + 64), 0i64) )
{
do
KeYieldProcessorEx(&v83);
while( *(_QWORD *)(v3 + 64) );
v64 = *((_QWORD *)v12 + 4247);
if( v64 && *((_BYTE *)v12 + 32) <= 1u )
++*(_DWORD *)(v64 + 24);
}
if( v4 >= *(_QWORD *)(v3 + 32) )
{
if( (*(_DWORD *)(v3 + 120) & 0x100) != 0 && *(char *)(v3 + 195) >= 16 )
{
v16 = 127;
}
else
{
v13 = KiComputeNewPriority(v3, 1);
v14 = KeGetCurrentPrcb();
v15 = v13;
HIDWORD(v83) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)CurrentPrcb + 12, 0i64) )
{
do
KeYieldProcessorEx((UINT64 *)((char *)&v83 + 4));
while( *((_QWORD *)CurrentPrcb + 6) );
v57 = *((_QWORD *)v14 + 4247);
if( v57 && *((_BYTE *)v14 + 32) <= 1u )
++*(_DWORD *)(v57 + 24);
}
if( !(unsigned __int8)KiUpdateVPBackingThreadPriority((PVOID)v3) )
KiUpdateThreadPriority(CurrentPrcb, (_KTHREAD *)v3, v15, *((_QWORD *)CurrentPrcb + 2) == 0i64);
_InterlockedAnd64((volatile signed __int64 *)CurrentPrcb + 6, 0i64);
v16 = *(unsigned __int8 *)(v3 + 651);
v2 = 1;
v99 = 1;
KiTryScheduleNextForegroundBoost(v3);
}
v17 = v4 + (unsigned int)(v16 * KiCyclesPerClockQuantum);
if( (*(_DWORD *)(v3 + 120) & 0x20) != 0 )
_interlockedbittestandreset((volatile signed __int32 *)(v3 + 120), 5u);
*(_QWORD *)(v3 + 32) = v17;
if( *((_QWORD *)CurrentPrcb + 25) != *((_QWORD *)CurrentPrcb + 4235)
&& !_bittestandreset((signed __int32 *)(v3 + 116), 7u)
&& (*((_QWORD *)CurrentPrcb + 4235) & (*((_QWORD *)CurrentPrcb + 25) | *(_QWORD *)(*((_QWORD *)CurrentPrcb + 24)
+ 24i64))) != *((_QWORD *)CurrentPrcb + 4235) )
{
v54 = *((_QWORD *)*(&KiProcessorBlock + *(unsigned int *)(v3 + 588)) + 24);
if( (*(_QWORD *)(v54 + 8) & *(_QWORD *)(v54 + 80) & *(_QWORD *)(v3 + 576)) != 0i64 )
{
*(_DWORD *)(v3 + 116) |= 0x80u;
_interlockedbittestandset((volatile signed __int32 *)(v3 + 120), 0xCu);
}
}
}
if( (unsigned int)KiCheckPreferredHeteroProcessor((_KTHREAD *)v3, CurrentPrcb) )
_interlockedbittestandset((volatile signed __int32 *)(v3 + 120), 0xCu);
KiReleaseThreadLockSafe(v3);
LODWORD(v1) = 0;
}
}
v5 = 10;
v6 = 0;
LowPart = KUSER_SHARED_DATA.TickCount.LowPart;
v8 = 16;
v9 = (signed int)(*((_DWORD *)CurrentPrcb + 3151) - KUSER_SHARED_DATA.TickCount.LowPart) < 0;
v89 = KUSER_SHARED_DATA.TickCount.LowPart;
if( !v9 )
goto LABEL_5;
v6 = 1;
if( !KiShouldScanSharedReadyQueue((__int64)CurrentPrcb) )
goto LABEL_5;
v21 = *((_QWORD *)CurrentPrcb + 4233);
v81 = v21;
if( (*(_DWORD *)(v21 + 8) & 0x7FFE) == 0 )
goto LABEL_5;
v22 = *(_BYTE *)(v21 + 594);
v95 = v1;
v102 = v22;
LODWORD(v84) = v1;
v23 = v81;
while( _interlockedbittestandset64((volatile signed __int32 *)v81, 0i64) )
{
do
KeYieldProcessorEx(&v84);
while( *(_QWORD *)v81 );
}
if( (*(_DWORD *)(v81 + 8) & 0x7FFE) != 0 )
{
v24 = 10;
v25 = v102;
v26 = v81 + 16;
v27 = 16;
v28 = __ROR4__(*(_DWORD *)(v81 + 8) & 0x7FFE, v102);
v29 = KUSER_SHARED_DATA.TickCount.LowPart - 300;
v100 = KUSER_SHARED_DATA.TickCount.LowPart - 300;
do
{
_BitScanForward(&v30, v28);
HIDWORD(v84) = v30;
LODWORD(v85) = v28 ^ (1 << v30);
v31 = (v30 + v25) & 0x1F;
v88 = v31;
v32 = (_QWORD **)(v26 + 16i64 * v31);
v33 = *v32;
do
{
v34 = (INT64)(v33 - 27);
v35 = 0;
v36 = (*(_DWORD *)(v33 - 12) & 0x400000) == 0;
v33 = (_QWORD *)*v33;
v87 = v33;
v106 = v34;
if( !v36 )
{
GuestSchedulerAssistPriority = KiReadGuestSchedulerAssistPriority(v34);
v34 = v106;
v33 = v87;
v29 = v100;
if( GuestSchedulerAssistPriority >= 16 )
GuestSchedulerAssistPriority = 15;
v35 = GuestSchedulerAssistPriority != *(_DWORD *)(v106 + 1024);
}
v107 = v29 - *(_DWORD *)(v34 + 436);
if( v107 > 0 || v35 )
{
KiRemoveThreadFromSharedReadyQueue(v81, v34, v31);
KiInsertDeferredReadyList((INT64)&v95, v61);
v29 = v100;
if( v107 > 0 )
--v24;
}
--v27;
}
while( v33 != v32 && v24 && v27 );
v28 = v85;
v26 = v81 + 16;
v108 = v24;
LODWORD(v87) = v27;
if( !(_DWORD)v85 )
break;
if( !v24 )
break;
v25 = v102;
}
while( v27 );
_InterlockedAnd64((volatile signed __int64 *)v81, 0i64);
v5 = 10;
CurrentPrcb = v94;
v2 = v99;
v8 = 16;
v37 = (UINT64 *)v95;
if( v95 )
{
do
{
v62 = (INT64)(v37 - 27);
v63 = *(v37 - 18);
v105 = (INT64)(v37 - 27);
CycleTime = *v37;
v85 = v63;
v94 = KeGetCurrentPrcb();
LODWORD(v86) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)(v62 + 64), 0i64) )
{
do
KeYieldProcessorEx(&v86);
while( *(_QWORD *)(v105 + 64) );
v62 = v105;
v66 = *((_QWORD *)v94 + 4247);
if( v66 && *((_BYTE *)v94 + 32) <= 1u )
{
v67 = *(_DWORD *)(v66 + 24) + 1;
*(_DWORD *)(v66 + 24) = v67;
}
}
if( (int)(v100 - *(_DWORD *)(v62 + 436)) > 0 && *(char *)(v62 + 195) < 15 )
KiSetPriorityBoost(0i64, (_KTHREAD *)v62, 15, v85);
KiReleaseThreadLockSafe(v62);
*(_QWORD *)(v62 + 216) = 0i64;
v97 = v62 + 216;
KiReadyDeferredReadyList(CurrentPrcb, &v97);
v37 = (UINT64 *)CycleTime;
}
while( CycleTime );
v2 = v99;
v23 = v81;
v27 = (int)v87;
}
if( !v27 || !v108 )
{
v38 = v88 + 1;
if( (unsigned int)(v88 + 1) <= 0xE )
goto LABEL_71;
}
}
else
{
_InterlockedAnd64((volatile signed __int64 *)v81, 0i64);
}
v38 = 1;
LABEL_71:
v3 = v93;
LODWORD(v1) = 0;
*(_BYTE *)(v23 + 594) = v38;
LowPart = v89;
LABEL_5:
if( KiGroupSchedulingEnabled )
{
KiGroupSchedulingQuantumEnd(CurrentPrcb, (_KTHREAD *)v3, v2, &ReadyList);
}
else
{
v10 = KeGetCurrentPrcb();
LODWORD(SpinCount) = v1;
while( _interlockedbittestandset64((volatile signed __int32 *)CurrentPrcb + 12, 0i64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( *((_QWORD *)CurrentPrcb + 6) );
v55 = *((_QWORD *)v10 + 4247);
if( v55 && *((_BYTE *)v10 + 32) <= 1u )
++*(_DWORD *)(v55 + 24);
}
v5 = 10;
}
if( v6 )
{
v39 = *((_DWORD *)CurrentPrcb + 7942);
*((_DWORD *)CurrentPrcb + 3151) = LowPart + 75;
v40 = v39 & 0x7FFE;
if( v40 )
{
v41 = (char *)CurrentPrcb + 31872;
v42 = *((_DWORD *)CurrentPrcb + 7944);
v96 = 0i64;
v43 = __ROR4__(v40, v42);
v44 = KUSER_SHARED_DATA.TickCount.LowPart - 300;
v101 = KUSER_SHARED_DATA.TickCount.LowPart - 300;
do
{
_BitScanForward(&v45, v43);
v43 ^= 1 << v45;
HIDWORD(SpinCount) = v45;
v46 = ((_BYTE)v45 + (_BYTE)v42) & 0x1F;
v47 = &v41[16 * (((_BYTE)v45 + (_BYTE)v42) & 0x1F)];
CycleTime = (UINT64)v47;
v48 = *(char **)v47;
do
{
v49 = (INT64)(v48 - 216);
v50 = 0;
v36 = (*((_DWORD *)v48 - 24) & 0x400000) == 0;
v48 = *(char **)v48;
v103 = (INT64)v48;
v81 = v49;
if( !v36 )
{
v68 = KiReadGuestSchedulerAssistPriority(v49);
v49 = v81;
v47 = (char *)CycleTime;
v48 = (char *)v103;
if( v68 >= 16 )
v68 = 15;
v44 = v101;
v50 = v68 != *(_DWORD *)(v81 + 1024);
}
v51 = v44 - *(_DWORD *)(v49 + 436);
v104 = v51;
if( v51 > 0 || v50 )
{
KiRemoveThreadFromReadyQueue((__int64)CurrentPrcb, v49 + 216, v46);
KiInsertDeferredReadyList((INT64)&v96, v81);
v44 = v101;
if( v104 > 0 )
--v5;
}
--v8;
}
while( v48 != v47 && v5 && v8 );
v41 = (char *)CurrentPrcb + 31872;
}
while( v43 && v5 && v8 );
v52 = (_QWORD *)v96;
v3 = v93;
v2 = v99;
if( v96 )
{
_InterlockedAnd64((volatile signed __int64 *)CurrentPrcb + 6, 0i64);
do
{
v58 = (INT64)(v52 - 27);
v59 = *(v52 - 18);
v52 = (_QWORD *)*v52;
CycleTime = v59;
LODWORD(v91) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)(v58 + 64), 0i64) )
{
do
KeYieldProcessorEx(&v91);
while( *(_QWORD *)(v58 + 64) );
}
if( (int)(v101 - *(_DWORD *)(v58 + 436)) > 0 && *(char *)(v58 + 195) < 15 )
KiSetPriorityBoost(0i64, (_KTHREAD *)v58, 15, CycleTime);
KiReleaseThreadLockSafe(v58);
v98[0] = v58 + 216;
*(_QWORD *)(v58 + 216) = 0i64;
KiReadyDeferredReadyList(CurrentPrcb, v98);
}
while( v52 );
v60 = KeGetCurrentPrcb();
HIDWORD(v91) = 0;
v3 = v93;
while( _interlockedbittestandset64((volatile signed __int32 *)CurrentPrcb + 12, 0i64) )
{
do
KeYieldProcessorEx((UINT64 *)((char *)&v91 + 4));
while( *((_QWORD *)CurrentPrcb + 6) );
v69 = *((_QWORD *)v60 + 4247);
if( v69 && *((_BYTE *)v60 + 32) <= 1u )
{
v70 = *(_DWORD *)(v69 + 24) + 1;
*(_DWORD *)(v69 + 24) = v70;
}
}
}
if( v8 && v5 || (v53 = v46 + 1, v53 > 0xE) )
v53 = 1;
*((_DWORD *)CurrentPrcb + 7944) = v53;
}
}
while( 1 )
{
v11 = (_ETHREAD *)*((_QWORD *)CurrentPrcb + 2);
if( v11 )
{
if( v2 )
*(_BYTE *)(v3 + 565) = 0;
LABEL_49:
if( !v11 )
goto LABEL_13;
goto LABEL_50;
}
if( !v2 || (v11 = (_ETHREAD *)KiSelectReadyThread((unsigned int)*(char *)(v3 + 195), CurrentPrcb)) == 0i64 )
{
if( (*(_DWORD *)(v3 + 120) & 0x1000) == 0 )
goto LABEL_13;
if( v3 == *((_QWORD *)CurrentPrcb + 3) )
{
_interlockedbittestandreset((volatile signed __int32 *)(v3 + 120), 0xCu);
goto LABEL_13;
}
KiSelectNextThread(CurrentPrcb, &ReadyList);
v11 = (_ETHREAD *)*((_QWORD *)CurrentPrcb + 2);
goto LABEL_49;
}
LABEL_50:
if( v11 != *((_ETHREAD **)CurrentPrcb + 3) && !KiCheckThreadAffinity((INT64)v11) )
{
if( (*(_BYTE *)(v3 + 2) & 4) == 0 || (KiIsThreadRankNonZero((_ETHREAD *)v3, CurrentPrcb), v71 = 1, !v72) )
v71 = *(_BYTE *)(v3 + 195);
**((_BYTE **)CurrentPrcb + 7) = v71;
if( *((_QWORD *)CurrentPrcb + 4247) )
{
v73 = (unsigned int)KiVpThreadSystemWorkPriority;
if( v3 != *((_QWORD *)CurrentPrcb + 3) )
v73 = (unsigned int)v71;
KiSetSchedulerAssistPriority(*((volatile INT32 **)CurrentPrcb + 4247), v73, 0);
}
if( *((_ETHREAD **)CurrentPrcb + 2) == v11 )
KiSelectNextThread(CurrentPrcb, &ReadyList);
KiInsertDeferredReadyList((INT64)&ReadyList, (INT64)v11);
v11 = 0i64;
}
LABEL_13:
if( !ReadyList.Next )
break;
if( v11 && v11 != *((_ETHREAD **)CurrentPrcb + 3) && *((_ETHREAD **)CurrentPrcb + 2) != v11 )
{
if( (*((_BYTE *)v11 + 2) & 4) == 0 || (KiIsThreadRankNonZero(v11, CurrentPrcb), v74 = 1, !v75) )
v74 = *((_BYTE *)v11 + 195);
**((_BYTE **)CurrentPrcb + 7) = v74;
v76 = *((_QWORD *)CurrentPrcb + 4247);
if( v76 )
{
if( v11 == *((_ETHREAD **)CurrentPrcb + 3) )
v77 = (unsigned int)KiVpThreadSystemWorkPriority;
else
v77 = (unsigned int)v74;
KiSetSchedulerAssistPriority((volatile INT32 *)v76, v77, 0);
v76 = *((_QWORD *)CurrentPrcb + 4247);
}
v78 = (_ETHREAD *)*((_QWORD *)CurrentPrcb + 3);
*((_QWORD *)CurrentPrcb + 2) = v11;
if( v76 )
*(_BYTE *)(v76 + 16) = v11 == v78;
if( *((_BYTE *)v11 + 388) == 1 )
*((_DWORD *)v11 + 33) = *((_DWORD *)v11 + 33) - *((_DWORD *)v11 + 109) + KUSER_SHARED_DATA.TickCount.LowPart;
*((_BYTE *)v11 + 388) = 3;
}
_InterlockedAnd64((volatile signed __int64 *)CurrentPrcb + 6, 0i64);
KiSetVpThreadSpinLockCount();
KiReadyDeferredReadyList(CurrentPrcb, &ReadyList);
LODWORD(v92) = 0;
ReadyList.Next = 0i64;
while( 1 )
{
KiSetVpThreadSpinLockCount();
if( !_interlockedbittestandset64((volatile signed __int32 *)CurrentPrcb + 12, 0i64) )
break;
KiSetVpThreadSpinLockCount();
do
KeYieldProcessorEx(&v92);
while( *((_QWORD *)CurrentPrcb + 6) );
}
}
if( !v11 || v3 == *((_QWORD *)CurrentPrcb + 3) )
{
_InterlockedAnd64((volatile signed __int64 *)CurrentPrcb + 6, 0i64);
KiSetVpThreadSpinLockCount();
}
else
{
*((_QWORD *)CurrentPrcb + 2) = 0i64;
_disable();
KiEndThreadCycleAccumulation(CurrentPrcb, (_KTHREAD *)v3, 0i64);
_enable();
if( (*((_BYTE *)v11 + 2) & 4) == 0 || (KiIsThreadRankNonZero(v11, CurrentPrcb), v19 = 1, !v56) )
v19 = *((_BYTE *)v11 + 195);
**((_BYTE **)CurrentPrcb + 7) = v19;
if( *((_QWORD *)CurrentPrcb + 4247) )
{
v79 = (unsigned int)KiVpThreadSystemWorkPriority;
if( v11 != *((_ETHREAD **)CurrentPrcb + 3) )
v79 = (unsigned int)v19;
KiSetSchedulerAssistPriority(*((volatile INT32 **)CurrentPrcb + 4247), v79, 0);
}
*((_QWORD *)CurrentPrcb + 1) = v11;
if( *((_BYTE *)v11 + 388) == 1 )
{
v18 = (unsigned int)(*((_DWORD *)v11 + 33) - *((_DWORD *)v11 + 109));
*((_DWORD *)v11 + 33) = v18 + KUSER_SHARED_DATA.TickCount.LowPart;
}
*((_BYTE *)v11 + 388) = 2;
*(_BYTE *)(v3 + 643) = 30;
KiQueueReadyThread((__int64)CurrentPrcb, v3, v18);
KiAbProcessContextSwitch((_KTHREAD *)v3, 1ui64);
IsUserVaAccessAllowed = KeIsUserVaAccessAllowed(0i64);
if( KeSmapEnabled )
__stac();
KiSwapContext((PKTHREAD)v3, (PKTHREAD)v11);
if( !IsUserVaAccessAllowed )
{
if( KeSmapEnabled )
__clac();
}
}
}Referenced by:
KiDispatchInterrupt
KiIdleLoop