KeSetThreadSchedulerAssist

NTSTATUS __stdcall KeSetThreadSchedulerAssist(_ETHREAD *Thread){
  __int64 v1; 
  int v2; 
  unsigned __int64 v3; 
  int v5; 
  int v6; 
  unsigned __int8 v7; 
  struct _KPRCB *v8; 
  ULONG_PTR v9; 
  __int64 v10; 
  __int64 v11; 
  bool v12; 
  __int64 v13; 
  unsigned __int8 v14; 
  __int16 v15; 
  INT64 v16; 
  bool v17; 
  INT64 v18; 
  INT64 v19; 
  unsigned __int8 CurrentIrql; 
  ULONG_PTR v21; 
  char v22; 
  char v23; 
  char v24; 
  unsigned int v25; 
  char v26; 
  char v27; 
  __int64 v28; 
  struct _KPRCB *CurrentPrcb; 
  ULONG_PTR v30; 
  __int64 v31; 
  __int64 v32; 
  UINT64 v34; 
  _SINGLE_LIST_ENTRY ReadyList; 
  _KSHARED_READY_QUEUE *ControlReadyQueue; 
  void *ControlPrcb[7]; 
  int v38; 
  void *retaddr; 
  UINT64 SpinCount; 
  UINT64 v41; 
  v3 = (unsigned __int64)&retaddr;
  ControlPrcb[0] = 0i64;
  ReadyList.Next = 0i64;
  ControlReadyQueue = 0i64;
  if( !v2 )
  {
    if( v1 )
    {
      *((_QWORD *)Thread + 121) = v1;
      _interlockedbittestandset((volatile signed __int32 *)Thread + 30, 0x16u);
      if( (KiVelocityFlags & 0x400) != 0 )
        _interlockedbittestandset((volatile signed __int32 *)Thread, 0x16u);
      *((_DWORD *)Thread + 256) = 32;
      return v3;
    }
    CurrentIrql = KeGetCurrentIrql();
    __writecr8(2ui64);
    LODWORD(v34) = 0;
    while( _interlockedbittestandset64((volatile signed __int32 *)Thread + 16, 0i64) )
    {
      do
        KeYieldProcessorEx(&v34);
      while( *((_QWORD *)Thread + 8) );
    }
    if( *((_DWORD *)Thread + 256) != 32 )
    {
      v21 = *((char *)Thread + 1024);
      v22 = *((_BYTE *)Thread + v21 + 824);
      if( !v22 )
        KeBugCheckEx(0x157u, (ULONG_PTR)Thread, v21, 2ui64, 0i64);
      v23 = v22 - 1;
      *((_BYTE *)Thread + v21 + 824) = v23;
      if( !v23 )
      {
        v24 = v21;
        v25 = *((_DWORD *)Thread + 214) ^ (1 << v21);
        *((_DWORD *)Thread + 214) = v25;
        if( v25 < 1 << v24 )
        {
          v26 = *((_BYTE *)Thread + 195);
          if( v26 < 16 )
          {
            v27 = *((_BYTE *)Thread + 563) + (*((_BYTE *)Thread + 564) & 0xF) + (*((_BYTE *)Thread + 564) >> 4);
            if( v27 < v26 )
              KiSetPriorityThread((_KTHREAD *)Thread, &ReadyList, (unsigned int)v27);
          }
        }
      }
      *((_DWORD *)Thread + 256) = 32;
    }
    KiAcquireThreadStateLock(Thread, (_KPRCB **)ControlPrcb, &ControlReadyQueue);
    _interlockedbittestandreset((volatile signed __int32 *)Thread + 30, 0x16u);
    *((_QWORD *)Thread + 121) = 0i64;
    if( (KiVelocityFlags & 0x400) != 0 )
      _interlockedbittestandreset((volatile signed __int32 *)Thread, 0x16u);
    KiReleaseThreadStateLock(v28, (__int64)ControlPrcb[0], (volatile signed __int64 *)ControlReadyQueue);
    KiReleaseThreadLockSafe((INT64)Thread);
    CurrentPrcb = KeGetCurrentPrcb();
    KiReadyDeferredReadyList(CurrentPrcb, &ReadyList);
    if( CurrentIrql >= 2u )
    {
      if( *((_QWORD *)CurrentPrcb + 2) && !*((_BYTE *)CurrentPrcb + 12586) )
        KiRequestSoftwareInterrupt(CurrentPrcb, 2);
      goto LABEL_69;
    }
    v30 = *((_QWORD *)CurrentPrcb + 1);
    if( *((_QWORD *)CurrentPrcb + 2) )
    {
      KiAbProcessContextSwitch(*((_KTHREAD **)CurrentPrcb + 1), 0i64);
      HIDWORD(v34) = 0;
      while( _interlockedbittestandset64((volatile signed __int32 *)CurrentPrcb + 12, 0i64) )
      {
        do
          KeYieldProcessorEx((UINT64 *)((char *)&v34 + 4));
        while( *((_QWORD *)CurrentPrcb + 6) );
      }
      v31 = *((_QWORD *)CurrentPrcb + 2);
      *((_QWORD *)CurrentPrcb + 2) = 0i64;
      _disable();
      KiEndThreadCycleAccumulation(CurrentPrcb, (_KTHREAD *)v30, 0i64);
      _enable();
      *((_QWORD *)CurrentPrcb + 1) = v31;
      if( *(_BYTE *)(v31 + 388) == 1 )
      {
        v32 = (unsigned int)(*(_DWORD *)(v31 + 132) - *(_DWORD *)(v31 + 436));
        *(_DWORD *)(v31 + 132) = v32 + KUSER_SHARED_DATA.TickCount.LowPart;
      }
      *(_BYTE *)(v31 + 388) = 2;
      *(_BYTE *)(v30 + 643) = 32;
      *(_BYTE *)(v30 + 390) = CurrentIrql;
      KiQueueReadyThread((__int64)CurrentPrcb, v30, v32);
      if( !KiSwapContext((PKTHREAD)v30, (PKTHREAD)v31) )
        goto LABEL_63;
    }
    else if( (*(_DWORD *)(v30 + 116) & 0x40) == 0 )
    {
      goto LABEL_63;
    }
    __writecr8(1ui64);
    *(_DWORD *)(v30 + 116) &= ~0x40u;
    KiDeliverApc(0, 0i64, 0i64);
LABEL_63:
    __writecr8(CurrentIrql);
LABEL_69:
    LODWORD(v3) = KeSetPriorityThread((PKTHREAD)Thread, *((char *)Thread + 563));
    return v3;
  }
  v5 = v2 - 1;
  if( v5 )
  {
    v6 = v5 - 1;
    if( !v6 || v6 == 1 )
    {
      v7 = KeGetCurrentIrql();
      __writecr8(2ui64);
      LODWORD(SpinCount) = 0;
      while( _interlockedbittestandset64((volatile signed __int32 *)Thread + 16, 0i64) )
      {
        do
          KeYieldProcessorEx(&SpinCount);
        while( *((_QWORD *)Thread + 8) );
      }
      KiUpdateVpBackingThreadPriorityFromTopLevel(Thread);
      KiReleaseThreadLockSafe((INT64)Thread);
      v8 = KeGetCurrentPrcb();
      LODWORD(v3) = (unsigned int)KiReadyDeferredReadyList(v8, &ReadyList);
      if( v7 < 2u )
      {
        v9 = *((_QWORD *)v8 + 1);
        if( *((_QWORD *)v8 + 2) )
        {
          KiAbProcessContextSwitch(*((_KTHREAD **)v8 + 1), 0i64);
          LODWORD(v41) = 0;
          while( _interlockedbittestandset64((volatile signed __int32 *)v8 + 12, 0i64) )
          {
            do
              KeYieldProcessorEx(&v41);
            while( *((_QWORD *)v8 + 6) );
          }
          v10 = *((_QWORD *)v8 + 2);
          *((_QWORD *)v8 + 2) = 0i64;
          _disable();
          KiEndThreadCycleAccumulation(v8, (_KTHREAD *)v9, 0i64);
          _enable();
          *((_QWORD *)v8 + 1) = v10;
          if( *(_BYTE *)(v10 + 388) == 1 )
          {
            v11 = (unsigned int)(*(_DWORD *)(v10 + 132) - *(_DWORD *)(v10 + 436));
            *(_DWORD *)(v10 + 132) = v11 + KUSER_SHARED_DATA.TickCount.LowPart;
          }
          *(_BYTE *)(v10 + 388) = 2;
          *(_BYTE *)(v9 + 643) = 32;
          *(_BYTE *)(v9 + 390) = v7;
          KiQueueReadyThread((__int64)v8, v9, v11);
          v12 = !KiSwapContext((PKTHREAD)v9, (PKTHREAD)v10);
        }
        else
        {
          v12 = (*(_DWORD *)(v9 + 116) & 0x40) == 0;
        }
        if( !v12 )
        {
          __writecr8(1ui64);
          *(_DWORD *)(v9 + 116) &= ~0x40u;
          KiDeliverApc(0, 0i64, 0i64);
        }
        v3 = v7;
LABEL_33:
        __writecr8(v3);
        return v3;
      }
      if( *((_QWORD *)v8 + 2) )
      {
        LOBYTE(v3) = *((_BYTE *)v8 + 12586);
        if( !(_BYTE)v3 )
          LODWORD(v3) = KiRequestSoftwareInterrupt(v8, 2);
      }
    }
  }
  else
  {
    LODWORD(v3) = KiVelocityFlags;
    v13 = *((_QWORD *)Thread + 121);
    if( (KiVelocityFlags & 0x10) != 0 && v13 )
    {
      v14 = KeGetCurrentIrql();
      __writecr8(2ui64);
      v15 = v38;
      _disable();
      v16 = *(unsigned int *)(v13 + 4);
      v17 = (v15 & 0x200) != 0;
      if( (_DWORD)v16 != (unsigned __int8)*((_DWORD *)Thread + 128) && (int)v16 < 5 )
      {
        KeSetThreadBamQosLevel((INT64)Thread, v16);
        KeCheckAndApplyBamQos((INT64)KeGetCurrentPrcb(), (INT64)Thread, v18, v19);
      }
      if( v17 )
        _enable();
      v3 = v14;
      goto LABEL_33;
    }
  }
  return v3;
}

Referenced by:

VmSetThreadSchedulerAssist