diff options
| -rw-r--r-- | tools/perf/util/annotate.c | 55 | ||||
| -rw-r--r-- | tools/perf/util/annotate.h | 1 |
2 files changed, 53 insertions, 3 deletions
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 435bf6d1a77..07aaeea6000 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c | |||
| @@ -858,12 +858,41 @@ static void insert_source_line(struct rb_root *root, struct source_line *src_lin | |||
| 858 | struct source_line *iter; | 858 | struct source_line *iter; |
| 859 | struct rb_node **p = &root->rb_node; | 859 | struct rb_node **p = &root->rb_node; |
| 860 | struct rb_node *parent = NULL; | 860 | struct rb_node *parent = NULL; |
| 861 | int ret; | ||
| 861 | 862 | ||
| 862 | while (*p != NULL) { | 863 | while (*p != NULL) { |
| 863 | parent = *p; | 864 | parent = *p; |
| 864 | iter = rb_entry(parent, struct source_line, node); | 865 | iter = rb_entry(parent, struct source_line, node); |
| 865 | 866 | ||
| 866 | if (src_line->percent > iter->percent) | 867 | ret = strcmp(iter->path, src_line->path); |
| 868 | if (ret == 0) { | ||
| 869 | iter->percent_sum += src_line->percent; | ||
| 870 | return; | ||
| 871 | } | ||
| 872 | |||
| 873 | if (ret < 0) | ||
| 874 | p = &(*p)->rb_left; | ||
| 875 | else | ||
| 876 | p = &(*p)->rb_right; | ||
| 877 | } | ||
| 878 | |||
| 879 | src_line->percent_sum = src_line->percent; | ||
| 880 | |||
| 881 | rb_link_node(&src_line->node, parent, p); | ||
| 882 | rb_insert_color(&src_line->node, root); | ||
| 883 | } | ||
| 884 | |||
| 885 | static void __resort_source_line(struct rb_root *root, struct source_line *src_line) | ||
| 886 | { | ||
| 887 | struct source_line *iter; | ||
| 888 | struct rb_node **p = &root->rb_node; | ||
| 889 | struct rb_node *parent = NULL; | ||
| 890 | |||
| 891 | while (*p != NULL) { | ||
| 892 | parent = *p; | ||
| 893 | iter = rb_entry(parent, struct source_line, node); | ||
| 894 | |||
| 895 | if (src_line->percent_sum > iter->percent_sum) | ||
| 867 | p = &(*p)->rb_left; | 896 | p = &(*p)->rb_left; |
| 868 | else | 897 | else |
| 869 | p = &(*p)->rb_right; | 898 | p = &(*p)->rb_right; |
| @@ -873,6 +902,24 @@ static void insert_source_line(struct rb_root *root, struct source_line *src_lin | |||
| 873 | rb_insert_color(&src_line->node, root); | 902 | rb_insert_color(&src_line->node, root); |
| 874 | } | 903 | } |
| 875 | 904 | ||
| 905 | static void resort_source_line(struct rb_root *dest_root, struct rb_root *src_root) | ||
| 906 | { | ||
| 907 | struct source_line *src_line; | ||
| 908 | struct rb_node *node; | ||
| 909 | |||
| 910 | node = rb_first(src_root); | ||
| 911 | while (node) { | ||
| 912 | struct rb_node *next; | ||
| 913 | |||
| 914 | src_line = rb_entry(node, struct source_line, node); | ||
| 915 | next = rb_next(node); | ||
| 916 | rb_erase(node, src_root); | ||
| 917 | |||
| 918 | __resort_source_line(dest_root, src_line); | ||
| 919 | node = next; | ||
| 920 | } | ||
| 921 | } | ||
| 922 | |||
| 876 | static void symbol__free_source_line(struct symbol *sym, int len) | 923 | static void symbol__free_source_line(struct symbol *sym, int len) |
| 877 | { | 924 | { |
| 878 | struct annotation *notes = symbol__annotation(sym); | 925 | struct annotation *notes = symbol__annotation(sym); |
| @@ -897,6 +944,7 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map, | |||
| 897 | struct source_line *src_line; | 944 | struct source_line *src_line; |
| 898 | struct annotation *notes = symbol__annotation(sym); | 945 | struct annotation *notes = symbol__annotation(sym); |
| 899 | struct sym_hist *h = annotation__histogram(notes, evidx); | 946 | struct sym_hist *h = annotation__histogram(notes, evidx); |
| 947 | struct rb_root tmp_root = RB_ROOT; | ||
| 900 | 948 | ||
| 901 | if (!h->sum) | 949 | if (!h->sum) |
| 902 | return 0; | 950 | return 0; |
| @@ -931,12 +979,13 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map, | |||
| 931 | goto next; | 979 | goto next; |
| 932 | 980 | ||
| 933 | strcpy(src_line[i].path, path); | 981 | strcpy(src_line[i].path, path); |
| 934 | insert_source_line(root, &src_line[i]); | 982 | insert_source_line(&tmp_root, &src_line[i]); |
| 935 | 983 | ||
| 936 | next: | 984 | next: |
| 937 | pclose(fp); | 985 | pclose(fp); |
| 938 | } | 986 | } |
| 939 | 987 | ||
| 988 | resort_source_line(root, &tmp_root); | ||
| 940 | return 0; | 989 | return 0; |
| 941 | } | 990 | } |
| 942 | 991 | ||
| @@ -960,7 +1009,7 @@ static void print_summary(struct rb_root *root, const char *filename) | |||
| 960 | char *path; | 1009 | char *path; |
| 961 | 1010 | ||
| 962 | src_line = rb_entry(node, struct source_line, node); | 1011 | src_line = rb_entry(node, struct source_line, node); |
| 963 | percent = src_line->percent; | 1012 | percent = src_line->percent_sum; |
| 964 | color = get_percent_color(percent); | 1013 | color = get_percent_color(percent); |
| 965 | path = src_line->path; | 1014 | path = src_line->path; |
| 966 | 1015 | ||
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index c6272011625..8eec94358a4 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h | |||
| @@ -76,6 +76,7 @@ struct sym_hist { | |||
| 76 | struct source_line { | 76 | struct source_line { |
| 77 | struct rb_node node; | 77 | struct rb_node node; |
| 78 | double percent; | 78 | double percent; |
| 79 | double percent_sum; | ||
| 79 | char *path; | 80 | char *path; |
| 80 | }; | 81 | }; |
| 81 | 82 | ||
