hists.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. #include "../evlist.h"
  2. #include "../cache.h"
  3. #include "../evsel.h"
  4. #include "../sort.h"
  5. #include "../hist.h"
  6. #include "../helpline.h"
  7. #include "gtk.h"
  8. #define MAX_COLUMNS 32
  9. #define HPP__COLOR_FN(_name, _field) \
  10. static int perf_gtk__hpp_color_ ## _name(struct perf_hpp *hpp, \
  11. struct hist_entry *he) \
  12. { \
  13. struct hists *hists = he->hists; \
  14. double percent = 100.0 * he->stat._field / hists->stats.total_period; \
  15. const char *markup; \
  16. int ret = 0; \
  17. \
  18. markup = perf_gtk__get_percent_color(percent); \
  19. if (markup) \
  20. ret += scnprintf(hpp->buf, hpp->size, "%s", markup); \
  21. ret += scnprintf(hpp->buf + ret, hpp->size - ret, "%6.2f%%", percent); \
  22. if (markup) \
  23. ret += scnprintf(hpp->buf + ret, hpp->size - ret, "</span>"); \
  24. \
  25. return ret; \
  26. }
  27. HPP__COLOR_FN(overhead, period)
  28. HPP__COLOR_FN(overhead_sys, period_sys)
  29. HPP__COLOR_FN(overhead_us, period_us)
  30. HPP__COLOR_FN(overhead_guest_sys, period_guest_sys)
  31. HPP__COLOR_FN(overhead_guest_us, period_guest_us)
  32. #undef HPP__COLOR_FN
  33. void perf_gtk__init_hpp(void)
  34. {
  35. perf_hpp__column_enable(PERF_HPP__OVERHEAD);
  36. perf_hpp__init();
  37. perf_hpp__format[PERF_HPP__OVERHEAD].color =
  38. perf_gtk__hpp_color_overhead;
  39. perf_hpp__format[PERF_HPP__OVERHEAD_SYS].color =
  40. perf_gtk__hpp_color_overhead_sys;
  41. perf_hpp__format[PERF_HPP__OVERHEAD_US].color =
  42. perf_gtk__hpp_color_overhead_us;
  43. perf_hpp__format[PERF_HPP__OVERHEAD_GUEST_SYS].color =
  44. perf_gtk__hpp_color_overhead_guest_sys;
  45. perf_hpp__format[PERF_HPP__OVERHEAD_GUEST_US].color =
  46. perf_gtk__hpp_color_overhead_guest_us;
  47. }
  48. static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists)
  49. {
  50. struct perf_hpp_fmt *fmt;
  51. GType col_types[MAX_COLUMNS];
  52. GtkCellRenderer *renderer;
  53. struct sort_entry *se;
  54. GtkListStore *store;
  55. struct rb_node *nd;
  56. GtkWidget *view;
  57. int col_idx;
  58. int nr_cols;
  59. char s[512];
  60. struct perf_hpp hpp = {
  61. .buf = s,
  62. .size = sizeof(s),
  63. };
  64. nr_cols = 0;
  65. perf_hpp__for_each_format(fmt)
  66. col_types[nr_cols++] = G_TYPE_STRING;
  67. list_for_each_entry(se, &hist_entry__sort_list, list) {
  68. if (se->elide)
  69. continue;
  70. col_types[nr_cols++] = G_TYPE_STRING;
  71. }
  72. store = gtk_list_store_newv(nr_cols, col_types);
  73. view = gtk_tree_view_new();
  74. renderer = gtk_cell_renderer_text_new();
  75. col_idx = 0;
  76. perf_hpp__for_each_format(fmt) {
  77. fmt->header(&hpp);
  78. gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view),
  79. -1, s,
  80. renderer, "markup",
  81. col_idx++, NULL);
  82. }
  83. list_for_each_entry(se, &hist_entry__sort_list, list) {
  84. if (se->elide)
  85. continue;
  86. gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(view),
  87. -1, se->se_header,
  88. renderer, "text",
  89. col_idx++, NULL);
  90. }
  91. gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(store));
  92. g_object_unref(GTK_TREE_MODEL(store));
  93. for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) {
  94. struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
  95. GtkTreeIter iter;
  96. if (h->filtered)
  97. continue;
  98. gtk_list_store_append(store, &iter);
  99. col_idx = 0;
  100. perf_hpp__for_each_format(fmt) {
  101. if (fmt->color)
  102. fmt->color(&hpp, h);
  103. else
  104. fmt->entry(&hpp, h);
  105. gtk_list_store_set(store, &iter, col_idx++, s, -1);
  106. }
  107. list_for_each_entry(se, &hist_entry__sort_list, list) {
  108. if (se->elide)
  109. continue;
  110. se->se_snprintf(h, s, ARRAY_SIZE(s),
  111. hists__col_len(hists, se->se_width_idx));
  112. gtk_list_store_set(store, &iter, col_idx++, s, -1);
  113. }
  114. }
  115. gtk_container_add(GTK_CONTAINER(window), view);
  116. }
  117. int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist,
  118. const char *help,
  119. struct hist_browser_timer *hbt __maybe_unused)
  120. {
  121. struct perf_evsel *pos;
  122. GtkWidget *vbox;
  123. GtkWidget *notebook;
  124. GtkWidget *info_bar;
  125. GtkWidget *statbar;
  126. GtkWidget *window;
  127. signal(SIGSEGV, perf_gtk__signal);
  128. signal(SIGFPE, perf_gtk__signal);
  129. signal(SIGINT, perf_gtk__signal);
  130. signal(SIGQUIT, perf_gtk__signal);
  131. signal(SIGTERM, perf_gtk__signal);
  132. window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  133. gtk_window_set_title(GTK_WINDOW(window), "perf report");
  134. g_signal_connect(window, "delete_event", gtk_main_quit, NULL);
  135. pgctx = perf_gtk__activate_context(window);
  136. if (!pgctx)
  137. return -1;
  138. vbox = gtk_vbox_new(FALSE, 0);
  139. notebook = gtk_notebook_new();
  140. gtk_box_pack_start(GTK_BOX(vbox), notebook, TRUE, TRUE, 0);
  141. info_bar = perf_gtk__setup_info_bar();
  142. if (info_bar)
  143. gtk_box_pack_start(GTK_BOX(vbox), info_bar, FALSE, FALSE, 0);
  144. statbar = perf_gtk__setup_statusbar();
  145. gtk_box_pack_start(GTK_BOX(vbox), statbar, FALSE, FALSE, 0);
  146. gtk_container_add(GTK_CONTAINER(window), vbox);
  147. list_for_each_entry(pos, &evlist->entries, node) {
  148. struct hists *hists = &pos->hists;
  149. const char *evname = perf_evsel__name(pos);
  150. GtkWidget *scrolled_window;
  151. GtkWidget *tab_label;
  152. scrolled_window = gtk_scrolled_window_new(NULL, NULL);
  153. gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
  154. GTK_POLICY_AUTOMATIC,
  155. GTK_POLICY_AUTOMATIC);
  156. perf_gtk__show_hists(scrolled_window, hists);
  157. tab_label = gtk_label_new(evname);
  158. gtk_notebook_append_page(GTK_NOTEBOOK(notebook), scrolled_window, tab_label);
  159. }
  160. gtk_widget_show_all(window);
  161. perf_gtk__resize_window(window);
  162. gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
  163. ui_helpline__push(help);
  164. gtk_main();
  165. perf_gtk__deactivate_context(&pgctx);
  166. return 0;
  167. }