Skip to content

Commit 1b3e83b

Browse files
committed
Fix the problem with inconsistent thread times that otherwise will occur for e.g. threads sitting in wait() for long enough time when createSnapshot() is invoked.
1 parent e52b1db commit 1b3e83b

File tree

3 files changed

+48
-7
lines changed

3 files changed

+48
-7
lines changed

visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/CPUCallGraphBuilder.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,7 @@ public CPUCCTContainer[] createPresentationCCTs(CPUResultsSnapshot cpuSnapshot)
160160

161161
// Fix the problem with inconsistent thread times that otherwise will occur for e.g. threads sitting in wait()
162162
// for long enough time when "get results" is pressed
163-
/* not in use any longer
164-
ti.applyDiffAtGetResultsMoment();
165-
*/
163+
applyDiffAtGetResultsMoment(ti);
166164
double[] activeTimes = calculateThreadActiveTimes(ti);
167165

168166
TimedCPUCCTNode rootNode = ti.stack[0];
@@ -173,6 +171,7 @@ public CPUCCTContainer[] createPresentationCCTs(CPUResultsSnapshot cpuSnapshot)
173171
if ((cct.rootNode != null) && (cct.rootNode.getNChildren() > 0)) {
174172
ccts.add(cct);
175173
}
174+
undoDiffAtGetResultsMoment(ti);
176175
}
177176

178177
return (CPUCCTContainer[]) ccts.toArray(new CPUCCTContainer[0]);
@@ -189,6 +188,17 @@ protected boolean isCollectingTwoTimeStamps() {
189188
return status.collectingTwoTimeStamps();
190189
}
191190

191+
/** See the comment to ThreadInfo.diffAtGetResultsMoment field. */
192+
protected void applyDiffAtGetResultsMoment(ThreadInfo ti) {
193+
}
194+
195+
/**
196+
* See the comment to ThreadInfo.diffAtGetResultsMoment field. When we resume data processing for the given thread,
197+
* we need to undo the effect of applyDiffAtGetResultsMoment.
198+
*/
199+
protected void undoDiffAtGetResultsMoment(ThreadInfo ti) {
200+
}
201+
192202
protected long getDumpAbsTimeStamp() {
193203
return status.dumpAbsTimeStamp;
194204
}

visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/StackTraceSnapshotBuilder.java

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@
5757
import org.graalvm.visualvm.lib.jfluid.global.CommonConstants;
5858
import org.graalvm.visualvm.lib.jfluid.global.ProfilingSessionStatus;
5959
import org.graalvm.visualvm.lib.jfluid.results.RuntimeCCTNode;
60+
import org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes.MethodCPUCCTNode;
61+
import org.graalvm.visualvm.lib.jfluid.results.cpu.cct.nodes.TimedCPUCCTNode;
6062

6163
/**
6264
*
@@ -626,7 +628,6 @@ public final CPUResultsSnapshot createSnapshot(
626628
instrMethodSigs[counter] = "";
627629
counter++;
628630
}
629-
addStacktrace(new java.lang.management.ThreadInfo[0], currentDumpTimeStamp+1);
630631
return new CPUResultsSnapshot(since, System.currentTimeMillis(), ccgb, ccgb.isCollectingTwoTimeStamps(), instrMethodClasses, instrMethodNames, instrMethodSigs, miCount);
631632
}
632633
}
@@ -690,6 +691,36 @@ protected long getDumpAbsTimeStamp() {
690691
}
691692
}
692693

693-
}
694+
@Override
695+
protected void applyDiffAtGetResultsMoment(ThreadInfo ti) {
696+
long time0 = getDumpAbsTimeStamp();
697+
long diff = time0 - ti.topMethodEntryTime0;
698+
699+
applyDiffToTopNode(ti, diff);
700+
ti.diffAtGetResultsMoment = diff;
701+
}
702+
703+
@Override
704+
protected void undoDiffAtGetResultsMoment(ThreadInfo ti) {
705+
applyDiffToTopNode(ti, -ti.diffAtGetResultsMoment);
706+
ti.diffAtGetResultsMoment = 0;
707+
}
708+
709+
private void applyDiffToTopNode(ThreadInfo ti, long diff) {
710+
if (diff>0) {
711+
TimedCPUCCTNode top = ti.peek();
694712

713+
if (top instanceof MethodCPUCCTNode) {
714+
top.addNetTime0(diff);
715+
if (isCollectingTwoTimeStamps()) {
716+
SampledThreadInfo sti = lastStackTrace.get().get(Long.valueOf(ti.threadId));
717+
718+
if (sti!=null && sti.getThreadState() == Thread.State.RUNNABLE) {
719+
top.addNetTime1(diff);
720+
}
721+
}
722+
}
723+
}
724+
}
725+
}
695726
}

visualvm/libs.profiler/lib.profiler/src/org/graalvm/visualvm/lib/jfluid/results/cpu/ThreadInfo.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@ public class ThreadInfo {
5050
// moment user hits "get results" and the timestamp for the method entry into the top stack method. To present
5151
// results consistenly, we add this value to the TimedCPUCCTNode for the top-stack method. However, when
5252
// processing of data is resumed, we need to subtract this value back from that node.
53-
// this is effectively the self time for the last invocation of the top method on stack - if we would not keep
53+
// This is effectively the self time for the last invocation of the top method on stack - if we would not keep
5454
// it separately, it would not be reported
55-
// private long diffAtGetResultsMoment; // diff between last methodEntry and current moment timestamp -
55+
long diffAtGetResultsMoment; // diff between last methodEntry and current moment timestamp -
5656
// we will have to compensate for the processing time
5757

5858
//~ Instance fields ------------------------------------------------------------------------------------------------------

0 commit comments

Comments
 (0)