KiTryUnwaitThread
UINT8 __stdcall KiTryUnwaitThread(_KPRCB *Prcb, _KWAIT_BLOCK *WaitBlock, INT64 WaitStatus, _KTHREAD **WakeThread){
struct _KPRCB *CurrentPrcb;
_ETHREAD *Thread;
UINT8 v7;
_KWAIT_STATUS_REGISTER v11;
int v12;
_DISPATCHER_HEADER *volatile Queue;
void *SystemArgument1;
volatile unsigned __int8 State;
__int64 v16;
UINT8 result;
struct _KPRCB *v18;
__int64 v19;
_ETHREAD **v20;
_KMUTANT *Object;
_DWORD *SchedulerAssist;
_DWORD *v23;
__int64 v24[7];
UINT64 SpinCount;
CurrentPrcb = KeGetCurrentPrcb();
Thread = WaitBlock->Thread;
v7 = 0;
LODWORD(SpinCount) = 0;
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];
}
if( Thread->Tcb.WaitBlockFill6[68] == 5 )
{
v11.Flags = (unsigned __int8)Thread->Tcb.WaitRegister;
v12 = v11.Flags & 7;
if( v12 == 1 || v12 == 4 )
{
Queue = Thread->Tcb.Queue;
if( Queue )
{
if( (*(_BYTE *)Queue & 0x7F) == 21 )
{
Thread->Tcb.QueuePriority = (unsigned __int8)Thread->Tcb.QueuePriority;
_InterlockedIncrement((volatile signed __int32 *)Queue + (unsigned int)Thread->Tcb.QueuePriority + 134);
}
else
{
_InterlockedIncrement((volatile signed __int32 *)Queue + 10);
}
}
SystemArgument1 = Thread->Tcb.SchedulerApc.SystemArgument1;
if( SystemArgument1 )
{
v18 = KeGetCurrentPrcb();
LODWORD(v24[0]) = 0;
while( _interlockedbittestandset64((volatile signed __int32 *)SystemArgument1 + 7940, 0i64) )
{
do
KeYieldProcessorEx((UINT64 *)v24);
while( *((_QWORD *)SystemArgument1 + 3970) );
v23 = v18->SchedulerAssist;
if( v23 && v18->NestingLevel <= 1u )
++v23[6];
}
if( Thread->Tcb.SchedulerApc.SystemArgument1 )
{
v19 = *(_QWORD *)Thread->Tcb.gapD8;
v20 = *(_ETHREAD ***)&Thread->Tcb.gapD8[8];
if( *(_ETHREAD **)(v19 + 8) != (_ETHREAD *)Thread->Tcb.gapD8 || *v20 != (_ETHREAD *)Thread->Tcb.gapD8 )
__fastfail(3u);
*v20 = (_ETHREAD *)v19;
*(_QWORD *)(v19 + 8) = v20;
Thread->Tcb.SchedulerApc.SystemArgument1 = 0i64;
}
_InterlockedAnd64((volatile signed __int64 *)SystemArgument1 + 3970, 0i64);
}
State = Thread->Tcb.State;
if( State == 1 )
{
Thread->Tcb._bf_0 |= 2u;
}
else if( State == 5 )
{
v16 = KUSER_SHARED_DATA.TickCount.LowPart - Thread->Tcb.WaitBlock[2].SpareLong;
if( Thread->Tcb.WaitMode )
Thread->Tcb.UserWaitTime += v16;
else
Thread->Tcb.KernelWaitTime += v16;
}
Thread->Tcb.WaitBlockFill6[68] = 7;
v7 = 1;
*(_QWORD *)Thread->Tcb.gapD8 = Prcb->DeferredReadyListHead.Next;
Prcb->DeferredReadyListHead.Next = (_SINGLE_LIST_ENTRY *)Thread->Tcb.gapD8;
Thread->Tcb.WaitStatus = WaitStatus;
Thread->Tcb.AbWaitObject = 0i64;
}
else
{
if( (Thread->Tcb.WaitRegister.Flags & 7) == 0 )
{
Thread->Tcb.WaitRegister.Flags = v11.Flags & 0xF8 | 2;
Thread->Tcb.WaitStatus = WaitStatus;
Thread->Tcb.AbWaitObject = 0i64;
WaitBlock->BlockState = 0;
v7 = 1;
LABEL_13:
if( WakeThread )
{
*WakeThread = &Thread->Tcb;
Object = (_KMUTANT *)WaitBlock->Object;
if( (Object->gap0[0] & 0x7F) == 2 )
KiWaitSatisfyMutant(Object, &Thread->Tcb, Prcb);
}
goto LABEL_14;
}
if( v12 == 5 )
{
Thread->Tcb.WaitRegister.Flags = v11.Flags & 0xF8 | 6;
goto LABEL_14;
}
if( v12 == 3 )
WaitBlock->BlockState = 2;
}
if( !v7 )
goto LABEL_14;
goto LABEL_13;
}
LABEL_14:
Thread->Tcb.ThreadLock = 0i64;
result = v7;
++WaitBlock->BlockState;
return result;
}Referenced by:
CcUnpinFileDataEx
ExpReleaseResourceExclusiveForThreadLite
ExpReleaseResourceSharedForThreadLite
KeDeleteMutant
KePulseEvent
KeReleaseMutant
KeReleaseSemaphore
KeReleaseSemaphoreEx
KeRundownQueueCommon
KeSetEvent
KeSetEventBoostPriorityEx
KeSetProcess
KeSignalGate
KeTerminateThread
KeTimeOutQueueWaiters
KeWakeWaitChain
KiExpireTimer2
KiResumeThread
KiRundownMutants
KiTimerWaitTest
NtWaitForWorkViaWorkerFactory