001 package edu.rice.cs.cunit.record.graph; 002 003 import com.sun.jdi.IncompatibleThreadStateException; 004 import com.sun.jdi.ObjectReference; 005 import com.sun.jdi.ThreadReference; 006 007 import java.util.HashSet; 008 import java.util.Set; 009 010 /** 011 * Information about a lock. 012 * 013 * @author Mathias Ricken 014 */ 015 public class LockInfo { 016 /** 017 * Unique id of this object. 018 */ 019 long _uniqueId; 020 021 /** 022 * Description of this lock. 023 */ 024 String _description; 025 026 /** 027 * Unique id of thread that owns this lock. 028 */ 029 Long _owningThreadId; 030 031 /** 032 * Set of unique ids of the threads that wait for this lock. 033 */ 034 Set<Long> _waitingThreadIds; 035 036 /** 037 * Constructor for lock information. 038 * @param uniqueId lock's unique id 039 * @param description description of the lock 040 * @param owningThreadId unique id of thread owning this lock 041 * @param waitingThreadIds set of unique ids of the threads waiting for this lock 042 */ 043 public LockInfo(Long uniqueId, String description, long owningThreadId, Set<Long> waitingThreadIds) { 044 _uniqueId = uniqueId; 045 _description = description; 046 _owningThreadId = owningThreadId; 047 _waitingThreadIds = new HashSet<Long>(waitingThreadIds); 048 } 049 050 /** 051 * Constructor for lock information. 052 * @param objRef ObjectReference for lock 053 */ 054 public LockInfo(ObjectReference objRef) { 055 _uniqueId = objRef.uniqueID(); 056 _description = objRef.type().toString(); 057 _waitingThreadIds = new HashSet<Long>(); 058 try { 059 ThreadReference threadRef = objRef.owningThread(); 060 if (threadRef!=null) { 061 _owningThreadId = threadRef.uniqueID(); 062 } 063 else { 064 _owningThreadId = null; 065 } 066 for(ThreadReference tr:objRef.waitingThreads()) { 067 _waitingThreadIds.add(tr.uniqueID()); 068 } 069 } 070 catch(IncompatibleThreadStateException e) { 071 throw new RuntimeException(e); 072 } 073 } 074 075 /** 076 * Returns the unique id. 077 * @return unique id 078 */ 079 public long getUniqueId() { 080 return _uniqueId; 081 } 082 083 /** 084 * Returns the unique id of the owning thread, or null if not owned. 085 * @return owning thread id, or null if not owned 086 */ 087 public Long getOwningThreadId() { 088 return _owningThreadId; 089 } 090 091 /** 092 * Sets the unique id of the owning thread, or null if not owned. 093 * @param owningThreadId owning thread id, or null if not owned 094 */ 095 public void setOwningThreadId(Long owningThreadId) { 096 _owningThreadId = owningThreadId; 097 } 098 099 /** 100 * Returns a list of unique ids of the threads waiting for this lock 101 * @return set of unique ids 102 */ 103 public Set<Long> getWaitingThreadIds() { 104 return _waitingThreadIds; 105 } 106 107 /** 108 * Returns the description. 109 * @return description. 110 */ 111 public String getDescription() { 112 return _description; 113 } 114 115 /** 116 * Returns a string representation of the object. 117 * 118 * @return a string representation of the object. 119 */ 120 public String toString() { 121 StringBuilder sb = new StringBuilder(); 122 sb.append(_description); 123 sb.append(" (id="); 124 sb.append(_uniqueId); 125 if (_owningThreadId!=null) { 126 sb.append("), owned by thread id="); 127 sb.append(_owningThreadId); 128 } 129 else { 130 sb.append("), not owned"); 131 } 132 if (_waitingThreadIds.size()==0) { 133 sb.append(", not contended"); 134 } 135 else 136 { 137 sb.append(", contended by thread ids="); 138 boolean first = true; 139 for (Long id:_waitingThreadIds) { 140 if (!first) { 141 sb.append(", "); 142 } 143 else { 144 first = false; 145 } 146 sb.append(id); 147 } 148 } 149 return sb.toString(); 150 } 151 }