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 }