KeClockInterruptNotify
VOID __stdcall KeClockInterruptNotify(_KTRAP_FRAME *TrapFrame, UINT8 PreviousIrql){
struct _KPRCB *CurrentPrcb;
char *v5;
UINT64 v6;
UINT64 v7;
int v8;
char v9;
int v10;
CHAR ProcessorMode;
__int64 v12;
unsigned __int64 *v13;
bool v14;
unsigned __int8 CurrentIrql;
unsigned __int8 v16;
unsigned __int64 v17;
__int64 v18;
struct _KPRCB *v19;
__int16 v20;
unsigned int LowPart;
_KHETERO_CPU_POLICY v22;
UINT64 PrcbFlags;
__int64 v24;
INT64 EfficiencySchedulingClass;
_ETHREAD *CurrentThread;
NTSTATUS SystemHeteroCpuPolicy;
_KNODE *ParentNode;
__int64 v29;
unsigned __int64 v30;
int v31;
unsigned __int64 v32;
unsigned __int8 v33;
struct _KPRCB *v34;
__int64 v35;
bool v36;
unsigned __int32 v37;
char v38;
_KSCHEDULING_GROUP *volatile SchedulingGroup;
char v40;
UINT64 v41;
char v42;
unsigned __int64 v43;
unsigned __int8 v44;
UINT64 SpinCount;
UINT64 IdealSetOut;
UINT64 RequestedIncrement;
UINT64 DeliveredIncrement;
UINT64 AvailableSetOut;
UINT64 PreferredSetOut;
__int64 CurrentQpc[2];
int v52;
char v53;
DeliveredIncrement = 0i64;
CurrentPrcb = KeGetCurrentPrcb();
v5 = 0i64;
CurrentQpc[0] = 0i64;
v53 = 0;
RequestedIncrement = 0i64;
if( KiForceIdleDisabled )
{
LABEL_16:
ProcessorMode = TrapFrame->SegCs & 1;
if( CurrentPrcb->ClockOwner )
{
v12 = 3i64 * (unsigned int)KiClockTickTraceIndex;
KiClockTickTraceIndex = ((_BYTE)KiClockTickTraceIndex + 1) & 0xF;
v13 = (unsigned __int64 *)((char *)&KiClockTickTraces + 8 * v12);
v14 = KiClockOwnerOneShotRequestState == 1;
v13[1] = *(_QWORD *)&KUSER_SHARED_DATA.InterruptTime.LowPart;
if( v14 )
{
CurrentIrql = KeGetCurrentIrql();
__writecr8(0xFui64);
KiClockOwnerOneShotRequestState = 2;
KiClockOwnerOneShotRequest = 0i64;
__writecr8(CurrentIrql);
}
KiUpdateTime(ProcessorMode, PreviousIrql);
if( KiClockOwnerOneShotRequestState == 2 )
{
v16 = KeGetCurrentIrql();
__writecr8(0xFui64);
KiSetClockIntervalToMinimumRequested();
__writecr8(v16);
}
*v13 = KUSER_SHARED_DATA.BaselineInterruptTimeQpc;
v17 = *(_QWORD *)&KUSER_SHARED_DATA.InterruptTime.LowPart;
if( KiClockState == ClockStatePendingPeriodic )
{
KiRestoreClockTickRate(*(INT64 *)&KUSER_SHARED_DATA.InterruptTime.LowPart, &RequestedIncrement);
_InterlockedExchange((volatile __int32 *)&KiClockState, 0);
KiEventClockStateChange(ClockStatePeriodic, ClockStatePendingPeriodic, &DeliveredIncrement, &RequestedIncrement);
}
v18 = v17 + (unsigned int)KeTimeIncrement;
v13[2] = v17;
KiClockTimerNextTickTime = v18;
goto LABEL_83;
}
v19 = KeGetCurrentPrcb();
v20 = v52;
++v19->ClockInterrupts;
++v19->InterruptLastCount;
_disable();
LowPart = KUSER_SHARED_DATA.TickCount.LowPart;
if( (v20 & 0x200) != 0 )
_enable();
KeAccumulateTicks(v19, v19->LastTick, KUSER_SHARED_DATA.TickCount.LowPart, PreviousIrql, ProcessorMode);
CurrentThread = v19->CurrentThread;
v19->ClockKeepAlive = 1;
if( CurrentThread != v19->IdleThread )
{
if( CurrentThread->Tcb.CycleTime >= CurrentThread->Tcb.QuantumTarget )
goto LABEL_69;
SystemHeteroCpuPolicy = CurrentThread->Tcb.SystemHeteroCpuPolicy;
AvailableSetOut = 0i64;
IdealSetOut = 0i64;
PreferredSetOut = 0i64;
if( SystemHeteroCpuPolicy )
{
if( (unsigned int)SystemHeteroCpuPolicy >= 5 )
SystemHeteroCpuPolicy = KiConvertDynamicHeteroPolicy(CurrentThread, v22, v19);
ParentNode = v19->ParentNode;
KiGenerateHeteroSets(
ParentNode,
CurrentThread->Tcb.Affinity.Mask,
(_KHETERO_CPU_POLICY)SystemHeteroCpuPolicy,
&IdealSetOut,
&PreferredSetOut,
&AvailableSetOut);
if( (AvailableSetOut & v19->GroupSetMember) == 0
|| KiIsQosGroupingActive()
&& (v29 & v24) != 0
&& (unsigned int)(unsigned __int8)CurrentThread->Tcb.ThreadFlags2 - 1 <= 1
&& (v29 & v19->GroupSetMember) == 0 )
{
goto LABEL_69;
}
if( (IdealSetOut & v19->GroupSetMember) == 0 )
{
if( (v24 & ParentNode->IdleSmtSet) != 0 )
v24 &= ParentNode->IdleSmtSet;
if( (v24 & IdealSetOut) != 0 )
goto LABEL_69;
v30 = v24 & PreferredSetOut & ~IdealSetOut;
if( (unsigned int)(SystemHeteroCpuPolicy - 3) <= 1 )
EfficiencySchedulingClass = v19->PowerState.EfficiencySchedulingClass;
else
EfficiencySchedulingClass = v19->PowerState.PerformanceSchedulingClass;
if( v30 )
{
v31 = ParentNode->Affinity.Group << 6;
do
{
_BitScanReverse64(&v32, v30);
HIDWORD(SpinCount) = v32;
v24 = (__int64)*(&KiProcessorBlock
+ (unsigned int)KiProcessorNumberToIndexMappingTable[(unsigned int)(v31 + v32)]);
v33 = (unsigned int)(SystemHeteroCpuPolicy - 3) <= 1 ? *(_BYTE *)(v24 + 33210) : *(_BYTE *)(v24 + 33209);
if( v33 > (unsigned __int8)EfficiencySchedulingClass )
goto LABEL_69;
v30 &= ~*(_QWORD *)(v24 + 200);
}
while( v30 );
}
}
}
v34 = KeGetCurrentPrcb();
PrcbFlags = (unsigned int)v34->PrcbFlags.PrcbFlags;
if( (PrcbFlags & 0x300) != 0 )
{
_disable();
PrcbFlags = (unsigned int)v34->PrcbFlags.PrcbFlags;
v35 = v34->PrcbFlags._bf_0 & 0xFFFFFCFF;
v36 = (v20 & 0x200) != 0;
if( (unsigned __int8)PrcbFlags != LOBYTE(CurrentThread->Tcb.ThreadFlags2) )
{
v37 = v35 | ((CurrentThread->Tcb._bf_0 & 3) << 8);
v34->PrcbFlags._bf_0 = v37;
v38 = PoSetProcessorQoS((INT64)v34, (v37 >> 8) & 3, v35, EfficiencySchedulingClass);
LODWORD(v35) = v34->PrcbFlags.PrcbFlags;
if( !v38 )
{
LABEL_55:
if( (v35 & 0x300) == 0 )
KeUpdatePendingQosRequest((INT64)v34);
if( v36 )
_enable();
goto LABEL_61;
}
LODWORD(v35) = v35 & 0xFFFFFCFF;
}
v34->PrcbFlags._bf_0 = v35;
goto LABEL_55;
}
if( (unsigned __int8)PrcbFlags != LOBYTE(CurrentThread->Tcb.ThreadFlags2) )
KeCheckAndApplyBamQos((INT64)v34, (__int64)CurrentThread, v24, EfficiencySchedulingClass);
}
LABEL_61:
if( KUSER_SHARED_DATA.TickCountQuad <= v19->GenerationTarget )
{
SchedulingGroup = CurrentThread->Tcb.SchedulingGroup;
if( !SchedulingGroup || (PrcbFlags = (UINT64)SchedulingGroup + v19->ScbOffset) == 0 )
{
LABEL_77:
if( (int)(v19->ReadyScanTick - LowPart) < 0
&& (!(unsigned int)KiShouldScanSharedReadyQueue(v19) || (v19->SharedReadyQueue->ReadySummary & 0x7FFE) == 0)
&& (v19->ReadySummary & 0x7FFE) == 0 )
{
v19->ReadyScanTick = LowPart + 75;
}
LABEL_83:
if( !v53 )
return;
goto LABEL_84;
}
while( 1 )
{
v40 = *(_BYTE *)(PrcbFlags + 112);
v41 = PrcbFlags - v19->ScbOffset;
v42 = v40 & 0x10;
if( (v40 & 4) != 0 )
{
if( v42 )
goto LABEL_74;
if( (v40 & 2) == 0 )
{
if( *(__int64 *)(v41 + 48) <= 0 )
break;
LABEL_74:
v43 = *(_QWORD *)(PrcbFlags + 24);
LABEL_75:
if( *(_QWORD *)PrcbFlags >= v43 )
break;
}
}
else
{
if( v42 )
{
v43 = *(_QWORD *)(PrcbFlags + 8);
goto LABEL_75;
}
if( (v40 & 2) == 0 && *(__int64 *)(v41 + 48) <= 0 )
break;
}
PrcbFlags = *(_QWORD *)(PrcbFlags + 408);
if( !PrcbFlags )
goto LABEL_77;
}
}
LABEL_69:
v19->QuantumEnd = 1;
if( v19->NestingLevel )
{
v19->InterruptRequest = 1;
}
else
{
LOBYTE(PrcbFlags) = 2;
HalRequestSoftwareInterrupt(PrcbFlags);
}
goto LABEL_83;
}
_disable();
LODWORD(SpinCount) = 0;
while( _interlockedbittestandset64((_DWORD *)&KiSwapEvent + 42, 0i64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( *(&KiSwapEvent + 21) );
}
if( CurrentPrcb->ClockOwner && KeIsForceIdleEngaged() )
{
LODWORD(v6) = RtlGetInterruptTimePrecise(CurrentQpc);
v7 = v6;
PoExecuteIdleCheck(v6);
if( KiForceIdleWatchdogResetCount == 32 )
{
off_140C008C0[0]();
v8 = 0;
}
else
{
v8 = KiForceIdleWatchdogResetCount + 1;
}
KiForceIdleWatchdogResetCount = v8;
if( v7 - KiForceIdleActiveLastStartTime <= 0x1312D00 )
{
++qword_140C31390;
v9 = 1;
v5 = (char *)&KiClockTickSkipTraces + 16 * (unsigned int)KiClockTickSkipTraceIndex;
v53 = 1;
v10 = ((_BYTE)KiClockTickSkipTraceIndex + 1) & 0xF;
KiClockTickSkipTraceIndex = v10;
*v5 = 0;
*((_QWORD *)v5 + 1) = v7;
goto LABEL_15;
}
KiResetForceIdle(2i64, 1);
}
v9 = 0;
LABEL_15:
_InterlockedAnd64((_QWORD *)&KiSwapEvent + 21, 0i64);
_enable();
if( !v9 )
goto LABEL_16;
LABEL_84:
if( KiClockOwnerOneShotRequestState == 1 )
{
v44 = KeGetCurrentIrql();
__writecr8(0xFui64);
KiClockOwnerOneShotRequestState = 2;
KiSetClockIntervalToMinimumRequested();
__writecr8(v44);
if( v5 )
*v5 = 1;
++qword_140C31398;
}
}Referenced by:
HalpTimerAlwaysOnClockInterrupt
HalpTimerClockInterrupt
HalpTimerClockIpiRoutine