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