/*
 *  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.deque;

import org.mmtk.plan.Plan;
import org.mmtk.utility.Constants;

import org.mmtk.vm.VM;

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

/**
 * Note this may perform poorly when being used as a FIFO structure with
 * insertHead and pop operations operating on the same buffer.  This
 * only uses the fields inherited from <code>LocalQueue</code>, but adds
 * the ability for entries to be added to the head of the deque and popped
 * from the rear.
 */
@Uninterruptible public class LocalDeque extends LocalQueue
  implements Constants {

  /****************************************************************************
   *
   * Public instance methods
   */

  /**
   * Constructor
   *
   * @param queue The shared deque to which this local deque will append
   * its buffers (when full or flushed).
   */
  LocalDeque(SharedDeque queue) {
    super(queue);
  }

  /**
   * Flush the buffer to the shared deque (this will make any entries
   * in the buffer visible to any other consumer associated with the
   * shared deque).
   */
  @Override
  public final void flushLocal() {
    super.flushLocal();
    if (head.NE(Deque.HEAD_INITIAL_VALUE)) {
      closeAndInsertHead(queue.getArity());
      head = Deque.HEAD_INITIAL_VALUE;
    }
  }

  /****************************************************************************
   *
   * Protected instance methods
   */

  /**
   * Check whether there is space in the buffer for a pending insert.
   * If there is not sufficient space, allocate a new buffer
   * (dispatching the full buffer to the shared deque if not null).
   *
   * @param arity The arity of the values stored in this deque: the
   * buffer must contain enough space for this many words.
   */
  @Inline
  protected final void checkHeadInsert(int arity) {
    if (bufferOffset(head).EQ(bufferSentinel(arity)) ||
        head.EQ(HEAD_INITIAL_VALUE))
      headOverflow(arity);
    else if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(bufferOffset(head).sLE(bufferLastOffset(arity)));
  }

  /**
   * Insert a value at the front of the deque (and buffer).  This is
   * <i>unchecked</i>.  The caller must first call
   * <code>checkHeadInsert()</code> to ensure the buffer can accommodate
   * the insertion.
   *
   * @param value the value to be inserted.
   */
  @Inline
  protected final void uncheckedHeadInsert(Address value) {
      if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(bufferOffset(head).sLT(bufferSentinel(queue.getArity())));
    head.store(value);
    head = head.plus(BYTES_IN_ADDRESS);
    // if (Interface.VerifyAssertions) enqueued++;
  }

  /****************************************************************************
   *
   * Private instance methods and fields
   */

  /**
   * Buffer space has been exhausted, allocate a new buffer and enqueue
   * the existing buffer (if any).
   *
   * @param arity The arity of this buffer (used for sanity test only).
   */
  private void headOverflow(int arity) {
    if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(arity == queue.getArity());
    if (head.NE(Deque.HEAD_INITIAL_VALUE))
      closeAndInsertHead(arity);

    head = queue.alloc();
    Plan.checkForAsyncCollection(); // possible side-effect of alloc()
  }

  /**
   * Close the head buffer and enqueue it at the front of the
   * shared buffer deque.
   *
   *  @param arity The arity of this buffer.
   */
  @Inline
  private void closeAndInsertHead(int arity) {
    queue.enqueue(head, arity, false);
  }

  /**
   * The tail is empty (or null), and the shared deque has no buffers
   * available.  If the head has sufficient entries, consume the head.
   * Otherwise try wait on the shared deque until either all other
   * clients of the reach exhaustion or a buffer becomes
   * available.
   *
   * @param arity The arity of this buffer
   * @return True if the consumer has eaten all of the entries
   */
  @SuppressWarnings("unused")
  private boolean tailStarved(int arity) {
    if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(arity == queue.getArity());
    // entries in tail, so consume tail
    if (!bufferOffset(head).isZero()) {
      tailBufferEnd = head;
      tail = bufferStart(tailBufferEnd);
      head = Deque.HEAD_INITIAL_VALUE;
      return false;
    }

    // Wait for another entry to materialize...
    tailBufferEnd = queue.dequeueAndWait(arity, true);
    tail = bufferStart(tail);

    // return true if a) there is not a tail buffer or b) it is empty
    return (tail.EQ(Deque.TAIL_INITIAL_VALUE) || tail.EQ(tailBufferEnd));
  }
}
