Skip to content

Commit 99fbf53

Browse files
committed
SampledThreadInfo can optionally include real thread CPU time
1 parent d322873 commit 99fbf53

File tree

1 file changed

+39
-8
lines changed

1 file changed

+39
-8
lines changed

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

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -190,12 +190,18 @@ static class SampledThreadInfo {
190190
private Thread.State state;
191191
private String threadName;
192192
private long threadId;
193+
private long threadCpuTime;
193194

194195
SampledThreadInfo(String tn, long tid, Thread.State ts, StackTraceElement[] st, InstrumentationFilter filter) {
196+
this (tn, tid,ts, st, -1, filter);
197+
}
198+
199+
SampledThreadInfo(String tn, long tid, Thread.State ts, StackTraceElement[] st, long tct, InstrumentationFilter filter) {
195200
threadName = tn;
196201
threadId = tid;
197202
state = ts;
198203
stackTrace = st;
204+
threadCpuTime = tct;
199205
if (state == Thread.State.RUNNABLE && containsKnownBlockingMethod(st)) { // known blocking method -> change state to waiting
200206
state = Thread.State.WAITING;
201207
}
@@ -339,6 +345,21 @@ final void addStacktrace(SampledThreadInfo[] threads, long dumpTimeStamp) throws
339345
// }
340346
}
341347
}
348+
349+
final public void addStacktrace(Map<String, Object>[] infoMap, long dumpTimeStamp) throws IllegalStateException {
350+
List<SampledThreadInfo> threads = new ArrayList<>(infoMap.length);
351+
352+
for (Map<String,Object> threadInfo : infoMap) {
353+
String name = (String) threadInfo.get("name");
354+
StackTraceElement[] stack = (StackTraceElement[]) threadInfo.get("stack");
355+
long tid = (Long) threadInfo.get("tid");
356+
long threadCpuTime = (Long) threadInfo.get("threadCpuTime");
357+
SampledThreadInfo i = new SampledThreadInfo(name, tid, State.RUNNABLE, stack, threadCpuTime, filter);
358+
359+
threads.add(i);
360+
}
361+
addStacktrace(threads.toArray(new SampledThreadInfo[0]), dumpTimeStamp);
362+
}
342363

343364
final public void addStacktrace(java.lang.management.ThreadInfo[] threads, long dumpTimeStamp) throws IllegalStateException {
344365
long timediff = processDumpTimeStamp(dumpTimeStamp);
@@ -383,10 +404,15 @@ private void processThreadDump(final long timediff, final long dumpTimeStamp, fi
383404

384405
long threadId = tinfo.getThreadId();
385406
if (!threadIds.contains(threadId)) {
407+
long threadCpuTime = tinfo.threadCpuTime;
386408
threadIds.add(threadId);
387409
threadNames.add(tname);
388410
ccgb.newThread((int) threadId, tname, "<none>");
389-
threadtimes.put(threadId,dumpTimeStamp);
411+
if (threadCpuTime != -1) {
412+
threadtimes.put(threadId,threadCpuTime);
413+
} else {
414+
threadtimes.put(threadId,dumpTimeStamp);
415+
}
390416
}
391417
StackTraceElement[] newElements = tinfo.getStackTrace();
392418
SampledThreadInfo oldTinfo = lastStackTrace.get().get(threadId);
@@ -397,14 +423,14 @@ private void processThreadDump(final long timediff, final long dumpTimeStamp, fi
397423
oldElements = oldTinfo.getStackTrace();
398424
oldState = oldTinfo.getThreadState();
399425
}
400-
processDiffs((int) threadId, oldElements, newElements, dumpTimeStamp, timediff, oldState, newState);
426+
processDiffs((int) threadId, oldElements, newElements, dumpTimeStamp, tinfo.threadCpuTime, timediff, oldState, newState);
401427
}
402428

403429
for (SampledThreadInfo oldTinfo : lastStackTrace.get().values()) {
404430
if (!tinfoMap.containsKey(oldTinfo.getThreadId())) {
405431
Thread.State oldState = oldTinfo.getThreadState();
406432
Thread.State newState = Thread.State.TERMINATED;
407-
processDiffs((int) oldTinfo.getThreadId(), oldTinfo.getStackTrace(), NO_STACK_TRACE, dumpTimeStamp, timediff, oldState, newState);
433+
processDiffs((int) oldTinfo.getThreadId(), oldTinfo.getStackTrace(), NO_STACK_TRACE, dumpTimeStamp, oldTinfo.threadCpuTime, timediff, oldState, newState);
408434
}
409435
}
410436

@@ -428,12 +454,11 @@ private long processDumpTimeStamp(long dumpTimeStamp) {
428454
return timediff;
429455
}
430456

431-
private void processDiffs(int threadId, StackTraceElement[] oldElements, StackTraceElement[] newElements, long timestamp, long timediff, Thread.State oldState, Thread.State newState) throws IllegalStateException {
457+
private void processDiffs(int threadId, StackTraceElement[] oldElements, StackTraceElement[] newElements, long timestamp, long threadCpuTime, long timediff, Thread.State oldState, Thread.State newState) throws IllegalStateException {
432458
assert newState != Thread.State.NEW : "Invalid thread state " + newState.name() + " for taking a stack trace"; // just to be sure
433459
if (oldState == Thread.State.TERMINATED && newState != Thread.State.TERMINATED) {
434460
throw new IllegalStateException("Thread has already been set to " + Thread.State.TERMINATED.name() + " - stack trace can not be taken");
435461
}
436-
long threadtime = threadtimes.get(Long.valueOf(threadId));
437462
// switch (oldState) {
438463
// case NEW: {
439464
// switch (newState) {
@@ -457,9 +482,15 @@ private void processDiffs(int threadId, StackTraceElement[] oldElements, StackTr
457482
// break;
458483
// }
459484
// }
460-
if (oldState == Thread.State.RUNNABLE) {
461-
threadtime += timediff;
462-
threadtimes.put(Long.valueOf(threadId),threadtime);
485+
long threadtime;
486+
if (threadCpuTime == -1) {
487+
threadtime = threadtimes.get(Long.valueOf(threadId));
488+
if (oldState == Thread.State.RUNNABLE) {
489+
threadtime += timediff;
490+
threadtimes.put(Long.valueOf(threadId),threadtime);
491+
}
492+
} else {
493+
threadtime = threadCpuTime;
463494
}
464495
// if (newState == Thread.State.RUNNABLE && newElements.length > 0) {
465496
// StackTraceElement top = newElements[0];

0 commit comments

Comments
 (0)