in analysis/jfr/src/main/java/org/eclipse/jifa/jfr/extractor/CPUTimeExtractor.java [221:283]
private List<TaskCPUTime> buildThreadCPUTime() {
List<TaskCPUTime> threadCPUTimes = new ArrayList<>();
if (this.isWallClockEvents) {
return threadCPUTimes;
}
for (CpuTaskData data : this.data.values()) {
if (data.getSamples() == null) {
continue;
}
JavaThreadCPUTime threadCPUTime = new JavaThreadCPUTime();
threadCPUTime.setTask(context.getThread(data.getThread()));
if (data.getSamples() != null) {
if (this.profiledByJFR) {
if (intervalJFR <= 0) {
throw new RuntimeException("need profiling interval to calculate approximate CPU time");
}
long cpuTimeMax = (data.user + data.system) * cpuCores;
long sampleTime = data.sampleCount * intervalJFR;
if (cpuTimeMax == 0) {
threadCPUTime.setUser(sampleTime);
} else {
threadCPUTime.setUser(Math.min(sampleTime, cpuTimeMax));
}
threadCPUTime.setSystem(0);
} else {
if (intervalAsyncProfiler <= 0) {
intervalAsyncProfiler = detectAsyncProfilerInterval();
}
threadCPUTime.setUser(data.sampleCount * intervalAsyncProfiler);
threadCPUTime.setSystem(0);
}
threadCPUTime.setSamples(data.getSamples().entrySet().stream().collect(
Collectors.toMap(
e -> StackTraceUtil.build(e.getKey(), context.getSymbols()),
Map.Entry::getValue,
Long::sum)
));
}
threadCPUTimes.add(threadCPUTime);
}
if (this.profiledByJFR) {
long gcTime = buildGCCpuTime();
if (gcTime > 0) {
JavaThreadCPUTime gc = new JavaThreadCPUTime();
gc.setTask(context.getThread(GC_THREAD));
gc.setUser(gcTime);
Map<StackTrace, Long> gcSamples = new HashMap<>();
gcSamples.put(StackTraceUtil.build(StackTraceUtil.newDummyStackTrace("", "JVM", "GC"), context.getSymbols()), 1L);
gc.setSamples(gcSamples);
threadCPUTimes.add(gc);
}
}
threadCPUTimes.sort((o1, o2) -> {
long delta = o2.totalCPUTime() - o1.totalCPUTime();
return delta > 0 ? 1 : (delta == 0 ? 0 : -1);
});
return threadCPUTimes;
}