001: /*
002: Copyright (c) 2005 - 2006, MentorGen, LLC
003: All rights reserved.
004:
005: Redistribution and use in source and binary forms, with or without
006: modification, are permitted provided that the following conditions are met:
007:
008: + Redistributions of source code must retain the above copyright notice,
009: this list of conditions and the following disclaimer.
010: + Redistributions in binary form must reproduce the above copyright notice,
011: this list of conditions and the following disclaimer in the documentation
012: and/or other materials provided with the distribution.
013: + Neither the name of MentorGen LLC nor the names of its contributors may be
014: used to endorse or promote products derived from this software without
015: specific prior written permission.
016:
017: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
018: AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
019: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
020: ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
021: LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
022: CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
023: SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
024: INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
025: CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
026: ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
027: POSSIBILITY OF SUCH DAMAGE.
028: */
029: package com.mentorgen.tools.profile.output;
030:
031: import java.io.PrintWriter;
032:
033: import com.mentorgen.tools.profile.Controller;
034: import com.mentorgen.tools.profile.runtime.Frame;
035:
036: /**
037: *
038: * @author Andrew Wilcox
039: * @see com.mentorgen.tools.profile.output.ProfileTextDump
040: */
041: final class FrameDump {
042: private static final String NEW_LINE = System
043: .getProperty("line.separator");
044:
045: static void dump(PrintWriter writer, Frame frame, int interaction) {
046:
047: if (Controller._compactThreadDepth) {
048: // If the root frame doesn't have any children,
049: // we're guessing that the user probably doesn't want to see it.
050: // Specifically, for web-apps, there are "worker" threads that
051: // aren't of any interest so this is a good way to filter out
052: // that kind of chaff.
053: //
054: if (!frame.hasChildren()) {
055: return;
056: }
057:
058: boolean childAboveThreshold = false;
059:
060: for (Frame child : frame.childIterator()) {
061:
062: if (!belowThreshold(child) || child.hasChildren()) {
063: childAboveThreshold = true;
064: break;
065: }
066: }
067:
068: if (!childAboveThreshold) {
069: return;
070: }
071: }
072:
073: writer.print("+------------------------------");
074: writer.print(NEW_LINE);
075: writer.print("| Thread: ");
076: writer.print(frame.getThreadId());
077:
078: if (interaction > 1) {
079: writer.print(" (interaction #");
080: writer.print(interaction);
081: writer.print(")");
082: }
083:
084: writer.print(NEW_LINE);
085: writer.print("+------------------------------");
086: writer.print(NEW_LINE);
087: writer.print(" Time Percent ");
088: writer.print(NEW_LINE);
089: writer.print(" ----------------- ---------------");
090: writer.print(NEW_LINE);
091: writer
092: .print(" Count Total Net Total Net Location");
093: writer.print(NEW_LINE);
094: writer
095: .print(" ===== ===== === ===== === =========");
096: writer.print(NEW_LINE);
097:
098: long threadTotalTime = frame._metrics.getTotalTime();
099: dump(writer, 0, frame, (double) threadTotalTime);
100: }
101:
102: private static void dump(PrintWriter writer, int depth,
103: Frame parent, double threadTotalTime) {
104:
105: long total = parent._metrics.getTotalTime();
106: long net = parent.netTime();
107: writer.printf("%6d ", parent._metrics.getCount());
108: writer.printf("%8.1f ", Math.nanoToMilli(total));
109: writer.printf("%8.1f ", Math.nanoToMilli(net));
110:
111: if (total > 0) {
112: double percent = Math.toPercent(total, threadTotalTime);
113: writer.printf("%7.1f ", percent);
114: } else {
115: writer.print(" ");
116: }
117:
118: if (net > 0 && threadTotalTime > 0.000) {
119: double percent = Math.toPercent(net, threadTotalTime);
120:
121: if (percent > 0.1) {
122: writer.printf("%7.1f ", percent);
123: } else {
124: writer.print(" ");
125: }
126: } else {
127: writer.print(" ");
128: }
129:
130: writer.print(" ");
131: for (int i = 0; i < depth; i++) {
132: writer.print("| ");
133: }
134:
135: writer.print("+--");
136: writer.print(parent.getInvertedName());
137: writer.print(NEW_LINE);
138:
139: if (Controller._threadDepth != Controller.UNLIMITED
140: && depth == Controller._threadDepth - 1) {
141: return;
142: }
143:
144: for (Frame child : parent.childIterator()) {
145:
146: if (belowThreshold(child)) {
147: continue;
148: }
149:
150: dump(writer, depth + 1, child, threadTotalTime);
151: }
152: }
153:
154: private static boolean belowThreshold(Frame f) {
155: return (Controller._compactThreadDepth && f._metrics
156: .getTotalTime() < Controller._compactThreadThreshold * 1000000);
157: }
158:
159: }
|