KiAbProcessContextSwitch

VOID __stdcall KiAbProcessContextSwitch(_ETHREAD *Thread, UINT64 RequestInterrupt){
  int i; 
  void *v3; 
  struct _KPRCB *CurrentPrcb; 
  char v5; 
  _SINGLE_LIST_ENTRY *v6; 
  __int64 v7; 
  int v8; 
  bool v9; 
  __int64 v10; 
  _KLOCK_ENTRY *v11; 
  __int64 LockState; 
  int v13; 
  _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; 
  CHAR v23; 
  char v24; 
  char v25; 
  KSPIN_LOCK *v26; 
  UINT64 ExtensionTable; 
  _SINGLE_LIST_ENTRY *v28; 
  int v29[8]; 
  _SINGLE_LIST_ENTRY ReadyList; 
  _SINGLE_LIST_ENTRY PropagateBoostsList; 
  _SINGLE_LIST_ENTRY *SelfBoostsList; 
  struct _KPRCB *v33; 
  struct _KLOCK_QUEUE_HANDLE LockHandle; 
  INT64 v35; 
  int v36; 
  int v37; 
  int v38; 
  v36 = RequestInterrupt;
  i = RequestInterrupt;
  if( (*((char *)Thread + 792) | *((char *)Thread + 870)) == 63 )
    return;
  v3 = 0i64;
  CurrentPrcb = KeGetCurrentPrcb();
  v5 = *((_BYTE *)Thread + 792) | *((_BYTE *)Thread + 870);
  ReadyList.Next = 0i64;
  PropagateBoostsList.Next = 0i64;
  v6 = (_SINGLE_LIST_ENTRY *)((char *)CurrentPrcb + 34672);
  SelfBoostsList = (_SINGLE_LIST_ENTRY *)((char *)CurrentPrcb + 34672);
  v33 = CurrentPrcb;
  v38 = 0;
  if( v5 == 63 )
  {
    Next = ReadyList.Next;
    goto LABEL_20;
  }
  v7 = *((_QWORD *)Thread + 100);
  v8 = (*((char *)Thread + 792) | *((char *)Thread + 870)) ^ 0x3F;
  v9 = !_BitScanForward((unsigned int *)&Thread, v8);
  if( v9 )
    goto LABEL_18;
  v10 = v7;
  do
  {
    v8 &= v8 - 1;
    v11 = (_KLOCK_ENTRY *)(v10 + 96i64 * (_QWORD)Thread);
    LockState = (__int64)v11->LockState.LockState;
    if( !LockState || (LockState & 2) != 0 || (LockState & 1) != 0 )
      goto LABEL_15;
    if( LockState >= 0 )
      goto LABEL_9;
    if( (v11->CrossThreadFlags & 1) != 0 )
      goto LABEL_15;
    if( (v11->ThreadLocalFlags & 1) == 0 )
    {
      if( KiAbOwnerComputeCpuPriorityKey((_KLOCK_ENTRY *)(v10 + 96i64 * (_QWORD)Thread)) == v11->CpuPriorityKey )
        goto LABEL_15;
LABEL_9:
      LODWORD(v35) = (_DWORD)v3;
      v37 = (int)v3;
      v13 = (int)v3;
      memset(&LockHandle, 0, sizeof(LockHandle));
      LockedHeadEntry = (_KLOCK_ENTRY *)KiAbEntryGetLockedHeadEntry((unsigned __int64)v11, 1, &LockHandle, v3);
      v15 = LockedHeadEntry;
      if( !LockedHeadEntry )
        goto LABEL_15;
      if( (v11->ThreadLocalFlags & 1) == 0 )
      {
        if( v11 != LockedHeadEntry )
          KiAbEntryUpdateOwnerTreePosition(v11, LockedHeadEntry);
        KiAbDetermineMaxWaiterPriority((INT64)v15, (INT64)&v35);
        if( !(_DWORD)v35 )
          goto LABEL_14;
        if( (unsigned int)KiAbSetMinimumThreadPriority(
                             (__int64)v11,
                             (__int64)&v35,
                             (__int64)&ReadyList,
                             &PropagateBoostsList,
                             v6,
                             &v37)
          && v11 != v15 )
        {
          KiAbEntryUpdateOwnerTreePosition(v11, v15);
        }
        v13 = v37;
        goto LABEL_37;
      }
      if( v11 != LockedHeadEntry )
        KiAbEntryUpdateWaiterTreePosition((SLIST_ENTRY *)v11);
      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((unsigned __int8 *)v11);
      if( v20 < CpuPriorityKey )
      {
        if( !v21 )
        {
          v6 = SelfBoostsList;
          goto LABEL_36;
        }
      }
      else if( !v21 )
      {
        v6 = SelfBoostsList;
LABEL_14:
        KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
        goto LABEL_15;
      }
      v6 = SelfBoostsList;
      KiAbIoBoostOwners(v15, v21, &ReadyList, &PropagateBoostsList, SelfBoostsList);
LABEL_36:
      KiAbCpuBoostOwners(v15, CpuPriorityKey, &ReadyList, &PropagateBoostsList, v6);
LABEL_37:
      KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
      if( v13 )
      {
        v26 = (KSPIN_LOCK *)((char *)v11 - 16 * v11->EntryOffset);
        if( ObReferenceObjectSafeWithTag(v26, 0x746C6644ui64) )
        {
          if( (v13 & 1) != 0 )
            IoBoostThreadIoPriority(v26, 2, 0x80000000);
          if( (v13 & 2) != 0 )
          {
            if( *((_DWORD *)v26 + 342) )
            {
              ExtensionTable = ExGetExtensionTable(IopIoRateExtensionHost);
              if( ExtensionTable )
              {
                (*(void(__fastcall **)(KSPIN_LOCK *))(ExtensionTable + 16))(v26);
                ExReleaseRundownProtection(IopIoRateExtensionHost + 8);
              }
            }
          }
          ObDereferenceObjectDeferDeleteWithTag(v26, 0x746C6644ui64);
        }
      }
      goto LABEL_15;
    }
    v25 = BYTE3((&v11[2].FreeListEntry.Next)[-2 * v11->EntryOffset]);
    if( v25 > 15 )
      v25 = 15;
    if( v25 != v11->CpuPriorityKey )
      goto LABEL_9;
LABEL_15:
    v9 = !_BitScanForward((unsigned int *)&Thread, v8);
    v3 = 0i64;
    v38 = (int)Thread;
  }
  while( !v9 );
  v16 = PropagateBoostsList.Next;
  for( i = v36; PropagateBoostsList.Next; v16 = PropagateBoostsList.Next )
  {
    v28 = v16 - 101;
    PropagateBoostsList.Next = v16->Next;
    v16->Next = (_SINGLE_LIST_ENTRY *)1;
    _InterlockedOr(v29, 0);
    if( BYTE1(v16[-2].Next) )
      KiAbProcessThreadLocks((_KTHREAD *)&v16[-101], 0i64, 1ui64, 0i64, &ReadyList, &PropagateBoostsList, v6);
    _InterlockedDecrement16((volatile signed __int16 *)&v28[108].Next + 2);
  }
  CurrentPrcb = v33;
LABEL_18:
  Next = ReadyList.Next;
  if( ReadyList.Next )
    ReadyList.Next = ReadyList.Next->Next;
LABEL_20:
  if( Next )
  {
    while( 1 )
    {
      KiDeferredReadySingleThread((INT64)CurrentPrcb, (INT64)&Next[-27], (INT64)&ReadyList);
      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