KiQuantumEnd

VOID __stdcall KiQuantumEnd(){
  unsigned __int64 v0; 
  INT64 v1; 
  _KPRCB *v2; 
  INT64 v3; 
  UINT8 v4; 
  INT64 CurrentThread; 
  unsigned __int64 v6; 
  int v7; 
  char v8; 
  unsigned int LowPart; 
  int v10; 
  bool v11; 
  struct _KPRCB *v12; 
  _ETHREAD *NextThread; 
  struct _KPRCB *v14; 
  INT8 v15; 
  struct _KPRCB *v16; 
  unsigned int v17; 
  int v18; 
  unsigned __int64 v19; 
  _KPRCB *v20; 
  char v21; 
  BOOL IsUserVaAccessAllowed; 
  INT64 SharedReadyQueue; 
  char v24; 
  INT64 v25; 
  int v26; 
  char v27; 
  INT64 v28; 
  int v29; 
  unsigned int v30; 
  unsigned int v31; 
  _QWORD **v32; 
  _QWORD *v33; 
  _ETHREAD *v34; 
  bool v35; 
  bool v36; 
  UINT64 *v37; 
  char v38; 
  unsigned int ReadySummary; 
  int v40; 
  _LIST_ENTRY *DispatcherReadyListHead; 
  unsigned int QueueIndex; 
  unsigned int v43; 
  unsigned int v44; 
  unsigned int v45; 
  _QWORD *p_Flink; 
  _QWORD *v47; 
  INT64 v48; 
  bool v49; 
  int v50; 
  _QWORD *v51; 
  unsigned int v52; 
  _KNODE *ParentNode; 
  _DWORD *v54; 
  UINT8 v55; 
  _DWORD *v56; 
  INT64 v57; 
  UINT64 v58; 
  struct _KPRCB *v59; 
  INT64 v60; 
  INT64 v61; 
  UINT64 v62; 
  _DWORD *SchedulerAssist; 
  NTSTATUS GuestSchedulerAssistPriority; 
  _DWORD *v65; 
  int v66; 
  NTSTATUS v67; 
  _DWORD *v68; 
  int v69; 
  UINT8 IsThreadRankNonZero; 
  char v71; 
  INT64 v72; 
  UINT8 v73; 
  char Priority; 
  INT32 *v75; 
  INT64 v76; 
  _ETHREAD *IdleThread; 
  INT64 v78; 
  _SINGLE_LIST_ENTRY ReadyList; 
  INT64 v80; 
  UINT64 CycleTime; 
  UINT64 v82; 
  UINT64 v83; 
  UINT64 v84; 
  UINT64 v85; 
  _QWORD *v86; 
  unsigned int v87; 
  unsigned int v88; 
  UINT64 SpinCount; 
  UINT64 v90; 
  UINT64 v91; 
  INT64 v92; 
  _KPRCB *CurrentPrcb; 
  INT64 v94; 
  INT64 v95; 
  _SINGLE_LIST_ENTRY v96; 
  _SINGLE_LIST_ENTRY v97; 
  char v98; 
  unsigned int v99; 
  unsigned int v100; 
  char OldPriority; 
  INT64 OldPrioritya; 
  int OldPriorityb; 
  INT64 OldPriorityc; 
  _ETHREAD *v105; 
  int v106; 
  int v107; 

  v2 = KeGetCurrentPrcb();
  LODWORD(v3) = 0;
  v4 = 0;
  ReadyList.Next = 0i64;
  v98 = 0;
  CurrentPrcb = v2;
  CurrentThread = (INT64)v2->CurrentThread;
  v92 = CurrentThread;
  if( (_ETHREAD *)CurrentThread != v2->IdleThread )
  {
    v6 = *(_QWORD *)(CurrentThread + 72);
    if( v6 >= *(_QWORD *)(CurrentThread + 32) || *(_BYTE *)(CurrentThread + 125) )
    {
      v14 = KeGetCurrentPrcb();
      LODWORD(v82) = 0;
      while( _interlockedbittestandset64((volatile signed __int32 *)(CurrentThread + 64), 0i64) )
      {
        do
          KeYieldProcessorEx(&v82);
        while( *(_QWORD *)(CurrentThread + 64) );
        SchedulerAssist = v14->SchedulerAssist;
        if( SchedulerAssist && v14->NestingLevel <= 1u )
          ++SchedulerAssist[6];
      }
      if( v6 >= *(_QWORD *)(CurrentThread + 32) )
      {
        if( (*(_DWORD *)(CurrentThread + 120) & 0x100) != 0 && *(char *)(CurrentThread + 195) >= 16 )
        {
          v18 = 127;
        }
        else
        {
          v15 = KiComputeNewPriority((_KTHREAD *)CurrentThread, 1);
          v16 = KeGetCurrentPrcb();
          v17 = v15;
          HIDWORD(v82) = 0;
          while( _interlockedbittestandset64((volatile signed __int32 *)&v2->PrcbLock, 0i64) )
          {
            do
              KeYieldProcessorEx((UINT64 *)((char *)&v82 + 4));
            while( v2->PrcbLock );
            v56 = v16->SchedulerAssist;
            if( v56 && v16->NestingLevel <= 1u )
              ++v56[6];
          }
          if( !(unsigned __int8)KiUpdateVPBackingThreadPriority((PVOID)CurrentThread) )
            KiUpdateThreadPriority(v2, (_KTHREAD *)CurrentThread, v17, v2->NextThread == 0i64);
          _InterlockedAnd64((volatile signed __int64 *)&v2->PrcbLock, 0i64);
          v18 = *(unsigned __int8 *)(CurrentThread + 651);
          v4 = 1;
          v98 = 1;
          KiTryScheduleNextForegroundBoost((_KTHREAD *)CurrentThread);
        }
        v19 = v6 + (unsigned int)(v18 * KiCyclesPerClockQuantum);
        if( (*(_DWORD *)(CurrentThread + 120) & 0x20) != 0 )
          _interlockedbittestandreset((volatile signed __int32 *)(CurrentThread + 120), 5u);
        *(_QWORD *)(CurrentThread + 32) = v19;
        if( v2->GroupSetMember != v2->CoreProcessorSet
          && !_bittestandreset((signed __int32 *)(CurrentThread + 116), 7u)
          && (v2->CoreProcessorSet & (v2->GroupSetMember | v2->ParentNode->IdleCpuSet)) != v2->CoreProcessorSet )
        {
          ParentNode = (*(&KiProcessorBlock + *(unsigned int *)(CurrentThread + 588)))->ParentNode;
          if( (ParentNode->IdleSmtSet & ParentNode->NonParkedSet & *(_QWORD *)(CurrentThread + 576)) != 0 )
          {
            *(_DWORD *)(CurrentThread + 116) |= 0x80u;
            _interlockedbittestandset((volatile signed __int32 *)(CurrentThread + 120), 0xCu);
          }
        }
      }
      if( (unsigned int)KiCheckPreferredHeteroProcessor((_KTHREAD *)CurrentThread, v2) )
        _interlockedbittestandset((volatile signed __int32 *)(CurrentThread + 120), 0xCu);
      KiReleaseThreadLockSafe(CurrentThread);
      LODWORD(v3) = 0;
    }
  }
  v7 = 10;
  v8 = 0;
  LowPart = KUSER_SHARED_DATA.TickCount.LowPart;
  v10 = 16;
  v11 = (signed int)(v2->ReadyScanTick - KUSER_SHARED_DATA.TickCount.LowPart) < 0;
  v88 = KUSER_SHARED_DATA.TickCount.LowPart;
  if( !v11 )
    goto LABEL_5;
  v8 = 1;
  if( !(unsigned int)KiShouldScanSharedReadyQueue(v2) )
    goto LABEL_5;
  SharedReadyQueue = (INT64)v2->SharedReadyQueue;
  v80 = SharedReadyQueue;
  if( (*(_DWORD *)(SharedReadyQueue + 8) & 0x7FFE) == 0 )
    goto LABEL_5;
  v24 = *(_BYTE *)(SharedReadyQueue + 594);
  v94 = v3;
  OldPriority = v24;
  LODWORD(v83) = v3;
  v25 = v80;
  while( _interlockedbittestandset64((volatile signed __int32 *)v80, 0i64) )
  {
    do
      KeYieldProcessorEx(&v83);
    while( *(_QWORD *)v80 );
  }
  v0 = *(_DWORD *)(v80 + 8) & 0x7FFE;
  if( (*(_DWORD *)(v80 + 8) & 0x7FFE) != 0 )
  {
    v26 = 10;
    v27 = OldPriority;
    v28 = v80 + 16;
    v29 = 16;
    LODWORD(v0) = __ROR4__(v0, OldPriority);
    v1 = KUSER_SHARED_DATA.TickCount.LowPart - 300;
    v99 = KUSER_SHARED_DATA.TickCount.LowPart - 300;
    do
    {
      _BitScanForward(&v30, v0);
      HIDWORD(v83) = v30;
      LODWORD(v84) = v0 ^ (1 << v30);
      v31 = ((_BYTE)v30 + v27) & 0x1F;
      v87 = v31;
      v32 = (_QWORD **)(v28 + 16i64 * (((_BYTE)v30 + v27) & 0x1F));
      v33 = *v32;
      do
      {
        v34 = (_ETHREAD *)(v33 - 27);
        v35 = 0;
        v36 = (*(_DWORD *)(v33 - 12) & 0x400000) == 0;
        v33 = (_QWORD *)*v33;
        v86 = v33;
        v105 = v34;
        if( !v36 )
        {
          GuestSchedulerAssistPriority = KiReadGuestSchedulerAssistPriority((INT64)v34);
          v34 = v105;
          v33 = v86;
          v1 = v99;
          if( GuestSchedulerAssistPriority >= 16 )
            GuestSchedulerAssistPriority = 15;
          v35 = GuestSchedulerAssistPriority != v105->Tcb.SchedulerAssistPriorityFloor;
        }
        v106 = v1 - v34->Tcb.WaitBlock[2].SpareLong;
        if( v106 > 0 || v35 )
        {
          KiRemoveThreadFromSharedReadyQueue((_KSHARED_READY_QUEUE *)v80, &v34->Tcb, v31);
          KiInsertDeferredReadyList((INT64)&v94, v60);
          v1 = v99;
          if( v106 > 0 )
            --v26;
        }
        --v29;
      }
      while( v33 != v32 && v26 && v29 );
      v0 = (unsigned int)v84;
      v28 = v80 + 16;
      v107 = v26;
      LODWORD(v86) = v29;
      if( !(_DWORD)v84 )
        break;
      if( !v26 )
        break;
      v27 = OldPriority;
    }
    while( v29 );
    _InterlockedAnd64((volatile signed __int64 *)v80, 0i64);
    v7 = 10;
    v2 = CurrentPrcb;
    v4 = v98;
    v10 = 16;
    v37 = (UINT64 *)v94;
    if( v94 )
    {
      do
      {
        v61 = (INT64)(v37 - 27);
        v62 = *(v37 - 18);
        OldPriorityc = (INT64)(v37 - 27);
        CycleTime = *v37;
        v84 = v62;
        CurrentPrcb = KeGetCurrentPrcb();
        LODWORD(v85) = 0;
        while( _interlockedbittestandset64((volatile signed __int32 *)(v61 + 64), 0i64) )
        {
          do
            KeYieldProcessorEx(&v85);
          while( *(_QWORD *)(OldPriorityc + 64) );
          v61 = OldPriorityc;
          v65 = CurrentPrcb->SchedulerAssist;
          if( v65 && CurrentPrcb->NestingLevel <= 1u )
          {
            v66 = v65[6] + 1;
            v65[6] = v66;
          }
        }
        if( (int)(v99 - *(_DWORD *)(v61 + 436)) > 0 && *(char *)(v61 + 195) < 15 )
          KiSetPriorityBoost(0i64, (_KTHREAD *)v61, 15, v84);
        KiReleaseThreadLockSafe(v61);
        *(_QWORD *)(v61 + 216) = 0i64;
        v96.Next = (_SINGLE_LIST_ENTRY *)(v61 + 216);
        KiReadyDeferredReadyList(v2, &v96);
        v37 = (UINT64 *)CycleTime;
      }
      while( CycleTime );
      v4 = v98;
      v25 = v80;
      v29 = (int)v86;
    }
    if( !v29 || !v107 )
    {
      v38 = v87 + 1;
      if( v87 + 1 <= 0xE )
        goto LABEL_71;
    }
  }
  else
  {
    _InterlockedAnd64((volatile signed __int64 *)v80, 0i64);
  }
  v38 = 1;
LABEL_71:
  CurrentThread = v92;
  LODWORD(v3) = 0;
  *(_BYTE *)(v25 + 594) = v38;
  LowPart = v88;
LABEL_5:
  if( KiGroupSchedulingEnabled )
  {
    KiGroupSchedulingQuantumEnd(v2, (_KTHREAD *)CurrentThread, v4, &ReadyList);
  }
  else
  {
    v12 = KeGetCurrentPrcb();
    LODWORD(SpinCount) = v3;
    while( _interlockedbittestandset64((volatile signed __int32 *)&v2->PrcbLock, 0i64) )
    {
      do
        KeYieldProcessorEx(&SpinCount);
      while( v2->PrcbLock );
      v54 = v12->SchedulerAssist;
      if( v54 && v12->NestingLevel <= 1u )
        ++v54[6];
    }
    v7 = 10;
  }
  if( v8 )
  {
    ReadySummary = v2->ReadySummary;
    v2->ReadyScanTick = LowPart + 75;
    v40 = ReadySummary & 0x7FFE;
    if( v40 )
    {
      DispatcherReadyListHead = v2->DispatcherReadyListHead;
      QueueIndex = v2->QueueIndex;
      v95 = 0i64;
      v43 = __ROR4__(v40, QueueIndex);
      v0 = KUSER_SHARED_DATA.TickCount.LowPart - 300;
      v100 = KUSER_SHARED_DATA.TickCount.LowPart - 300;
      do
      {
        _BitScanForward(&v44, v43);
        v43 ^= 1 << v44;
        HIDWORD(SpinCount) = v44;
        v45 = ((_BYTE)v44 + (_BYTE)QueueIndex) & 0x1F;
        p_Flink = &DispatcherReadyListHead[((_BYTE)v44 + (_BYTE)QueueIndex) & 0x1F].Flink;
        CycleTime = (UINT64)p_Flink;
        v47 = (_QWORD *)*p_Flink;
        do
        {
          v48 = (INT64)(v47 - 27);
          v49 = 0;
          v36 = (*(_DWORD *)(v47 - 12) & 0x400000) == 0;
          v47 = (_QWORD *)*v47;
          OldPrioritya = (INT64)v47;
          v80 = v48;
          if( !v36 )
          {
            v67 = KiReadGuestSchedulerAssistPriority(v48);
            v48 = v80;
            p_Flink = (_QWORD *)CycleTime;
            v47 = (_QWORD *)OldPrioritya;
            if( v67 >= 16 )
              v67 = 15;
            v0 = v100;
            v49 = v67 != *(_DWORD *)(v80 + 1024);
          }
          v50 = v0 - *(_DWORD *)(v48 + 436);
          OldPriorityb = v50;
          if( v50 > 0 || v49 )
          {
            KiRemoveThreadFromReadyQueue(v2, (_LIST_ENTRY *)(v48 + 216), v45);
            KiInsertDeferredReadyList((INT64)&v95, v80);
            v0 = v100;
            if( OldPriorityb > 0 )
              --v7;
          }
          --v10;
        }
        while( v47 != p_Flink && v7 && v10 );
        DispatcherReadyListHead = v2->DispatcherReadyListHead;
      }
      while( v43 && v7 && v10 );
      v51 = (_QWORD *)v95;
      CurrentThread = v92;
      v4 = v98;
      if( v95 )
      {
        _InterlockedAnd64((volatile signed __int64 *)&v2->PrcbLock, 0i64);
        do
        {
          v57 = (INT64)(v51 - 27);
          v58 = *(v51 - 18);
          v51 = (_QWORD *)*v51;
          CycleTime = v58;
          LODWORD(v90) = 0;
          while( _interlockedbittestandset64((volatile signed __int32 *)(v57 + 64), 0i64) )
          {
            do
              KeYieldProcessorEx(&v90);
            while( *(_QWORD *)(v57 + 64) );
          }
          if( (int)(v100 - *(_DWORD *)(v57 + 436)) > 0 && *(char *)(v57 + 195) < 15 )
            KiSetPriorityBoost(0i64, (_KTHREAD *)v57, 15, CycleTime);
          KiReleaseThreadLockSafe(v57);
          v97.Next = (_SINGLE_LIST_ENTRY *)(v57 + 216);
          *(_QWORD *)(v57 + 216) = 0i64;
          KiReadyDeferredReadyList(v2, &v97);
        }
        while( v51 );
        v59 = KeGetCurrentPrcb();
        HIDWORD(v90) = 0;
        CurrentThread = v92;
        while( _interlockedbittestandset64((volatile signed __int32 *)&v2->PrcbLock, 0i64) )
        {
          do
            KeYieldProcessorEx((UINT64 *)((char *)&v90 + 4));
          while( v2->PrcbLock );
          v68 = v59->SchedulerAssist;
          if( v68 && v59->NestingLevel <= 1u )
          {
            v69 = v68[6] + 1;
            v68[6] = v69;
          }
        }
      }
      if( v10 && v7 || (v52 = v45 + 1, v52 > 0xE) )
        v52 = 1;
      v2->QueueIndex = v52;
    }
  }
  while( 1 )
  {
    NextThread = v2->NextThread;
    if( NextThread )
    {
      if( v4 )
        *(_BYTE *)(CurrentThread + 565) = 0;
LABEL_49:
      if( !NextThread )
        goto LABEL_13;
      goto LABEL_50;
    }
    if( !v4 || (NextThread = (_ETHREAD *)KiSelectReadyThread((unsigned int)*(char *)(CurrentThread + 195), v2)) == 0i64 )
    {
      if( (*(_DWORD *)(CurrentThread + 120) & 0x1000) == 0 )
        goto LABEL_13;
      if( (_ETHREAD *)CurrentThread == v2->IdleThread )
      {
        _interlockedbittestandreset((volatile signed __int32 *)(CurrentThread + 120), 0xCu);
        goto LABEL_13;
      }
      KiSelectNextThread(v2, &ReadyList);
      NextThread = v2->NextThread;
      goto LABEL_49;
    }
LABEL_50:
    if( NextThread != v2->IdleThread && !(unsigned int)KiCheckThreadAffinity(&NextThread->Tcb) )
    {
      if( (*(_BYTE *)(CurrentThread + 2) & 4) == 0
        || (IsThreadRankNonZero = KiIsThreadRankNonZero((_KTHREAD *)CurrentThread, v2, (_KPRCB *)v0),
            v71 = 1,
            !IsThreadRankNonZero) )
      {
        v71 = *(_BYTE *)(CurrentThread + 195);
      }
      *v2->PriorityState = v71;
      if( v2->SchedulerAssist )
      {
        v72 = (unsigned int)KiVpThreadSystemWorkPriority;
        if( (_ETHREAD *)CurrentThread != v2->IdleThread )
          v72 = (unsigned int)v71;
        KiSetSchedulerAssistPriority((INT32 *)v2->SchedulerAssist, v72, 0);
      }
      if( v2->NextThread == NextThread )
        KiSelectNextThread(v2, &ReadyList);
      KiInsertDeferredReadyList((INT64)&ReadyList, (INT64)NextThread);
      NextThread = 0i64;
    }
LABEL_13:
    if( !ReadyList.Next )
      break;
    if( NextThread && NextThread != v2->IdleThread && v2->NextThread != NextThread )
    {
      if( (NextThread->Tcb.gap0[2] & 4) == 0
        || (v73 = KiIsThreadRankNonZero(&NextThread->Tcb, v2, (_KPRCB *)v0), Priority = 1, !v73) )
      {
        Priority = NextThread->Tcb.Priority;
      }
      *v2->PriorityState = Priority;
      v75 = (INT32 *)v2->SchedulerAssist;
      if( v75 )
      {
        if( NextThread == v2->IdleThread )
          v76 = (unsigned int)KiVpThreadSystemWorkPriority;
        else
          v76 = (unsigned int)Priority;
        KiSetSchedulerAssistPriority(v75, v76, 0);
        v75 = (INT32 *)v2->SchedulerAssist;
      }
      IdleThread = v2->IdleThread;
      v2->NextThread = NextThread;
      if( v75 )
        *((_BYTE *)v75 + 16) = NextThread == IdleThread;
      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] = 3;
    }
    _InterlockedAnd64((volatile signed __int64 *)&v2->PrcbLock, 0i64);
    KiSetVpThreadSpinLockCount();
    KiReadyDeferredReadyList(v2, &ReadyList);
    LODWORD(v91) = 0;
    ReadyList.Next = 0i64;
    while( 1 )
    {
      KiSetVpThreadSpinLockCount();
      if( !_interlockedbittestandset64((volatile signed __int32 *)&v2->PrcbLock, 0i64) )
        break;
      KiSetVpThreadSpinLockCount();
      do
        KeYieldProcessorEx(&v91);
      while( v2->PrcbLock );
    }
  }
  if( !NextThread || (_ETHREAD *)CurrentThread == v2->IdleThread )
  {
    _InterlockedAnd64((volatile signed __int64 *)&v2->PrcbLock, 0i64);
    KiSetVpThreadSpinLockCount();
  }
  else
  {
    v2->NextThread = 0i64;
    _disable();
    KiEndThreadCycleAccumulation((INT64)v2, CurrentThread, 0i64, v1, (INT64)ReadyList.Next, v80, CycleTime);
    _enable();
    if( (NextThread->Tcb.gap0[2] & 4) == 0 || (v55 = KiIsThreadRankNonZero(&NextThread->Tcb, v2, v20), v21 = 1, !v55) )
      v21 = NextThread->Tcb.Priority;
    *v2->PriorityState = v21;
    if( v2->SchedulerAssist )
    {
      v78 = (unsigned int)KiVpThreadSystemWorkPriority;
      if( NextThread != v2->IdleThread )
        v78 = (unsigned int)v21;
      KiSetSchedulerAssistPriority((INT32 *)v2->SchedulerAssist, v78, 0);
    }
    v2->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;
    *(_BYTE *)(CurrentThread + 643) = 30;
    KiQueueReadyThread(v2, (_KTHREAD *)CurrentThread);
    KiAbProcessContextSwitch((_KTHREAD *)CurrentThread, 1ui64);
    IsUserVaAccessAllowed = KeIsUserVaAccessAllowed(0i64);
    if( KeSmapEnabled )
      __stac();
    KiSwapContext();
    if( !IsUserVaAccessAllowed )
    {
      if( KeSmapEnabled )
        __clac();
    }
  }
}

Referenced by:

KiDispatchInterrupt
KiIdleLoop