MiIncreaseAvailablePages

VOID __stdcall MiIncreaseAvailablePages(_MI_PARTITION *Partition, UINT64 NumberOfPages, UINT8 a3){
  unsigned __int64 v4; 
  signed int v5; 
  unsigned __int64 v6; 
  int v7; 
  unsigned __int64 HighMemoryThreshold; 
  unsigned __int64 LowMemoryThreshold; 
  unsigned int *p_EventSets; 
  unsigned __int64 v11; 
  __int64 v12; 
  _KEVENT *v13; 
  unsigned __int64 v14; 
  _KLOCK_QUEUE_HANDLE LockQueue[2]; 

  memset(LockQueue, 0, 24);
  if( NumberOfPages != 1 )
  {
    v4 = _InterlockedExchangeAdd64((volatile signed __int64 *)&Partition->Vp.AvailablePages, NumberOfPages);
    v5 = 0;
    v6 = NumberOfPages + v4;
    v7 = 0;
    if( v4 < 0xA0 && v6 >= 0xA0 )
      v7 = 2;
    if( v4 < 0x22 && v6 >= 0x22 )
      v7 |= 1u;
    if( v4 < 0x420 && v6 >= 0x420 )
      v7 |= 4u;
    if( v7 )
    {
      LockQueue[0].LockQueue.Lock = &Partition->PageLists.AvailableEventsLock;
      LockQueue[0].LockQueue.Next = 0i64;
      KxAcquireQueuedSpinLock(&LockQueue[0].LockQueue, &Partition->PageLists.AvailableEventsLock);
      p_EventSets = &Partition->PageLists.AvailablePageWaitStates[0].EventSets;
      do
      {
        if( _bittest(&v7, v5) )
        {
          KeSetEvent((PRKEVENT)(p_EventSets - 6), 0, 0);
          ++*p_EventSets;
        }
        ++v5;
        p_EventSets += 8;
      }
      while( v5 < 3 );
      KeReleaseInStackQueuedSpinLockFromDpcLevel(LockQueue);
    }
    HighMemoryThreshold = Partition->PageLists.HighMemoryThreshold;
    if( v4 <= HighMemoryThreshold && v6 > HighMemoryThreshold )
      goto LABEL_34;
    LowMemoryThreshold = Partition->PageLists.LowMemoryThreshold;
    if( v4 <= LowMemoryThreshold && v6 > LowMemoryThreshold )
      goto LABEL_34;
    return;
  }
  v11 = _InterlockedIncrement64((volatile signed __int64 *)&Partition->Vp.AvailablePages);
  if( v11 <= 0x420 )
  {
    switch( v11 )
    {
      case 0xA0ui64:
        v12 = 4968i64;
LABEL_23:
        v13 = (_KEVENT *)((char *)Partition + v12);
        LockQueue[0].LockQueue.Lock = &Partition->PageLists.AvailableEventsLock;
        LockQueue[0].LockQueue.Next = 0i64;
        KxAcquireQueuedSpinLock(&LockQueue[0].LockQueue, &Partition->PageLists.AvailableEventsLock);
        KeSetEvent(v13, 0, 0);
        ++*((_DWORD *)v13 + 6);
        KeReleaseInStackQueuedSpinLockFromDpcLevel(LockQueue);
        break;
      case 0x420ui64:
        v12 = 5000i64;
        goto LABEL_23;
      case 0x22ui64:
        v12 = 4936i64;
        goto LABEL_23;
    }
  }
  v14 = v11 - 1;
  if( v14 == Partition->PageLists.LowMemoryThreshold || v14 == Partition->PageLists.HighMemoryThreshold )
LABEL_34:
    MiUpdateAvailableEvents(Partition);
}

Referenced by:

MiInsertLargePageInNodeList
MiReplenishPageSlist
MiUnlinkNodeLargePageHelper