KiSwapThread
VOID __fastcall KiSwapThread(_ETHREAD *OldThread, _KPRCB *CurrentPrcb){
void *volatile *v2;
unsigned __int64 v5;
unsigned __int64 v6;
unsigned __int64 v7;
unsigned __int64 v8;
_THREAD_ENERGY_VALUES *EnergyValues;
_PROC_PERF_DOMAIN *Domain;
_PROC_PERF_CONSTRAINT *Constraint;
unsigned int LatestFrequencyPercent;
unsigned int v13;
__int64 ArchitecturalEfficiencyClass;
__int64 v15;
__int64 v16;
unsigned __int64 v17;
unsigned __int64 *v18;
unsigned int v19;
unsigned int EndTime;
unsigned int v21;
unsigned int v22;
struct _KPRCB *v23;
_KSCHEDULING_GROUP *volatile v24;
_KSCHEDULING_GROUP *v25;
_ETHREAD *NextThread;
_RTL_BALANCED_NODE *Min;
unsigned __int64 v28;
int v29;
_KNODE *ParentNode;
int v31;
int IdleState;
_BYTE *v33;
int v34;
unsigned __int64 v35;
_ETHREAD *IdleThread;
char Priority;
int v39;
_KNODE *v40;
unsigned __int64 v41;
unsigned __int8 GroupIndex;
int Group;
unsigned __int64 Mask;
unsigned __int64 SharedReadyQueueMask;
unsigned __int64 v46;
unsigned __int64 v47;
struct _KPRCB *v48;
char v49;
unsigned __int64 WaitIrql;
char v51;
bool v52;
bool v53;
unsigned __int64 v54;
int v55;
unsigned __int64 v56;
__int64 v57;
__int64 v58;
unsigned __int64 v59;
int v60;
unsigned __int64 v61;
int v62;
unsigned __int64 v63;
__int64 v64;
char v65;
_BYTE *v66;
unsigned __int64 v67;
_KSCHEDULING_GROUP *volatile SchedulingGroup;
_QWORD *i;
char v70;
unsigned int v71;
_KSCB *v72;
int v73;
_DWORD *v74;
UINT8 v75;
unsigned __int64 v76;
_DWORD *v77;
UINT8 v78;
struct _KPRCB *v79;
UINT8 v80;
_BYTE *SchedulerAssist;
unsigned __int64 v82;
unsigned __int64 GroupSetMember;
unsigned __int64 CoreProcessorSet;
unsigned __int64 v85;
unsigned __int64 v86;
__int64 v87;
__int64 v88;
_DWORD *v89;
int v90;
UINT8 IsThreadRankNonZero;
INT64 v92;
INT64 v93;
int v94;
struct _KPRCB *v95;
_DWORD *v96;
int v97;
INT64 v98;
INT64 v99;
PVOID v100;
int v101;
int v102;
int v103;
unsigned __int64 v104;
UINT64 v105;
UINT64 v106;
UINT64 SpinCount;
UINT64 v108;
_KSCHEDULING_GROUP *volatile v109;
_SINGLE_LIST_ENTRY ReadyList;
unsigned __int8 v111;
_TIMELINE_BITMAP v112;
void *volatile *v113;
int v114;
v113 = v2;
if( CurrentPrcb->DeferredReadyListHead.Next )
KiProcessThreadWaitList(CurrentPrcb, AdjustUnwait, 0i64, 2ui64);
KiAbProcessContextSwitch(&OldThread->Tcb, 0i64);
_disable();
CurrentPrcb->NestingLevel = 1;
v5 = __rdtsc();
v6 = v5 - CurrentPrcb->StartCycles;
v7 = v6 + OldThread->Tcb.CurrentRunTime;
OldThread->Tcb.CycleTime += v6;
if( v7 > 0xFFFFFFFF )
LODWORD(v7) = -1;
CurrentPrcb->StartCycles = v5;
v8 = (unsigned __int8)OldThread->Tcb.gap0[2];
OldThread->Tcb.CurrentRunTime = v7;
if( (v8 & 0x3E) != 0 )
{
if( (v8 & 0x10) != 0 )
{
CurrentPrcb->TaggedCycles[OldThread->Tcb.Tag] += CurrentPrcb->StartCycles - CurrentPrcb->TaggedCyclesStart;
LOBYTE(v8) = v8 & 0xEF;
CurrentPrcb->TaggedCyclesStart = 0i64;
}
if( (v8 & 0x20) != 0 )
{
EnergyValues = OldThread->EnergyValues;
if( EnergyValues )
{
Domain = CurrentPrcb->PowerState.CheckContext.Domain;
Constraint = CurrentPrcb->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 )
v13 = LatestFrequencyPercent / 0x19;
else
v13 = 3;
ArchitecturalEfficiencyClass = CurrentPrcb->PowerState.ArchitecturalEfficiencyClass;
v15 = v13;
v16 = ArchitecturalEfficiencyClass + 2i64 * v13;
v17 = EnergyValues->Cycles[0][v16];
v18 = (unsigned __int64 *)((char *)EnergyValues + 8 * v16);
v19 = KiTimelineBitmapTime;
*v18 = v6 + v17;
EndTime = EnergyValues->CpuTimeline.EndTime;
if( v19 > EndTime )
{
v112.EndTime = v19;
if( v19 - EndTime >= 0x20 )
v112.Bitmap = 1;
else
v112.Bitmap = (EnergyValues->CpuTimeline.Bitmap << (v19 - EndTime)) | 1;
EnergyValues->CpuTimeline = v112;
}
else
{
v21 = EndTime - v19;
if( v21 < 0x20 )
EnergyValues->CpuTimeline.Bitmap |= 1 << v21;
}
if( !KiEfficiencyClassSystem && (unsigned __int8)OldThread->Tcb.ThreadFlags2 == 2 )
EnergyValues->Cycles[v15][1] += v6;
if( OldThread->WorkOnBehalfThread )
{
EnergyValues->WorkOnBehalfCycles[v15][ArchitecturalEfficiencyClass] += v6;
_InterlockedExchangeAdd64(
(volatile signed __int64 *)(*((_QWORD *)OldThread->WorkOnBehalfThread + 191)
+ 8 * (ArchitecturalEfficiencyClass + 8 + 2 * v15)),
v6);
}
}
LOBYTE(v8) = v8 & 0xDF;
}
if( (v8 & 0x40) != 0 )
{
SchedulerAssist = OldThread->Tcb.SchedulerAssist;
if( SchedulerAssist )
SchedulerAssist[64] = 0;
LOBYTE(v8) = v8 & 0xBF;
}
if( (v8 & 0x3E) != 0 )
{
SchedulingGroup = OldThread->Tcb.SchedulingGroup;
if( SchedulingGroup )
{
for( i = (_QWORD *)((char *)&SchedulingGroup->Policy + CurrentPrcb->ScbOffset); i; i = (_QWORD *)i[51] )
*i += v6;
}
if( (OldThread->Tcb.gap0[2] & 8) != 0
&& (OldThread->Tcb.Affinity.Mask & CurrentPrcb->ParentNode->Affinity.Mask) != CurrentPrcb->ParentNode->Affinity.Mask )
{
CurrentPrcb->AffinitizedCycles += v6;
}
if( OldThread->Tcb.SystemHeteroCpuPolicy )
{
if( (unsigned __int8)OldThread->Tcb.ThreadFlags2 == 2 )
CurrentPrcb->UnimportantCycles += v6;
else
CurrentPrcb->ImportantCycles += v6;
}
if( OldThread->Tcb.WaitBlock[0].SparePtr )
KiEndCounterAccumulation(&OldThread->Tcb);
}
}
_enable();
v22 = (OldThread->Tcb.CurrentRunTime >> 1) + (OldThread->Tcb.ExpectedRunTime >> 1);
OldThread->Tcb.CurrentRunTime = 0;
OldThread->Tcb.ExpectedRunTime = v22;
v23 = KeGetCurrentPrcb();
LODWORD(v105) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&CurrentPrcb->PrcbLock, 0i64) )
{
do
KeYieldProcessorEx(&v105);
while( CurrentPrcb->PrcbLock );
v77 = v23->SchedulerAssist;
if( v77 && v23->NestingLevel <= 1u )
++v77[6];
}
v24 = OldThread->Tcb.SchedulingGroup;
v109 = v24;
v25 = v24;
if( v24 )
{
v72 = (_KSCB *)((char *)v24 + CurrentPrcb->ScbOffset);
if( v72 )
{
v73 = 0;
while( 1 )
{
if( (*((_BYTE *)v72 + 112) & 4) != 0 )
{
if( KiCheckMaxOverQuotaTransition(v72, v25) )
{
if( (*((_BYTE *)v72 + 112) & 1) != 0 )
KiRemoveSchedulingGroupQueue(CurrentPrcb, v72, 1u);
}
else if( v72->GenerationCycles >= v72->RankCycleTarget && (*((_BYTE *)v72 + 112) & 2) == 0 )
{
KiRecomputeGroupSchedulingRank(v25, v72, CurrentPrcb);
}
}
else
{
KiComputeGroupSchedulingRank(v25, CurrentPrcb, v72);
}
v73 += v72->Rank;
v72 = v72->Parent;
if( !v72 )
break;
v25 = (_KSCHEDULING_GROUP *)((char *)v72 - CurrentPrcb->ScbOffset);
v109 = v25;
}
}
}
NextThread = CurrentPrcb->NextThread;
if( NextThread )
{
LABEL_126:
CurrentPrcb->NextThread = 0i64;
CurrentPrcb->CurrentThread = NextThread;
if( NextThread->Tcb.WaitBlockFill6[68] == 1 )
goto LABEL_133;
goto LABEL_127;
}
while( 1 )
{
NextThread = (_ETHREAD *)KiSelectReadyThread(1i64, CurrentPrcb);
if( NextThread )
goto LABEL_128;
HIDWORD(v105) = 0;
if( !KiPerfIsoEnabled
|| (v82 = CurrentPrcb->ParentNode->IdleNonParkedCpuSet
- ((CurrentPrcb->ParentNode->IdleNonParkedCpuSet >> 1) & 0x5555555555555555i64),
(unsigned int)((0x101010101010101i64
* (((v82 & 0x3333333333333333i64)
+ ((v82 >> 2) & 0x3333333333333333i64)
+ (((v82 & 0x3333333333333333i64) + ((v82 >> 2) & 0x3333333333333333i64)) >> 4)) & 0xF0F0F0F0F0F0F0Fi64)) >> 32) >> 24 >= KiPerfIsoEnabled)
&& ((GroupSetMember = CurrentPrcb->GroupSetMember,
CoreProcessorSet = CurrentPrcb->CoreProcessorSet,
GroupSetMember == CoreProcessorSet)
|| (v85 = CoreProcessorSet & ~GroupSetMember, (CurrentPrcb->ParentNode->IdleCpuSet & v85) != 0)
|| (_BitScanForward64(&v86, v85),
v87 = (unsigned int)KiProcessorNumberToIndexMappingTable[64 * CurrentPrcb->Group + (int)v86],
HIDWORD(v105) = v87,
((*(&KiProcessorBlock + v87))->PrcbFlags._bf_0 & 0x400) != 0)) )
{
NextThread = 0i64;
Min = CurrentPrcb->ScbQueue.Min;
if( ((unsigned __int8)Min & 1) == 0 )
{
v28 = (unsigned __int64)CurrentPrcb->ScbQueue.Min;
goto LABEL_36;
}
if( Min != (_RTL_BALANCED_NODE *)1 )
{
v28 = (unsigned __int64)Min ^ ((unsigned __int64)&CurrentPrcb->ScbQueue | 1);
LABEL_36:
while( v28 )
{
v76 = v28 - 88;
NextThread = KiSelectThreadFromSchedulingGroup(CurrentPrcb, (_KSCB *)(v28 - 88), 0i64);
if( NextThread )
break;
v88 = *(_QWORD *)(v76 + 400);
if( (v88 & 1) != 0 )
{
if( v88 == 1 )
goto LABEL_38;
v28 = v88 ^ ((v76 + 392) | 1);
}
else
{
v28 = *(_QWORD *)(v76 + 400);
}
}
if( NextThread )
goto LABEL_128;
}
}
LABEL_38:
NextThread = (_ETHREAD *)KiSelectReadyThread(0i64, CurrentPrcb);
if( !NextThread )
{
v29 = 0;
ParentNode = CurrentPrcb->ParentNode;
v31 = 1;
IdleState = CurrentPrcb->IdleState;
v33 = CurrentPrcb->SchedulerAssist;
if( CurrentPrcb->IdleState == 7 )
v29 = 1;
if( v33 )
v33[16] = 1;
CurrentPrcb->IdleSchedule = 0;
if( (IdleState & 1) != 0 )
{
v34 = IdleState - 1;
CurrentPrcb->IdleState = v34;
if( !v34 )
_interlockedbittestandset64((volatile signed __int32 *)ParentNode, CurrentPrcb->GroupIndex);
_interlockedbittestandset64((volatile signed __int32 *)&ParentNode->IdleCpuSet, CurrentPrcb->GroupIndex);
v35 = CurrentPrcb->CoreProcessorSet;
if( (v35 & ParentNode->IdleCpuSet) == v35 )
{
_InterlockedOr64((volatile signed __int64 *)&ParentNode->IdleSmtSet, v35);
}
else
{
v67 = CurrentPrcb->CoreProcessorSet & ~ParentNode->IdleCpuSet;
if( ((v67 - 1) & v67) == 0 )
_InterlockedOr64((volatile signed __int64 *)&ParentNode->NonPairedSmtSet, v67);
}
_interlockedbittestandreset64((volatile signed __int32 *)&ParentNode->NonPairedSmtSet, CurrentPrcb->GroupIndex);
}
IdleThread = CurrentPrcb->IdleThread;
if( (IdleThread->Tcb.gap0[2] & 4) != 0 )
{
IsThreadRankNonZero = KiIsThreadRankNonZero(&CurrentPrcb->IdleThread->Tcb, CurrentPrcb, (_KPRCB *)v8);
Priority = 1;
if( !IsThreadRankNonZero )
Priority = IdleThread->Tcb.Priority;
v31 = 1;
}
else
{
Priority = IdleThread->Tcb.Priority;
}
*CurrentPrcb->PriorityState = Priority;
if( CurrentPrcb->SchedulerAssist )
{
v92 = (unsigned int)KiVpThreadSystemWorkPriority;
if( IdleThread != CurrentPrcb->IdleThread )
v92 = (unsigned int)Priority;
KiSetSchedulerAssistPriority((INT32 *)CurrentPrcb->SchedulerAssist, v92, 0);
}
v39 = 0;
if( (CurrentPrcb->IdleState & 2) != 0 )
v39 = v31;
_InterlockedAnd64((volatile signed __int64 *)&CurrentPrcb->PrcbLock, 0i64);
if( !v39 || v29 )
{
v40 = CurrentPrcb->ParentNode;
v103 = 0;
LODWORD(v41) = v40->SiblingMask;
HIDWORD(v106) = v40->Affinity.Reserved[0];
LABEL_56:
GroupIndex = CurrentPrcb->GroupIndex;
Group = CurrentPrcb->Group;
Mask = v40->Affinity.Mask;
SharedReadyQueueMask = v40->SharedReadyQueueMask;
v46 = Mask;
v111 = GroupIndex;
v114 = Group;
v104 = SharedReadyQueueMask;
if( v40 == CurrentPrcb->ParentNode )
{
SharedReadyQueueMask ^= CurrentPrcb->SharedReadyQueueMask;
Mask ^= CurrentPrcb->GroupSetMember;
v104 = SharedReadyQueueMask;
if( (KiCacheAwareScheduling & 2) != 0 )
v46 &= CurrentPrcb->LLCMask;
}
v47 = ~v40->IdleCpuSet & Mask;
while( 1 )
{
if( !v47 && !SharedReadyQueueMask )
{
v41 = (unsigned int)v41 & (unsigned __int64)~(1i64 << v40->Affinity.Reserved[0]);
if( (_DWORD)v41 )
{
v8 = (unsigned __int16)KeNumberNodes;
while( 1 )
{
v62 = v103 + 1;
v103 = v62;
if( v62 == (unsigned __int16)KeNumberNodes )
break;
v63 = *(unsigned int *)(*(&stru_140C4DB30 + 21)
+ 4i64 * ((unsigned int)(unsigned __int16)KeNumberNodes * HIDWORD(v106) + v62));
if( (_DWORD)v63 == -1 )
break;
v64 = (unsigned int)v41;
if( _bittest64(&v64, v63) )
{
v40 = (_KNODE *)KeNodeBlock[v63];
goto LABEL_56;
}
}
}
goto LABEL_63;
}
if( (SharedReadyQueueMask & v46) != 0 )
break;
LABEL_89:
if( (v47 & v46) != 0 )
{
v59 = __ROR8__(v47 & v46, GroupIndex);
v60 = Group << 6;
v102 = v60;
do
{
_BitScanForward64(&v61, v59);
v59 ^= 1i64 << v61;
NextThread = (_ETHREAD *)KiSearchForNewThreadOnProcessor(
CurrentPrcb,
*(&KiProcessorBlock
+ (unsigned int)KiProcessorNumberToIndexMappingTable[v60
+ (((_BYTE)v61 + GroupIndex) & 0x3F)]),
0i64);
if( NextThread )
goto LABEL_73;
v60 = v102;
GroupIndex = v111;
}
while( v59 );
}
SharedReadyQueueMask = v104;
GroupIndex = v111;
v47 &= ~v46;
v46 = v40->Affinity.Mask;
Group = v114;
}
v54 = __ROR8__(SharedReadyQueueMask & v46, GroupIndex);
v55 = Group << 6;
v101 = v55;
while( 1 )
{
_BitScanForward64(&v56, v54);
v57 = (__int64)*(&KiProcessorBlock
+ (unsigned int)KiProcessorNumberToIndexMappingTable[v55 + ((GroupIndex + (_BYTE)v56) & 0x3F)]);
v58 = *(_QWORD *)(v57 + 33856);
v104 = ~v58 & SharedReadyQueueMask;
v54 &= __ROR8__(~v58, GroupIndex);
NextThread = (_ETHREAD *)KiSearchForNewThreadOnProcessor(
CurrentPrcb,
0i64,
*(_KSHARED_READY_QUEUE **)(v57 + 33864));
if( NextThread )
goto LABEL_73;
SharedReadyQueueMask = v104;
v55 = v101;
GroupIndex = v111;
if( !v54 )
{
Group = v114;
goto LABEL_89;
}
}
}
LABEL_63:
v48 = KeGetCurrentPrcb();
LODWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&CurrentPrcb->PrcbLock, 0i64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( CurrentPrcb->PrcbLock );
v74 = v48->SchedulerAssist;
if( v74 && v48->NestingLevel <= 1u )
{
v94 = v74[6] + 1;
v74[6] = v94;
}
}
NextThread = CurrentPrcb->NextThread;
if( !NextThread )
{
NextThread = CurrentPrcb->IdleThread;
if( !KeHeteroSystem || KeHeteroSystemVirtual )
goto LABEL_67;
_InterlockedAnd64((volatile signed __int64 *)&CurrentPrcb->PrcbLock, 0i64);
KiSendHeteroRescheduleIntRequest(CurrentPrcb);
v95 = KeGetCurrentPrcb();
HIDWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&CurrentPrcb->PrcbLock, 0i64) )
{
do
KeYieldProcessorEx((UINT64 *)((char *)&SpinCount + 4));
while( CurrentPrcb->PrcbLock );
v96 = v95->SchedulerAssist;
if( v96 && v95->NestingLevel <= 1u )
{
v97 = v96[6] + 1;
v96[6] = v97;
}
}
if( !CurrentPrcb->NextThread )
goto LABEL_67;
NextThread = CurrentPrcb->NextThread;
}
CurrentPrcb->NextThread = 0i64;
LABEL_67:
if( (NextThread->Tcb.gap0[2] & 4) == 0
|| (v78 = KiIsThreadRankNonZero(&NextThread->Tcb, CurrentPrcb, (_KPRCB *)v8), v49 = 1, !v78) )
{
v49 = NextThread->Tcb.Priority;
}
*CurrentPrcb->PriorityState = v49;
if( CurrentPrcb->SchedulerAssist )
{
v98 = (unsigned int)KiVpThreadSystemWorkPriority;
if( NextThread != CurrentPrcb->IdleThread )
v98 = (unsigned int)v49;
KiSetSchedulerAssistPriority((INT32 *)CurrentPrcb->SchedulerAssist, v98, 0);
}
CurrentPrcb->CurrentThread = NextThread;
if( NextThread->Tcb.WaitBlockFill6[68] == 1 )
NextThread->Tcb.ReadyTime = NextThread->Tcb.ReadyTime
- NextThread->Tcb.WaitBlock[2].SpareLong
+ KUSER_SHARED_DATA.TickCount.LowPart;
NextThread->Tcb.WaitBlockFill6[68] = 2;
goto LABEL_73;
}
LABEL_128:
if( NextThread->Tcb.AffinityVersion == KiCpuSetSequence || (NextThread->Tcb._bf_0 & 8) != 0 )
break;
KiEnterDeferredReadyState((INT64)NextThread);
_InterlockedAnd64((volatile signed __int64 *)&CurrentPrcb->PrcbLock, 0i64);
*(_QWORD *)NextThread->Tcb.gapD8 = 0i64;
ReadyList.Next = (_SINGLE_LIST_ENTRY *)NextThread->Tcb.gapD8;
KiReadyDeferredReadyList(CurrentPrcb, &ReadyList);
v79 = KeGetCurrentPrcb();
LODWORD(v106) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&CurrentPrcb->PrcbLock, 0i64) )
{
do
KeYieldProcessorEx(&v106);
while( CurrentPrcb->PrcbLock );
v89 = v79->SchedulerAssist;
if( v89 && v79->NestingLevel <= 1u )
{
v90 = v89[6] + 1;
v89[6] = v90;
}
}
NextThread = CurrentPrcb->NextThread;
if( NextThread )
goto LABEL_126;
}
if( (NextThread->Tcb.gap0[2] & 4) == 0
|| (v75 = KiIsThreadRankNonZero(&NextThread->Tcb, CurrentPrcb, (_KPRCB *)v8), v70 = 1, !v75) )
{
v70 = NextThread->Tcb.Priority;
}
*CurrentPrcb->PriorityState = v70;
if( CurrentPrcb->SchedulerAssist )
{
v93 = (unsigned int)KiVpThreadSystemWorkPriority;
if( NextThread != CurrentPrcb->IdleThread )
v93 = (unsigned int)v70;
KiSetSchedulerAssistPriority((INT32 *)CurrentPrcb->SchedulerAssist, v93, 0);
}
CurrentPrcb->CurrentThread = NextThread;
if( NextThread->Tcb.WaitBlockFill6[68] == 1 )
{
LABEL_133:
v71 = NextThread->Tcb.ReadyTime - NextThread->Tcb.WaitBlock[2].SpareLong + KUSER_SHARED_DATA.TickCount.LowPart;
NextThread->Tcb.ReadyTime = v71;
}
LABEL_127:
NextThread->Tcb.WaitBlockFill6[68] = 2;
LABEL_73:
if( NextThread != CurrentPrcb->IdleThread && NextThread != OldThread && NextThread->Tcb.Running )
{
if( (NextThread->Tcb.gap0[2] & 4) == 0
|| (v80 = KiIsThreadRankNonZero(&NextThread->Tcb, CurrentPrcb, (_KPRCB *)v8), v65 = 1, !v80) )
{
v65 = NextThread->Tcb.Priority;
}
*CurrentPrcb->PriorityState = v65;
v66 = CurrentPrcb->SchedulerAssist;
if( v66 )
{
v99 = (unsigned int)KiVpThreadSystemWorkPriority;
if( NextThread != CurrentPrcb->IdleThread )
v99 = (unsigned int)v65;
KiSetSchedulerAssistPriority((INT32 *)CurrentPrcb->SchedulerAssist, v99, 0);
v66 = CurrentPrcb->SchedulerAssist;
}
CurrentPrcb->NextThread = NextThread;
if( v66 )
v66[16] = NextThread == CurrentPrcb->IdleThread;
if( NextThread->Tcb.WaitBlockFill6[68] == 1 )
NextThread->Tcb.ReadyTime = NextThread->Tcb.ReadyTime
- NextThread->Tcb.WaitBlock[2].SpareLong
+ KUSER_SHARED_DATA.TickCount.LowPart;
NextThread->Tcb.WaitBlockFill6[68] = 3;
NextThread = CurrentPrcb->IdleThread;
CurrentPrcb->CurrentThread = NextThread;
if( NextThread->Tcb.WaitBlockFill6[68] == 1 )
NextThread->Tcb.ReadyTime = NextThread->Tcb.ReadyTime
- NextThread->Tcb.WaitBlock[2].SpareLong
+ KUSER_SHARED_DATA.TickCount.LowPart;
NextThread->Tcb.WaitBlockFill6[68] = 2;
}
_InterlockedAnd64((volatile signed __int64 *)&CurrentPrcb->PrcbLock, 0i64);
KiSetVpThreadSpinLockCount();
WaitIrql = OldThread->Tcb.WaitIrql;
if( OldThread == NextThread )
{
v53 = NextThread->Tcb.ApcState.KernelApcPending && !NextThread->Tcb.SpecialApcDisable && !(_BYTE)WaitIrql;
_disable();
KiStartThreadCycleAccumulation(CurrentPrcb, &NextThread->Tcb, 0);
_enable();
if( (*(&NextThread->Tcb.MiscFlags + 1) & 0x800) != 0 )
{
_interlockedbittestandreset((volatile signed __int32 *)&NextThread->Tcb.116 + 1, 0xBu);
KiInsertDeferredPreemptionApc(CurrentPrcb, &NextThread->Tcb, 0);
}
}
else
{
v51 = 0;
if( (*(&OldThread->Tcb.MiscFlags + 1) & 0x400000) != 0
&& OldThread->Tcb.WaitBlockFill6[68] == 5
&& OldThread->Tcb.AbWaitEntryCount )
{
LODWORD(v108) = 0;
while( 1 )
{
KiSetVpThreadSpinLockCount();
if( !_interlockedbittestandset64((volatile signed __int32 *)&OldThread->Tcb.ThreadLock, 0i64) )
break;
KiSetVpThreadSpinLockCount();
do
KeYieldProcessorEx(&v108);
while( OldThread->Tcb.ThreadLock );
}
if( (*(&OldThread->Tcb.MiscFlags + 1) & 0x400000) != 0 && OldThread->Tcb.WaitBlockFill6[68] == 5 )
{
KiUpdateVpBackingRequiresPriorityKickState((INT64)OldThread, 1);
KiUpdateVPBackingThreadPriority(v100);
v51 = 1;
}
KiReleaseThreadLockSafe((INT64)OldThread);
}
KiSwapContext();
v53 = v52;
if( v51 )
KiUpdateVpBackingRequiresPriorityKickState((INT64)OldThread, 0);
}
if( _bittestandreset((signed __int32 *)&OldThread->Tcb.116, 9u) && !KiCancelTimer(&OldThread->Tcb.Timer, 1u) )
{
OldThread->Tcb.WaitBlockFill7[161] = 4;
*(_QWORD *)&OldThread->Tcb.Timer.gap0[8] = &OldThread->Tcb.WaitBlock[3];
*(_QWORD *)&OldThread->Tcb.Timer.gap0[16] = &OldThread->Tcb.WaitBlock[3];
}
if( v113 )
*v113 = OldThread->Tcb.AbWaitObject;
if( v53 )
{
__writecr8(1ui64);
KiDeliverApc(0, 0i64, 0i64);
}
__writecr8(WaitIrql);
}Referenced by:
KeTerminateThread
KiCommitThreadWait
KiInSwapSingleProcess