KiAbProcessContextSwitch

VOID __stdcall KiAbProcessContextSwitch(_ETHREAD *Thread, UINT64 RequestInterrupt){
  int i; 
  _AB_PRIORITY v3; 
  struct _KPRCB *CurrentPrcb; 
  char v5; 
  _SINGLE_LIST_ENTRY *p_AbSelfIoBoostsList; 
  _KLOCK_ENTRY *LockEntries; 
  int v8; 
  bool v9; 
  _KLOCK_ENTRY *v10; 
  _KLOCK_ENTRY *v11; 
  __int64 bf_0; 
  int AllPriorities; 
  _KLOCK_ENTRY *LockedHeadEntry; 
  _KLOCK_ENTRY *v15; 
  _SINGLE_LIST_ENTRY *v16; 
  _SINGLE_LIST_ENTRY *Next; 
  _RTL_BALANCED_NODE *Min; 
  char v19; 
  char v20; 
  unsigned int v21; 
  CHAR CpuPriorityKey; 
  INT8 v23; 
  char v24; 
  int v25; 
  char v26; 
  _ETHREAD *v27; 
  void(__fastcall **ExtensionTable)(_ETHREAD *); 
  _SINGLE_LIST_ENTRY *v29; 
  int v30[8]; 
  _SINGLE_LIST_ENTRY ReadyList; 
  _SINGLE_LIST_ENTRY PropagateBoostsList; 
  _SINGLE_LIST_ENTRY *SelfBoostsList; 
  struct _KPRCB *v34; 
  _KLOCK_QUEUE_HANDLE HeadEntryLockQueue; 
  _AB_PRIORITY MaxPriority; 
  int v37; 
  UINT64 BoostOutstandingIOsRequired; 
  int v39; 

  v37 = RequestInterrupt;
  i = RequestInterrupt;
  if( ((char)Thread->Tcb.AbEntrySummary | (char)Thread->Tcb.AbOrphanedEntrySummary) == 63 )
    return;
  v3 = 0;
  CurrentPrcb = KeGetCurrentPrcb();
  v5 = Thread->Tcb.AbEntrySummary | Thread->Tcb.AbOrphanedEntrySummary;
  ReadyList.Next = 0i64;
  PropagateBoostsList.Next = 0i64;
  p_AbSelfIoBoostsList = &CurrentPrcb->AbSelfIoBoostsList;
  SelfBoostsList = &CurrentPrcb->AbSelfIoBoostsList;
  v34 = CurrentPrcb;
  v39 = 0;
  if( v5 == 63 )
  {
    Next = ReadyList.Next;
    goto LABEL_20;
  }
  LockEntries = Thread->Tcb.LockEntries;
  v8 = ((char)Thread->Tcb.AbEntrySummary | (char)Thread->Tcb.AbOrphanedEntrySummary) ^ 0x3F;
  v9 = !_BitScanForward((unsigned int *)&Thread, v8);
  if( v9 )
    goto LABEL_18;
  v10 = LockEntries;
  do
  {
    v8 &= v8 - 1;
    v11 = &v10[(_QWORD)Thread];
    bf_0 = v11->LockState.$E8276A2CF8B819ED32D1B6FEB35D730A::_bf_0;
    if( !bf_0 || (bf_0 & 2) != 0 || (bf_0 & 1) != 0 )
      goto LABEL_15;
    if( bf_0 >= 0 )
      goto LABEL_9;
    if( (v11->CrossThreadFlags & 1) != 0 )
      goto LABEL_15;
    if( (v11->ThreadLocalFlags & 1) == 0 )
    {
      if( KiAbOwnerComputeCpuPriorityKey(&v10[(_QWORD)Thread]) == v11->CpuPriorityKey )
        goto LABEL_15;
LABEL_9:
      MaxPriority = v3;
      LODWORD(BoostOutstandingIOsRequired) = v3;
      AllPriorities = v3.AllPriorities;
      memset(&HeadEntryLockQueue, 0, sizeof(HeadEntryLockQueue));
      LockedHeadEntry = KiAbEntryGetLockedHeadEntry(v11, 1ui64, &HeadEntryLockQueue);
      v15 = LockedHeadEntry;
      if( !LockedHeadEntry )
        goto LABEL_15;
      if( (v11->ThreadLocalFlags & 1) == 0 )
      {
        if( v11 != LockedHeadEntry )
          KiAbEntryUpdateOwnerTreePosition(v11, LockedHeadEntry);
        KiAbDetermineMaxWaiterPriority(v15, &MaxPriority);
        if( !*(_DWORD *)&MaxPriority )
          goto LABEL_14;
        KiAbSetMinimumThreadPriority(
          v11,
          &MaxPriority,
          &ReadyList,
          &PropagateBoostsList,
          p_AbSelfIoBoostsList,
          &BoostOutstandingIOsRequired);
        if( v25 && v11 != v15 )
          KiAbEntryUpdateOwnerTreePosition(v11, v15);
        AllPriorities = BoostOutstandingIOsRequired;
        goto LABEL_37;
      }
      if( v11 != LockedHeadEntry )
        KiAbEntryUpdateWaiterTreePosition(v11, LockedHeadEntry);
      Min = v15->OwnerTree.Min;
      if( Min )
        v19 = (char)Min[2].Children[0];
      else
        v19 = 15;
      v20 = v19;
      if( (v15->ThreadLocalFlags & 1) == 0 )
      {
        v23 = KiAbOwnerComputeCpuPriorityKey(v15);
        if( v23 < v24 )
          v20 = v23;
      }
      KiAbTryIncrementIoWaiterCounts(v11, v15);
      CpuPriorityKey = KiAbEntryGetCpuPriorityKey(v11);
      if( v20 < CpuPriorityKey )
      {
        if( !v21 )
        {
          p_AbSelfIoBoostsList = SelfBoostsList;
          goto LABEL_36;
        }
      }
      else if( !v21 )
      {
        p_AbSelfIoBoostsList = SelfBoostsList;
LABEL_14:
        KeReleaseInStackQueuedSpinLockFromDpcLevel(&HeadEntryLockQueue);
        goto LABEL_15;
      }
      p_AbSelfIoBoostsList = SelfBoostsList;
      KiAbIoBoostOwners(v15, (_BYTE *)v21, &ReadyList, &PropagateBoostsList, SelfBoostsList);
LABEL_36:
      KiAbCpuBoostOwners(v15, CpuPriorityKey, &ReadyList, &PropagateBoostsList, p_AbSelfIoBoostsList);
LABEL_37:
      KeReleaseInStackQueuedSpinLockFromDpcLevel(&HeadEntryLockQueue);
      if( AllPriorities )
      {
        v27 = (_ETHREAD *)((char *)v11 - 16 * v11->EntryOffset);
        if( ObReferenceObjectSafeWithTag((INT64)v27, 1953261124i64) )
        {
          if( (AllPriorities & 1) != 0 )
            IoBoostThreadIoPriority(v27, IoPriorityNormal, 0x80000000ui64);
          if( (AllPriorities & 2) != 0 )
          {
            if( v27->IoQoSThrottleCount )
            {
              ExtensionTable = (void(__fastcall **)(_ETHREAD *))ExGetExtensionTable(*(&stru_140C452E0 + 122));
              if( ExtensionTable )
              {
                ExtensionTable[2](v27);
                ExReleaseRundownProtection((_EX_RUNDOWN_REF *)(*(&stru_140C452E0 + 122) + 64i64));
              }
            }
          }
          ObDereferenceObjectDeferDeleteWithTag((UINT64)v27, 1953261124i64);
        }
      }
      goto LABEL_15;
    }
    v26 = BYTE3((&v11[2].FreeListEntry.Next)[-2 * v11->EntryOffset]);
    if( v26 > 15 )
      v26 = 15;
    if( v26 != v11->CpuPriorityKey )
      goto LABEL_9;
LABEL_15:
    v9 = !_BitScanForward((unsigned int *)&Thread, v8);
    v3 = 0;
    v39 = (int)Thread;
  }
  while( !v9 );
  v16 = PropagateBoostsList.Next;
  for( i = v37; PropagateBoostsList.Next; v16 = PropagateBoostsList.Next )
  {
    v29 = v16 - 101;
    PropagateBoostsList.Next = v16->Next;
    v16->Next = (_SINGLE_LIST_ENTRY *)1;
    _InterlockedOr(v30, 0);
    if( BYTE1(v16[-2].Next) )
      KiAbProcessThreadLocks(
        (_KTHREAD *)&v16[-101],
        0i64,
        1ui64,
        0i64,
        &ReadyList,
        &PropagateBoostsList,
        p_AbSelfIoBoostsList);
    _InterlockedDecrement16((volatile signed __int16 *)&v29[108].Next + 2);
  }
  CurrentPrcb = v34;
LABEL_18:
  Next = ReadyList.Next;
  if( ReadyList.Next )
    ReadyList.Next = ReadyList.Next->Next;
LABEL_20:
  if( Next )
  {
    while( 1 )
    {
      KiDeferredReadySingleThread((INT64)CurrentPrcb, (_DWORD)Next - 216, (INT64)&ReadyList);
      LODWORD(Next) = ReadyList.Next;
      if( !ReadyList.Next )
        break;
      ReadyList.Next = ReadyList.Next->Next;
    }
  }
  if( i )
    KiCheckForThreadDispatch(CurrentPrcb, 2u);
}

Referenced by:

KeBoostPriorityThread
KeCpuSetReportParkedProcessors
KeDelayExecutionThread
KeRecomputeCpuSetAffinityProcess
KeRemoveQueueEx
KeSetAffinityThread
KeSetBasePriorityThread
KeSetCpuSetsProcess
KeSetLegacyAffinityThread
KeSetSchedulingGroupRankBias
KeSetSelectedCpuSetsThread
KeSetThreadSchedulerAssist
KeUpdateThreadCpuSets
KeYieldExecution
KiAbForceProcessLockEntry
KiAbThreadUnboostCpuPriority
KiCheckForThreadDispatch
KiExitDispatcher
KiProcessDeferredReadyList
KiQuantumEnd
KiReadyOutSwappedThreads
KiSchedulerApc
KiSetHeteroPolicyThread
KiSwapThread
KxDispatchInterrupt
PsImpersonateContainerOfThread