KiEndThreadAccountingPeriod
VOID __stdcall KiEndThreadAccountingPeriod(_KPRCB *Prcb, _ETHREAD *Thread, UINT64 NetCycles){
char v3;
_THREAD_ENERGY_VALUES *EnergyValues;
_PROC_PERF_DOMAIN *Domain;
_PROC_PERF_CONSTRAINT *Constraint;
unsigned int LatestFrequencyPercent;
unsigned int v10;
__int64 ArchitecturalEfficiencyClass;
__int64 v12;
__int64 v13;
unsigned __int64 v14;
unsigned __int64 *v15;
unsigned int v16;
unsigned int EndTime;
unsigned int v18;
_KSCHEDULING_GROUP *volatile SchedulingGroup;
_QWORD *i;
int v21;
_BYTE *SchedulerAssist;
_TIMELINE_BITMAP v23;
v3 = Thread->Tcb.gap0[2];
if( (v3 & 0x10) != 0 )
{
Prcb->TaggedCycles[Thread->Tcb.Tag] += Prcb->StartCycles - Prcb->TaggedCyclesStart;
v3 &= ~0x10u;
Prcb->TaggedCyclesStart = 0i64;
}
if( (v3 & 0x20) != 0 )
{
EnergyValues = Thread->EnergyValues;
if( EnergyValues )
{
Domain = Prcb->PowerState.CheckContext.Domain;
Constraint = Prcb->PowerState.CheckContext.Constraint;
if( Domain && Constraint )
{
if( Constraint->Selection.Autonomous )
{
LatestFrequencyPercent = Constraint->LatestFrequencyPercent;
}
else
{
LatestFrequencyPercent = Constraint->Selection.SelectedPercent;
if( LatestFrequencyPercent >= Domain->GuaranteedPercent )
LatestFrequencyPercent = Domain->GuaranteedPercent;
}
}
else
{
LatestFrequencyPercent = 100;
}
if( LatestFrequencyPercent < 0x4B )
v10 = LatestFrequencyPercent / 0x19;
else
v10 = 3;
ArchitecturalEfficiencyClass = Prcb->PowerState.ArchitecturalEfficiencyClass;
v12 = v10;
v13 = ArchitecturalEfficiencyClass + 2i64 * v10;
v14 = EnergyValues->Cycles[0][v13];
v15 = (unsigned __int64 *)((char *)EnergyValues + 8 * v13);
v16 = KiTimelineBitmapTime;
*v15 = NetCycles + v14;
EndTime = EnergyValues->CpuTimeline.EndTime;
if( v16 > EndTime )
{
v23.EndTime = v16;
if( v16 - EndTime >= 0x20 )
v21 = 1;
else
v21 = (EnergyValues->CpuTimeline.Bitmap << (v16 - EndTime)) | 1;
v23.Bitmap = v21;
EnergyValues->CpuTimeline = v23;
}
else
{
v18 = EndTime - v16;
if( v18 < 0x20 )
EnergyValues->CpuTimeline.Bitmap |= 1 << v18;
}
if( !KiEfficiencyClassSystem && (unsigned __int8)Thread->Tcb.ThreadFlags2 == 2 )
EnergyValues->Cycles[v12][1] += NetCycles;
if( Thread->WorkOnBehalfThread )
{
EnergyValues->WorkOnBehalfCycles[v12][ArchitecturalEfficiencyClass] += NetCycles;
_InterlockedExchangeAdd64(
(volatile signed __int64 *)(*((_QWORD *)Thread->WorkOnBehalfThread + 191)
+ 8 * (ArchitecturalEfficiencyClass + 8 + 2 * v12)),
NetCycles);
}
}
v3 &= ~0x20u;
}
if( (v3 & 0x40) != 0 )
{
SchedulerAssist = Thread->Tcb.SchedulerAssist;
if( SchedulerAssist )
SchedulerAssist[64] = 0;
v3 &= ~0x40u;
}
if( (v3 & 0x3E) != 0 )
{
SchedulingGroup = Thread->Tcb.SchedulingGroup;
if( SchedulingGroup )
{
for( i = (_QWORD *)((char *)&SchedulingGroup->Policy + Prcb->ScbOffset); i; i = (_QWORD *)i[51] )
*i += NetCycles;
}
if( (Thread->Tcb.gap0[2] & 8) != 0
&& (Thread->Tcb.Affinity.Mask & Prcb->ParentNode->Affinity.Mask) != Prcb->ParentNode->Affinity.Mask )
{
Prcb->AffinitizedCycles += NetCycles;
}
if( Thread->Tcb.SystemHeteroCpuPolicy )
{
if( (unsigned __int8)Thread->Tcb.ThreadFlags2 == 2 )
Prcb->UnimportantCycles += NetCycles;
else
Prcb->ImportantCycles += NetCycles;
}
if( Thread->Tcb.WaitBlock[0].SparePtr )
KiEndCounterAccumulation(&Thread->Tcb);
}
}Referenced by:
KeQueryTotalCycleTimeThread
KiEndThreadCycleAccumulation
KiHvInterruptSubDispatch
KiInterruptSubDispatch
KiInterruptSubDispatchNoLock
KiInterruptSubDispatchNoLockNoEtw
KiIpiInterruptSubDispatch
KiScanInterruptObjectList
KiSpuriousDispatchNoEOI
KiSwInterrupt
KiUpdateTotalCyclesCurrentThread
KiVmbusInterruptSubDispatch
KxDispatchInterrupt
KxIsrLinkage