KeTransitionProcessorParkState

VOID __stdcall KeTransitionProcessorParkState(_KPRCB *CurrentPrcb){
  int v1; 
  char v3; 
  char v4; 
  _KNODE *ParentNode; 
  unsigned __int64 GroupSetMember; 
  bool v7; 
  unsigned __int64 SharedReadyQueueMask; 
  _KSHARED_READY_QUEUE *SharedReadyQueue; 
  unsigned __int64 v10; 
  unsigned __int8 GroupIndex; 
  unsigned __int64 v12; 
  __int64 v13; 
  __int64 v14; 
  _ETHREAD *IdleThread; 
  int IdleState; 
  int v17; 
  UINT8 v18; 
  int v19; 
  unsigned __int8 v20; 
  _ETHREAD *NextThread; 
  char v22; 
  _ETHREAD *CurrentThread; 
  char v24; 
  bool v25; 
  _KPRCB *v26; 
  UINT64 v27; 
  UINT8 IsThreadRankNonZero; 
  char Priority; 
  INT64 v30; 
  UINT64 v31; 
  _KSHARED_READY_QUEUE *v32; 
  bool v33; 
  UINT64 SpinCount; 
  UINT64 v35; 
  INT64 v36[11]; 
  char v37; 
  char v38; 

  v36[0] = 0i64;
  v3 = 0;
  v38 = 0;
  v4 = 0;
  v37 = 0;
  ParentNode = CurrentPrcb->ParentNode;
  GroupSetMember = CurrentPrcb->GroupSetMember;
  if( !v1 )
  {
    v37 = 1;
    v7 = (GroupSetMember & ParentNode->SoftParkedSet) != 0;
    goto LABEL_10;
  }
  _m_prefetchw(&ParentNode->NonParkedSet);
  if( (GroupSetMember & ParentNode->NonParkedSet) != 0 )
  {
    v3 = 1;
    v4 = 1;
    if( v1 == 2 )
    {
      v7 = 1;
      goto LABEL_10;
    }
    v7 = 0;
  }
  else
  {
    v7 = 1;
  }
  v4 = v3;
  if( v1 == 1 )
    v3 = 1;
LABEL_10:
  ExAcquireSpinLockExclusiveAtDpcLevel((INT64 *)&ParentNode->ParkLock);
  LODWORD(SpinCount) = 0;
  while( _interlockedbittestandset64((volatile signed __int32 *)&CurrentPrcb->PrcbLock, 0i64) )
  {
    do
      KeYieldProcessorEx(&SpinCount);
    while( CurrentPrcb->PrcbLock );
  }
  if( v4 || v37 )
  {
    _InterlockedXor64((volatile signed __int64 *)&ParentNode->NonParkedSet, GroupSetMember);
    SharedReadyQueueMask = CurrentPrcb->SharedReadyQueueMask;
    if( SharedReadyQueueMask )
    {
      SharedReadyQueue = CurrentPrcb->SharedReadyQueue;
      v10 = SharedReadyQueueMask & ParentNode->NonParkedSet;
      if( !v10 )
      {
        v38 = 1;
        goto LABEL_25;
      }
      if( v10 == GroupSetMember )
      {
        (*(&KiProcessorBlock
         + (unsigned int)KiProcessorNumberToIndexMappingTable[64 * (unsigned __int64)CurrentPrcb->Group
                                                            + SharedReadyQueue->ScanOwner]))->SharedQueueScanOwner = 0;
        GroupIndex = CurrentPrcb->GroupIndex;
        CurrentPrcb->SharedQueueScanOwner = 1;
LABEL_24:
        SharedReadyQueue->ScanOwner = GroupIndex;
        goto LABEL_25;
      }
      if( CurrentPrcb->SharedQueueScanOwner && v4 )
      {
        _BitScanReverse64(&v12, v10);
        v13 = (unsigned int)v12 + (CurrentPrcb->Group << 6);
        HIDWORD(SpinCount) = v12;
        v14 = (__int64)*(&KiProcessorBlock + (unsigned int)KiProcessorNumberToIndexMappingTable[v13]);
        CurrentPrcb->SharedQueueScanOwner = 0;
        *(_DWORD *)(v14 + 33872) = 1;
        GroupIndex = *(_BYTE *)(v14 + 209);
        goto LABEL_24;
      }
    }
  }
LABEL_25:
  if( v7 )
    _InterlockedXor64((volatile signed __int64 *)&ParentNode->SoftParkedSet, GroupSetMember);
  ExReleaseSpinLockExclusiveFromDpcLevel((INT64 *)&ParentNode->ParkLock);
  IdleThread = CurrentPrcb->IdleThread;
  if( v37 )
  {
    IdleState = CurrentPrcb->IdleState;
    if( (IdleState & 2) != 0 )
    {
      v17 = IdleState - 2;
      if( v7 )
        v17 = CurrentPrcb->IdleState - 6;
      CurrentPrcb->IdleState = v17;
      if( !v17 )
        _InterlockedXor64((volatile signed __int64 *)ParentNode, GroupSetMember);
      v18 = 0;
      if( !v17 )
      {
        CurrentPrcb->IdleSchedule = 1;
        v18 = 1;
      }
      KiUpdateThreadPriority(CurrentPrcb, &IdleThread->Tcb, 0i64, v18);
      _InterlockedAnd64((volatile signed __int64 *)&CurrentPrcb->PrcbLock, 0i64);
      if( v18 && KeHeteroSystem && !KeHeteroSystemVirtual )
        KiSendHeteroRescheduleIntRequest(CurrentPrcb);
      _InterlockedAdd16((volatile signed __int16 *)&KUSER_SHARED_DATA.UnparkedProcessorCount, 1u);
      return;
    }
LABEL_53:
    __fastfail(0x21u);
  }
  if( !v4 && !v3 )
  {
    if( (CurrentPrcb->IdleState & 6) == 2 )
    {
      CurrentPrcb->IdleState += 4;
      _InterlockedAnd64((volatile signed __int64 *)&CurrentPrcb->PrcbLock, 0i64);
      return;
    }
    goto LABEL_53;
  }
  v19 = CurrentPrcb->IdleState;
  if( v4 )
  {
    if( (v19 & 6) != 0 )
      goto LABEL_53;
    v19 += 2;
    if( v19 == 2 )
      _InterlockedXor64((volatile signed __int64 *)ParentNode, GroupSetMember);
  }
  v20 = v19 ^ 4;
  if( !v7 )
    v20 = v19;
  NextThread = CurrentPrcb->NextThread;
  CurrentPrcb->IdleState = v20;
  if( !NextThread || NextThread == IdleThread )
  {
    v22 = 0;
  }
  else
  {
    CurrentPrcb->NextThread = 0i64;
    _interlockedbittestandreset((volatile signed __int32 *)&NextThread->Tcb.116 + 1, 0xCu);
    KiInsertDeferredReadyList((INT64)v36, (INT64)NextThread);
    NextThread = 0i64;
    v22 = 1;
  }
  CurrentThread = CurrentPrcb->CurrentThread;
  v24 = 1;
  if( CurrentThread == IdleThread )
  {
    if( v22 )
    {
      KiSetProcessorIdle(CurrentPrcb, 1ui64, 0i64);
      v25 = v33;
      goto LABEL_61;
    }
    goto LABEL_60;
  }
  if( NextThread )
  {
LABEL_60:
    v25 = 0;
    goto LABEL_61;
  }
  if( (KeGetCurrentPrcb()->$A81AFC2514E605CDBADB8E27B49DE82B::_bf_0 & 0x10000) != 0 )
  {
    v24 = 0;
    goto LABEL_60;
  }
  CurrentThread->Tcb.Preempted = 1;
  _interlockedbittestandset((volatile signed __int32 *)&CurrentThread->Tcb.116 + 1, 0xCu);
  CurrentPrcb->NextThread = IdleThread;
  KiSetProcessorIdle(CurrentPrcb, 1ui64, 0i64);
  v25 = (CurrentPrcb->DpcRequestSummary & 1) == 0;
LABEL_61:
  if( v4 )
  {
    KiUpdateThreadPriority(CurrentPrcb, &IdleThread->Tcb, 127i64, 0);
    if( v24 )
    {
      if( (IdleThread->Tcb.gap0[2] & 4) == 0
        || (IsThreadRankNonZero = KiIsThreadRankNonZero(&IdleThread->Tcb, CurrentPrcb, v26),
            Priority = 1,
            !IsThreadRankNonZero) )
      {
        Priority = IdleThread->Tcb.Priority;
      }
      *CurrentPrcb->PriorityState = Priority;
      if( CurrentPrcb->SchedulerAssist )
      {
        v30 = (unsigned int)KiVpThreadSystemWorkPriority;
        if( IdleThread != CurrentPrcb->IdleThread )
          v30 = (unsigned int)Priority;
        KiSetSchedulerAssistPriority((INT32 *)CurrentPrcb->SchedulerAssist, v30, 0);
      }
    }
    if( KiGroupSchedulingEnabled )
      KiGroupSchedulingGenerationEnd(CurrentPrcb, KUSER_SHARED_DATA.TickCountQuad, 1u);
    KiFlushReadyLists(
      CurrentPrcb->DispatcherReadyListHead,
      (UINT64 *)&CurrentPrcb->ReadySummary,
      (_SINGLE_LIST_ENTRY *)v36,
      v27);
    if( v38 )
    {
      v32 = CurrentPrcb->SharedReadyQueue;
      LODWORD(v35) = 0;
      while( _interlockedbittestandset64((volatile signed __int32 *)v32, 0i64) )
      {
        do
          KeYieldProcessorEx(&v35);
        while( v32->Lock );
      }
      KiFlushReadyLists(v32->ReadyListHead, (UINT64 *)&v32->ReadySummary, (_SINGLE_LIST_ENTRY *)v36, v31);
      _InterlockedAnd64((volatile signed __int64 *)v32, 0i64);
    }
  }
  _InterlockedAnd64((volatile signed __int64 *)&CurrentPrcb->PrcbLock, 0i64);
  KiReadyDeferredReadyList(CurrentPrcb, (_SINGLE_LIST_ENTRY *)v36);
  if( CurrentPrcb->NextThread && !CurrentPrcb->DpcRoutineActive )
    KiRequestSoftwareInterrupt(CurrentPrcb, 2);
  if( v4 )
    _InterlockedDecrement16((volatile signed __int16 *)&KUSER_SHARED_DATA.UnparkedProcessorCount);
  if( v25 )
    KiRequestSoftwareInterrupt(CurrentPrcb, 2);
}

Referenced by:

KiForceIdleParkUnparkProcessor
PpmParkReportParkedCore
PpmParkReportSoftParkChange
PpmParkReportUnparkedCore