/*
 * (C) Copyright IBM Corp 2001,2002
 */
package s3.core.services.memory.JMTk;

import ovm.core.services.memory.VM_Address;
import s3.core.services.memory.vmInterface.Constants;

/**
 * Each instance of this class is a doubly-linked list, in which
 * each item or node is a piece of memory.  The first two words of each node
 * contains the forward and backward links.  The third word contains
 * the treadmill.  The remaining portion is the payload.
 *  
 * The treadmill object itself must not be moved.
 *
 * Access to the instances may be synchronized depending on the constructor argument.
 *
 * @author Perry Cheng
 * @version $Revision: 1.3 $
 * @date $Date: 2003/12/24 02:17:23 $
 */
final class Treadmill
  implements Constants, VM_Uninterruptible {
  public final static String Id = "$Id: Treadmill.java,v 1.3 2003/12/24 02:17:23 jv Exp $"; 

  /****************************************************************************
   *
   * Class variables
   */

  /****************************************************************************
   *
   * Instance variables
   */
  private DoublyLinkedList fromSpace;
  private DoublyLinkedList toSpace;

  /****************************************************************************
   *
   * Instance Methods
   */

  /**
   * Constructor
   */
  Treadmill (int granularity, boolean shared) {
    fromSpace = new DoublyLinkedList (granularity, shared, this); 
    toSpace = new DoublyLinkedList (granularity, shared, this); 
  }

  static public final Treadmill getTreadmill (VM_Address node) {
    return (Treadmill) DoublyLinkedList.getOwner(node);
  }

  static public final int headerSize() throws VM_PragmaInline {
    return DoublyLinkedList.headerSize();
  }

  static public final VM_Address nodeToPayload(VM_Address node) throws VM_PragmaInline {
    return DoublyLinkedList.nodeToPayload(node);
  }

  static public final VM_Address payloadToNode(VM_Address payload) throws VM_PragmaInline {
    return DoublyLinkedList.payloadToNode(payload);
  }

  public final void addToFromSpace (VM_Address node) throws VM_PragmaInline {
    fromSpace.add(node);
  }

  public final VM_Address popFromSpace () throws VM_PragmaInline {
    return fromSpace.pop();
  }

  public final void copy (VM_Address node) throws VM_PragmaInline { 
    fromSpace.remove(node);
    toSpace.add(node);
  }

  public final boolean toSpaceEmpty () throws VM_PragmaInline {
    return toSpace.isEmpty();
  }

  public final void flip() {  
    DoublyLinkedList tmp = fromSpace;
    fromSpace = toSpace;
    toSpace = tmp;
  }

}
