KeAccumulateTicks
VOID __stdcall KeAccumulateTicks(
_KPRCB *Prcb,
UINT64 LastTick,
UINT64 CurrentTick,
UINT8 PreviousIrql,
INT8 ProcessorMode){
unsigned int v6;
int v7;
char v9;
unsigned int v10;
_ETHREAD *CurrentThread;
unsigned int InterruptRate;
void **DpcWatchdogProfile;
__int64 v14;
int DpcWatchdogPeriod;
int v17;
signed int DpcWatchdogProfileCumulativeDpcThreshold;
int DpcWatchdogCount;
int v20;
UINT64 v21;
unsigned int *v22;
unsigned int v23;
__int16 v24;
unsigned int v25;
unsigned int MaximumDpcQueueDepth;
unsigned int DpcTimeCount;
unsigned int v28;
unsigned int DpcTimeLimit;
unsigned int DpcWatchdogProfileSingleDpcThreshold;
unsigned int v31;
_KSCHEDULING_GROUP *volatile SchedulingGroup;
_KSCB *v33;
int v34;
size_t v35;
v6 = CurrentTick;
v7 = LastTick;
v9 = 0;
KiCheckForTimerExpiration(Prcb);
Prcb->LastTick = v6;
v10 = v6 - v7;
if( !v10 )
{
if( KiForceIdleDisabled || (_DWORD)KiForceIdleState != 4 )
return;
goto LABEL_18;
}
CurrentThread = Prcb->CurrentThread;
InterruptRate = 0;
if( Prcb->ClockOwner )
{
if( !--KiClockPollCycle )
{
KiClockPollCycle = KiClockKeepAliveCycle;
v21 = (unsigned __int8)KiClockCheckSlot;
v22 = (unsigned int *)*(&KiProcessorBlock + (unsigned __int8)KiClockCheckSlot);
v23 = (unsigned __int8)KiClockCheckSlot + 1;
if( v23 >= (unsigned int)KeNumberProcessors_0 )
LOBYTE(v23) = 0;
KiClockCheckSlot = v23;
if( KiCheckKeepAlive(v22[9]) )
{
if( !v22[7928] && KeEnableWatchdogTimeout && (KiBugCheckActive & 3) == 0 )
{
HvlInvokeHypervisorDebugger(1ui64, v21);
KeBugCheckEx(0x101u, (PVOID)(unsigned __int8)KiClockKeepAliveCycle, 0i64, v22, (PVOID)v21);
}
v22[7928] = 0;
}
}
}
if( ProcessorMode )
{
Prcb->UserTime += v10;
CurrentThread->Tcb.UserTime += v10;
}
else
{
Prcb->KernelTime += v10;
if( Prcb->NestingLevel == 2 && Prcb->DpcRoutineActive )
{
DpcTimeCount = Prcb->DpcTimeCount;
Prcb->DpcTime += v10;
v28 = DpcTimeCount + 1;
DpcTimeLimit = Prcb->DpcTimeLimit;
Prcb->DpcTimeCount = v28;
if( DpcTimeLimit )
{
DpcWatchdogProfileSingleDpcThreshold = Prcb->DpcWatchdogProfileSingleDpcThreshold;
v31 = v28;
if( DpcWatchdogProfileSingleDpcThreshold && v28 >= DpcWatchdogProfileSingleDpcThreshold )
{
KiDpcWatchdogCaptureStack((__int64)Prcb);
v31 = Prcb->DpcTimeCount;
v9 = 1;
DpcTimeLimit = Prcb->DpcTimeLimit;
}
if( v31 > DpcTimeLimit )
{
if( KeEnableWatchdogTimeout )
{
__rdtsc();
HvlInvokeHypervisorDebugger(3ui64, 0i64);
if( !(_BYTE)KdDebuggerEnabled || (_BYTE)KdDebuggerNotPresent )
KeBugCheckEx(
0x133u,
0i64,
(PVOID)Prcb->DpcTimeCount,
(PVOID)Prcb->DpcTimeLimit,
&KeDpcWatchdogProfileGlobalTriageBlock);
__int2c();
}
Prcb->DpcTimeCount = 0;
KiResetGlobalDpcWatchdogProfiler((INT64)Prcb);
}
}
}
else if( Prcb->NestingLevel > 1u )
{
Prcb->InterruptTime += v10;
}
else
{
CurrentThread->Tcb.SchedulerApc.SpareLong0 += v10;
}
if( PreviousIrql < 2u )
{
++Prcb->DpcWatchdogSequenceNumber;
DpcWatchdogProfile = Prcb->DpcWatchdogProfile;
Prcb->DpcWatchdogCount = 0;
if( DpcWatchdogProfile
&& Prcb->DpcWatchdogProfileCurrentEmptyCapture != DpcWatchdogProfile
&& (int)Prcb->DpcWatchdogProfileCumulativeDpcThreshold > 0 )
{
v35 = 8 * dword_140C50A78;
Prcb->DpcWatchdogProfileCurrentEmptyCapture = DpcWatchdogProfile;
memset(DpcWatchdogProfile, 0i64, v35);
}
goto LABEL_12;
}
DpcWatchdogPeriod = Prcb->DpcWatchdogPeriod;
v17 = Prcb->DpcWatchdogCount + 1;
Prcb->DpcWatchdogCount = v17;
if( !DpcWatchdogPeriod )
goto LABEL_12;
DpcWatchdogProfileCumulativeDpcThreshold = Prcb->DpcWatchdogProfileCumulativeDpcThreshold;
DpcWatchdogCount = v17;
v20 = DpcWatchdogPeriod;
if( DpcWatchdogProfileCumulativeDpcThreshold && v17 >= DpcWatchdogProfileCumulativeDpcThreshold && !v9 )
{
KiDpcWatchdogCaptureStack((__int64)Prcb);
DpcWatchdogCount = Prcb->DpcWatchdogCount;
v20 = Prcb->DpcWatchdogPeriod;
}
if( DpcWatchdogCount < v20 )
goto LABEL_12;
if( KeEnableWatchdogTimeout )
{
__rdtsc();
HvlInvokeHypervisorDebugger(2ui64, 0i64);
if( !(_BYTE)KdDebuggerEnabled || (_BYTE)KdDebuggerNotPresent )
KeBugCheckEx(0x133u, (PVOID)1, (PVOID)Prcb->DpcWatchdogPeriod, &KeDpcWatchdogProfileGlobalTriageBlock, 0i64);
__int2c();
}
}
++Prcb->DpcWatchdogSequenceNumber;
Prcb->DpcWatchdogCount = 0;
KiResetGlobalDpcWatchdogProfiler((INT64)Prcb);
LABEL_12:
if( CurrentThread != Prcb->IdleThread && Prcb->NestingLevel <= 1u )
{
if( CurrentThread->Tcb.Priority < 16
&& CurrentThread->Tcb.SchedulingGroup
&& (SchedulingGroup = CurrentThread->Tcb.SchedulingGroup) != 0i64
&& (v33 = (_KSCB *)((char *)SchedulingGroup + Prcb->ScbOffset)) != 0i64
&& (KiGetThreadEffectiveRankNonZero(CurrentThread, v33, 0i64, 0, 0i64), v34)
|| CurrentThread->Tcb.Priority < 8 )
{
Prcb->AvailableTime += v10;
}
}
if( v10 < 8 )
{
Prcb->InterruptRate += 15 * (Prcb->InterruptCount - Prcb->InterruptLastCount);
InterruptRate = Prcb->InterruptRate;
v14 = v10;
do
{
InterruptRate >>= 4;
--v14;
}
while( v14 );
}
Prcb->InterruptRate = InterruptRate;
Prcb->InterruptLastCount = Prcb->InterruptCount;
Prcb->DpcRequestRate = (Prcb->DpcRequestRate + Prcb->DpcData[0].DpcCount - Prcb->DpcLastCount) >> v10;
Prcb->DpcLastCount = Prcb->DpcData[0].DpcCount;
if( !Prcb->DpcData[0].DpcQueueDepth || (v24 = Prcb->DpcRequestSlot[0], (v24 & 3) != 0) )
{
if( Prcb->AdjustDpcThreshold-- == 1 )
{
Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold;
MaximumDpcQueueDepth = Prcb->MaximumDpcQueueDepth;
if( MaximumDpcQueueDepth < KiMaximumDpcQueueDepth )
Prcb->MaximumDpcQueueDepth = MaximumDpcQueueDepth + 1;
}
}
else
{
Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold;
if( (v24 & 0x2F) == 0 )
KiRequestSoftwareInterrupt(Prcb, 2);
v25 = Prcb->MaximumDpcQueueDepth;
if( Prcb->DpcRequestRate < KiIdealDpcRate && v25 > 1 )
Prcb->MaximumDpcQueueDepth = v25 - 1;
}
LABEL_18:
if( ((_BYTE)KdDebuggerEnabled || KdEventLoggingEnabled) && KiPollSlot == Prcb->Number )
KdCheckForDebugBreak();
}Referenced by:
KeClockInterruptNotify
KiUpdateRunTime
PpmIdleExecuteTransition