/*
 * (C) Copyright Department of Computer Science,
 *     Australian National University. 2002
 */
package s3.core.services.memory.JMTk;

import s3.core.services.memory.vmInterface.VM_Interface;
import s3.core.services.memory.vmInterface.Constants;

import ovm.core.services.memory.VM_Address;
/**
 * This supports <i>unsynchronized</i> enqueuing and dequeuing of
 * address pairs
 *
 * @author <a href="http://cs.anu.edu.au/~Steve.Blackburn">Steve Blackburn</a>
 * @version $Revision: 1.2 $
 * @date $Date: 2003/12/04 16:44:06 $
 */ 
public class AddressPairDeque extends LocalDeque implements Constants, VM_Uninterruptible {
  public final static String Id = "$Id: AddressPairDeque.java,v 1.2 2003/12/04 16:44:06 flack Exp $"; 
 
  /****************************************************************************
   *
   * Public instance methods
   */

  /**
   * Constructor
   *
   * @param queue The shared queue to which this queue will append
   * its buffers (when full or flushed) and from which it will aquire new
   * buffers when it has exhausted its own.
   */
  AddressPairDeque(SharedDeque queue) {
    super(queue);
  }
 
  /**
   * Insert an address pair into the address queue.
   *
   * @param addr1 the first address to be inserted into the address queue
   * @param addr2 the second address to be inserted into the address queue
   */
  public final void insert(VM_Address addr1, VM_Address addr2) {
    if (VM_Interface.VerifyAssertions) VM_Interface._assert(!addr1.isNull());
    if (VM_Interface.VerifyAssertions) VM_Interface._assert(!addr2.isNull());
    checkInsert(2);
    uncheckedInsert(addr1);
    uncheckedInsert(addr2);
  }
 
  /**
   * Push an address pair onto the address queue.
   *
   * @param addr1 the first value to be pushed onto the address queue
   * @param addr2 the second value to be pushed onto the address queue
   */
  public final void push(VM_Address addr1, VM_Address addr2) {
    if (VM_Interface.VerifyAssertions) VM_Interface._assert(!addr1.isNull());
    if (VM_Interface.VerifyAssertions) VM_Interface._assert(!addr2.isNull());
    checkPush(2);
    uncheckedPush(addr2);
    uncheckedPush(addr1);
  }

  /**
   * Pop the first address in a pair from the address queue, return
   * zero if the queue is empty.
   *
   * @return The next address in the address queue, or zero if the
   * queue is empty
   */
  public final VM_Address pop1() {
     if (checkPop(2))
      return uncheckedPop();
    else
      return VM_Address.fromInt(0);
  }
  
  /**
   * Pop the second address in a pair from the address queue.
   *
   * @return The next address in the address queue
   */
  public final VM_Address pop2() {
    return uncheckedPop();
  }

  public final boolean isEmpty() {
    return !checkPop(2);
  }
}
