KeSetThreadSchedulerAssist

NTSTATUS __stdcall KeSetThreadSchedulerAssist(_ETHREAD *Thread){
  void *v1; 
  int v2; 
  unsigned __int64 v3; 
  int v5; 
  int v6; 
  unsigned __int8 v7; 
  struct _KPRCB *v8; 
  _ETHREAD *v9; 
  INT64 v10; 
  _ETHREAD *v11; 
  char v12; 
  bool v13; 
  unsigned int *SchedulerAssist; 
  unsigned __int8 v15; 
  __int16 v16; 
  INT64 v17; 
  bool v18; 
  __int64 v19; 
  INT64 v20; 
  unsigned __int8 CurrentIrql; 
  void *SchedulerAssistPriorityFloor_low; 
  unsigned __int8 v23; 
  unsigned __int8 v24; 
  char v25; 
  unsigned int v26; 
  char Priority; 
  char v28; 
  _KPRCB *v29; 
  struct _KPRCB *CurrentPrcb; 
  _ETHREAD *CurrentThread; 
  INT64 v32; 
  _ETHREAD *NextThread; 
  char v34; 
  INT64 v36; 
  INT64 v37; 
  UINT64 v38; 
  _SINGLE_LIST_ENTRY ReadyList; 
  _KSHARED_READY_QUEUE *ControlReadyQueue; 
  _KPRCB *ControlPrcb; 
  int v42; 
  void *retaddr; 
  UINT64 SpinCount; 
  UINT64 v45; 

  v3 = (unsigned __int64)&retaddr;
  ControlPrcb = 0i64;
  ReadyList.Next = 0i64;
  ControlReadyQueue = 0i64;
  if( !v2 )
  {
    if( v1 )
    {
      Thread->Tcb.SchedulerAssist = v1;
      _interlockedbittestandset((volatile signed __int32 *)&Thread->Tcb.116 + 1, 0x16u);
      if( (KiVelocityFlags & 0x400) != 0 )
        _interlockedbittestandset((volatile signed __int32 *)Thread, 0x16u);
      Thread->Tcb.SchedulerAssistPriorityFloor = 32;
      return v3;
    }
    CurrentIrql = KeGetCurrentIrql();
    __writecr8(2ui64);
    LODWORD(v38) = 0;
    while( _interlockedbittestandset64((volatile signed __int32 *)&Thread->Tcb.ThreadLock, 0i64) )
    {
      do
        KeYieldProcessorEx(&v38);
      while( Thread->Tcb.ThreadLock );
    }
    if( Thread->Tcb.SchedulerAssistPriorityFloor != 32 )
    {
      SchedulerAssistPriorityFloor_low = (void *)SLOBYTE(Thread->Tcb.SchedulerAssistPriorityFloor);
      v23 = Thread->Tcb.PriorityFloorCounts[(_QWORD)SchedulerAssistPriorityFloor_low];
      if( !v23 )
        KeBugCheckEx(0x157u, Thread, SchedulerAssistPriorityFloor_low, (PVOID)2, 0i64);
      v24 = v23 - 1;
      Thread->Tcb.PriorityFloorCounts[(_QWORD)SchedulerAssistPriorityFloor_low] = v24;
      if( !v24 )
      {
        v25 = (char)SchedulerAssistPriorityFloor_low;
        v26 = Thread->Tcb.PriorityFloorSummary ^ (1 << (char)SchedulerAssistPriorityFloor_low);
        Thread->Tcb.PriorityFloorSummary = v26;
        if( v26 < 1 << v25 )
        {
          Priority = Thread->Tcb.Priority;
          if( Priority < 16 )
          {
            v28 = Thread->Tcb.BasePriority
                + (Thread->Tcb.PriorityDecrement & 0xF)
                + ((unsigned __int8)Thread->Tcb.PriorityDecrement >> 4);
            if( v28 < Priority )
              KiSetPriorityThread(&Thread->Tcb, &ReadyList, (unsigned int)v28);
          }
        }
      }
      Thread->Tcb.SchedulerAssistPriorityFloor = 32;
    }
    KiAcquireThreadStateLock(Thread, &ControlPrcb, &ControlReadyQueue);
    _interlockedbittestandreset((volatile signed __int32 *)&Thread->Tcb.116 + 1, 0x16u);
    Thread->Tcb.SchedulerAssist = 0i64;
    if( (KiVelocityFlags & 0x400) != 0 )
      _interlockedbittestandreset((volatile signed __int32 *)Thread, 0x16u);
    KiReleaseThreadStateLock(v29, (_KSHARED_READY_QUEUE *)ControlPrcb);
    KiReleaseThreadLockSafe((INT64)Thread);
    CurrentPrcb = KeGetCurrentPrcb();
    KiReadyDeferredReadyList(CurrentPrcb, &ReadyList);
    if( CurrentIrql >= 2u )
    {
      if( CurrentPrcb->NextThread && !CurrentPrcb->DpcRoutineActive )
        KiRequestSoftwareInterrupt(CurrentPrcb, 2);
      goto LABEL_69;
    }
    CurrentThread = CurrentPrcb->CurrentThread;
    if( CurrentPrcb->NextThread )
    {
      KiAbProcessContextSwitch(&CurrentPrcb->CurrentThread->Tcb, 0i64);
      HIDWORD(v38) = 0;
      while( _interlockedbittestandset64((volatile signed __int32 *)&CurrentPrcb->PrcbLock, 0i64) )
      {
        do
          KeYieldProcessorEx((UINT64 *)((char *)&v38 + 4));
        while( CurrentPrcb->PrcbLock );
      }
      NextThread = CurrentPrcb->NextThread;
      CurrentPrcb->NextThread = 0i64;
      _disable();
      KiEndThreadCycleAccumulation((INT64)CurrentPrcb, (INT64)CurrentThread, 0i64, v32, v36, v37, v38);
      _enable();
      CurrentPrcb->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;
      CurrentThread->Tcb.WaitReason = 32;
      CurrentThread->Tcb.WaitIrql = CurrentIrql;
      KiQueueReadyThread(CurrentPrcb, &CurrentThread->Tcb);
      KiSwapContext();
      if( !v34 )
        goto LABEL_63;
    }
    else if( (CurrentThread->Tcb._bf_0 & 0x40) == 0 )
    {
      goto LABEL_63;
    }
    __writecr8(1ui64);
    CurrentThread->Tcb._bf_0 &= ~0x40u;
    KiDeliverApc(0, 0i64, 0i64);
LABEL_63:
    __writecr8(CurrentIrql);
LABEL_69:
    LODWORD(v3) = KeSetPriorityThread(&Thread->Tcb, Thread->Tcb.BasePriority);
    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->Tcb.ThreadLock, 0i64) )
      {
        do
          KeYieldProcessorEx(&SpinCount);
        while( Thread->Tcb.ThreadLock );
      }
      KiUpdateVpBackingThreadPriorityFromTopLevel(Thread);
      KiReleaseThreadLockSafe((INT64)Thread);
      v8 = KeGetCurrentPrcb();
      KiReadyDeferredReadyList(v8, &ReadyList);
      if( v7 < 2u )
      {
        v9 = v8->CurrentThread;
        if( v8->NextThread )
        {
          KiAbProcessContextSwitch(&v8->CurrentThread->Tcb, 0i64);
          LODWORD(v45) = 0;
          while( _interlockedbittestandset64((volatile signed __int32 *)&v8->PrcbLock, 0i64) )
          {
            do
              KeYieldProcessorEx(&v45);
            while( v8->PrcbLock );
          }
          v11 = v8->NextThread;
          v8->NextThread = 0i64;
          _disable();
          KiEndThreadCycleAccumulation((INT64)v8, (INT64)v9, 0i64, v10, v36, v37, v38);
          _enable();
          v8->CurrentThread = v11;
          if( v11->Tcb.WaitBlockFill6[68] == 1 )
            v11->Tcb.ReadyTime = v11->Tcb.ReadyTime
                               - v11->Tcb.WaitBlock[2].SpareLong
                               + KUSER_SHARED_DATA.TickCount.LowPart;
          v11->Tcb.WaitBlockFill6[68] = 2;
          v9->Tcb.WaitReason = 32;
          v9->Tcb.WaitIrql = v7;
          KiQueueReadyThread(v8, &v9->Tcb);
          KiSwapContext();
          v13 = v12 == 0;
        }
        else
        {
          v13 = (v9->Tcb._bf_0 & 0x40) == 0;
        }
        if( !v13 )
        {
          __writecr8(1ui64);
          v9->Tcb._bf_0 &= ~0x40u;
          KiDeliverApc(0, 0i64, 0i64);
        }
        v3 = v7;
LABEL_33:
        __writecr8(v3);
        return v3;
      }
      if( v8->NextThread )
      {
        LOBYTE(v3) = v8->DpcRoutineActive;
        if( !(_BYTE)v3 )
          KiRequestSoftwareInterrupt(v8, 2);
      }
    }
  }
  else
  {
    LODWORD(v3) = KiVelocityFlags;
    SchedulerAssist = (unsigned int *)Thread->Tcb.SchedulerAssist;
    if( (KiVelocityFlags & 0x10) != 0 && SchedulerAssist )
    {
      v15 = KeGetCurrentIrql();
      __writecr8(2ui64);
      v16 = v42;
      _disable();
      v17 = SchedulerAssist[1];
      v18 = (v16 & 0x200) != 0;
      if( (_DWORD)v17 != (unsigned __int8)Thread->Tcb.ThreadFlags2 && (int)v17 < 5 )
      {
        KeSetThreadBamQosLevel((INT64)Thread, v17);
        KeCheckAndApplyBamQos((INT64)KeGetCurrentPrcb(), (__int64)Thread, v19, v20);
      }
      if( v18 )
        _enable();
      v3 = v15;
      goto LABEL_33;
    }
  }
  return v3;
}

Referenced by:

VmSetThreadSchedulerAssist