// Copyright 2014 The Bazel Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.google.devtools.build.lib.profiler.chart; import com.google.devtools.build.lib.profiler.ProfileInfo; import com.google.devtools.build.lib.profiler.ProfileInfo.CriticalPathEntry; import com.google.devtools.build.lib.profiler.ProfileInfo.Task; import com.google.devtools.build.lib.profiler.ProfilerTask; import java.util.EnumSet; /** * Implementation of {@link ChartCreator} that creates Gantt Charts that contain * bars for all tasks in the profile. */ public class DetailedChartCreator implements ChartCreator { /** The data of the profiled build. */ private final ProfileInfo info; /** * Creates the chart creator. * * @param info the data of the profiled build */ public DetailedChartCreator(ProfileInfo info) { this.info = info; } @Override public Chart create() { Chart chart = new Chart(); CommonChartCreator.createCommonChartItems(chart, info); createTypes(chart); // calculate the critical path EnumSet<ProfilerTask> typeFilter = EnumSet.noneOf(ProfilerTask.class); CriticalPathEntry criticalPath = info.getCriticalPath(typeFilter); info.analyzeCriticalPath(typeFilter, criticalPath); for (Task task : info.allTasksById) { String label = task.type.description + ": " + task.getDescription(); ChartBarType type = chart.lookUpType(task.type.description); long stop = task.startTime + task.durationNanos; CriticalPathEntry entry = null; // for top level tasks, check if they are on the critical path if (task.parentId == 0 && criticalPath != null) { entry = info.getNextCriticalPathEntryForTask(criticalPath, task); // find next top-level entry if (entry != null) { CriticalPathEntry nextEntry = entry.next; while (nextEntry != null && nextEntry.task.parentId != 0) { nextEntry = nextEntry.next; } if (nextEntry != null) { // time is start and not stop as we traverse the critical back backwards chart.addVerticalLine(task.threadId, nextEntry.task.threadId, task.startTime); } } } chart.addBar(task.threadId, task.startTime, stop, type, (entry != null), label); } return chart; } /** * Creates a {@link ChartBarType} for every known {@link ProfilerTask} and * adds it to the chart. * * @param chart the chart to add the types to */ private void createTypes(Chart chart) { for (ProfilerTask task : ProfilerTask.values()) { chart.createType(task.description, new Color(task.color)); } } }