builtin-trace.c (efd5745e43f3aabd95d521289e0caa0e30668cf4) | builtin-trace.c (1302d88e66f12a7b46a5598e641d93f0713007e0) |
---|---|
1#include "builtin.h" 2#include "util/color.h" 3#include "util/evlist.h" 4#include "util/machine.h" 5#include "util/thread.h" 6#include "util/parse-options.h" 7#include "util/thread_map.h" 8#include "event-parse.h" --- 55 unchanged lines hidden (view full) --- 64} 65 66struct thread_trace { 67 u64 entry_time; 68 u64 exit_time; 69 bool entry_pending; 70 unsigned long nr_events; 71 char *entry_str; | 1#include "builtin.h" 2#include "util/color.h" 3#include "util/evlist.h" 4#include "util/machine.h" 5#include "util/thread.h" 6#include "util/parse-options.h" 7#include "util/thread_map.h" 8#include "event-parse.h" --- 55 unchanged lines hidden (view full) --- 64} 65 66struct thread_trace { 67 u64 entry_time; 68 u64 exit_time; 69 bool entry_pending; 70 unsigned long nr_events; 71 char *entry_str; |
72 double runtime_ms; |
|
72}; 73 74static struct thread_trace *thread_trace__new(void) 75{ 76 return zalloc(sizeof(struct thread_trace)); 77} 78 79static struct thread_trace *thread__trace(struct thread *thread) --- 24 unchanged lines hidden (view full) --- 104 struct { 105 int max; 106 struct syscall *table; 107 } syscalls; 108 struct perf_record_opts opts; 109 struct machine host; 110 u64 base_time; 111 unsigned long nr_events; | 73}; 74 75static struct thread_trace *thread_trace__new(void) 76{ 77 return zalloc(sizeof(struct thread_trace)); 78} 79 80static struct thread_trace *thread__trace(struct thread *thread) --- 24 unchanged lines hidden (view full) --- 105 struct { 106 int max; 107 struct syscall *table; 108 } syscalls; 109 struct perf_record_opts opts; 110 struct machine host; 111 u64 base_time; 112 unsigned long nr_events; |
113 bool sched; |
|
112 bool multiple_threads; 113 double duration_filter; | 114 bool multiple_threads; 115 double duration_filter; |
116 double runtime_ms; |
|
114}; 115 116static bool trace__filter_duration(struct trace *trace, double t) 117{ 118 return t < (trace->duration_filter * NSEC_PER_MSEC); 119} 120 121static size_t trace__fprintf_tstamp(struct trace *trace, u64 tstamp, FILE *fp) --- 262 unchanged lines hidden (view full) --- 384 385 putchar('\n'); 386out: 387 ttrace->entry_pending = false; 388 389 return 0; 390} 391 | 117}; 118 119static bool trace__filter_duration(struct trace *trace, double t) 120{ 121 return t < (trace->duration_filter * NSEC_PER_MSEC); 122} 123 124static size_t trace__fprintf_tstamp(struct trace *trace, u64 tstamp, FILE *fp) --- 262 unchanged lines hidden (view full) --- 387 388 putchar('\n'); 389out: 390 ttrace->entry_pending = false; 391 392 return 0; 393} 394 |
395static int trace__sched_stat_runtime(struct trace *trace, struct perf_evsel *evsel, 396 struct perf_sample *sample) 397{ 398 u64 runtime = perf_evsel__intval(evsel, sample, "runtime"); 399 double runtime_ms = (double)runtime / NSEC_PER_MSEC; 400 struct thread *thread = machine__findnew_thread(&trace->host, sample->tid); 401 struct thread_trace *ttrace = thread__trace(thread); 402 403 if (ttrace == NULL) 404 goto out_dump; 405 406 ttrace->runtime_ms += runtime_ms; 407 trace->runtime_ms += runtime_ms; 408 return 0; 409 410out_dump: 411 printf("%s: comm=%s,pid=%u,runtime=%" PRIu64 ",vruntime=%" PRIu64 ")\n", 412 evsel->name, 413 perf_evsel__strval(evsel, sample, "comm"), 414 (pid_t)perf_evsel__intval(evsel, sample, "pid"), 415 runtime, 416 perf_evsel__intval(evsel, sample, "vruntime")); 417 return 0; 418} 419 |
|
392static int trace__run(struct trace *trace, int argc, const char **argv) 393{ 394 struct perf_evlist *evlist = perf_evlist__new(NULL, NULL); 395 struct perf_evsel *evsel; 396 int err = -1, i; 397 unsigned long before; 398 const bool forks = argc > 0; 399 400 if (evlist == NULL) { 401 printf("Not enough memory to run!\n"); 402 goto out; 403 } 404 405 if (perf_evlist__add_newtp(evlist, "raw_syscalls", "sys_enter", trace__sys_enter) || 406 perf_evlist__add_newtp(evlist, "raw_syscalls", "sys_exit", trace__sys_exit)) { 407 printf("Couldn't read the raw_syscalls tracepoints information!\n"); 408 goto out_delete_evlist; 409 } 410 | 420static int trace__run(struct trace *trace, int argc, const char **argv) 421{ 422 struct perf_evlist *evlist = perf_evlist__new(NULL, NULL); 423 struct perf_evsel *evsel; 424 int err = -1, i; 425 unsigned long before; 426 const bool forks = argc > 0; 427 428 if (evlist == NULL) { 429 printf("Not enough memory to run!\n"); 430 goto out; 431 } 432 433 if (perf_evlist__add_newtp(evlist, "raw_syscalls", "sys_enter", trace__sys_enter) || 434 perf_evlist__add_newtp(evlist, "raw_syscalls", "sys_exit", trace__sys_exit)) { 435 printf("Couldn't read the raw_syscalls tracepoints information!\n"); 436 goto out_delete_evlist; 437 } 438 |
439 if (trace->sched && 440 perf_evlist__add_newtp(evlist, "sched", "sched_stat_runtime", 441 trace__sched_stat_runtime)) { 442 printf("Couldn't read the sched_stat_runtime tracepoint information!\n"); 443 goto out_delete_evlist; 444 } 445 |
|
411 err = perf_evlist__create_maps(evlist, &trace->opts.target); 412 if (err < 0) { 413 printf("Problems parsing the target to trace, check your options!\n"); 414 goto out_delete_evlist; 415 } 416 417 err = trace__symbols_init(trace, evlist); 418 if (err < 0) { --- 97 unchanged lines hidden (view full) --- 516 goto again; 517 518out_delete_evlist: 519 perf_evlist__delete(evlist); 520out: 521 return err; 522} 523 | 446 err = perf_evlist__create_maps(evlist, &trace->opts.target); 447 if (err < 0) { 448 printf("Problems parsing the target to trace, check your options!\n"); 449 goto out_delete_evlist; 450 } 451 452 err = trace__symbols_init(trace, evlist); 453 if (err < 0) { --- 97 unchanged lines hidden (view full) --- 551 goto again; 552 553out_delete_evlist: 554 perf_evlist__delete(evlist); 555out: 556 return err; 557} 558 |
559static size_t trace__fprintf_threads_header(FILE *fp) 560{ 561 size_t printed; 562 563 printed = fprintf(fp, "\n _____________________________________________________________________\n"); 564 printed += fprintf(fp," __) Summary of events (__\n\n"); 565 printed += fprintf(fp," [ task - pid ] [ events ] [ ratio ] [ runtime ]\n"); 566 printed += fprintf(fp," _____________________________________________________________________\n\n"); 567 568 return printed; 569} 570 571static size_t trace__fprintf_thread_summary(struct trace *trace, FILE *fp) 572{ 573 size_t printed = trace__fprintf_threads_header(fp); 574 struct rb_node *nd; 575 576 for (nd = rb_first(&trace->host.threads); nd; nd = rb_next(nd)) { 577 struct thread *thread = rb_entry(nd, struct thread, rb_node); 578 struct thread_trace *ttrace = thread->priv; 579 const char *color; 580 double ratio; 581 582 if (ttrace == NULL) 583 continue; 584 585 ratio = (double)ttrace->nr_events / trace->nr_events * 100.0; 586 587 color = PERF_COLOR_NORMAL; 588 if (ratio > 50.0) 589 color = PERF_COLOR_RED; 590 else if (ratio > 25.0) 591 color = PERF_COLOR_GREEN; 592 else if (ratio > 5.0) 593 color = PERF_COLOR_YELLOW; 594 595 printed += color_fprintf(fp, color, "%20s", thread->comm); 596 printed += fprintf(fp, " - %-5d :%11lu [", thread->pid, ttrace->nr_events); 597 printed += color_fprintf(fp, color, "%5.1f%%", ratio); 598 printed += fprintf(fp, " ] %10.3f ms\n", ttrace->runtime_ms); 599 } 600 601 return printed; 602} 603 |
|
524static int trace__set_duration(const struct option *opt, const char *str, 525 int unset __maybe_unused) 526{ 527 struct trace *trace = opt->value; 528 529 trace->duration_filter = atof(str); 530 return 0; 531} --- 34 unchanged lines hidden (view full) --- 566 "child tasks do not inherit counters"), 567 OPT_UINTEGER(0, "mmap-pages", &trace.opts.mmap_pages, 568 "number of mmap data pages"), 569 OPT_STRING(0, "uid", &trace.opts.target.uid_str, "user", 570 "user to profile"), 571 OPT_CALLBACK(0, "duration", &trace, "float", 572 "show only events with duration > N.M ms", 573 trace__set_duration), | 604static int trace__set_duration(const struct option *opt, const char *str, 605 int unset __maybe_unused) 606{ 607 struct trace *trace = opt->value; 608 609 trace->duration_filter = atof(str); 610 return 0; 611} --- 34 unchanged lines hidden (view full) --- 646 "child tasks do not inherit counters"), 647 OPT_UINTEGER(0, "mmap-pages", &trace.opts.mmap_pages, 648 "number of mmap data pages"), 649 OPT_STRING(0, "uid", &trace.opts.target.uid_str, "user", 650 "user to profile"), 651 OPT_CALLBACK(0, "duration", &trace, "float", 652 "show only events with duration > N.M ms", 653 trace__set_duration), |
654 OPT_BOOLEAN(0, "sched", &trace.sched, "show blocking scheduler events"), |
|
574 OPT_END() 575 }; 576 int err; 577 char bf[BUFSIZ]; 578 579 argc = parse_options(argc, argv, trace_options, trace_usage, 0); 580 581 err = perf_target__validate(&trace.opts.target); --- 8 unchanged lines hidden (view full) --- 590 perf_target__strerror(&trace.opts.target, err, bf, sizeof(bf)); 591 printf("%s", bf); 592 return err; 593 } 594 595 if (!argc && perf_target__none(&trace.opts.target)) 596 trace.opts.target.system_wide = true; 597 | 655 OPT_END() 656 }; 657 int err; 658 char bf[BUFSIZ]; 659 660 argc = parse_options(argc, argv, trace_options, trace_usage, 0); 661 662 err = perf_target__validate(&trace.opts.target); --- 8 unchanged lines hidden (view full) --- 671 perf_target__strerror(&trace.opts.target, err, bf, sizeof(bf)); 672 printf("%s", bf); 673 return err; 674 } 675 676 if (!argc && perf_target__none(&trace.opts.target)) 677 trace.opts.target.system_wide = true; 678 |
598 return trace__run(&trace, argc, argv); | 679 err = trace__run(&trace, argc, argv); 680 681 if (trace.sched && !err) 682 trace__fprintf_thread_summary(&trace, stdout); 683 684 return err; |
599} | 685} |