diff options
author | Steven Rostedt <rostedt@goodmis.org> | 2010-09-02 09:08:23 -0400 |
---|---|---|
committer | Steven Rostedt <rostedt@goodmis.org> | 2010-09-02 14:39:44 -0400 |
commit | 2c38f91822abdbe6ea611f977bf149a1af3cac73 (patch) | |
tree | 0adb1befa32bf09981d0164d227465ca3113aea6 | |
parent | 2e5b970e1dbd1ecb5eb8db292604b98e0c22525a (diff) |
trace-cmd: Add range for cpus to filter on trace-cmd report
Currently, we can only filter the report on one CPU or all CPUS.
This patch allows users to add a range:
trace-cmd report --cpu 1-5
trace-cmd report --cpu 1,3,6
trace-cmd report --cpu 1,2-4,6,9
trace-cmd report --cpu 1 --cpu 2 --cpu 5,6 --cpu 9-12
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r-- | trace-read.c | 104 |
1 files changed, 102 insertions, 2 deletions
diff --git a/trace-read.c b/trace-read.c index a5c27e2..f09dcf8 100644 --- a/trace-read.c +++ b/trace-read.c | |||
@@ -56,6 +56,8 @@ const char *default_input_file = "trace.dat"; | |||
56 | const char *input_file; | 56 | const char *input_file; |
57 | 57 | ||
58 | static int filter_cpu = -1; | 58 | static int filter_cpu = -1; |
59 | static int *filter_cpus; | ||
60 | static int nr_filter_cpus; | ||
59 | 61 | ||
60 | static int show_wakeup; | 62 | static int show_wakeup; |
61 | static int wakeup_id; | 63 | static int wakeup_id; |
@@ -519,7 +521,26 @@ static void read_data_info(struct tracecmd_input *handle) | |||
519 | do { | 521 | do { |
520 | next = -1; | 522 | next = -1; |
521 | ts = 0; | 523 | ts = 0; |
522 | if (filter_cpu >= 0) { | 524 | if (filter_cpus) { |
525 | unsigned long long last_stamp = 0; | ||
526 | struct record *precord; | ||
527 | int next_cpu = -1; | ||
528 | int i; | ||
529 | |||
530 | for (i = 0; (cpu = filter_cpus[i]) >= 0; i++) { | ||
531 | precord = tracecmd_peek_data(handle, cpu); | ||
532 | if (precord && | ||
533 | (!last_stamp || precord->ts < last_stamp)) { | ||
534 | next_cpu = cpu; | ||
535 | last_stamp = precord->ts; | ||
536 | } | ||
537 | } | ||
538 | if (last_stamp) | ||
539 | record = tracecmd_read_data(handle, next_cpu); | ||
540 | else | ||
541 | record = NULL; | ||
542 | |||
543 | } else if (filter_cpu >= 0) { | ||
523 | cpu = filter_cpu; | 544 | cpu = filter_cpu; |
524 | record = tracecmd_read_data(handle, cpu); | 545 | record = tracecmd_read_data(handle, cpu); |
525 | } else | 546 | } else |
@@ -560,6 +581,82 @@ static void sig_end(int sig) | |||
560 | exit(0); | 581 | exit(0); |
561 | } | 582 | } |
562 | 583 | ||
584 | static const char *inc_and_test_char(const char *p, const char *cpu_str) | ||
585 | { | ||
586 | p++; | ||
587 | while (isspace(*p)) | ||
588 | p++; | ||
589 | if (!isdigit(*p)) | ||
590 | die("invalid character '%c' in cpu string '%s'", | ||
591 | *p, cpu_str); | ||
592 | return p; | ||
593 | } | ||
594 | |||
595 | static void __add_cpu(int cpu) | ||
596 | { | ||
597 | filter_cpus = tracecmd_add_id(filter_cpus, cpu, nr_filter_cpus++); | ||
598 | } | ||
599 | |||
600 | static int process_cpu_str(const char *cpu_str) | ||
601 | { | ||
602 | const char *p = cpu_str; | ||
603 | int cpu, ncpu, ret_cpu = 1; | ||
604 | |||
605 | do { | ||
606 | while (isspace(*p)) | ||
607 | p++; | ||
608 | |||
609 | cpu = atoi(p); | ||
610 | __add_cpu(cpu); | ||
611 | |||
612 | again: | ||
613 | while (isdigit(*p)) | ||
614 | p++; | ||
615 | while (isspace(*p)) | ||
616 | p++; | ||
617 | |||
618 | if (*p) { | ||
619 | ret_cpu = 0; | ||
620 | switch (*p) { | ||
621 | case '-': | ||
622 | p = inc_and_test_char(p, cpu_str); | ||
623 | ncpu = atoi(p); | ||
624 | if (ncpu < cpu) | ||
625 | die("range of cpu numbers must be lower to greater"); | ||
626 | for (; cpu <= ncpu; cpu++) | ||
627 | __add_cpu(cpu); | ||
628 | break; | ||
629 | |||
630 | case ',': | ||
631 | case ':': | ||
632 | p = inc_and_test_char(p, cpu_str); | ||
633 | ncpu = atoi(p); | ||
634 | __add_cpu(ncpu); | ||
635 | break; | ||
636 | default: | ||
637 | die("invalid character '%c' in cpu string '%s'", | ||
638 | *p, cpu_str); | ||
639 | } | ||
640 | goto again; | ||
641 | } | ||
642 | } while (*p); | ||
643 | |||
644 | if (ret_cpu) | ||
645 | return cpu; | ||
646 | |||
647 | /* Return -1 if we added more than one CPU */ | ||
648 | return -1; | ||
649 | } | ||
650 | |||
651 | static void add_cpu(const char *cpu_str) | ||
652 | { | ||
653 | int cpu; | ||
654 | |||
655 | cpu = process_cpu_str(cpu_str); | ||
656 | if (cpu >= 0) | ||
657 | __add_cpu(cpu); | ||
658 | } | ||
659 | |||
563 | void trace_report (int argc, char **argv) | 660 | void trace_report (int argc, char **argv) |
564 | { | 661 | { |
565 | struct tracecmd_input *handle; | 662 | struct tracecmd_input *handle; |
@@ -650,7 +747,10 @@ void trace_report (int argc, char **argv) | |||
650 | case 0: | 747 | case 0: |
651 | switch(option_index) { | 748 | switch(option_index) { |
652 | case 0: | 749 | case 0: |
653 | filter_cpu = atoi(optarg); | 750 | if (filter_cpu) |
751 | add_cpu(optarg); | ||
752 | else | ||
753 | filter_cpu = atoi(optarg); | ||
654 | break; | 754 | break; |
655 | case 1: | 755 | case 1: |
656 | print_events = 1; | 756 | print_events = 1; |