aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/builtin-report.c47
1 files changed, 44 insertions, 3 deletions
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index c4a8e108e521..99274cec0adb 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -891,6 +891,21 @@ ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain, int depth,
891 return ret; 891 return ret;
892} 892}
893 893
894static struct symbol *rem_sq_bracket;
895static struct callchain_list rem_hits;
896
897static void init_rem_hits(void)
898{
899 rem_sq_bracket = malloc(sizeof(*rem_sq_bracket) + 6);
900 if (!rem_sq_bracket) {
901 fprintf(stderr, "Not enough memory to display remaining hits\n");
902 return;
903 }
904
905 strcpy(rem_sq_bracket->name, "[...]");
906 rem_hits.sym = rem_sq_bracket;
907}
908
894static size_t 909static size_t
895callchain__fprintf_graph(FILE *fp, struct callchain_node *self, 910callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
896 u64 total_samples, int depth, int depth_mask) 911 u64 total_samples, int depth, int depth_mask)
@@ -900,6 +915,7 @@ callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
900 struct callchain_list *chain; 915 struct callchain_list *chain;
901 int new_depth_mask = depth_mask; 916 int new_depth_mask = depth_mask;
902 u64 new_total; 917 u64 new_total;
918 u64 remaining;
903 size_t ret = 0; 919 size_t ret = 0;
904 int i; 920 int i;
905 921
@@ -908,17 +924,25 @@ callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
908 else 924 else
909 new_total = total_samples; 925 new_total = total_samples;
910 926
927 remaining = new_total;
928
911 node = rb_first(&self->rb_root); 929 node = rb_first(&self->rb_root);
912 while (node) { 930 while (node) {
931 u64 cumul;
932
913 child = rb_entry(node, struct callchain_node, rb_node); 933 child = rb_entry(node, struct callchain_node, rb_node);
934 cumul = cumul_hits(child);
935 remaining -= cumul;
914 936
915 /* 937 /*
916 * The depth mask manages the output of pipes that show 938 * The depth mask manages the output of pipes that show
917 * the depth. We don't want to keep the pipes of the current 939 * the depth. We don't want to keep the pipes of the current
918 * level for the last child of this depth 940 * level for the last child of this depth.
941 * Except if we have remaining filtered hits. They will
942 * supersede the last child
919 */ 943 */
920 next = rb_next(node); 944 next = rb_next(node);
921 if (!next) 945 if (!next && (callchain_param.mode != CHAIN_GRAPH_REL || !remaining))
922 new_depth_mask &= ~(1 << (depth - 1)); 946 new_depth_mask &= ~(1 << (depth - 1));
923 947
924 /* 948 /*
@@ -933,7 +957,7 @@ callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
933 ret += ipchain__fprintf_graph(fp, chain, depth, 957 ret += ipchain__fprintf_graph(fp, chain, depth,
934 new_depth_mask, i++, 958 new_depth_mask, i++,
935 new_total, 959 new_total,
936 cumul_hits(child)); 960 cumul);
937 } 961 }
938 ret += callchain__fprintf_graph(fp, child, new_total, 962 ret += callchain__fprintf_graph(fp, child, new_total,
939 depth + 1, 963 depth + 1,
@@ -941,6 +965,19 @@ callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
941 node = next; 965 node = next;
942 } 966 }
943 967
968 if (callchain_param.mode == CHAIN_GRAPH_REL &&
969 remaining && remaining != new_total) {
970
971 if (!rem_sq_bracket)
972 return ret;
973
974 new_depth_mask &= ~(1 << (depth - 1));
975
976 ret += ipchain__fprintf_graph(fp, &rem_hits, depth,
977 new_depth_mask, 0, new_total,
978 remaining);
979 }
980
944 return ret; 981 return ret;
945} 982}
946 983
@@ -1361,6 +1398,8 @@ static size_t output__fprintf(FILE *fp, u64 total_samples)
1361 unsigned int width; 1398 unsigned int width;
1362 char *col_width = col_width_list_str; 1399 char *col_width = col_width_list_str;
1363 1400
1401 init_rem_hits();
1402
1364 fprintf(fp, "# Samples: %Ld\n", (u64)total_samples); 1403 fprintf(fp, "# Samples: %Ld\n", (u64)total_samples);
1365 fprintf(fp, "#\n"); 1404 fprintf(fp, "#\n");
1366 1405
@@ -1432,6 +1471,8 @@ print_entries:
1432 } 1471 }
1433 fprintf(fp, "\n"); 1472 fprintf(fp, "\n");
1434 1473
1474 free(rem_sq_bracket);
1475
1435 return ret; 1476 return ret;
1436} 1477}
1437 1478