ExpUnblockPushLock

VOID __stdcall ExpUnblockPushLock(_EX_PUSH_LOCK *PushLock, VOID *WaitBlock, UINT8 AlreadyWaited){
  char v3; 
  __int64 v4; 
  unsigned __int8 CurrentIrql; 
  __int64 v9; 

  v3 = 0;
  v4 = _InterlockedExchange64(&PushLock->_bf_0, 0i64);
  CurrentIrql = 2;
  if( v4 )
  {
    if( *(_QWORD *)(v4 + 24) )
    {
      CurrentIrql = KeGetCurrentIrql();
      __writecr8(2ui64);
    }
    do
    {
      v9 = *(_QWORD *)(v4 + 24);
      if( (VOID *)v4 == WaitBlock )
        v3 = 1;
      if( !_interlockedbittestandreset((volatile signed __int32 *)(v4 + 52), 1u) )
        KeSetEvent((PRKEVENT)v4, 1, 0);
      v4 = v9;
    }
    while( v9 );
    if( CurrentIrql != 2 )
      __writecr8(CurrentIrql);
  }
  if( WaitBlock && !v3 )
  {
    if( AlreadyWaited )
      KeWaitForSingleObject((UINT64)WaitBlock, 28, 0, 0, 0i64);
    else
      ExTimedWaitForUnblockPushLock(PushLock, (_EX_PUSH_LOCK_WAIT_BLOCK *)WaitBlock, 0i64);
  }
}

Referenced by:

CmpDecrementAppHiveUnloadCount
CmpTryToRundownHive
ExBlockOnAddressPushLock
ExSweepSingleHandle
ExTimedWaitForUnblockPushLock
ExUnblockOnAddressPushLockEx
ExUnblockPushLockEx
ExfUnblockPushLock
IopCheckHandleForRevocation
MiUnlockImageSection
PspHandleTableWalker
RtlReleaseSwapReference
RtlpCSparseBitmapPageDecommit