aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-timechart.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-timechart.c')
-rw-r--r--tools/perf/builtin-timechart.c79
1 files changed, 70 insertions, 9 deletions
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index 0bda620a717d..20d4212fa337 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -58,7 +58,8 @@ struct timechart {
58 first_time, last_time; 58 first_time, last_time;
59 bool power_only, 59 bool power_only,
60 tasks_only, 60 tasks_only,
61 with_backtrace; 61 with_backtrace,
62 topology;
62}; 63};
63 64
64struct per_pidcomm; 65struct per_pidcomm;
@@ -531,12 +532,10 @@ static int process_sample_event(struct perf_tool *tool,
531 tchart->last_time = sample->time; 532 tchart->last_time = sample->time;
532 } 533 }
533 534
534 if (sample->cpu > tchart->numcpus)
535 tchart->numcpus = sample->cpu;
536
537 if (evsel->handler != NULL) { 535 if (evsel->handler != NULL) {
538 tracepoint_handler f = evsel->handler; 536 tracepoint_handler f = evsel->handler;
539 return f(tchart, evsel, sample, cat_backtrace(event, sample, machine)); 537 return f(tchart, evsel, sample,
538 cat_backtrace(event, sample, machine));
540 } 539 }
541 540
542 return 0; 541 return 0;
@@ -837,8 +836,14 @@ static void draw_cpu_usage(struct timechart *tchart)
837 while (c) { 836 while (c) {
838 sample = c->samples; 837 sample = c->samples;
839 while (sample) { 838 while (sample) {
840 if (sample->type == TYPE_RUNNING) 839 if (sample->type == TYPE_RUNNING) {
841 svg_process(sample->cpu, sample->start_time, sample->end_time, "sample", c->comm); 840 svg_process(sample->cpu,
841 sample->start_time,
842 sample->end_time,
843 p->pid,
844 c->comm,
845 sample->backtrace);
846 }
842 847
843 sample = sample->next; 848 sample = sample->next;
844 } 849 }
@@ -1031,8 +1036,6 @@ static void write_svg_file(struct timechart *tchart, const char *filename)
1031 int count; 1036 int count;
1032 int thresh = TIME_THRESH; 1037 int thresh = TIME_THRESH;
1033 1038
1034 tchart->numcpus++;
1035
1036 if (tchart->power_only) 1039 if (tchart->power_only)
1037 tchart->proc_num = 0; 1040 tchart->proc_num = 0;
1038 1041
@@ -1062,6 +1065,37 @@ static void write_svg_file(struct timechart *tchart, const char *filename)
1062 svg_close(); 1065 svg_close();
1063} 1066}
1064 1067
1068static int process_header(struct perf_file_section *section __maybe_unused,
1069 struct perf_header *ph,
1070 int feat,
1071 int fd __maybe_unused,
1072 void *data)
1073{
1074 struct timechart *tchart = data;
1075
1076 switch (feat) {
1077 case HEADER_NRCPUS:
1078 tchart->numcpus = ph->env.nr_cpus_avail;
1079 break;
1080
1081 case HEADER_CPU_TOPOLOGY:
1082 if (!tchart->topology)
1083 break;
1084
1085 if (svg_build_topology_map(ph->env.sibling_cores,
1086 ph->env.nr_sibling_cores,
1087 ph->env.sibling_threads,
1088 ph->env.nr_sibling_threads))
1089 fprintf(stderr, "problem building topology\n");
1090 break;
1091
1092 default:
1093 break;
1094 }
1095
1096 return 0;
1097}
1098
1065static int __cmd_timechart(struct timechart *tchart, const char *output_name) 1099static int __cmd_timechart(struct timechart *tchart, const char *output_name)
1066{ 1100{
1067 const struct perf_evsel_str_handler power_tracepoints[] = { 1101 const struct perf_evsel_str_handler power_tracepoints[] = {
@@ -1087,6 +1121,11 @@ static int __cmd_timechart(struct timechart *tchart, const char *output_name)
1087 if (session == NULL) 1121 if (session == NULL)
1088 return -ENOMEM; 1122 return -ENOMEM;
1089 1123
1124 (void)perf_header__process_sections(&session->header,
1125 perf_data_file__fd(session->file),
1126 tchart,
1127 process_header);
1128
1090 if (!perf_session__has_traces(session, "timechart record")) 1129 if (!perf_session__has_traces(session, "timechart record"))
1091 goto out_delete; 1130 goto out_delete;
1092 1131
@@ -1212,6 +1251,23 @@ parse_process(const struct option *opt __maybe_unused, const char *arg,
1212 return 0; 1251 return 0;
1213} 1252}
1214 1253
1254static int
1255parse_highlight(const struct option *opt __maybe_unused, const char *arg,
1256 int __maybe_unused unset)
1257{
1258 unsigned long duration = strtoul(arg, NULL, 0);
1259
1260 if (svg_highlight || svg_highlight_name)
1261 return -1;
1262
1263 if (duration)
1264 svg_highlight = duration;
1265 else
1266 svg_highlight_name = strdup(arg);
1267
1268 return 0;
1269}
1270
1215int cmd_timechart(int argc, const char **argv, 1271int cmd_timechart(int argc, const char **argv,
1216 const char *prefix __maybe_unused) 1272 const char *prefix __maybe_unused)
1217{ 1273{
@@ -1230,6 +1286,9 @@ int cmd_timechart(int argc, const char **argv,
1230 OPT_STRING('i', "input", &input_name, "file", "input file name"), 1286 OPT_STRING('i', "input", &input_name, "file", "input file name"),
1231 OPT_STRING('o', "output", &output_name, "file", "output file name"), 1287 OPT_STRING('o', "output", &output_name, "file", "output file name"),
1232 OPT_INTEGER('w', "width", &svg_page_width, "page width"), 1288 OPT_INTEGER('w', "width", &svg_page_width, "page width"),
1289 OPT_CALLBACK(0, "highlight", NULL, "duration or task name",
1290 "highlight tasks. Pass duration in ns or process name.",
1291 parse_highlight),
1233 OPT_BOOLEAN('P', "power-only", &tchart.power_only, "output power data only"), 1292 OPT_BOOLEAN('P', "power-only", &tchart.power_only, "output power data only"),
1234 OPT_BOOLEAN('T', "tasks-only", &tchart.tasks_only, 1293 OPT_BOOLEAN('T', "tasks-only", &tchart.tasks_only,
1235 "output processes data only"), 1294 "output processes data only"),
@@ -1240,6 +1299,8 @@ int cmd_timechart(int argc, const char **argv,
1240 "Look for files with symbols relative to this directory"), 1299 "Look for files with symbols relative to this directory"),
1241 OPT_INTEGER('n', "proc-num", &tchart.proc_num, 1300 OPT_INTEGER('n', "proc-num", &tchart.proc_num,
1242 "min. number of tasks to print"), 1301 "min. number of tasks to print"),
1302 OPT_BOOLEAN('t', "topology", &tchart.topology,
1303 "sort CPUs according to topology"),
1243 OPT_END() 1304 OPT_END()
1244 }; 1305 };
1245 const char * const timechart_usage[] = { 1306 const char * const timechart_usage[] = {