KiSearchForNewThreadOnProcessor

_KTHREAD *__stdcall KiSearchForNewThreadOnProcessor(
        _KPRCB *CurrentPrcb,
        _KPRCB *TargetPrcb,
        _KSHARED_READY_QUEUE *ReadyQueue){
  int v6; 
  struct _KPRCB *v8; 
  struct _KPRCB *v9; 
  __int64 v10; 
  struct _KPRCB *v11; 
  _KPRCB *v12; 
  _KPRCB *v13; 
  struct _KPRCB *v14; 
  _QWORD *ReadyThread; 
  char v16; 
  unsigned int v17; 
  _QWORD *v18; 
  __int64 v19; 
  struct _KPRCB *v20; 
  __int64 v21; 
  char v22; 
  int v23; 
  __int64 v24; 
  int v25; 
  __int64 v26; 
  __int64 v27; 
  char v28; 
  struct _KPRCB *v29; 
  __int64 v30; 
  __int64 v31; 
  unsigned __int64 v32; 
  __int64 v33; 
  __int64 v34; 
  unsigned __int64 v35; 
  unsigned __int64 v36; 
  INT64 v37; 
  UINT64 SpinCount; 
  unsigned int v39; 
  __int64 v40[9]; 
  UINT64 v41; 
  UINT64 v42; 
  v6 = 0;
  while( 1 )
  {
    while( 1 )
    {
      if( TargetPrcb )
      {
        if( !*((_DWORD *)TargetPrcb + 7942)
          && !KiMayStealStandbyThread((__int64)TargetPrcb, (__int64)CurrentPrcb)
          && !*((_QWORD *)TargetPrcb + 3982) )
        {
          return 0i64;
        }
        v11 = KeGetCurrentPrcb();
        v12 = CurrentPrcb;
        LODWORD(v41) = 0;
        v13 = TargetPrcb;
        if( CurrentPrcb <= TargetPrcb )
          v12 = TargetPrcb;
        if( CurrentPrcb <= TargetPrcb )
          v13 = CurrentPrcb;
        while( _interlockedbittestandset64((volatile signed __int32 *)v13 + 12, 0i64) )
        {
          do
            KeYieldProcessorEx(&v41);
          while( *((_QWORD *)v13 + 6) );
          v27 = *((_QWORD *)v11 + 4247);
          if( v27 && *((_BYTE *)v11 + 32) <= 1u )
            ++*(_DWORD *)(v27 + 24);
        }
        if( v13 != v12 )
        {
          v14 = KeGetCurrentPrcb();
          LODWORD(v42) = 0;
          while( _interlockedbittestandset64((volatile signed __int32 *)v12 + 12, 0i64) )
          {
            do
              KeYieldProcessorEx(&v42);
            while( *((_QWORD *)v12 + 6) );
            v26 = *((_QWORD *)v14 + 4247);
            if( v26 && *((_BYTE *)v14 + 32) <= 1u )
              ++*(_DWORD *)(v26 + 24);
          }
        }
      }
      else
      {
        if( (ReadyQueue->ReadySummary & 0xFFFFFFFE) == 0 )
          return 0i64;
        v8 = KeGetCurrentPrcb();
        LODWORD(SpinCount) = 0;
        while( _interlockedbittestandset64((volatile signed __int32 *)CurrentPrcb + 12, 0i64) )
        {
          do
            KeYieldProcessorEx(&SpinCount);
          while( *((_QWORD *)CurrentPrcb + 6) );
          v31 = *((_QWORD *)v8 + 4247);
          if( v31 && *((_BYTE *)v8 + 32) <= 1u )
            ++*(_DWORD *)(v31 + 24);
        }
        v9 = KeGetCurrentPrcb();
        HIDWORD(SpinCount) = 0;
        while( _interlockedbittestandset64((volatile signed __int32 *)ReadyQueue, 0i64) )
        {
          do
            KeYieldProcessorEx((UINT64 *)((char *)&SpinCount + 4));
          while( ReadyQueue->Lock );
          v10 = *((_QWORD *)v9 + 4247);
          if( v10 && *((_BYTE *)v9 + 32) <= 1u )
            ++*(_DWORD *)(v10 + 24);
        }
      }
      ReadyThread = (_QWORD *)*((_QWORD *)CurrentPrcb + 2);
      v16 = 0;
      if( ReadyThread )
        break;
      if( !ReadyQueue )
      {
        if( KiMayStealStandbyThread((__int64)TargetPrcb, (__int64)CurrentPrcb)
          && KiCheckThreadAffinity(*((_QWORD *)TargetPrcb + 2)) )
        {
          ReadyThread = (_QWORD *)*((_QWORD *)TargetPrcb + 2);
          if( KiPrcbInGroupAffinity((__int64)CurrentPrcb, (__int64)(ReadyThread + 72)) )
          {
            KiSelectNextThread(TargetPrcb, 0i64);
            *((_DWORD *)ReadyThread + 134) = *((_DWORD *)CurrentPrcb + 9);
            if( ReadyThread )
            {
LABEL_30:
              _InterlockedAnd64((volatile signed __int64 *)TargetPrcb + 6, 0i64);
              goto LABEL_31;
            }
          }
          else
          {
            ReadyThread = 0i64;
          }
        }
        v17 = *((_DWORD *)TargetPrcb + 7942);
        if( !v17 || (ReadyThread = KiFindReadyThread((__int64)CurrentPrcb, (__int64)TargetPrcb, 0i64, v17)) == 0i64 )
        {
          v39 = 0;
          if( !KiPerfIsoEnabled
            || (v32 = **((_QWORD **)CurrentPrcb + 24) - ((**((_QWORD **)CurrentPrcb + 24) >> 1) & 0x5555555555555555i64),
                (unsigned int)((0x101010101010101i64
                              * (((v32 & 0x3333333333333333i64)
                                + ((v32 >> 2) & 0x3333333333333333i64)
                                + (((v32 & 0x3333333333333333i64) + ((v32 >> 2) & 0x3333333333333333i64)) >> 4)) & 0xF0F0F0F0F0F0F0Fi64)) >> 32) >> 24 >= KiPerfIsoEnabled)
            && ((v33 = *((_QWORD *)CurrentPrcb + 25), v34 = *((_QWORD *)CurrentPrcb + 4235), v33 == v34)
             || (v35 = v34 & ~v33, (*(_QWORD *)(*((_QWORD *)CurrentPrcb + 24) + 24i64) & v35) != 0)
             || (_BitScanForward64(&v36, v35),
                 v39 = KiProcessorNumberToIndexMappingTable[64 * *((unsigned __int8 *)CurrentPrcb + 208)
                                                          + (unsigned int)v36],
                 (*((_DWORD *)*(&KiProcessorBlock + v39) + 59) & 0x400) != 0)) )
          {
            KiGroupSchedulingMoveThread(CurrentPrcb, TargetPrcb, (_RTL_RB_TREE *)TargetPrcb + 1991);
            ReadyThread = v18;
          }
        }
        goto LABEL_30;
      }
      if( (ReadyQueue->ReadySummary & 0xFFFFFFFE) != 0 )
        ReadyThread = KiFindReadyThread(
                        (__int64)CurrentPrcb,
                        0i64,
                        (__int64)ReadyQueue,
                        ReadyQueue->ReadySummary & 0xFFFFFFFE);
      _InterlockedAnd64((volatile signed __int64 *)ReadyQueue, 0i64);
      v20 = KeGetCurrentPrcb();
      v21 = *((_QWORD *)v20 + 4247);
      if( v21 && *((_BYTE *)v20 + 32) <= 1u )
        --*(_DWORD *)(v21 + 24);
LABEL_31:
      if( !ReadyThread )
      {
        v19 = *((_QWORD *)CurrentPrcb + 4247);
        if( v19 )
          *(_BYTE *)(v19 + 16) = 1;
        _InterlockedAnd64((volatile signed __int64 *)CurrentPrcb + 6, 0i64);
        return(_KTHREAD *)ReadyThread;
      }
      if( ReadyThread[71] == KiCpuSetSequence || (*((_DWORD *)ReadyThread + 29) & 8) != 0 )
      {
        v6 = 2;
        goto LABEL_42;
      }
      KiEnterDeferredReadyState((INT64)ReadyThread);
      _InterlockedAnd64((volatile signed __int64 *)CurrentPrcb + 6, 0i64);
      ReadyThread[27] = 0i64;
      v40[0] = (__int64)(ReadyThread + 27);
      KiReadyDeferredReadyList(CurrentPrcb, v40);
    }
    if( ReadyQueue )
    {
      _InterlockedAnd64((volatile signed __int64 *)ReadyQueue, 0i64);
      v29 = KeGetCurrentPrcb();
      v30 = *((_QWORD *)v29 + 4247);
      if( v30 && *((_BYTE *)v29 + 32) <= 1u )
        --*(_DWORD *)(v30 + 24);
    }
    else
    {
      _InterlockedAnd64((volatile signed __int64 *)TargetPrcb + 6, 0i64);
    }
    *((_QWORD *)CurrentPrcb + 2) = 0i64;
    if( ReadyThread != *((_QWORD **)CurrentPrcb + 3) )
      break;
    _InterlockedAnd64((volatile signed __int64 *)CurrentPrcb + 6, 0i64);
  }
  v16 = 1;
LABEL_42:
  if( v6 )
  {
    if( (*((_BYTE *)ReadyThread + 2) & 4) == 0
      || (KiIsThreadRankNonZero((_ETHREAD *)ReadyThread, CurrentPrcb), v22 = 1, !v28) )
    {
      v22 = *((_BYTE *)ReadyThread + 195);
    }
    **((_BYTE **)CurrentPrcb + 7) = v22;
    if( *((_QWORD *)CurrentPrcb + 4247) )
    {
      v37 = (unsigned int)KiVpThreadSystemWorkPriority;
      if( ReadyThread != *((_QWORD **)CurrentPrcb + 3) )
        v37 = (unsigned int)v22;
      KiSetSchedulerAssistPriority(*((volatile INT32 **)CurrentPrcb + 4247), v37, 0);
    }
  }
  *((_QWORD *)CurrentPrcb + 1) = ReadyThread;
  if( *((_BYTE *)ReadyThread + 388) == 1 )
    *((_DWORD *)ReadyThread + 33) = *((_DWORD *)ReadyThread + 33)
                                  - *((_DWORD *)ReadyThread + 109)
                                  + KUSER_SHARED_DATA.TickCount.LowPart;
  *((_BYTE *)ReadyThread + 388) = 2;
  if( !v16 )
  {
    v23 = *((unsigned __int8 *)CurrentPrcb + 35);
    v24 = *((_QWORD *)CurrentPrcb + 24);
    *((_BYTE *)CurrentPrcb + 12587) = 0;
    if( (v23 & 1) != 0 )
      __fastfail(0x21u);
    v25 = v23 + 1;
    *((_BYTE *)CurrentPrcb + 35) = v25;
    if( v25 == 1 )
      _interlockedbittestandreset64((volatile signed __int32 *)v24, *((unsigned __int8 *)CurrentPrcb + 209));
    _interlockedbittestandreset64((volatile signed __int32 *)(v24 + 24), *((unsigned __int8 *)CurrentPrcb + 209));
    _InterlockedAnd64((volatile signed __int64 *)(v24 + 8), ~*((_QWORD *)CurrentPrcb + 4235));
    _InterlockedAnd64((volatile signed __int64 *)(v24 + 16), ~*((_QWORD *)CurrentPrcb + 4235));
    if( (*((_QWORD *)CurrentPrcb + 4235) & ~*(_QWORD *)(v24 + 24)) == *((_QWORD *)CurrentPrcb + 25) )
      _interlockedbittestandset64((volatile signed __int32 *)(v24 + 16), *((unsigned __int8 *)CurrentPrcb + 209));
  }
  return(_KTHREAD *)ReadyThread;
}

Referenced by:

KiSearchForNewThreadOnNode
KiSwapThread