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 014 package org.jikesrvm.tuningfork; 015 016 import org.jikesrvm.VM; 017 import org.jikesrvm.scheduler.SpinLock; 018 import org.vmmagic.pragma.Uninterruptible; 019 import org.vmmagic.pragma.Untraced; 020 021 import 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 033 public 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 }