KeSetBasePriorityThread
NTSTATUS __stdcall KeSetBasePriorityThread(_ETHREAD *Thread, INT64 Increment){
_EPROCESS *Process;
int v3;
unsigned __int8 CurrentIrql;
struct _KPRCB *CurrentPrcb;
_ETHREAD *CurrentThread;
int BasePriority;
NTSTATUS v9;
char v10;
int v11;
int v12;
int v13;
_KPRCB *v14;
char PriorityDecrement;
_KPRIQUEUE *Queue;
_ETHREAD *v17;
_SINGLE_LIST_ENTRY *p_IoSelfBoostsEntry;
_SINGLE_LIST_ENTRY *p_AbSelfIoBoostsList;
unsigned __int64 CycleTime;
unsigned __int64 v22;
INT64 v23;
struct _KPRCB *v24;
_ETHREAD *NextThread;
char v26;
_DWORD *SchedulerAssist;
_DWORD *v28;
_BYTE *DynamicPriority;
INT64 v30;
_SINGLE_LIST_ENTRY ReadyList;
unsigned int Priority;
UINT64 SpinCount;
UINT64 v34;
Process = Thread->Tcb.Process;
v3 = Increment;
if( Process != (_EPROCESS *)&KiInitialProcess )
{
ReadyList.Next = 0i64;
CurrentIrql = KeGetCurrentIrql();
__writecr8(2ui64);
CurrentPrcb = KeGetCurrentPrcb();
LODWORD(SpinCount) = 0;
CurrentThread = CurrentPrcb->CurrentThread;
while( _interlockedbittestandset64((volatile signed __int32 *)&Thread->Tcb.ThreadLock, 0i64) )
{
do
KeYieldProcessorEx(&SpinCount);
while( Thread->Tcb.ThreadLock );
SchedulerAssist = CurrentPrcb->SchedulerAssist;
if( SchedulerAssist && CurrentPrcb->NestingLevel <= 1u )
++SchedulerAssist[6];
}
BasePriority = Thread->Tcb.BasePriority;
v9 = BasePriority - Process->Pcb.BasePriority;
if( Thread->Tcb.Saturation )
v9 = 16 * Thread->Tcb.Saturation;
Thread->Tcb.Saturation = 0;
v10 = 0;
if( (int)abs32(v3) >= 16 )
{
v10 = 1;
if( v3 <= 0 )
v10 = -1;
Thread->Tcb.Saturation = v10;
}
v11 = Process->Pcb.BasePriority;
v12 = v11 + v3;
if( (char)v11 >= 16 )
{
if( v12 >= 16 )
{
if( v12 > 31 )
v12 = 31;
}
else
{
v12 = 16;
}
Priority = v12;
}
else
{
if( v12 >= 16 )
{
v12 = 15;
}
else if( v12 <= 0 )
{
v12 = 1;
}
if( v10 )
{
Priority = v12;
}
else
{
v13 = v12 - BasePriority + KiComputeNewPriority(&Thread->Tcb, 0);
Priority = v13;
if( v13 >= 16 )
{
Priority = 15;
}
else if( v13 <= 0 )
{
Priority = 1;
}
}
}
v14 = KeGetCurrentPrcb();
if( (char)v12 < Thread->Tcb.BasePriority )
{
if( Thread->Tcb.AbOwnedEntryCount )
{
p_IoSelfBoostsEntry = &Thread->Tcb.IoSelfBoostsEntry;
if( Thread->Tcb.IoSelfBoostsEntry.Next == (_SINGLE_LIST_ENTRY *)1 )
{
p_AbSelfIoBoostsList = &v14->AbSelfIoBoostsList;
if( v14 != (_KPRCB *)-34672i64 )
{
p_IoSelfBoostsEntry->Next = p_AbSelfIoBoostsList->Next;
p_AbSelfIoBoostsList->Next = p_IoSelfBoostsEntry;
_InterlockedIncrement16(&Thread->Tcb.KeReferenceCount);
KiAbQueueAutoBoostDpc(v14);
}
}
}
}
PriorityDecrement = Thread->Tcb.PriorityDecrement;
Thread->Tcb.BasePriority = v12;
if( PriorityDecrement )
{
if( (PriorityDecrement & 0xF) != 0 )
Thread->Tcb.ForegroundLossTime = KUSER_SHARED_DATA.TickCount.LowPart;
Thread->Tcb.PriorityDecrement = 0;
}
if( Priority != Thread->Tcb.Priority )
{
if( Thread != CurrentThread || CurrentPrcb->NestingLevel )
{
CycleTime = Thread->Tcb.CycleTime;
}
else
{
_disable();
CycleTime = KiUpdateTotalCyclesCurrentThread(CurrentPrcb, &Thread->Tcb, 0i64);
_enable();
}
v22 = CycleTime + KiCyclesPerClockQuantum * (unsigned int)Thread->Tcb.SchedulerApc.SpareByte1;
if( (*(&Thread->Tcb.MiscFlags + 1) & 0x20) != 0 )
_interlockedbittestandreset((volatile signed __int32 *)&Thread->Tcb.116 + 1, 5u);
Thread->Tcb.QuantumTarget = v22;
KiSetPriorityThread(&Thread->Tcb, &ReadyList, Priority);
}
Queue = (_KPRIQUEUE *)Thread->Tcb.Queue;
if( Queue && (*(_BYTE *)Queue & 0x7F) == 21 )
KiPriQueueThreadPriorityChanged(Queue, &Thread->Tcb);
else
KiReleaseThreadLockSafe((INT64)Thread);
KiReadyDeferredReadyList(CurrentPrcb, &ReadyList);
if( CurrentIrql >= 2u )
{
if( CurrentPrcb->NextThread && !CurrentPrcb->DpcRoutineActive )
KiRequestSoftwareInterrupt(CurrentPrcb, 2);
return v9;
}
v17 = CurrentPrcb->CurrentThread;
if( CurrentPrcb->NextThread )
{
KiAbProcessContextSwitch(&CurrentPrcb->CurrentThread->Tcb, 0i64);
v24 = KeGetCurrentPrcb();
LODWORD(v34) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)&CurrentPrcb->PrcbLock, 0i64) )
{
do
KeYieldProcessorEx(&v34);
while( CurrentPrcb->PrcbLock );
v28 = v24->SchedulerAssist;
if( v28 && v24->NestingLevel <= 1u )
++v28[6];
}
NextThread = CurrentPrcb->NextThread;
CurrentPrcb->NextThread = 0i64;
_disable();
KiEndThreadCycleAccumulation(
(INT64)CurrentPrcb,
(INT64)v17,
0i64,
v23,
(INT64)DynamicPriority,
v30,
(INT64)ReadyList.Next);
_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;
v17->Tcb.WaitReason = 32;
v17->Tcb.WaitIrql = CurrentIrql;
KiQueueReadyThread(CurrentPrcb, &v17->Tcb);
KiSwapContext();
if( !v26 )
goto LABEL_23;
}
else if( (v17->Tcb._bf_0 & 0x40) == 0 )
{
LABEL_23:
__writecr8(CurrentIrql);
return v9;
}
__writecr8(1ui64);
v17->Tcb._bf_0 &= ~0x40u;
KiDeliverApc(0, 0i64, 0i64);
goto LABEL_23;
}
return 0;
}Referenced by:
EtwpCovSampCaptureContextStart
NtSetInformationThread
PfTLoggingWorker