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.results.cpu;
042:
043: //import org.netbeans.lib.profiler.global.Platform;
044: //import org.netbeans.lib.profiler.global.ProfilingSessionStatus;
045: //import org.netbeans.lib.profiler.utils.StringUtils;
046:
047: /**
048: *
049: * @author Jaroslav Bachorik
050: */
051: public class TimingAdjuster {
052: // // @GuardedBy this
053: // private InstrTimingData timingData;
054: //
055: // public TimingAdjuster(final ProfilingSessionStatus status, final boolean collectingTwoTimeStamps) {
056: // calculateTimingData(status, collectingTwoTimeStamps);
057: // }
058: //
059: // final public synchronized TimeStamp adjustTime(TimeStamp time, int incommingInv, int outgoingInv) {
060: // TimeStamp result = null;
061: //
062: // long timeExCleansed = timingData.timerCountsInSecond1 == 0 ? 0 : (long)((double) time.getExtendedTime() - incommingInv * timingData.methodEntryExitInnerTime1 - outgoingInv * timingData.methodEntryExitOuterTime1) * 1000000 / timingData.timerCountsInSecond1;
063: // long timeCleansed = timingData.timerCountsInSecond0 == 0 ? 0 : (long)((double) time.getTime() - incommingInv * timingData.methodEntryExitInnerTime0 - outgoingInv * timingData.methodEntryExitOuterTime0) * 1000000 / timingData.timerCountsInSecond0;
064: //
065: // timeCleansed = timeCleansed < 0 ? 0 : timeCleansed;
066: // timeExCleansed = timeExCleansed < 0 ? 0 : timeExCleansed;
067: //
068: // result = TimeStamp.createTimeStamp(timeCleansed, timeExCleansed);
069: //
070: // return result;
071: // }
072: //
073: // final public synchronized double delta(int incommingInv, int outgoingInv, boolean secondTimestamp) {
074: // double adjusted = 0;
075: // if (secondTimestamp) {
076: // adjusted = ((double) incommingInv * timingData.methodEntryExitInnerTime1 - outgoingInv * timingData.methodEntryExitOuterTime1) * 1000000 / timingData.timerCountsInSecond1;
077: // } else {
078: // adjusted = ((double) incommingInv * timingData.methodEntryExitInnerTime0 - outgoingInv * timingData.methodEntryExitOuterTime0) * 1000000 / timingData.timerCountsInSecond0;
079: // }
080: //
081: // if (adjusted < 0) adjusted = 0;
082: // return adjusted;
083: // }
084: //
085: // final public synchronized boolean isAdjustible(long time, int incommingInv, int outgoingInv, boolean secondTimestamp) {
086: // if (secondTimestamp) {
087: // return time > (incommingInv * timingData.methodEntryExitInnerTime1 + outgoingInv * timingData.methodEntryExitOuterTime1);
088: // } else {
089: // return time > (incommingInv * timingData.methodEntryExitInnerTime0 + outgoingInv * timingData.methodEntryExitOuterTime0);
090: // }
091: // }
092: //
093: // public synchronized void calculateTimingData(final ProfilingSessionStatus status, final boolean collectingTwoTimeStamps) {
094: // timingData = new InstrTimingData();
095: // // We use the following "safety margins" to artificially decrease the time spent in instrumentation.
096: // // That's because it looks like due to various CPU level speed optimizations the execution time for some code with
097: // // added instrumentation may be pretty much equal to the execution time of the instrumentation itself. The profiled
098: // // code, esp. if it's just one or two lines, is effectively executed in parallel with instrumentation.
099: // // Furthermore, highly optimizing CPU plus possibly smth. like rounding errors may occasionally result in the
100: // // measured time that is even *smaller* than the execution time of the instrumentation. This will result in
101: // // *negative* cleansed times presented to the user.
102: // // This safety margin is rough, but probably most reliable way to deal with these issues. The value has been
103: // // chosen experimentally, and seems to result in reasonable compromise between data accuracy and no occurrences
104: // // of zero time results.
105: // double safetyMargin0 = 0.88;
106: // double safetyMargin1 = 0.88;
107: // double safetyMargin2 = 0.88;
108: // if (collectingTwoTimeStamps) {
109: // // Note that all methodEntryExitXXX times are measured in status in absolute timer counts.
110: // // For usage in factor-out operations, we need to convert those that are used with thread CPU time values
111: // // into thread CPU time units.
112: // timingData.methodEntryExitCallTime0 = status.methodEntryExitCallTime[2] * safetyMargin2;
113: // timingData.methodEntryExitCallTime1 =
114: // status.methodEntryExitCallTime[3] * status.timerCountsInSecond[1] / status.timerCountsInSecond[0]
115: // * safetyMargin2;
116: // timingData.methodEntryExitInnerTime0 = status.methodEntryExitInnerTime[2] * safetyMargin2;
117: // timingData.methodEntryExitOuterTime0 = status.methodEntryExitOuterTime[2] * safetyMargin2;
118: // timingData.methodEntryExitInnerTime1 =
119: // status.methodEntryExitInnerTime[3] * status.timerCountsInSecond[1] / status.timerCountsInSecond[0]
120: // * safetyMargin2;
121: // timingData.methodEntryExitOuterTime1 =
122: // status.methodEntryExitOuterTime[3] * status.timerCountsInSecond[1] / status.timerCountsInSecond[0]
123: // * safetyMargin2;
124: // timingData.timerCountsInSecond0 = status.timerCountsInSecond[0];
125: // timingData.timerCountsInSecond1 = status.timerCountsInSecond[1];
126: // } else {
127: // if (status.absoluteTimerOn) {
128: // timingData.methodEntryExitCallTime0 = status.methodEntryExitCallTime[0] * safetyMargin0;
129: // timingData.methodEntryExitInnerTime0 = status.methodEntryExitInnerTime[0] * safetyMargin0;
130: // timingData.methodEntryExitOuterTime0 = status.methodEntryExitOuterTime[0] * safetyMargin0;
131: // timingData.timerCountsInSecond0 = status.timerCountsInSecond[0];
132: // } else {
133: // // Thread CPU only timer used. On Windows and Linux, with extremely low (10 ms or even worse) resolution of
134: // // this timer, it doesn't make sense to use cleansing - it introduces negative figures for short-running
135: // // methods, for which I didn't find any graceful way to deal with.
136: // // Also, cleansing is needed to make results sensible for short-running methods - but here for such methods
137: // // they are already non-sensible, with 0 as a most typical result.
138: // String targetMachineOSName = status.targetMachineOSName;
139: // if (targetMachineOSName == null) return; // dont calculate timings for an undefined OS
140: // if (Platform.isWindows(targetMachineOSName) || Platform.isLinux(targetMachineOSName)) {
141: // safetyMargin1 = 0;
142: // }
143: // timingData.methodEntryExitCallTime0 =
144: // status.methodEntryExitCallTime[1] * status.timerCountsInSecond[1] / status.timerCountsInSecond[0]
145: // * safetyMargin1;
146: // timingData.methodEntryExitInnerTime0 =
147: // status.methodEntryExitInnerTime[1] * status.timerCountsInSecond[1] / status.timerCountsInSecond[0]
148: // * safetyMargin1;
149: // timingData.methodEntryExitOuterTime0 =
150: // status.methodEntryExitOuterTime[1] * status.timerCountsInSecond[1] / status.timerCountsInSecond[0]
151: // * safetyMargin1;
152: // timingData.timerCountsInSecond0 = status.timerCountsInSecond[1];
153: // }
154: // }
155: // System.out.println(timingData);
156: // }
157: }
|