001/*
002 *  This file is part of the Jikes RVM project (http://jikesrvm.org).
003 *
004 *  This file is licensed to You under the Eclipse Public License (EPL);
005 *  You may not use this file except in compliance with the License. You
006 *  may obtain a copy of the License at
007 *
008 *      http://www.opensource.org/licenses/eclipse-1.0.php
009 *
010 *  See the COPYRIGHT.txt file distributed with this work for information
011 *  regarding copyright ownership.
012 */
013
014package org.jikesrvm.tuningfork;
015
016import org.jikesrvm.VM;
017import org.jikesrvm.scheduler.SpinLock;
018import org.vmmagic.pragma.Uninterruptible;
019import org.vmmagic.pragma.Untraced;
020
021import com.ibm.tuningfork.tracegen.chunk.EventChunk;
022
023/**
024 * A Queue of EventChunks.
025 * <p>
026 * Unlike ChunkQueue, this queue is designed to be used in uninterruptible contexts.
027 * It assumes that all EventChunks are NonMoving and externally kept alive for the GC;
028 * therefore it can mark its head and tail fields as Untraced.
029 * <p>
030 * TODO: consider implementing a non-blocking queue instead of using spin locks.
031 */
032@Uninterruptible
033public class EventChunkQueue {
034
035  @Untraced
036  private EventChunk head = null;
037  @Untraced
038  private EventChunk tail = null;
039  private final SpinLock lock = new SpinLock();
040
041
042  public void enqueue(EventChunk c) {
043    if (VM.VerifyAssertions) VM._assert(c.next == null);
044    lock.lock("EventChunkQueue::enqueue");
045    if (tail == null) {
046      head = c;
047      tail = c;
048    } else {
049      tail.next = c;
050      tail = c;
051    }
052    lock.unlock();
053  }
054
055  public EventChunk dequeue() {
056    lock.lock("EventChunkQueue::dequeue");
057    EventChunk result = head;
058    if (head != null) {
059      head = head.next;
060      result.next = null;
061      if (head == null) {
062        if (VM.VerifyAssertions) VM._assert(tail == result);
063        tail = null;
064      }
065    }
066    lock.unlock();
067    return result;
068  }
069
070  public boolean isEmpty() {
071    return head == null;
072  }
073
074}