001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: * The Original Software is NetBeans. The Initial Developer of the Original
026: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
027: * Microsystems, Inc. All Rights Reserved.
028: *
029: * If you wish your version of this file to be governed by only the CDDL
030: * or only the GPL Version 2, indicate your decision by adding
031: * "[Contributor] elects to include this software in this distribution
032: * under the [CDDL or GPL Version 2] license." If you do not indicate a
033: * single choice of license, a recipient has the option to distribute
034: * your version of this file under either the CDDL, the GPL Version 2 or
035: * to extend the choice of license to its licensees as provided above.
036: * However, if you add GPL Version 2 code and therefore, elected the GPL
037: * Version 2 license, then the option applies only if the new code is
038: * made subject to such option by the copyright holder.
039: */
040:
041: package org.netbeans.lib.profiler.server;
042:
043: import org.netbeans.lib.profiler.server.system.Timers;
044:
045: /**
046: * Functionality for single code region profiling.
047: *
048: * @author Misha Dmitriev
049: */
050: public class ProfilerRuntimeCPUCodeRegion extends ProfilerRuntime {
051: //~ Static fields/initializers -----------------------------------------------------------------------------------------------
052:
053: protected static long[] codeRegionResults = new long[0];
054: protected static int newBufSize;
055: protected static int bufSize;
056: protected static int curIdx;
057: protected static long invCount;
058: protected static boolean codeRegionInstrumentationDisabled;
059:
060: //~ Methods ------------------------------------------------------------------------------------------------------------------
061:
062: public static void setCPUResBufSize(int size) {
063: newBufSize = size; // We don't set bufSize immediately to prevent the collector from crash if it's already active
064: }
065:
066: public static long[] getProfilingResults() {
067: synchronized (codeRegionResults) {
068: int size = (invCount < bufSize) ? (int) invCount : bufSize;
069: size++; // The very first element of the returned array is the total number of invocations
070:
071: long[] res = new long[size];
072: res[0] = (int) invCount;
073:
074: if (invCount < bufSize) {
075: System.arraycopy(codeRegionResults, 0, res, 1,
076: (int) invCount);
077: } else {
078: System.arraycopy(codeRegionResults, curIdx, res, 1,
079: bufSize - curIdx);
080: System.arraycopy(codeRegionResults, 0, res, bufSize
081: - curIdx + 1, curIdx);
082: }
083:
084: return res;
085: }
086: }
087:
088: public static void codeRegionEntry() {
089: //System.out.println("+++++++++ codeRegionEntry " + Thread.currentThread());
090: if (codeRegionInstrumentationDisabled) {
091: return;
092: }
093:
094: ThreadInfo ti = ThreadInfo.getThreadInfo();
095:
096: if (!ti.isInitialized()) {
097: ti.initialize();
098: }
099:
100: ti.inCallGraph = true;
101: ti.absEntryTime = Timers.getCurrentTimeInCounts();
102: }
103:
104: public static void codeRegionExit() {
105: if (codeRegionInstrumentationDisabled) {
106: return;
107: }
108:
109: long time = Timers.getCurrentTimeInCounts();
110:
111: //System.out.println("--------- codeRegionExit " + Thread.currentThread());
112: ThreadInfo ti = ThreadInfo.getThreadInfo();
113:
114: if (!ti.isInitialized() || !ti.inCallGraph) {
115: return;
116: }
117:
118: time = time - ti.absEntryTime;
119:
120: synchronized (codeRegionResults) {
121: codeRegionResults[curIdx++] = time;
122: invCount++;
123:
124: if (curIdx == bufSize) {
125: curIdx = 0;
126: }
127: }
128:
129: ti.inCallGraph = false;
130: }
131:
132: public static void enableProfiling(boolean v) {
133: if (v) {
134: createNewDataStructures();
135: codeRegionInstrumentationDisabled = false;
136: } else {
137: codeRegionInstrumentationDisabled = true;
138: clearDataStructures();
139: }
140: }
141:
142: public static void resetProfilerCollectors() {
143: synchronized (codeRegionResults) {
144: bufSize = newBufSize;
145: codeRegionResults = new long[bufSize];
146: invCount = 0;
147: curIdx = 0;
148: }
149: }
150:
151: protected static void clearDataStructures() {
152: ProfilerRuntime.clearDataStructures();
153:
154: synchronized (codeRegionResults) {
155: codeRegionResults = new long[0];
156: invCount = 0;
157: curIdx = 0;
158: }
159: }
160:
161: // ---------------------------------- Handling wait/sleep/monitor times ----------------------------
162: protected static void monitorEntryRegion(Thread t, Object monitor) {
163: if (codeRegionInstrumentationDisabled) {
164: return;
165: }
166:
167: ThreadInfo ti = ThreadInfo.getThreadInfo();
168:
169: if (!ti.isInitialized() || !ti.inCallGraph) {
170: return;
171: }
172:
173: // take note of the time we started waiting
174: ti.lastWaitStartTime = Timers.getCurrentTimeInCounts();
175: }
176:
177: protected static void monitorExitRegion(Thread t, Object monitor) {
178: if (codeRegionInstrumentationDisabled) {
179: return;
180: }
181:
182: ThreadInfo ti = ThreadInfo.getThreadInfo();
183:
184: if ((ti == null) || !ti.inCallGraph) {
185: return;
186: }
187:
188: // adjust the entry time so that the time spent waiting is not accounted for
189: ti.absEntryTime += (Timers.getCurrentTimeInCounts() - ti.lastWaitStartTime);
190: }
191:
192: protected static void sleepEntryRegion() {
193: if (codeRegionInstrumentationDisabled) {
194: return;
195: }
196:
197: ThreadInfo ti = ThreadInfo.getThreadInfo();
198:
199: if (!ti.isInitialized() || !ti.inCallGraph) {
200: return;
201: }
202:
203: // take note of the time we started waiting
204: ti.lastWaitStartTime = Timers.getCurrentTimeInCounts();
205: }
206:
207: protected static void sleepExitRegion() {
208: if (codeRegionInstrumentationDisabled) {
209: return;
210: }
211:
212: ThreadInfo ti = ThreadInfo.getThreadInfo();
213:
214: if (!ti.isInitialized() || !ti.inCallGraph) {
215: return;
216: }
217:
218: // adjust the entry time so that the time spent waiting is not accounted for
219: ti.absEntryTime += (Timers.getCurrentTimeInCounts() - ti.lastWaitStartTime);
220: }
221:
222: protected static void waitEntryRegion() {
223: if (codeRegionInstrumentationDisabled) {
224: return;
225: }
226:
227: ThreadInfo ti = ThreadInfo.getThreadInfo();
228:
229: if (!ti.isInitialized() || !ti.inCallGraph) {
230: return;
231: }
232:
233: // take note of the time we started waiting
234: ti.lastWaitStartTime = Timers.getCurrentTimeInCounts();
235: }
236:
237: protected static void waitExitRegion() {
238: if (codeRegionInstrumentationDisabled) {
239: return;
240: }
241:
242: ThreadInfo ti = ThreadInfo.getThreadInfo();
243:
244: if (!ti.isInitialized() || !ti.inCallGraph) {
245: return;
246: }
247:
248: // adjust the entry time so that the time spent waiting is not accounted for
249: ti.absEntryTime += (Timers.getCurrentTimeInCounts() - ti.lastWaitStartTime);
250: }
251: }
|