aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-timechart.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-01-23 01:45:46 -0500
committerDavid S. Miller <davem@davemloft.net>2010-01-23 01:45:46 -0500
commit6be325719b3e54624397e413efd4b33a997e55a3 (patch)
tree57f321a56794cab2222e179b16731e0d76a4a68a /tools/perf/builtin-timechart.c
parent26d92f9276a56d55511a427fb70bd70886af647a (diff)
parent92dcffb916d309aa01778bf8963a6932e4014d07 (diff)
Merge branch 'master' of /home/davem/src/GIT/linux-2.6/
Diffstat (limited to 'tools/perf/builtin-timechart.c')
-rw-r--r--tools/perf/builtin-timechart.c120
1 files changed, 45 insertions, 75 deletions
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index cb58b6605fcc..3f8bbcfb1e9b 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -30,15 +30,12 @@
30#include "util/parse-options.h" 30#include "util/parse-options.h"
31#include "util/parse-events.h" 31#include "util/parse-events.h"
32#include "util/event.h" 32#include "util/event.h"
33#include "util/data_map.h" 33#include "util/session.h"
34#include "util/svghelper.h" 34#include "util/svghelper.h"
35 35
36static char const *input_name = "perf.data"; 36static char const *input_name = "perf.data";
37static char const *output_name = "output.svg"; 37static char const *output_name = "output.svg";
38 38
39
40static u64 sample_type;
41
42static unsigned int numcpus; 39static unsigned int numcpus;
43static u64 min_freq; /* Lowest CPU frequency seen */ 40static u64 min_freq; /* Lowest CPU frequency seen */
44static u64 max_freq; /* Highest CPU frequency seen */ 41static u64 max_freq; /* Highest CPU frequency seen */
@@ -281,33 +278,30 @@ static int cpus_cstate_state[MAX_CPUS];
281static u64 cpus_pstate_start_times[MAX_CPUS]; 278static u64 cpus_pstate_start_times[MAX_CPUS];
282static u64 cpus_pstate_state[MAX_CPUS]; 279static u64 cpus_pstate_state[MAX_CPUS];
283 280
284static int 281static int process_comm_event(event_t *event, struct perf_session *session __used)
285process_comm_event(event_t *event)
286{ 282{
287 pid_set_comm(event->comm.pid, event->comm.comm); 283 pid_set_comm(event->comm.tid, event->comm.comm);
288 return 0; 284 return 0;
289} 285}
290static int 286
291process_fork_event(event_t *event) 287static int process_fork_event(event_t *event, struct perf_session *session __used)
292{ 288{
293 pid_fork(event->fork.pid, event->fork.ppid, event->fork.time); 289 pid_fork(event->fork.pid, event->fork.ppid, event->fork.time);
294 return 0; 290 return 0;
295} 291}
296 292
297static int 293static int process_exit_event(event_t *event, struct perf_session *session __used)
298process_exit_event(event_t *event)
299{ 294{
300 pid_exit(event->fork.pid, event->fork.time); 295 pid_exit(event->fork.pid, event->fork.time);
301 return 0; 296 return 0;
302} 297}
303 298
304struct trace_entry { 299struct trace_entry {
305 u32 size;
306 unsigned short type; 300 unsigned short type;
307 unsigned char flags; 301 unsigned char flags;
308 unsigned char preempt_count; 302 unsigned char preempt_count;
309 int pid; 303 int pid;
310 int tgid; 304 int lock_depth;
311}; 305};
312 306
313struct power_entry { 307struct power_entry {
@@ -481,46 +475,24 @@ static void sched_switch(int cpu, u64 timestamp, struct trace_entry *te)
481} 475}
482 476
483 477
484static int 478static int process_sample_event(event_t *event, struct perf_session *session)
485process_sample_event(event_t *event)
486{ 479{
487 int cursor = 0; 480 struct sample_data data;
488 u64 addr = 0;
489 u64 stamp = 0;
490 u32 cpu = 0;
491 u32 pid = 0;
492 struct trace_entry *te; 481 struct trace_entry *te;
493 482
494 if (sample_type & PERF_SAMPLE_IP) 483 memset(&data, 0, sizeof(data));
495 cursor++;
496
497 if (sample_type & PERF_SAMPLE_TID) {
498 pid = event->sample.array[cursor]>>32;
499 cursor++;
500 }
501 if (sample_type & PERF_SAMPLE_TIME) {
502 stamp = event->sample.array[cursor++];
503 484
504 if (!first_time || first_time > stamp) 485 event__parse_sample(event, session->sample_type, &data);
505 first_time = stamp;
506 if (last_time < stamp)
507 last_time = stamp;
508 486
487 if (session->sample_type & PERF_SAMPLE_TIME) {
488 if (!first_time || first_time > data.time)
489 first_time = data.time;
490 if (last_time < data.time)
491 last_time = data.time;
509 } 492 }
510 if (sample_type & PERF_SAMPLE_ADDR)
511 addr = event->sample.array[cursor++];
512 if (sample_type & PERF_SAMPLE_ID)
513 cursor++;
514 if (sample_type & PERF_SAMPLE_STREAM_ID)
515 cursor++;
516 if (sample_type & PERF_SAMPLE_CPU)
517 cpu = event->sample.array[cursor++] & 0xFFFFFFFF;
518 if (sample_type & PERF_SAMPLE_PERIOD)
519 cursor++;
520
521 te = (void *)&event->sample.array[cursor];
522 493
523 if (sample_type & PERF_SAMPLE_RAW && te->size > 0) { 494 te = (void *)data.raw_data;
495 if (session->sample_type & PERF_SAMPLE_RAW && data.raw_size > 0) {
524 char *event_str; 496 char *event_str;
525 struct power_entry *pe; 497 struct power_entry *pe;
526 498
@@ -532,19 +504,19 @@ process_sample_event(event_t *event)
532 return 0; 504 return 0;
533 505
534 if (strcmp(event_str, "power:power_start") == 0) 506 if (strcmp(event_str, "power:power_start") == 0)
535 c_state_start(cpu, stamp, pe->value); 507 c_state_start(data.cpu, data.time, pe->value);
536 508
537 if (strcmp(event_str, "power:power_end") == 0) 509 if (strcmp(event_str, "power:power_end") == 0)
538 c_state_end(cpu, stamp); 510 c_state_end(data.cpu, data.time);
539 511
540 if (strcmp(event_str, "power:power_frequency") == 0) 512 if (strcmp(event_str, "power:power_frequency") == 0)
541 p_state_change(cpu, stamp, pe->value); 513 p_state_change(data.cpu, data.time, pe->value);
542 514
543 if (strcmp(event_str, "sched:sched_wakeup") == 0) 515 if (strcmp(event_str, "sched:sched_wakeup") == 0)
544 sched_wakeup(cpu, stamp, pid, te); 516 sched_wakeup(data.cpu, data.time, data.pid, te);
545 517
546 if (strcmp(event_str, "sched:sched_switch") == 0) 518 if (strcmp(event_str, "sched:sched_switch") == 0)
547 sched_switch(cpu, stamp, te); 519 sched_switch(data.cpu, data.time, te);
548 } 520 }
549 return 0; 521 return 0;
550} 522}
@@ -597,16 +569,16 @@ static void end_sample_processing(void)
597 } 569 }
598} 570}
599 571
600static u64 sample_time(event_t *event) 572static u64 sample_time(event_t *event, const struct perf_session *session)
601{ 573{
602 int cursor; 574 int cursor;
603 575
604 cursor = 0; 576 cursor = 0;
605 if (sample_type & PERF_SAMPLE_IP) 577 if (session->sample_type & PERF_SAMPLE_IP)
606 cursor++; 578 cursor++;
607 if (sample_type & PERF_SAMPLE_TID) 579 if (session->sample_type & PERF_SAMPLE_TID)
608 cursor++; 580 cursor++;
609 if (sample_type & PERF_SAMPLE_TIME) 581 if (session->sample_type & PERF_SAMPLE_TIME)
610 return event->sample.array[cursor]; 582 return event->sample.array[cursor];
611 return 0; 583 return 0;
612} 584}
@@ -616,8 +588,7 @@ static u64 sample_time(event_t *event)
616 * We first queue all events, sorted backwards by insertion. 588 * We first queue all events, sorted backwards by insertion.
617 * The order will get flipped later. 589 * The order will get flipped later.
618 */ 590 */
619static int 591static int queue_sample_event(event_t *event, struct perf_session *session)
620queue_sample_event(event_t *event)
621{ 592{
622 struct sample_wrapper *copy, *prev; 593 struct sample_wrapper *copy, *prev;
623 int size; 594 int size;
@@ -631,7 +602,7 @@ queue_sample_event(event_t *event)
631 memset(copy, 0, size); 602 memset(copy, 0, size);
632 603
633 copy->next = NULL; 604 copy->next = NULL;
634 copy->timestamp = sample_time(event); 605 copy->timestamp = sample_time(event, session);
635 606
636 memcpy(&copy->data, event, event->sample.header.size); 607 memcpy(&copy->data, event, event->sample.header.size);
637 608
@@ -1043,7 +1014,7 @@ static void write_svg_file(const char *filename)
1043 svg_close(); 1014 svg_close();
1044} 1015}
1045 1016
1046static void process_samples(void) 1017static void process_samples(struct perf_session *session)
1047{ 1018{
1048 struct sample_wrapper *cursor; 1019 struct sample_wrapper *cursor;
1049 event_t *event; 1020 event_t *event;
@@ -1054,15 +1025,13 @@ static void process_samples(void)
1054 while (cursor) { 1025 while (cursor) {
1055 event = (void *)&cursor->data; 1026 event = (void *)&cursor->data;
1056 cursor = cursor->next; 1027 cursor = cursor->next;
1057 process_sample_event(event); 1028 process_sample_event(event, session);
1058 } 1029 }
1059} 1030}
1060 1031
1061static int sample_type_check(u64 type) 1032static int sample_type_check(struct perf_session *session)
1062{ 1033{
1063 sample_type = type; 1034 if (!(session->sample_type & PERF_SAMPLE_RAW)) {
1064
1065 if (!(sample_type & PERF_SAMPLE_RAW)) {
1066 fprintf(stderr, "No trace samples found in the file.\n" 1035 fprintf(stderr, "No trace samples found in the file.\n"
1067 "Have you used 'perf timechart record' to record it?\n"); 1036 "Have you used 'perf timechart record' to record it?\n");
1068 return -1; 1037 return -1;
@@ -1071,7 +1040,7 @@ static int sample_type_check(u64 type)
1071 return 0; 1040 return 0;
1072} 1041}
1073 1042
1074static struct perf_file_handler file_handler = { 1043static struct perf_event_ops event_ops = {
1075 .process_comm_event = process_comm_event, 1044 .process_comm_event = process_comm_event,
1076 .process_fork_event = process_fork_event, 1045 .process_fork_event = process_fork_event,
1077 .process_exit_event = process_exit_event, 1046 .process_exit_event = process_exit_event,
@@ -1081,17 +1050,17 @@ static struct perf_file_handler file_handler = {
1081 1050
1082static int __cmd_timechart(void) 1051static int __cmd_timechart(void)
1083{ 1052{
1084 struct perf_header *header; 1053 struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0);
1085 int ret; 1054 int ret;
1086 1055
1087 register_perf_file_handler(&file_handler); 1056 if (session == NULL)
1057 return -ENOMEM;
1088 1058
1089 ret = mmap_dispatch_perf_file(&header, input_name, 0, 0, 1059 ret = perf_session__process_events(session, &event_ops);
1090 &event__cwdlen, &event__cwd);
1091 if (ret) 1060 if (ret)
1092 return EXIT_FAILURE; 1061 goto out_delete;
1093 1062
1094 process_samples(); 1063 process_samples(session);
1095 1064
1096 end_sample_processing(); 1065 end_sample_processing();
1097 1066
@@ -1101,8 +1070,9 @@ static int __cmd_timechart(void)
1101 1070
1102 pr_info("Written %2.1f seconds of trace to %s.\n", 1071 pr_info("Written %2.1f seconds of trace to %s.\n",
1103 (last_time - first_time) / 1000000000.0, output_name); 1072 (last_time - first_time) / 1000000000.0, output_name);
1104 1073out_delete:
1105 return EXIT_SUCCESS; 1074 perf_session__delete(session);
1075 return ret;
1106} 1076}
1107 1077
1108static const char * const timechart_usage[] = { 1078static const char * const timechart_usage[] = {
@@ -1167,11 +1137,11 @@ static const struct option options[] = {
1167 1137
1168int cmd_timechart(int argc, const char **argv, const char *prefix __used) 1138int cmd_timechart(int argc, const char **argv, const char *prefix __used)
1169{ 1139{
1170 symbol__init(0);
1171
1172 argc = parse_options(argc, argv, options, timechart_usage, 1140 argc = parse_options(argc, argv, options, timechart_usage,
1173 PARSE_OPT_STOP_AT_NON_OPTION); 1141 PARSE_OPT_STOP_AT_NON_OPTION);
1174 1142
1143 symbol__init();
1144
1175 if (argc && !strncmp(argv[0], "rec", 3)) 1145 if (argc && !strncmp(argv[0], "rec", 3))
1176 return __cmd_record(argc, argv); 1146 return __cmd_record(argc, argv);
1177 else if (argc) 1147 else if (argc)