1 28 29 30 package com.caucho.tools.profiler; 31 32 import com.caucho.util.Alarm; 33 34 import java.util.ArrayList ; 35 import java.util.logging.Level ; 36 import java.util.logging.Logger ; 37 38 final class ThreadProfiler 39 implements Profiler 40 { 41 private static final Logger log = Logger.getLogger(ThreadProfiler.class.getName()); 42 43 private static ThreadLocal <ThreadProfiler> _current 44 = new ThreadLocal <ThreadProfiler>(); 45 46 private final ArrayList <ProfilerNode> _nodeStack = new ArrayList <ProfilerNode>(); 47 private long[] _cumulativeTimeStack = new long[16]; 48 private boolean[] _unwindStack = new boolean[16]; 49 private long[] _startTimeStack = new long[16]; 50 51 static ThreadProfiler current() 52 { 53 ThreadProfiler current = _current.get(); 54 55 if (current == null) { 56 current = new ThreadProfiler(); 57 _current.set(current); 58 } 59 60 return current; 61 } 62 63 private long currentTimeNanoseconds() 64 { 65 return Alarm.getExactTimeNanoseconds(); 66 } 67 68 void start(ProfilerPoint profilerPoint) 69 { 70 start(profilerPoint, false); 71 } 72 73 void start(ProfilerPoint guaranteedParent, ProfilerPoint profilerPoint) 74 { 75 int stackLen = _nodeStack.size(); 76 77 boolean isParentFound = false; 78 79 for (int i = 0; i < stackLen; i++) { 80 if (_nodeStack.get(i).getProfilerPoint() == guaranteedParent) { 81 isParentFound = true; 82 break; 83 } 84 } 85 86 if (!isParentFound) 87 start(guaranteedParent, true); 88 89 start(profilerPoint, false); 90 } 91 92 private void start(ProfilerPoint profilerPoint, boolean isUnwind) 93 { 94 int stackLen = _nodeStack.size(); 95 int topOfStack = stackLen - 1; 96 97 ProfilerNode parentNode; 98 99 105 106 if (stackLen == 0) { 107 parentNode = null; 108 } 109 else { 110 parentNode = _nodeStack.get(topOfStack); 113 114 long parentStartTime = _startTimeStack[topOfStack]; 115 116 long parentTime = currentTimeNanoseconds() - parentStartTime; 117 118 _cumulativeTimeStack[topOfStack] 119 = _cumulativeTimeStack[topOfStack] + parentTime; 120 } 121 122 124 int stackCapacity = _startTimeStack.length; 125 int newStackCapacity = stackLen + 2; 126 127 if (newStackCapacity > stackCapacity) { 128 long[] newStartTimeStack = new long[stackCapacity * 3 / 2 + 1]; 129 System.arraycopy(_startTimeStack, 0, newStartTimeStack, 0, stackCapacity); 130 _startTimeStack = newStartTimeStack; 131 132 long[] newCumulativeTimeStack = new long[stackCapacity * 3 / 2 + 1]; 133 System.arraycopy(_cumulativeTimeStack, 0, newCumulativeTimeStack, 0, stackCapacity); 134 _cumulativeTimeStack = newCumulativeTimeStack; 135 136 boolean[] newUnwindStack = new boolean[stackCapacity * 3 / 2 + 1]; 137 System.arraycopy(_unwindStack, 0, newUnwindStack, 0, stackCapacity); 138 _unwindStack = newUnwindStack; 139 } 140 141 143 long currentTime = currentTimeNanoseconds(); 144 145 ProfilerNode node = profilerPoint.getProfilerNode(parentNode); 146 147 _nodeStack.add(node); 148 149 _unwindStack[stackLen] = isUnwind; 150 _startTimeStack[stackLen] = currentTime; 151 _cumulativeTimeStack[stackLen] = 0; 152 153 158 159 if (log.isLoggable(Level.FINEST)) { 160 log.finest("[" + stackLen + "] start " + node + " isUnwind=" + isUnwind); 161 log.log(Level.FINEST, "", new Exception ()); 162 } 163 } 164 165 public void finish() 166 { 167 int removeIndex = _nodeStack.size() - 1; 168 169 ProfilerNode node = _nodeStack.remove(removeIndex); 170 long startTime = _startTimeStack[removeIndex]; 171 172 long currentTime = currentTimeNanoseconds(); 173 174 long time = currentTime - startTime; 175 176 long totalTime = _cumulativeTimeStack[removeIndex] + time; 177 178 node.update(totalTime); 179 180 189 190 int parentIndex = removeIndex - 1; 191 192 if (parentIndex >= 0) { 193 _startTimeStack[parentIndex] = currentTimeNanoseconds(); 194 195 boolean isUnwind = _unwindStack[parentIndex]; 196 197 if (log.isLoggable(Level.FINEST)) { 198 log.finest("[" + removeIndex + "] finish " + node + " isUnwind=" + isUnwind); 199 } 200 201 if (isUnwind) 202 finish(); 203 } 204 else { 205 if (log.isLoggable(Level.FINEST)) { 206 log.finest("[" + removeIndex + "] finish " + node); 207 } 208 } 209 210 215 } 216 217 public String toString() 218 { 219 return "Profiler[" + Thread.currentThread().getName() + "]"; 220 } 221 } 222 | Popular Tags |