diff options
author | Taeung Song <treeze.taeung@gmail.com> | 2017-07-19 17:36:45 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2017-07-21 07:23:38 -0400 |
commit | 896bccd3cb8d95cbc565687715516009c5169e71 (patch) | |
tree | 32faa9f4668fb1b503926520ab0cf471f3220c73 /tools/perf/util/annotate.c | |
parent | b99e4850df86dfd9dc2cf3f3494e403ff8b46876 (diff) |
perf annotate: Introduce struct sym_hist_entry
struct sym_hist has addr[] but it should have not only number of samples
but also the sample period. So use new struct symhist_entry to pave the
way to have that.
Committer notes:
This initial patch will only introduce the struct sym_hist_entry and use
only the nr_samples member, which makes the code clearer and paves the
way to save the period as well.
Signed-off-by: Taeung Song <treeze.taeung@gmail.com>
Suggested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Link: http://lkml.kernel.org/r/1500500205-16553-1-git-send-email-treeze.taeung@gmail.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/annotate.c')
-rw-r--r-- | tools/perf/util/annotate.c | 45 |
1 files changed, 23 insertions, 22 deletions
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 1742510f0120..c3829555ce1c 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c | |||
@@ -610,10 +610,10 @@ int symbol__alloc_hist(struct symbol *sym) | |||
610 | size_t sizeof_sym_hist; | 610 | size_t sizeof_sym_hist; |
611 | 611 | ||
612 | /* Check for overflow when calculating sizeof_sym_hist */ | 612 | /* Check for overflow when calculating sizeof_sym_hist */ |
613 | if (size > (SIZE_MAX - sizeof(struct sym_hist)) / sizeof(u64)) | 613 | if (size > (SIZE_MAX - sizeof(struct sym_hist)) / sizeof(struct sym_hist_entry)) |
614 | return -1; | 614 | return -1; |
615 | 615 | ||
616 | sizeof_sym_hist = (sizeof(struct sym_hist) + size * sizeof(u64)); | 616 | sizeof_sym_hist = (sizeof(struct sym_hist) + size * sizeof(struct sym_hist_entry)); |
617 | 617 | ||
618 | /* Check for overflow in zalloc argument */ | 618 | /* Check for overflow in zalloc argument */ |
619 | if (sizeof_sym_hist > (SIZE_MAX - sizeof(*notes->src)) | 619 | if (sizeof_sym_hist > (SIZE_MAX - sizeof(*notes->src)) |
@@ -714,11 +714,11 @@ static int __symbol__inc_addr_samples(struct symbol *sym, struct map *map, | |||
714 | offset = addr - sym->start; | 714 | offset = addr - sym->start; |
715 | h = annotation__histogram(notes, evidx); | 715 | h = annotation__histogram(notes, evidx); |
716 | h->sum++; | 716 | h->sum++; |
717 | h->addr[offset]++; | 717 | h->addr[offset].nr_samples++; |
718 | 718 | ||
719 | pr_debug3("%#" PRIx64 " %s: period++ [addr: %#" PRIx64 ", %#" PRIx64 | 719 | pr_debug3("%#" PRIx64 " %s: period++ [addr: %#" PRIx64 ", %#" PRIx64 |
720 | ", evidx=%d] => %" PRIu64 "\n", sym->start, sym->name, | 720 | ", evidx=%d] => %" PRIu64 "\n", sym->start, sym->name, |
721 | addr, addr - sym->start, evidx, h->addr[offset]); | 721 | addr, addr - sym->start, evidx, h->addr[offset].nr_samples); |
722 | return 0; | 722 | return 0; |
723 | } | 723 | } |
724 | 724 | ||
@@ -928,11 +928,12 @@ struct disasm_line *disasm__get_next_ip_line(struct list_head *head, struct disa | |||
928 | } | 928 | } |
929 | 929 | ||
930 | double disasm__calc_percent(struct annotation *notes, int evidx, s64 offset, | 930 | double disasm__calc_percent(struct annotation *notes, int evidx, s64 offset, |
931 | s64 end, const char **path, u64 *nr_samples) | 931 | s64 end, const char **path, struct sym_hist_entry *sample) |
932 | { | 932 | { |
933 | struct source_line *src_line = notes->src->lines; | 933 | struct source_line *src_line = notes->src->lines; |
934 | double percent = 0.0; | 934 | double percent = 0.0; |
935 | *nr_samples = 0; | 935 | |
936 | sample->nr_samples = 0; | ||
936 | 937 | ||
937 | if (src_line) { | 938 | if (src_line) { |
938 | size_t sizeof_src_line = sizeof(*src_line) + | 939 | size_t sizeof_src_line = sizeof(*src_line) + |
@@ -946,7 +947,7 @@ double disasm__calc_percent(struct annotation *notes, int evidx, s64 offset, | |||
946 | *path = src_line->path; | 947 | *path = src_line->path; |
947 | 948 | ||
948 | percent += src_line->samples[evidx].percent; | 949 | percent += src_line->samples[evidx].percent; |
949 | *nr_samples += src_line->samples[evidx].nr; | 950 | sample->nr_samples += src_line->samples[evidx].nr; |
950 | offset++; | 951 | offset++; |
951 | } | 952 | } |
952 | } else { | 953 | } else { |
@@ -954,10 +955,10 @@ double disasm__calc_percent(struct annotation *notes, int evidx, s64 offset, | |||
954 | unsigned int hits = 0; | 955 | unsigned int hits = 0; |
955 | 956 | ||
956 | while (offset < end) | 957 | while (offset < end) |
957 | hits += h->addr[offset++]; | 958 | hits += h->addr[offset++].nr_samples; |
958 | 959 | ||
959 | if (h->sum) { | 960 | if (h->sum) { |
960 | *nr_samples = hits; | 961 | sample->nr_samples = hits; |
961 | percent = 100.0 * hits / h->sum; | 962 | percent = 100.0 * hits / h->sum; |
962 | } | 963 | } |
963 | } | 964 | } |
@@ -1057,10 +1058,10 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st | |||
1057 | 1058 | ||
1058 | if (dl->offset != -1) { | 1059 | if (dl->offset != -1) { |
1059 | const char *path = NULL; | 1060 | const char *path = NULL; |
1060 | u64 nr_samples; | ||
1061 | double percent, max_percent = 0.0; | 1061 | double percent, max_percent = 0.0; |
1062 | double *ppercents = &percent; | 1062 | double *ppercents = &percent; |
1063 | u64 *psamples = &nr_samples; | 1063 | struct sym_hist_entry sample; |
1064 | struct sym_hist_entry *psamples = &sample; | ||
1064 | int i, nr_percent = 1; | 1065 | int i, nr_percent = 1; |
1065 | const char *color; | 1066 | const char *color; |
1066 | struct annotation *notes = symbol__annotation(sym); | 1067 | struct annotation *notes = symbol__annotation(sym); |
@@ -1074,7 +1075,7 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st | |||
1074 | if (perf_evsel__is_group_event(evsel)) { | 1075 | if (perf_evsel__is_group_event(evsel)) { |
1075 | nr_percent = evsel->nr_members; | 1076 | nr_percent = evsel->nr_members; |
1076 | ppercents = calloc(nr_percent, sizeof(double)); | 1077 | ppercents = calloc(nr_percent, sizeof(double)); |
1077 | psamples = calloc(nr_percent, sizeof(u64)); | 1078 | psamples = calloc(nr_percent, sizeof(struct sym_hist_entry)); |
1078 | if (ppercents == NULL || psamples == NULL) { | 1079 | if (ppercents == NULL || psamples == NULL) { |
1079 | return -1; | 1080 | return -1; |
1080 | } | 1081 | } |
@@ -1085,10 +1086,10 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st | |||
1085 | notes->src->lines ? i : evsel->idx + i, | 1086 | notes->src->lines ? i : evsel->idx + i, |
1086 | offset, | 1087 | offset, |
1087 | next ? next->offset : (s64) len, | 1088 | next ? next->offset : (s64) len, |
1088 | &path, &nr_samples); | 1089 | &path, &sample); |
1089 | 1090 | ||
1090 | ppercents[i] = percent; | 1091 | ppercents[i] = percent; |
1091 | psamples[i] = nr_samples; | 1092 | psamples[i] = sample; |
1092 | if (percent > max_percent) | 1093 | if (percent > max_percent) |
1093 | max_percent = percent; | 1094 | max_percent = percent; |
1094 | } | 1095 | } |
@@ -1126,12 +1127,12 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st | |||
1126 | 1127 | ||
1127 | for (i = 0; i < nr_percent; i++) { | 1128 | for (i = 0; i < nr_percent; i++) { |
1128 | percent = ppercents[i]; | 1129 | percent = ppercents[i]; |
1129 | nr_samples = psamples[i]; | 1130 | sample = psamples[i]; |
1130 | color = get_percent_color(percent); | 1131 | color = get_percent_color(percent); |
1131 | 1132 | ||
1132 | if (symbol_conf.show_total_period) | 1133 | if (symbol_conf.show_total_period) |
1133 | color_fprintf(stdout, color, " %7" PRIu64, | 1134 | color_fprintf(stdout, color, " %7" PRIu64, |
1134 | nr_samples); | 1135 | sample.nr_samples); |
1135 | else | 1136 | else |
1136 | color_fprintf(stdout, color, " %7.2f", percent); | 1137 | color_fprintf(stdout, color, " %7.2f", percent); |
1137 | } | 1138 | } |
@@ -1147,7 +1148,7 @@ static int disasm_line__print(struct disasm_line *dl, struct symbol *sym, u64 st | |||
1147 | if (ppercents != &percent) | 1148 | if (ppercents != &percent) |
1148 | free(ppercents); | 1149 | free(ppercents); |
1149 | 1150 | ||
1150 | if (psamples != &nr_samples) | 1151 | if (psamples != &sample) |
1151 | free(psamples); | 1152 | free(psamples); |
1152 | 1153 | ||
1153 | } else if (max_lines && printed >= max_lines) | 1154 | } else if (max_lines && printed >= max_lines) |
@@ -1702,7 +1703,7 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map, | |||
1702 | double percent = 0.0; | 1703 | double percent = 0.0; |
1703 | 1704 | ||
1704 | h = annotation__histogram(notes, evidx + k); | 1705 | h = annotation__histogram(notes, evidx + k); |
1705 | nr_samples = h->addr[i]; | 1706 | nr_samples = h->addr[i].nr_samples; |
1706 | if (h->sum) | 1707 | if (h->sum) |
1707 | percent = 100.0 * nr_samples / h->sum; | 1708 | percent = 100.0 * nr_samples / h->sum; |
1708 | 1709 | ||
@@ -1773,9 +1774,9 @@ static void symbol__annotate_hits(struct symbol *sym, struct perf_evsel *evsel) | |||
1773 | u64 len = symbol__size(sym), offset; | 1774 | u64 len = symbol__size(sym), offset; |
1774 | 1775 | ||
1775 | for (offset = 0; offset < len; ++offset) | 1776 | for (offset = 0; offset < len; ++offset) |
1776 | if (h->addr[offset] != 0) | 1777 | if (h->addr[offset].nr_samples != 0) |
1777 | printf("%*" PRIx64 ": %" PRIu64 "\n", BITS_PER_LONG / 2, | 1778 | printf("%*" PRIx64 ": %" PRIu64 "\n", BITS_PER_LONG / 2, |
1778 | sym->start + offset, h->addr[offset]); | 1779 | sym->start + offset, h->addr[offset].nr_samples); |
1779 | printf("%*s: %" PRIu64 "\n", BITS_PER_LONG / 2, "h->sum", h->sum); | 1780 | printf("%*s: %" PRIu64 "\n", BITS_PER_LONG / 2, "h->sum", h->sum); |
1780 | } | 1781 | } |
1781 | 1782 | ||
@@ -1878,8 +1879,8 @@ void symbol__annotate_decay_histogram(struct symbol *sym, int evidx) | |||
1878 | 1879 | ||
1879 | h->sum = 0; | 1880 | h->sum = 0; |
1880 | for (offset = 0; offset < len; ++offset) { | 1881 | for (offset = 0; offset < len; ++offset) { |
1881 | h->addr[offset] = h->addr[offset] * 7 / 8; | 1882 | h->addr[offset].nr_samples = h->addr[offset].nr_samples * 7 / 8; |
1882 | h->sum += h->addr[offset]; | 1883 | h->sum += h->addr[offset].nr_samples; |
1883 | } | 1884 | } |
1884 | } | 1885 | } |
1885 | 1886 | ||