KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > tools > profiler > ThreadProfiler


1 /*
2  * Copyright (c) 1998-2005 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  * Free SoftwareFoundation, Inc.
23  * 59 Temple Place, Suite 330
24  * Boston, MA 02111-1307 USA
25  *
26  * @author Sam
27  */

28
29
30 package com.caucho.tools.profiler;
31
32 import com.caucho.util.Alarm;
33
34 import java.util.ArrayList JavaDoc;
35 import java.util.logging.Level JavaDoc;
36 import java.util.logging.Logger JavaDoc;
37
38 final class ThreadProfiler
39   implements Profiler
40 {
41   private static final Logger JavaDoc log = Logger.getLogger(ThreadProfiler.class.getName());
42
43   private static ThreadLocal JavaDoc<ThreadProfiler> _current
44     = new ThreadLocal JavaDoc<ThreadProfiler>();
45
46   private final ArrayList JavaDoc<ProfilerNode> _nodeStack = new ArrayList JavaDoc<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     /** XXX:>>
100     for (int i = 0; i < stackLen; i++)
101       System.out.print(" ");
102     System.out.println(">>start " + profilerPoint);
103     (new Exception()).printStackTrace(System.out);
104      */

105
106     if (stackLen == 0) {
107       parentNode = null;
108     }
109     else {
110       // if there is parent, update it's cumulativeTimeStack so that
111
// when the stack unwinds past it in finish() the time is added to the total
112
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     // ensure capacity
123

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     // push a new node onto the stack
142

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     /** XXX:>>
154     for (int i = 0; i < stackLen; i++)
155       System.out.print(" ");
156     System.out.println(">>startNode " + node + " currentTime " + currentTime);
157      */

158
159     if (log.isLoggable(Level.FINEST)) {
160       log.finest("[" + stackLen + "] start " + node + " isUnwind=" + isUnwind);
161       log.log(Level.FINEST, "", new Exception JavaDoc());
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     /** XXX:>>
181     for (int i = 0; i < removeIndex; i++)
182       System.out.print(" ");
183     System.out.println(">>finishNode " + node +
184       " startTime " + startTime +
185       " currentTime " + currentTime +
186       " totalTime" + time +
187       " time" + totalTime);
188      */

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     /** XXX:>>
211     for (int i = 0; i < removeIndex; i++)
212       System.out.print(" ");
213     System.out.println(">>finish " + node + " " + totalTime);
214      */

215   }
216
217   public String JavaDoc toString()
218   {
219     return "Profiler[" + Thread.currentThread().getName() + "]";
220   }
221 }
222
Popular Tags