MiWaitForFreePagesToZero

NTSTATUS __stdcall MiWaitForFreePagesToZero(_MI_PARTITION *Partition, INT64 *a2, UINT64 a3){
  _MI_NODE_INFORMATION *NodeInformation; 
  _BYTE *v4; 
  _KEVENT *p_Zeroing; 
  unsigned int v6; 
  unsigned int v9; 
  int v11; 
  __int64 v12; 
  unsigned int v13; 
  unsigned __int64 *v14; 
  unsigned __int8 *p_BackgroundZeroingActive; 
  __int64 v16; 
  _KLOCK_QUEUE_HANDLE LockHandle; 
  VOID *Object[3]; 
  _KWAIT_BLOCK WaitBlockArray; 

  NodeInformation = Partition->Core.NodeInformation;
  v4 = Partition->Core.gap68;
  Object[0] = Partition->Core.gap68;
  p_Zeroing = (_KEVENT *)&Partition->Zeroing;
  memset(&LockHandle, 0, sizeof(LockHandle));
  Object[1] = &Partition->Zeroing;
  v6 = a3;
  v9 = a3;
  while( 1 )
  {
    while( 1 )
    {
      if( *a2 )
      {
        MiDereferencePageRunsEx(*a2, 1i64);
        *a2 = 0i64;
      }
      if( !KeWaitForMultipleObjects(2ui64, Object, WaitAny, WrFreePage, 0, 0, 0i64, &WaitBlockArray) )
        return -1;
LABEL_16:
      if( Partition->PageLists.FreePageListHead.Total )
        break;
      KeAcquireInStackQueuedSpinLock(&Partition->PageLists.AvailableEventsLock, &LockHandle);
      if( !Partition->PageLists.FreePageListHead.Total )
      {
        if( KeNumberNodes )
        {
          p_BackgroundZeroingActive = &NodeInformation->BackgroundZeroingActive;
          v16 = (unsigned __int16)KeNumberNodes;
          do
          {
            *p_BackgroundZeroingActive = 0;
            p_BackgroundZeroingActive += 4544;
            --v16;
          }
          while( v16 );
        }
        KeResetEvent(p_Zeroing);
      }
      KeReleaseInStackQueuedSpinLockFromDpcLevel(&LockHandle);
      __writecr8(LockHandle.OldIrql);
    }
    if( !Partition->Zeroing.BackgroundZeroingDisabled && !*(&stru_140C4DB30 + 1082) )
      break;
    KeWaitForSingleObject((UINT64)v4, 8, 0, 0, (INT64)&unk_140010580);
  }
  v11 = *(&stru_140C4DB30 + 1082) + 1;
  if( (unsigned __int16)KeNumberNodes > (unsigned __int16)(*(&stru_140C4DB30 + 2164) + 1) )
  {
    v9 = v6;
    while( 1 )
    {
      v12 = v9;
      if( NodeInformation[v12].FreeCount[1] )
        break;
      v13 = 0;
      v14 = &NodeInformation[v12].FreeLargePages[0].LargePageFreeCount[1];
      do
      {
        if( *v14 )
          break;
        v13 += v11;
        v14 += 134;
      }
      while( v13 < 3 );
      if( v13 != 3 )
        break;
      v9 = (v9 + 1) % (unsigned __int16)KeNumberNodes;
      v11 = 1;
      if( v9 == v6 )
        goto LABEL_16;
    }
  }
  *a2 = (INT64)MiReferencePageRuns((ULONG_PTR *)&Partition->Core.PartitionId, 0i64);
  return v9;
}

Referenced by:

MiZeroPageThread