KiSearchForNewThread
_KTHREAD *__stdcall KiSearchForNewThread(_KPRCB *CurrentPrcb, UINT8 IdleScan){
_ETHREAD *NextThread;
_ETHREAD *v5;
_RTL_RB_TREE *i;
_RTL_BALANCED_NODE *Min;
__int64 v8;
unsigned __int8 IdleState;
char v10;
_KNODE *ParentNode;
unsigned int v12;
unsigned __int64 v13;
_ETHREAD *result;
unsigned int NextNode;
unsigned __int64 v16;
__int64 v17;
_ETHREAD *v18;
_KPRCB *v19;
char Priority;
UINT8 IsThreadRankNonZero;
__int64 v22;
unsigned __int64 v23;
unsigned __int64 GroupSetMember;
unsigned __int64 CoreProcessorSet;
unsigned __int64 v26;
unsigned __int64 v27;
_KPRCB *v28;
_ETHREAD *IdleThread;
UINT8 v30;
char v31;
INT64 v32;
INT64 v33;
_SINGLE_LIST_ENTRY ReadyList;
UINT64 SpinCount;
UINT64 LookupIndex;
LODWORD(LookupIndex) = 0;
NextThread = CurrentPrcb->NextThread;
if( NextThread )
{
LABEL_31:
CurrentPrcb->NextThread = 0i64;
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;
return &NextThread->Tcb;
}
while( 1 )
{
v5 = (_ETHREAD *)KiSelectReadyThread(1i64, CurrentPrcb);
if( !v5 )
{
if( KiPerfIsoEnabled )
{
v23 = CurrentPrcb->ParentNode->IdleNonParkedCpuSet
- ((CurrentPrcb->ParentNode->IdleNonParkedCpuSet >> 1) & 0x5555555555555555i64);
if( (unsigned int)((0x101010101010101i64
* (((v23 & 0x3333333333333333i64)
+ ((v23 >> 2) & 0x3333333333333333i64)
+ (((v23 & 0x3333333333333333i64) + ((v23 >> 2) & 0x3333333333333333i64)) >> 4)) & 0xF0F0F0F0F0F0F0Fi64)) >> 32) >> 24 < KiPerfIsoEnabled )
break;
GroupSetMember = CurrentPrcb->GroupSetMember;
CoreProcessorSet = CurrentPrcb->CoreProcessorSet;
if( GroupSetMember != CoreProcessorSet )
{
v26 = CoreProcessorSet & ~GroupSetMember;
if( (CurrentPrcb->ParentNode->IdleCpuSet & v26) == 0 )
{
_BitScanForward64(&v27, v26);
if( ((*(&KiProcessorBlock
+ (unsigned int)KiProcessorNumberToIndexMappingTable[64 * CurrentPrcb->Group + (unsigned int)v27]))->PrcbFlags._bf_0 & 0x400) == 0 )
break;
}
}
}
v5 = 0i64;
for( i = &CurrentPrcb->ScbQueue; ; i = (_RTL_RB_TREE *)(v22 + 392) )
{
Min = i->Min;
if( ((unsigned __int8)Min & 1) != 0 )
{
if( Min == (_RTL_BALANCED_NODE *)1 )
goto LABEL_9;
v8 = (unsigned __int64)Min ^ ((unsigned __int64)i | 1);
}
else
{
v8 = (__int64)i->Min;
}
if( !v8 )
break;
v22 = v8 - 88;
v5 = KiSelectThreadFromSchedulingGroup(CurrentPrcb, (_KSCB *)(v8 - 88), 0i64);
if( v5 )
break;
}
if( !v5 )
break;
}
LABEL_22:
if( (unsigned int)KiCheckThreadAffinity(&v5->Tcb) )
{
if( (v5->Tcb.gap0[2] & 4) == 0
|| (IsThreadRankNonZero = KiIsThreadRankNonZero(&v18->Tcb, CurrentPrcb, v19), Priority = 1, !IsThreadRankNonZero) )
{
Priority = v5->Tcb.Priority;
}
*CurrentPrcb->PriorityState = Priority;
if( CurrentPrcb->SchedulerAssist )
{
v33 = (unsigned int)KiVpThreadSystemWorkPriority;
if( v5 != CurrentPrcb->IdleThread )
v33 = (unsigned int)Priority;
KiSetSchedulerAssistPriority((INT32 *)CurrentPrcb->SchedulerAssist, v33, 0);
}
CurrentPrcb->CurrentThread = v5;
if( v5->Tcb.WaitBlockFill6[68] == 1 )
v5->Tcb.ReadyTime = v5->Tcb.ReadyTime - v5->Tcb.WaitBlock[2].SpareLong + KUSER_SHARED_DATA.TickCount.LowPart;
v5->Tcb.WaitBlockFill6[68] = 2;
if( IdleScan )
KiSetProcessorIdle(CurrentPrcb, 0i64, 0i64);
return &v5->Tcb;
}
KiEnterDeferredReadyState((INT64)v18);
_InterlockedAnd64((volatile signed __int64 *)&CurrentPrcb->PrcbLock, 0i64);
*(_QWORD *)v5->Tcb.gapD8 = 0i64;
ReadyList.Next = (_SINGLE_LIST_ENTRY *)v5->Tcb.gapD8;
KiReadyDeferredReadyList(CurrentPrcb, &ReadyList);
LODWORD(SpinCount) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&CurrentPrcb->PrcbLock, 0i64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( CurrentPrcb->PrcbLock );
}
if( IdleScan && CurrentPrcb->NextThread == CurrentPrcb->IdleThread )
CurrentPrcb->NextThread = 0i64;
NextThread = CurrentPrcb->NextThread;
if( NextThread )
goto LABEL_31;
}
LABEL_9:
v5 = (_ETHREAD *)KiSelectReadyThread(0i64, CurrentPrcb);
if( v5 )
goto LABEL_22;
IdleState = CurrentPrcb->IdleState;
if( !IdleScan )
{
KiSetProcessorIdle(CurrentPrcb, 1ui64, 0i64);
IdleThread = CurrentPrcb->IdleThread;
if( (IdleThread->Tcb.gap0[2] & 4) == 0
|| (v30 = KiIsThreadRankNonZero(&CurrentPrcb->IdleThread->Tcb, CurrentPrcb, v28), v31 = 1, !v30) )
{
v31 = IdleThread->Tcb.Priority;
}
*CurrentPrcb->PriorityState = v31;
if( CurrentPrcb->SchedulerAssist )
{
v32 = (unsigned int)KiVpThreadSystemWorkPriority;
if( IdleThread != CurrentPrcb->IdleThread )
v32 = (unsigned int)v31;
KiSetSchedulerAssistPriority((INT32 *)CurrentPrcb->SchedulerAssist, v32, 0);
}
}
v10 = CurrentPrcb->IdleState & 2;
_InterlockedAnd64((volatile signed __int64 *)&CurrentPrcb->PrcbLock, 0i64);
if( v10 && IdleState != 7 )
return 0i64;
ParentNode = CurrentPrcb->ParentNode;
v12 = ParentNode->Affinity.Reserved[0];
LODWORD(v13) = ParentNode->SiblingMask;
LABEL_13:
result = (_ETHREAD *)KiSearchForNewThreadOnNode(CurrentPrcb, ParentNode);
if( !result )
{
v13 = (unsigned int)v13 & (unsigned __int64)~(1i64 << ParentNode->Affinity.Reserved[0]);
if( (_DWORD)v13 )
{
while( 1 )
{
NextNode = MmGetNextNode(v12, &LookupIndex);
v16 = NextNode;
if( NextNode == -1 )
break;
v17 = (unsigned int)v13;
if( _bittest64(&v17, v16) )
{
ParentNode = (_KNODE *)KeNodeBlock[v16];
goto LABEL_13;
}
}
}
return 0i64;
}
return &result->Tcb;
}Referenced by:
No references.