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