KeQueryTotalCycleTimeThread
UINT64 __stdcall KeQueryTotalCycleTimeThread(_ETHREAD *Thread, PULONG64 CycleTimeStamp){
struct _KPRCB *CurrentPrcb;
unsigned __int64 v5;
UINT64 v6;
unsigned __int64 v7;
unsigned __int64 v8;
bool v9;
unsigned __int8 CurrentIrql;
struct _KPRCB *v12;
_DWORD *SchedulerAssist;
int v14;
_KPRCB *v15;
char v16;
volatile unsigned int NextProcessor;
struct _KPRCB *v18;
UINT64 CycleTime;
UINT64 SpinCount;
_KSHARED_READY_QUEUE *ControlReadyQueue;
_KPRCB *ControlPrcb;
_KAFFINITY_EX Affinity;
memset(&Affinity, 0i64, sizeof(Affinity));
ControlPrcb = 0i64;
ControlReadyQueue = 0i64;
if( Thread == (_ETHREAD *)KeGetCurrentThread() )
{
_disable();
CurrentPrcb = KeGetCurrentPrcb();
CurrentPrcb->NestingLevel = 1;
v5 = __rdtsc();
v6 = v5 - CurrentPrcb->StartCycles;
v7 = v6 + Thread->Tcb.CycleTime;
v8 = v6 + Thread->Tcb.CurrentRunTime;
Thread->Tcb.CycleTime = v7;
if( v8 > 0xFFFFFFFF )
LODWORD(v8) = -1;
CurrentPrcb->StartCycles = v5;
v9 = (Thread->Tcb.gap0[2] & 0x3E) == 0;
Thread->Tcb.CurrentRunTime = v8;
if( !v9 )
KiEndThreadAccountingPeriod(CurrentPrcb, &Thread->Tcb, v6);
if( CycleTimeStamp )
*CycleTimeStamp = v5;
KiStartThreadCycleAccumulation(CurrentPrcb, &Thread->Tcb, 0);
_enable();
return v7;
}
else
{
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
v12 = KeGetCurrentPrcb();
LODWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&Thread->Tcb.ThreadLock, 0i64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( Thread->Tcb.ThreadLock );
SchedulerAssist = v12->SchedulerAssist;
if( SchedulerAssist && v12->NestingLevel <= 1u )
{
v14 = SchedulerAssist[6] + 1;
SchedulerAssist[6] = v14;
}
}
KiAcquireThreadStateLock(Thread, &ControlPrcb, &ControlReadyQueue);
if( v16 == 2 )
{
NextProcessor = Thread->Tcb.NextProcessor;
KiReleaseThreadStateLock(v15, (_KSHARED_READY_QUEUE *)ControlPrcb);
KiReleaseThreadLockSafe((INT64)Thread);
*(_DWORD *)&Affinity.Count = 1310721;
memset(&Affinity.Reserved, 0i64, 0xA4u);
KeAddProcessorAffinityEx(&Affinity.Count, NextProcessor);
KeGetCurrentIrql();
__writecr8(0xCui64);
KiIpiSendPacket(IpiAffinity, &Affinity, (INT64)xHalTimerWatchdogStop, 0i64, 0i64, 0i64);
v18 = KeGetCurrentPrcb();
while( v18->PacketBarrier )
_mm_pause();
*CycleTimeStamp = __rdtsc();
CycleTime = Thread->Tcb.CycleTime;
}
else
{
if( Thread->Tcb.Running )
KeFlushProcessWriteBuffers(1u);
*CycleTimeStamp = __rdtsc();
CycleTime = Thread->Tcb.CycleTime;
KiReleaseThreadStateLock(v15, (_KSHARED_READY_QUEUE *)ControlPrcb);
KiReleaseThreadLockSafe((INT64)Thread);
}
__writecr8(CurrentIrql);
return CycleTime;
}
}Referenced by:
NtQueryInformationThread