KiProcessExpiredTimerList
VOID __stdcall KiProcessExpiredTimerList(
_KPRCB *Prcb,
_KDPC_TRACKER_TABLE *DpcTracker,
_KTIMER **ExpiredTimers,
UINT64 TimerCount){
_ETHREAD *CurrentThread;
int v5;
unsigned int v8;
__int64 v9;
volatile signed __int32 *v10;
_KDPC *v11;
_KDPC_TRACKER_TABLE v12;
void(__fastcall *v13)(_KDPC *, void *, void *, void *);
__int64 v14;
void **DpcWatchdogProfile;
void(__fastcall *v16)(_KDPC *, void *, void *, void *);
void *v17;
_SINGLE_LIST_ENTRY *Next;
__int64 v19;
_SINGLE_LIST_ENTRY *v20;
_SINGLE_LIST_ENTRY *v21;
_SINGLE_LIST_ENTRY *v22;
_SINGLE_LIST_ENTRY *v23;
_SINGLE_LIST_ENTRY *v24;
_SINGLE_LIST_ENTRY *v25;
size_t v26;
UINT64 Flag;
void(__fastcall *Data)(_KDPC *, void *, void *, void *);
UINT64 SpinCount;
unsigned int v30;
_ETHREAD *v31;
_KTIMER **v32;
__int128 v33;
__int128 v34;
_LARGE_INTEGER TimeStamp[2];
__int128 v36;
CurrentThread = Prcb->CurrentThread;
v30 = TimerCount;
v5 = *(_BYTE *)(&PerfGlobalGroupMask + 1) & 0x80;
v31 = CurrentThread;
Data = 0i64;
v33 = 0i64;
v32 = ExpiredTimers;
v8 = 0;
v34 = 0i64;
*(_OWORD *)&TimeStamp[0].anonymous_0.LowPart = 0i64;
v36 = 0i64;
HIDWORD(SpinCount) = CurrentThread->Tcb.WaitBlock[3].SpareLong;
while( 1 )
{
v9 = v8++;
v10 = (volatile signed __int32 *)_InterlockedExchange64((volatile __int64 *)&ExpiredTimers[v9], 0i64);
if( v10 )
{
LODWORD(SpinCount) = 0;
while( _interlockedbittestandset(v10, 7u) )
{
do
KeYieldProcessorEx(&SpinCount);
while( (*v10 & 0x80u) != 0 );
}
v11 = KiTimerWaitTest(Prcb, (_KTIMER *)v10, (_ULARGE_INTEGER *)DpcTracker + 1);
if( v11 )
{
if( Prcb->DeferredReadyListHead.Next )
KiProcessThreadWaitList(Prcb, AdjustUnwait, 0i64, 2ui64);
if( v5 )
EtwGetKernelTraceTimestamp(TimeStamp, 0x20000080ui64);
v12 = *DpcTracker;
Data = v11->DeferredRoutine;
v13 = Data;
*DpcTracker = v12 + 1;
v14 = 2 * ((v12 & 0xF) + 1i64);
*(_QWORD *)&DpcTracker[2 * v14] = v13;
DpcTracker[2 * v14 + 2] = KUSER_SHARED_DATA.TickCount.LowPart;
DpcWatchdogProfile = Prcb->DpcWatchdogProfile;
Prcb->DpcTimeCount = 0;
if( DpcWatchdogProfile
&& Prcb->DpcWatchdogProfileCurrentEmptyCapture != DpcWatchdogProfile
&& Prcb->DpcWatchdogCount < (signed int)Prcb->DpcWatchdogProfileCumulativeDpcThreshold )
{
v26 = 8 * dword_140C50A78;
Prcb->DpcWatchdogProfileCurrentEmptyCapture = DpcWatchdogProfile;
memset(DpcWatchdogProfile, 0i64, v26);
}
v16 = Data;
Prcb->DpcRoutineActive = 1;
v16(v11, v11->DeferredContext, (void *)(unsigned int)DpcTracker[2], (void *)(unsigned int)DpcTracker[3]);
v17 = (void *)HIDWORD(SpinCount);
Prcb->DpcRoutineActive = 0;
DpcTracker[2 * v14 + 3] = KUSER_SHARED_DATA.TickCount.LowPart;
if( (_DWORD)v17 != v31->Tcb.WaitBlock[3].SpareLong )
KeBugCheckEx(0xC7u, (PVOID)5, Data, v17, (PVOID)v31->Tcb.CombinedApcDisable);
if( v5 )
{
LODWORD(Flag) = 4196866;
EtwTraceTimedEvent(0xF45u, 0x20000080ui64, &Data, 8ui64, Flag, (_ETW_KERNEL_TRACE_TIMESTAMP *)TimeStamp);
}
}
}
if( v8 >= v30 )
break;
ExpiredTimers = v32;
}
Next = Prcb->DeferredReadyListHead.Next;
if( Next )
{
Prcb->DeferredReadyListHead.Next = 0i64;
do
{
v19 = BYTE3(Next[46].Next);
v20 = Next - 27;
v21 = Next[-1].Next;
Next = Next->Next;
v22 = &v21[6 * v19];
do
{
if( BYTE1(v21[2].Next) < 5u )
{
v23 = v21[4].Next;
KiAcquireKobjectLockSafe(v23);
if( BYTE1(v21[2].Next) == 4 )
{
v24 = v21->Next;
if( v21->Next[1].Next != v21 || (v25 = v21[1].Next, v25->Next != v21) )
__fastfail(3u);
v25->Next = v24;
v24[1].Next = v25;
}
_InterlockedAnd((volatile signed __int32 *)v23, 0xFFFFFF7F);
}
v21 += 6;
}
while( v21 != v22 );
HIWORD(v20[70].Next) = 1;
KiReadyThread(Prcb, (_KTHREAD *)v20);
}
while( Next );
}
}Referenced by:
KiExpireTimerTable
KiRetireDpcList