/*
 *  This file is part of the Jikes RVM project (http://jikesrvm.org).
 *
 *  This file is licensed to You under the Eclipse Public License (EPL);
 *  You may not use this file except in compliance with the License. You
 *  may obtain a copy of the License at
 *
 *      http://www.opensource.org/licenses/eclipse-1.0.php
 *
 *  See the COPYRIGHT.txt file distributed with this work for information
 *  regarding copyright ownership.
 */
package org.mmtk.utility.heap;

import org.mmtk.utility.alloc.EmbeddedMetaData;
import org.mmtk.utility.options.Options;
import org.mmtk.policy.Space;
import org.mmtk.utility.Conversions;
import org.mmtk.utility.Constants;

import org.mmtk.vm.VM;

import org.vmmagic.pragma.*;
import org.vmmagic.unboxed.*;

/**
 * This class manages the allocation of pages for a space.  When a
 * page is requested by the space both a page budget and the use of
 * virtual address space are checked.  If the request for space can't
 * be satisfied (for either reason) a GC may be triggered.<p>
 */
@Uninterruptible
public final class MonotonePageResource extends PageResource
  implements Constants {

  /****************************************************************************
   *
   * Instance variables
   */
  private Address cursor;
  private Address sentinel;
  private final int metaDataPagesPerRegion;
  private Address currentChunk = Address.zero();

  /**
   * Constructor
   *
   * Contiguous monotone resource. The address range is pre-defined at
   * initialization time and is immutable.
   *
   * @param pageBudget The budget of pages available to this memory
   * manager before it must poll the collector.
   * @param space The space to which this resource is attached
   * @param start The start of the address range allocated to this resource
   * @param bytes The size of the address rage allocated to this resource
   * @param metaDataPagesPerRegion The number of pages of meta data
   * that are embedded in each region.
   */
  public MonotonePageResource(int pageBudget, Space space, Address start,
      Extent bytes, int metaDataPagesPerRegion) {
    super(pageBudget, space, start);
    this.cursor = start;
    this.sentinel = start.plus(bytes);
    this.metaDataPagesPerRegion = metaDataPagesPerRegion;
  }

  /**
   * Constructor
   *
   * Discontiguous monotone resource. The address range is <i>not</i>
   * pre-defined at initialization time and is dynamically defined to
   * be some set of pages, according to demand and availability.
   *
   * CURRENTLY UNIMPLEMENTED
   *
   * @param pageBudget The budget of pages available to this memory
   * manager before it must poll the collector.
   * @param space The space to which this resource is attached
   * @param metaDataPagesPerRegion The number of pages of meta data
   * that are embedded in each region.
   */
  public MonotonePageResource(int pageBudget, Space space, int metaDataPagesPerRegion) {
    super(pageBudget, space);
    /* unimplemented */
    this.start = Address.zero();
    this.cursor = Address.zero();
    this.sentinel = Address.zero();
    this.metaDataPagesPerRegion = metaDataPagesPerRegion;
  }

  /**
   * Return the number of available physical pages for this resource.
   * This includes all pages currently unused by this resource's page
   * cursor. If the resource is using discontiguous space it also includes
   * currently unassigned discontiguous space.<p>
   *
   * Note: This just considers physical pages (ie virtual memory pages
   * allocated for use by this resource). This calculation is orthogonal
   * to and does not consider any restrictions on the number of pages
   * this resource may actually use at any time (ie the number of
   * committed and reserved pages).<p>
   *
   * Note: The calculation is made on the assumption that all space that
   * could be assigned to this resource would be assigned to this resource
   * (ie the unused discontiguous space could just as likely be assigned
   * to another competing resource).
   *
   * @return The number of available physical pages for this resource.
   */
  @Override
  public int getAvailablePhysicalPages() {
    int rtn = Conversions.bytesToPages(sentinel.diff(cursor));
    if (!contiguous)
      rtn += Map.getAvailableDiscontiguousChunks()*Space.PAGES_IN_CHUNK;
    return rtn;
  }

  /**
   * Allocate <code>pages</code> pages from this resource.  Simply
   * bump the cursor, and fail if we hit the sentinel.<p>
   *
   * If the request can be satisfied, then ensure the pages are
   * mmpapped and zeroed before returning the address of the start of
   * the region.  If the request cannot be satisfied, return zero.
   *
   * @param requestPages The number of pages to be allocated.
   * @return The start of the first page if successful, zero on
   * failure.
   */
  @Inline
  protected Address allocPages(int requestPages) {
    int pages = requestPages;
    boolean newChunk = false;
    lock();
    Address rtn = cursor;
    if (Space.chunkAlign(rtn, true).NE(currentChunk)) {
      newChunk = true;
      currentChunk = Space.chunkAlign(rtn, true);
    }

    if (metaDataPagesPerRegion != 0) {
      /* adjust allocation for metadata */
      Address regionStart = getRegionStart(cursor.plus(Conversions.pagesToBytes(pages)));
      Offset regionDelta = regionStart.diff(cursor);
      if (regionDelta.sGE(Offset.zero())) {
        /* start new region, so adjust pages and return address accordingly */
        pages += Conversions.bytesToPages(regionDelta) + metaDataPagesPerRegion;
        rtn = regionStart.plus(Conversions.pagesToBytes(metaDataPagesPerRegion));
      }
    }
    Extent bytes = Conversions.pagesToBytes(pages);
    Address tmp = cursor.plus(bytes);

    if (!contiguous && tmp.GT(sentinel)) {
      /* we're out of virtual memory within our discontiguous region, so ask for more */
      int requiredChunks = Space.requiredChunks(pages);
      start = space.growDiscontiguousSpace(requiredChunks);
      cursor = start;
      sentinel = cursor.plus(start.isZero() ? 0 : requiredChunks<<Space.LOG_BYTES_IN_CHUNK);
      rtn = cursor;
      tmp = cursor.plus(bytes);
      newChunk = true;
    }
    if (VM.VERIFY_ASSERTIONS)
      VM.assertions._assert(rtn.GE(cursor) && rtn.LT(cursor.plus(bytes)));
    if (tmp.GT(sentinel)) {
      unlock();
      return Address.zero();
    } else {
      Address old = cursor;
      cursor = tmp;
      commitPages(requestPages, pages);
      space.growSpace(old, bytes, newChunk);
      unlock();
      Mmapper.ensureMapped(old, pages);
      VM.memory.zero(old, bytes);
      VM.events.tracePageAcquired(space, rtn, pages);
      return rtn;
    }
  }

  /**
   * Adjust a page request to include metadata requirements, if any.<p>
   *
   * In this case we simply report the expected page cost. We can't use
   * worst case here because we would exhaust our budget every time.
   *
   * @param pages The size of the pending allocation in pages
   * @return The number of required pages, inclusive of any metadata
   */
  public int adjustForMetaData(int pages) {
    return (metaDataPagesPerRegion * pages) / EmbeddedMetaData.PAGES_IN_REGION;
   }

  /**
   * Adjust a page request to include metadata requirements, if any.<p>
   *
   * Note that there could be a race here, with multiple threads each
   * adjusting their request on account of the same single metadata
   * region.  This should not be harmful, as the failing requests will
   * just retry, and if multiple requests succeed, only one of them
   * will actually have the metadata accounted against it, the others
   * will simply have more space than they originally requested.
   *
   * @param pages The size of the pending allocation in pages
   * @param begin The start address of the region assigned to this pending
   * request
   * @return The number of required pages, inclusive of any metadata
   */
  public int adjustForMetaData(int pages, Address begin) {
    if (getRegionStart(begin).plus(metaDataPagesPerRegion<<LOG_BYTES_IN_PAGE).EQ(begin))
      pages += metaDataPagesPerRegion;
    return pages;
   }

  private static Address getRegionStart(Address addr) {
    return addr.toWord().and(Word.fromIntSignExtend(EmbeddedMetaData.BYTES_IN_REGION - 1).not()).toAddress();
  }

  /**
   * Reset this page resource, freeing all pages and resetting
   * reserved and committed pages appropriately.
   */
  @Inline
  public void reset() {
    lock();
    reserved = 0;
    committed = 0;
    releasePages();
    unlock();
  }

  /**
   * Notify that several pages are no longer in use.
   *
   * @param pages The number of pages
   */
  public void unusePages(int pages) {
    lock();
    reserved -= pages;
    committed -= pages;
    unlock();
  }

  /**
   * Notify that previously unused pages are in use again.
   *
   * @param pages The number of pages
   */
  public void reusePages(int pages) {
    lock();
    reserved += pages;
    committed += pages;
    unlock();
  }

  /**
   * Release all pages associated with this page resource, optionally
   * zeroing on release and optionally memory protecting on release.
   */
  @Inline
  private void releasePages() {
    Address first = start;
    do {
      Extent bytes = cursor.diff(start).toWord().toExtent();
      releasePages(start, bytes);
      cursor = start;
    } while (!contiguous && moveToNextChunk());
    if (!contiguous) {
      sentinel = Address.zero();
      Map.freeAllChunks(first);
    }
  }

  /**
   * Adjust the start and cursor fields to point to the next chunk
   * in the linked list of chunks tied down by this page resource.
   *
   * @return True if we moved to the next chunk; false if we hit the
   * end of the linked list.
   */
  private boolean moveToNextChunk() {
    start = Map.getNextContiguousRegion(start);
    if (start.isZero())
      return false;
    else {
      cursor = start.plus(Map.getContiguousRegionSize(start));
      return true;
    }
  }

  /**
   * Release a range of pages associated with this page resource, optionally
   * zeroing on release and optionally memory protecting on release.
   */
  @Inline
  private void releasePages(Address first, Extent bytes) {
    int pages = Conversions.bytesToPages(bytes);
    if (VM.VERIFY_ASSERTIONS)
      VM.assertions._assert(bytes.EQ(Conversions.pagesToBytes(pages)));
    if (ZERO_ON_RELEASE)
      VM.memory.zero(first, bytes);
    if (Options.protectOnRelease.getValue())
      Mmapper.protect(first, pages);
    VM.events.tracePageReleased(space, first, pages);
  }
}
