aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-05-30 14:12:00 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-30 14:12:00 -0400
commit65a50c951a38e9827dd9655b6e686bde912e799b (patch)
treecce85e74511741d52069977fee6984ce66c9277c /tools
parent42fe55ce905212542426fa6407a76534a5fb696a (diff)
parent59cd358a7a5b2f6b61faa01dae6cfda3830ac62a (diff)
Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf updates from Ingo Molnar. * 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (21 commits) perf ui browser: Stop using 'self' perf annotate browser: Read perf config file for settings perf config: Allow '_' in config file variable names perf annotate browser: Make feature toggles global perf annotate browser: The idx_asm field should be used in asm only view perf tools: Convert critical messages to ui__error() perf ui: Make --stdio default when TUI is not supported tools lib traceevent: Silence compiler warning on 32bit build perf record: Fix branch_stack type in perf_record_opts perf tools: Reconstruct event with modifiers from perf_event_attr perf top: Fix counter name fixup when fallbacking to cpu-clock perf tools: fix thread_map__new_by_pid_str() memory leak in error path perf tools: Do not use _FORTIFY_SOURCE when DEBUG=1 is specified tools lib traceevent: Fix signature of create_arg_item() tools lib traceevent: Use proper function parameter type tools lib traceevent: Fix freeing arg on process_dynamic_array() tools lib traceevent: Fix a possibly wrong memory dereference tools lib traceevent: Fix a possible memory leak tools lib traceevent: Allow expressions in __print_symbolic() fields perf evlist: Explicititely initialize input_name ...
Diffstat (limited to 'tools')
-rw-r--r--tools/lib/traceevent/event-parse.c22
-rw-r--r--tools/lib/traceevent/parse-filter.c7
-rw-r--r--tools/perf/Documentation/perfconfig.example8
-rw-r--r--tools/perf/Makefile4
-rw-r--r--tools/perf/builtin-annotate.c2
-rw-r--r--tools/perf/builtin-evlist.c2
-rw-r--r--tools/perf/builtin-record.c14
-rw-r--r--tools/perf/builtin-report.c14
-rw-r--r--tools/perf/builtin-top.c24
-rw-r--r--tools/perf/perf.h2
-rw-r--r--tools/perf/ui/browser.c182
-rw-r--r--tools/perf/ui/browser.h1
-rw-r--r--tools/perf/ui/browsers/annotate.c262
-rw-r--r--tools/perf/ui/browsers/hists.c338
-rw-r--r--tools/perf/ui/setup.c1
-rw-r--r--tools/perf/util/config.c2
-rw-r--r--tools/perf/util/evsel.c90
-rw-r--r--tools/perf/util/evsel.h3
-rw-r--r--tools/perf/util/parse-events.c27
-rw-r--r--tools/perf/util/thread_map.c21
20 files changed, 610 insertions, 416 deletions
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index 998534992197..554828219c33 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -1434,8 +1434,11 @@ static int event_read_fields(struct event_format *event, struct format_field **f
1434fail: 1434fail:
1435 free_token(token); 1435 free_token(token);
1436fail_expect: 1436fail_expect:
1437 if (field) 1437 if (field) {
1438 free(field->type);
1439 free(field->name);
1438 free(field); 1440 free(field);
1441 }
1439 return -1; 1442 return -1;
1440} 1443}
1441 1444
@@ -1712,6 +1715,8 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok)
1712 1715
1713 if (set_op_prio(arg) == -1) { 1716 if (set_op_prio(arg) == -1) {
1714 event->flags |= EVENT_FL_FAILED; 1717 event->flags |= EVENT_FL_FAILED;
1718 /* arg->op.op (= token) will be freed at out_free */
1719 arg->op.op = NULL;
1715 goto out_free; 1720 goto out_free;
1716 } 1721 }
1717 1722
@@ -2124,6 +2129,13 @@ process_fields(struct event_format *event, struct print_flag_sym **list, char **
2124 2129
2125 free_token(token); 2130 free_token(token);
2126 type = process_arg(event, arg, &token); 2131 type = process_arg(event, arg, &token);
2132
2133 if (type == EVENT_OP)
2134 type = process_op(event, arg, &token);
2135
2136 if (type == EVENT_ERROR)
2137 goto out_free;
2138
2127 if (test_type_token(type, token, EVENT_DELIM, ",")) 2139 if (test_type_token(type, token, EVENT_DELIM, ","))
2128 goto out_free; 2140 goto out_free;
2129 2141
@@ -2288,17 +2300,18 @@ process_dynamic_array(struct event_format *event, struct print_arg *arg, char **
2288 arg = alloc_arg(); 2300 arg = alloc_arg();
2289 type = process_arg(event, arg, &token); 2301 type = process_arg(event, arg, &token);
2290 if (type == EVENT_ERROR) 2302 if (type == EVENT_ERROR)
2291 goto out_free; 2303 goto out_free_arg;
2292 2304
2293 if (!test_type_token(type, token, EVENT_OP, "]")) 2305 if (!test_type_token(type, token, EVENT_OP, "]"))
2294 goto out_free; 2306 goto out_free_arg;
2295 2307
2296 free_token(token); 2308 free_token(token);
2297 type = read_token_item(tok); 2309 type = read_token_item(tok);
2298 return type; 2310 return type;
2299 2311
2312 out_free_arg:
2313 free_arg(arg);
2300 out_free: 2314 out_free:
2301 free(arg);
2302 free_token(token); 2315 free_token(token);
2303 *tok = NULL; 2316 *tok = NULL;
2304 return EVENT_ERROR; 2317 return EVENT_ERROR;
@@ -3362,6 +3375,7 @@ process_defined_func(struct trace_seq *s, void *data, int size,
3362 break; 3375 break;
3363 } 3376 }
3364 farg = farg->next; 3377 farg = farg->next;
3378 param = param->next;
3365 } 3379 }
3366 3380
3367 ret = (*func_handle->func)(s, args); 3381 ret = (*func_handle->func)(s, args);
diff --git a/tools/lib/traceevent/parse-filter.c b/tools/lib/traceevent/parse-filter.c
index 2d40c5ed81d6..dfcfe2c131de 100644
--- a/tools/lib/traceevent/parse-filter.c
+++ b/tools/lib/traceevent/parse-filter.c
@@ -325,9 +325,8 @@ static void free_events(struct event_list *events)
325} 325}
326 326
327static struct filter_arg * 327static struct filter_arg *
328create_arg_item(struct event_format *event, 328create_arg_item(struct event_format *event, const char *token,
329 const char *token, enum filter_arg_type type, 329 enum event_type type, char **error_str)
330 char **error_str)
331{ 330{
332 struct format_field *field; 331 struct format_field *field;
333 struct filter_arg *arg; 332 struct filter_arg *arg;
@@ -1585,7 +1584,7 @@ get_value(struct event_format *event,
1585 const char *name; 1584 const char *name;
1586 1585
1587 name = get_comm(event, record); 1586 name = get_comm(event, record);
1588 return (unsigned long long)name; 1587 return (unsigned long)name;
1589 } 1588 }
1590 1589
1591 pevent_read_number_field(field, record->data, &val); 1590 pevent_read_number_field(field, record->data, &val);
diff --git a/tools/perf/Documentation/perfconfig.example b/tools/perf/Documentation/perfconfig.example
index 42c6fd2ae85d..767ea2436e1c 100644
--- a/tools/perf/Documentation/perfconfig.example
+++ b/tools/perf/Documentation/perfconfig.example
@@ -19,3 +19,11 @@
19 19
20 # Default, disable using /dev/null 20 # Default, disable using /dev/null
21 dir = /root/.debug 21 dir = /root/.debug
22
23[annotate]
24
25 # Defaults
26 hide_src_code = false
27 use_offset = true
28 jump_arrows = true
29 show_nr_jumps = false
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 1d3d513beb9b..0eee64cfe9a0 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -80,7 +80,7 @@ ifeq ("$(origin DEBUG)", "command line")
80 PERF_DEBUG = $(DEBUG) 80 PERF_DEBUG = $(DEBUG)
81endif 81endif
82ifndef PERF_DEBUG 82ifndef PERF_DEBUG
83 CFLAGS_OPTIMIZE = -O6 83 CFLAGS_OPTIMIZE = -O6 -D_FORTIFY_SOURCE=2
84endif 84endif
85 85
86ifdef PARSER_DEBUG 86ifdef PARSER_DEBUG
@@ -89,7 +89,7 @@ ifdef PARSER_DEBUG
89 PARSER_DEBUG_CFLAGS := -DPARSER_DEBUG 89 PARSER_DEBUG_CFLAGS := -DPARSER_DEBUG
90endif 90endif
91 91
92CFLAGS = -fno-omit-frame-pointer -ggdb3 -Wall -Wextra -std=gnu99 $(CFLAGS_WERROR) $(CFLAGS_OPTIMIZE) -D_FORTIFY_SOURCE=2 $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) $(PARSER_DEBUG_CFLAGS) 92CFLAGS = -fno-omit-frame-pointer -ggdb3 -Wall -Wextra -std=gnu99 $(CFLAGS_WERROR) $(CFLAGS_OPTIMIZE) $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) $(PARSER_DEBUG_CFLAGS)
93EXTLIBS = -lpthread -lrt -lelf -lm 93EXTLIBS = -lpthread -lrt -lelf -lm
94ALL_CFLAGS = $(CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE 94ALL_CFLAGS = $(CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
95ALL_LDFLAGS = $(LDFLAGS) 95ALL_LDFLAGS = $(LDFLAGS)
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 806e0a286634..67522cf87405 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -215,7 +215,7 @@ static int __cmd_annotate(struct perf_annotate *ann)
215 } 215 }
216 216
217 if (total_nr_samples == 0) { 217 if (total_nr_samples == 0) {
218 ui__warning("The %s file has no samples!\n", session->filename); 218 ui__error("The %s file has no samples!\n", session->filename);
219 goto out_delete; 219 goto out_delete;
220 } 220 }
221out_delete: 221out_delete:
diff --git a/tools/perf/builtin-evlist.c b/tools/perf/builtin-evlist.c
index e52d77ec7084..acd78dc28341 100644
--- a/tools/perf/builtin-evlist.c
+++ b/tools/perf/builtin-evlist.c
@@ -116,7 +116,7 @@ static const char * const evlist_usage[] = {
116int cmd_evlist(int argc, const char **argv, const char *prefix __used) 116int cmd_evlist(int argc, const char **argv, const char *prefix __used)
117{ 117{
118 struct perf_attr_details details = { .verbose = false, }; 118 struct perf_attr_details details = { .verbose = false, };
119 const char *input_name; 119 const char *input_name = NULL;
120 const struct option options[] = { 120 const struct option options[] = {
121 OPT_STRING('i', "input", &input_name, "file", 121 OPT_STRING('i', "input", &input_name, "file",
122 "Input file name"), 122 "Input file name"),
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index e5cb08427e13..f95840d04e4c 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -264,7 +264,7 @@ try_again:
264 } 264 }
265 265
266 if (err == ENOENT) { 266 if (err == ENOENT) {
267 ui__warning("The %s event is not supported.\n", 267 ui__error("The %s event is not supported.\n",
268 event_name(pos)); 268 event_name(pos));
269 exit(EXIT_FAILURE); 269 exit(EXIT_FAILURE);
270 } 270 }
@@ -858,8 +858,8 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
858 usage_with_options(record_usage, record_options); 858 usage_with_options(record_usage, record_options);
859 859
860 if (rec->force && rec->append_file) { 860 if (rec->force && rec->append_file) {
861 fprintf(stderr, "Can't overwrite and append at the same time." 861 ui__error("Can't overwrite and append at the same time."
862 " You need to choose between -f and -A"); 862 " You need to choose between -f and -A");
863 usage_with_options(record_usage, record_options); 863 usage_with_options(record_usage, record_options);
864 } else if (rec->append_file) { 864 } else if (rec->append_file) {
865 rec->write_mode = WRITE_APPEND; 865 rec->write_mode = WRITE_APPEND;
@@ -868,8 +868,8 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
868 } 868 }
869 869
870 if (nr_cgroups && !rec->opts.target.system_wide) { 870 if (nr_cgroups && !rec->opts.target.system_wide) {
871 fprintf(stderr, "cgroup monitoring only available in" 871 ui__error("cgroup monitoring only available in"
872 " system-wide mode\n"); 872 " system-wide mode\n");
873 usage_with_options(record_usage, record_options); 873 usage_with_options(record_usage, record_options);
874 } 874 }
875 875
@@ -905,7 +905,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
905 int saved_errno = errno; 905 int saved_errno = errno;
906 906
907 perf_target__strerror(&rec->opts.target, err, errbuf, BUFSIZ); 907 perf_target__strerror(&rec->opts.target, err, errbuf, BUFSIZ);
908 ui__warning("%s", errbuf); 908 ui__error("%s", errbuf);
909 909
910 err = -saved_errno; 910 err = -saved_errno;
911 goto out_free_fd; 911 goto out_free_fd;
@@ -933,7 +933,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
933 else if (rec->opts.freq) { 933 else if (rec->opts.freq) {
934 rec->opts.default_interval = rec->opts.freq; 934 rec->opts.default_interval = rec->opts.freq;
935 } else { 935 } else {
936 fprintf(stderr, "frequency and count are zero, aborting\n"); 936 ui__error("frequency and count are zero, aborting\n");
937 err = -EINVAL; 937 err = -EINVAL;
938 goto out_free_fd; 938 goto out_free_fd;
939 } 939 }
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index d58e41445d0d..8c767c6bca91 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -251,13 +251,13 @@ static int perf_report__setup_sample_type(struct perf_report *rep)
251 251
252 if (!(self->sample_type & PERF_SAMPLE_CALLCHAIN)) { 252 if (!(self->sample_type & PERF_SAMPLE_CALLCHAIN)) {
253 if (sort__has_parent) { 253 if (sort__has_parent) {
254 ui__warning("Selected --sort parent, but no " 254 ui__error("Selected --sort parent, but no "
255 "callchain data. Did you call " 255 "callchain data. Did you call "
256 "'perf record' without -g?\n"); 256 "'perf record' without -g?\n");
257 return -EINVAL; 257 return -EINVAL;
258 } 258 }
259 if (symbol_conf.use_callchain) { 259 if (symbol_conf.use_callchain) {
260 ui__warning("Selected -g but no callchain data. Did " 260 ui__error("Selected -g but no callchain data. Did "
261 "you call 'perf record' without -g?\n"); 261 "you call 'perf record' without -g?\n");
262 return -1; 262 return -1;
263 } 263 }
@@ -266,17 +266,15 @@ static int perf_report__setup_sample_type(struct perf_report *rep)
266 !symbol_conf.use_callchain) { 266 !symbol_conf.use_callchain) {
267 symbol_conf.use_callchain = true; 267 symbol_conf.use_callchain = true;
268 if (callchain_register_param(&callchain_param) < 0) { 268 if (callchain_register_param(&callchain_param) < 0) {
269 ui__warning("Can't register callchain " 269 ui__error("Can't register callchain params.\n");
270 "params.\n");
271 return -EINVAL; 270 return -EINVAL;
272 } 271 }
273 } 272 }
274 273
275 if (sort__branch_mode == 1) { 274 if (sort__branch_mode == 1) {
276 if (!(self->sample_type & PERF_SAMPLE_BRANCH_STACK)) { 275 if (!(self->sample_type & PERF_SAMPLE_BRANCH_STACK)) {
277 fprintf(stderr, "selected -b but no branch data." 276 ui__error("Selected -b but no branch data. "
278 " Did you call perf record without" 277 "Did you call perf record without -b?\n");
279 " -b?\n");
280 return -1; 278 return -1;
281 } 279 }
282 } 280 }
@@ -420,7 +418,7 @@ static int __cmd_report(struct perf_report *rep)
420 } 418 }
421 419
422 if (nr_samples == 0) { 420 if (nr_samples == 0) {
423 ui__warning("The %s file has no samples!\n", session->filename); 421 ui__error("The %s file has no samples!\n", session->filename);
424 goto out_delete; 422 goto out_delete;
425 } 423 }
426 424
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 6031dce0429f..871b540293e1 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -953,22 +953,22 @@ try_again:
953 attr->config = PERF_COUNT_SW_CPU_CLOCK; 953 attr->config = PERF_COUNT_SW_CPU_CLOCK;
954 if (counter->name) { 954 if (counter->name) {
955 free(counter->name); 955 free(counter->name);
956 counter->name = strdup(event_name(counter)); 956 counter->name = NULL;
957 } 957 }
958 goto try_again; 958 goto try_again;
959 } 959 }
960 960
961 if (err == ENOENT) { 961 if (err == ENOENT) {
962 ui__warning("The %s event is not supported.\n", 962 ui__error("The %s event is not supported.\n",
963 event_name(counter)); 963 event_name(counter));
964 goto out_err; 964 goto out_err;
965 } else if (err == EMFILE) { 965 } else if (err == EMFILE) {
966 ui__warning("Too many events are opened.\n" 966 ui__error("Too many events are opened.\n"
967 "Try again after reducing the number of events\n"); 967 "Try again after reducing the number of events\n");
968 goto out_err; 968 goto out_err;
969 } 969 }
970 970
971 ui__warning("The sys_perf_event_open() syscall " 971 ui__error("The sys_perf_event_open() syscall "
972 "returned with %d (%s). /bin/dmesg " 972 "returned with %d (%s). /bin/dmesg "
973 "may provide additional information.\n" 973 "may provide additional information.\n"
974 "No CONFIG_PERF_EVENTS=y kernel support " 974 "No CONFIG_PERF_EVENTS=y kernel support "
@@ -978,7 +978,7 @@ try_again:
978 } 978 }
979 979
980 if (perf_evlist__mmap(evlist, top->mmap_pages, false) < 0) { 980 if (perf_evlist__mmap(evlist, top->mmap_pages, false) < 0) {
981 ui__warning("Failed to mmap with %d (%s)\n", 981 ui__error("Failed to mmap with %d (%s)\n",
982 errno, strerror(errno)); 982 errno, strerror(errno));
983 goto out_err; 983 goto out_err;
984 } 984 }
@@ -994,12 +994,12 @@ static int perf_top__setup_sample_type(struct perf_top *top)
994{ 994{
995 if (!top->sort_has_symbols) { 995 if (!top->sort_has_symbols) {
996 if (symbol_conf.use_callchain) { 996 if (symbol_conf.use_callchain) {
997 ui__warning("Selected -g but \"sym\" not present in --sort/-s."); 997 ui__error("Selected -g but \"sym\" not present in --sort/-s.");
998 return -EINVAL; 998 return -EINVAL;
999 } 999 }
1000 } else if (!top->dont_use_callchains && callchain_param.mode != CHAIN_NONE) { 1000 } else if (!top->dont_use_callchains && callchain_param.mode != CHAIN_NONE) {
1001 if (callchain_register_param(&callchain_param) < 0) { 1001 if (callchain_register_param(&callchain_param) < 0) {
1002 ui__warning("Can't register callchain params.\n"); 1002 ui__error("Can't register callchain params.\n");
1003 return -EINVAL; 1003 return -EINVAL;
1004 } 1004 }
1005 } 1005 }
@@ -1041,7 +1041,7 @@ static int __cmd_top(struct perf_top *top)
1041 1041
1042 if (pthread_create(&thread, NULL, (use_browser > 0 ? display_thread_tui : 1042 if (pthread_create(&thread, NULL, (use_browser > 0 ? display_thread_tui :
1043 display_thread), top)) { 1043 display_thread), top)) {
1044 printf("Could not create display thread.\n"); 1044 ui__error("Could not create display thread.\n");
1045 exit(-1); 1045 exit(-1);
1046 } 1046 }
1047 1047
@@ -1050,7 +1050,7 @@ static int __cmd_top(struct perf_top *top)
1050 1050
1051 param.sched_priority = top->realtime_prio; 1051 param.sched_priority = top->realtime_prio;
1052 if (sched_setscheduler(0, SCHED_FIFO, &param)) { 1052 if (sched_setscheduler(0, SCHED_FIFO, &param)) {
1053 printf("Could not set realtime priority.\n"); 1053 ui__error("Could not set realtime priority.\n");
1054 exit(-1); 1054 exit(-1);
1055 } 1055 }
1056 } 1056 }
@@ -1274,7 +1274,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
1274 int saved_errno = errno; 1274 int saved_errno = errno;
1275 1275
1276 perf_target__strerror(&top.target, status, errbuf, BUFSIZ); 1276 perf_target__strerror(&top.target, status, errbuf, BUFSIZ);
1277 ui__warning("%s", errbuf); 1277 ui__error("%s", errbuf);
1278 1278
1279 status = -saved_errno; 1279 status = -saved_errno;
1280 goto out_delete_evlist; 1280 goto out_delete_evlist;
@@ -1288,7 +1288,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
1288 1288
1289 if (!top.evlist->nr_entries && 1289 if (!top.evlist->nr_entries &&
1290 perf_evlist__add_default(top.evlist) < 0) { 1290 perf_evlist__add_default(top.evlist) < 0) {
1291 pr_err("Not enough memory for event selector list\n"); 1291 ui__error("Not enough memory for event selector list\n");
1292 return -ENOMEM; 1292 return -ENOMEM;
1293 } 1293 }
1294 1294
@@ -1305,7 +1305,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
1305 else if (top.freq) { 1305 else if (top.freq) {
1306 top.default_interval = top.freq; 1306 top.default_interval = top.freq;
1307 } else { 1307 } else {
1308 fprintf(stderr, "frequency and count are zero, aborting\n"); 1308 ui__error("frequency and count are zero, aborting\n");
1309 exit(EXIT_FAILURE); 1309 exit(EXIT_FAILURE);
1310 } 1310 }
1311 1311
diff --git a/tools/perf/perf.h b/tools/perf/perf.h
index 14f1034f14f9..f960ccb2edc6 100644
--- a/tools/perf/perf.h
+++ b/tools/perf/perf.h
@@ -227,7 +227,7 @@ struct perf_record_opts {
227 unsigned int freq; 227 unsigned int freq;
228 unsigned int mmap_pages; 228 unsigned int mmap_pages;
229 unsigned int user_freq; 229 unsigned int user_freq;
230 int branch_stack; 230 u64 branch_stack;
231 u64 default_interval; 231 u64 default_interval;
232 u64 user_interval; 232 u64 user_interval;
233}; 233};
diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c
index cde4d0f0ddb9..1818a531f1d3 100644
--- a/tools/perf/ui/browser.c
+++ b/tools/perf/ui/browser.c
@@ -35,16 +35,16 @@ int ui_browser__set_color(struct ui_browser *browser, int color)
35 return ret; 35 return ret;
36} 36}
37 37
38void ui_browser__set_percent_color(struct ui_browser *self, 38void ui_browser__set_percent_color(struct ui_browser *browser,
39 double percent, bool current) 39 double percent, bool current)
40{ 40{
41 int color = ui_browser__percent_color(self, percent, current); 41 int color = ui_browser__percent_color(browser, percent, current);
42 ui_browser__set_color(self, color); 42 ui_browser__set_color(browser, color);
43} 43}
44 44
45void ui_browser__gotorc(struct ui_browser *self, int y, int x) 45void ui_browser__gotorc(struct ui_browser *browser, int y, int x)
46{ 46{
47 SLsmg_gotorc(self->y + y, self->x + x); 47 SLsmg_gotorc(browser->y + y, browser->x + x);
48} 48}
49 49
50static struct list_head * 50static struct list_head *
@@ -73,23 +73,23 @@ ui_browser__list_head_filter_prev_entries(struct ui_browser *browser,
73 return NULL; 73 return NULL;
74} 74}
75 75
76void ui_browser__list_head_seek(struct ui_browser *self, off_t offset, int whence) 76void ui_browser__list_head_seek(struct ui_browser *browser, off_t offset, int whence)
77{ 77{
78 struct list_head *head = self->entries; 78 struct list_head *head = browser->entries;
79 struct list_head *pos; 79 struct list_head *pos;
80 80
81 if (self->nr_entries == 0) 81 if (browser->nr_entries == 0)
82 return; 82 return;
83 83
84 switch (whence) { 84 switch (whence) {
85 case SEEK_SET: 85 case SEEK_SET:
86 pos = ui_browser__list_head_filter_entries(self, head->next); 86 pos = ui_browser__list_head_filter_entries(browser, head->next);
87 break; 87 break;
88 case SEEK_CUR: 88 case SEEK_CUR:
89 pos = self->top; 89 pos = browser->top;
90 break; 90 break;
91 case SEEK_END: 91 case SEEK_END:
92 pos = ui_browser__list_head_filter_prev_entries(self, head->prev); 92 pos = ui_browser__list_head_filter_prev_entries(browser, head->prev);
93 break; 93 break;
94 default: 94 default:
95 return; 95 return;
@@ -99,18 +99,18 @@ void ui_browser__list_head_seek(struct ui_browser *self, off_t offset, int whenc
99 99
100 if (offset > 0) { 100 if (offset > 0) {
101 while (offset-- != 0) 101 while (offset-- != 0)
102 pos = ui_browser__list_head_filter_entries(self, pos->next); 102 pos = ui_browser__list_head_filter_entries(browser, pos->next);
103 } else { 103 } else {
104 while (offset++ != 0) 104 while (offset++ != 0)
105 pos = ui_browser__list_head_filter_prev_entries(self, pos->prev); 105 pos = ui_browser__list_head_filter_prev_entries(browser, pos->prev);
106 } 106 }
107 107
108 self->top = pos; 108 browser->top = pos;
109} 109}
110 110
111void ui_browser__rb_tree_seek(struct ui_browser *self, off_t offset, int whence) 111void ui_browser__rb_tree_seek(struct ui_browser *browser, off_t offset, int whence)
112{ 112{
113 struct rb_root *root = self->entries; 113 struct rb_root *root = browser->entries;
114 struct rb_node *nd; 114 struct rb_node *nd;
115 115
116 switch (whence) { 116 switch (whence) {
@@ -118,7 +118,7 @@ void ui_browser__rb_tree_seek(struct ui_browser *self, off_t offset, int whence)
118 nd = rb_first(root); 118 nd = rb_first(root);
119 break; 119 break;
120 case SEEK_CUR: 120 case SEEK_CUR:
121 nd = self->top; 121 nd = browser->top;
122 break; 122 break;
123 case SEEK_END: 123 case SEEK_END:
124 nd = rb_last(root); 124 nd = rb_last(root);
@@ -135,23 +135,23 @@ void ui_browser__rb_tree_seek(struct ui_browser *self, off_t offset, int whence)
135 nd = rb_prev(nd); 135 nd = rb_prev(nd);
136 } 136 }
137 137
138 self->top = nd; 138 browser->top = nd;
139} 139}
140 140
141unsigned int ui_browser__rb_tree_refresh(struct ui_browser *self) 141unsigned int ui_browser__rb_tree_refresh(struct ui_browser *browser)
142{ 142{
143 struct rb_node *nd; 143 struct rb_node *nd;
144 int row = 0; 144 int row = 0;
145 145
146 if (self->top == NULL) 146 if (browser->top == NULL)
147 self->top = rb_first(self->entries); 147 browser->top = rb_first(browser->entries);
148 148
149 nd = self->top; 149 nd = browser->top;
150 150
151 while (nd != NULL) { 151 while (nd != NULL) {
152 ui_browser__gotorc(self, row, 0); 152 ui_browser__gotorc(browser, row, 0);
153 self->write(self, nd, row); 153 browser->write(browser, nd, row);
154 if (++row == self->height) 154 if (++row == browser->height)
155 break; 155 break;
156 nd = rb_next(nd); 156 nd = rb_next(nd);
157 } 157 }
@@ -159,17 +159,17 @@ unsigned int ui_browser__rb_tree_refresh(struct ui_browser *self)
159 return row; 159 return row;
160} 160}
161 161
162bool ui_browser__is_current_entry(struct ui_browser *self, unsigned row) 162bool ui_browser__is_current_entry(struct ui_browser *browser, unsigned row)
163{ 163{
164 return self->top_idx + row == self->index; 164 return browser->top_idx + row == browser->index;
165} 165}
166 166
167void ui_browser__refresh_dimensions(struct ui_browser *self) 167void ui_browser__refresh_dimensions(struct ui_browser *browser)
168{ 168{
169 self->width = SLtt_Screen_Cols - 1; 169 browser->width = SLtt_Screen_Cols - 1;
170 self->height = SLtt_Screen_Rows - 2; 170 browser->height = SLtt_Screen_Rows - 2;
171 self->y = 1; 171 browser->y = 1;
172 self->x = 0; 172 browser->x = 0;
173} 173}
174 174
175void ui_browser__handle_resize(struct ui_browser *browser) 175void ui_browser__handle_resize(struct ui_browser *browser)
@@ -225,10 +225,10 @@ bool ui_browser__dialog_yesno(struct ui_browser *browser, const char *text)
225 return key == K_ENTER || toupper(key) == 'Y'; 225 return key == K_ENTER || toupper(key) == 'Y';
226} 226}
227 227
228void ui_browser__reset_index(struct ui_browser *self) 228void ui_browser__reset_index(struct ui_browser *browser)
229{ 229{
230 self->index = self->top_idx = 0; 230 browser->index = browser->top_idx = 0;
231 self->seek(self, 0, SEEK_SET); 231 browser->seek(browser, 0, SEEK_SET);
232} 232}
233 233
234void __ui_browser__show_title(struct ui_browser *browser, const char *title) 234void __ui_browser__show_title(struct ui_browser *browser, const char *title)
@@ -245,26 +245,26 @@ void ui_browser__show_title(struct ui_browser *browser, const char *title)
245 pthread_mutex_unlock(&ui__lock); 245 pthread_mutex_unlock(&ui__lock);
246} 246}
247 247
248int ui_browser__show(struct ui_browser *self, const char *title, 248int ui_browser__show(struct ui_browser *browser, const char *title,
249 const char *helpline, ...) 249 const char *helpline, ...)
250{ 250{
251 int err; 251 int err;
252 va_list ap; 252 va_list ap;
253 253
254 ui_browser__refresh_dimensions(self); 254 ui_browser__refresh_dimensions(browser);
255 255
256 pthread_mutex_lock(&ui__lock); 256 pthread_mutex_lock(&ui__lock);
257 __ui_browser__show_title(self, title); 257 __ui_browser__show_title(browser, title);
258 258
259 self->title = title; 259 browser->title = title;
260 free(self->helpline); 260 free(browser->helpline);
261 self->helpline = NULL; 261 browser->helpline = NULL;
262 262
263 va_start(ap, helpline); 263 va_start(ap, helpline);
264 err = vasprintf(&self->helpline, helpline, ap); 264 err = vasprintf(&browser->helpline, helpline, ap);
265 va_end(ap); 265 va_end(ap);
266 if (err > 0) 266 if (err > 0)
267 ui_helpline__push(self->helpline); 267 ui_helpline__push(browser->helpline);
268 pthread_mutex_unlock(&ui__lock); 268 pthread_mutex_unlock(&ui__lock);
269 return err ? 0 : -1; 269 return err ? 0 : -1;
270} 270}
@@ -350,7 +350,7 @@ void ui_browser__update_nr_entries(struct ui_browser *browser, u32 nr_entries)
350 browser->seek(browser, browser->top_idx, SEEK_SET); 350 browser->seek(browser, browser->top_idx, SEEK_SET);
351} 351}
352 352
353int ui_browser__run(struct ui_browser *self, int delay_secs) 353int ui_browser__run(struct ui_browser *browser, int delay_secs)
354{ 354{
355 int err, key; 355 int err, key;
356 356
@@ -358,7 +358,7 @@ int ui_browser__run(struct ui_browser *self, int delay_secs)
358 off_t offset; 358 off_t offset;
359 359
360 pthread_mutex_lock(&ui__lock); 360 pthread_mutex_lock(&ui__lock);
361 err = __ui_browser__refresh(self); 361 err = __ui_browser__refresh(browser);
362 SLsmg_refresh(); 362 SLsmg_refresh();
363 pthread_mutex_unlock(&ui__lock); 363 pthread_mutex_unlock(&ui__lock);
364 if (err < 0) 364 if (err < 0)
@@ -368,18 +368,18 @@ int ui_browser__run(struct ui_browser *self, int delay_secs)
368 368
369 if (key == K_RESIZE) { 369 if (key == K_RESIZE) {
370 ui__refresh_dimensions(false); 370 ui__refresh_dimensions(false);
371 ui_browser__refresh_dimensions(self); 371 ui_browser__refresh_dimensions(browser);
372 __ui_browser__show_title(self, self->title); 372 __ui_browser__show_title(browser, browser->title);
373 ui_helpline__puts(self->helpline); 373 ui_helpline__puts(browser->helpline);
374 continue; 374 continue;
375 } 375 }
376 376
377 if (self->use_navkeypressed && !self->navkeypressed) { 377 if (browser->use_navkeypressed && !browser->navkeypressed) {
378 if (key == K_DOWN || key == K_UP || 378 if (key == K_DOWN || key == K_UP ||
379 key == K_PGDN || key == K_PGUP || 379 key == K_PGDN || key == K_PGUP ||
380 key == K_HOME || key == K_END || 380 key == K_HOME || key == K_END ||
381 key == ' ') { 381 key == ' ') {
382 self->navkeypressed = true; 382 browser->navkeypressed = true;
383 continue; 383 continue;
384 } else 384 } else
385 return key; 385 return key;
@@ -387,59 +387,59 @@ int ui_browser__run(struct ui_browser *self, int delay_secs)
387 387
388 switch (key) { 388 switch (key) {
389 case K_DOWN: 389 case K_DOWN:
390 if (self->index == self->nr_entries - 1) 390 if (browser->index == browser->nr_entries - 1)
391 break; 391 break;
392 ++self->index; 392 ++browser->index;
393 if (self->index == self->top_idx + self->height) { 393 if (browser->index == browser->top_idx + browser->height) {
394 ++self->top_idx; 394 ++browser->top_idx;
395 self->seek(self, +1, SEEK_CUR); 395 browser->seek(browser, +1, SEEK_CUR);
396 } 396 }
397 break; 397 break;
398 case K_UP: 398 case K_UP:
399 if (self->index == 0) 399 if (browser->index == 0)
400 break; 400 break;
401 --self->index; 401 --browser->index;
402 if (self->index < self->top_idx) { 402 if (browser->index < browser->top_idx) {
403 --self->top_idx; 403 --browser->top_idx;
404 self->seek(self, -1, SEEK_CUR); 404 browser->seek(browser, -1, SEEK_CUR);
405 } 405 }
406 break; 406 break;
407 case K_PGDN: 407 case K_PGDN:
408 case ' ': 408 case ' ':
409 if (self->top_idx + self->height > self->nr_entries - 1) 409 if (browser->top_idx + browser->height > browser->nr_entries - 1)
410 break; 410 break;
411 411
412 offset = self->height; 412 offset = browser->height;
413 if (self->index + offset > self->nr_entries - 1) 413 if (browser->index + offset > browser->nr_entries - 1)
414 offset = self->nr_entries - 1 - self->index; 414 offset = browser->nr_entries - 1 - browser->index;
415 self->index += offset; 415 browser->index += offset;
416 self->top_idx += offset; 416 browser->top_idx += offset;
417 self->seek(self, +offset, SEEK_CUR); 417 browser->seek(browser, +offset, SEEK_CUR);
418 break; 418 break;
419 case K_PGUP: 419 case K_PGUP:
420 if (self->top_idx == 0) 420 if (browser->top_idx == 0)
421 break; 421 break;
422 422
423 if (self->top_idx < self->height) 423 if (browser->top_idx < browser->height)
424 offset = self->top_idx; 424 offset = browser->top_idx;
425 else 425 else
426 offset = self->height; 426 offset = browser->height;
427 427
428 self->index -= offset; 428 browser->index -= offset;
429 self->top_idx -= offset; 429 browser->top_idx -= offset;
430 self->seek(self, -offset, SEEK_CUR); 430 browser->seek(browser, -offset, SEEK_CUR);
431 break; 431 break;
432 case K_HOME: 432 case K_HOME:
433 ui_browser__reset_index(self); 433 ui_browser__reset_index(browser);
434 break; 434 break;
435 case K_END: 435 case K_END:
436 offset = self->height - 1; 436 offset = browser->height - 1;
437 if (offset >= self->nr_entries) 437 if (offset >= browser->nr_entries)
438 offset = self->nr_entries - 1; 438 offset = browser->nr_entries - 1;
439 439
440 self->index = self->nr_entries - 1; 440 browser->index = browser->nr_entries - 1;
441 self->top_idx = self->index - offset; 441 browser->top_idx = browser->index - offset;
442 self->seek(self, -offset, SEEK_END); 442 browser->seek(browser, -offset, SEEK_END);
443 break; 443 break;
444 default: 444 default:
445 return key; 445 return key;
@@ -448,22 +448,22 @@ int ui_browser__run(struct ui_browser *self, int delay_secs)
448 return -1; 448 return -1;
449} 449}
450 450
451unsigned int ui_browser__list_head_refresh(struct ui_browser *self) 451unsigned int ui_browser__list_head_refresh(struct ui_browser *browser)
452{ 452{
453 struct list_head *pos; 453 struct list_head *pos;
454 struct list_head *head = self->entries; 454 struct list_head *head = browser->entries;
455 int row = 0; 455 int row = 0;
456 456
457 if (self->top == NULL || self->top == self->entries) 457 if (browser->top == NULL || browser->top == browser->entries)
458 self->top = ui_browser__list_head_filter_entries(self, head->next); 458 browser->top = ui_browser__list_head_filter_entries(browser, head->next);
459 459
460 pos = self->top; 460 pos = browser->top;
461 461
462 list_for_each_from(pos, head) { 462 list_for_each_from(pos, head) {
463 if (!self->filter || !self->filter(self, pos)) { 463 if (!browser->filter || !browser->filter(browser, pos)) {
464 ui_browser__gotorc(self, row, 0); 464 ui_browser__gotorc(browser, row, 0);
465 self->write(self, pos, row); 465 browser->write(browser, pos, row);
466 if (++row == self->height) 466 if (++row == browser->height)
467 break; 467 break;
468 } 468 }
469 } 469 }
@@ -708,4 +708,6 @@ void ui_browser__init(void)
708 struct ui_browser__colorset *c = &ui_browser__colorsets[i++]; 708 struct ui_browser__colorset *c = &ui_browser__colorsets[i++];
709 sltt_set_color(c->colorset, c->name, c->fg, c->bg); 709 sltt_set_color(c->colorset, c->name, c->fg, c->bg);
710 } 710 }
711
712 annotate_browser__init();
711} 713}
diff --git a/tools/perf/ui/browser.h b/tools/perf/ui/browser.h
index dd96d8229902..af70314605e5 100644
--- a/tools/perf/ui/browser.h
+++ b/tools/perf/ui/browser.h
@@ -69,4 +69,5 @@ void ui_browser__list_head_seek(struct ui_browser *self, off_t offset, int whenc
69unsigned int ui_browser__list_head_refresh(struct ui_browser *self); 69unsigned int ui_browser__list_head_refresh(struct ui_browser *self);
70 70
71void ui_browser__init(void); 71void ui_browser__init(void);
72void annotate_browser__init(void);
72#endif /* _PERF_UI_BROWSER_H_ */ 73#endif /* _PERF_UI_BROWSER_H_ */
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c
index 6e0ef79be169..4deea6aaf927 100644
--- a/tools/perf/ui/browsers/annotate.c
+++ b/tools/perf/ui/browsers/annotate.c
@@ -19,6 +19,16 @@ struct browser_disasm_line {
19 int jump_sources; 19 int jump_sources;
20}; 20};
21 21
22static struct annotate_browser_opt {
23 bool hide_src_code,
24 use_offset,
25 jump_arrows,
26 show_nr_jumps;
27} annotate_browser__opts = {
28 .use_offset = true,
29 .jump_arrows = true,
30};
31
22struct annotate_browser { 32struct annotate_browser {
23 struct ui_browser b; 33 struct ui_browser b;
24 struct rb_root entries; 34 struct rb_root entries;
@@ -30,10 +40,6 @@ struct annotate_browser {
30 int nr_entries; 40 int nr_entries;
31 int max_jump_sources; 41 int max_jump_sources;
32 int nr_jumps; 42 int nr_jumps;
33 bool hide_src_code;
34 bool use_offset;
35 bool jump_arrows;
36 bool show_nr_jumps;
37 bool searching_backwards; 43 bool searching_backwards;
38 u8 addr_width; 44 u8 addr_width;
39 u8 jumps_width; 45 u8 jumps_width;
@@ -48,11 +54,9 @@ static inline struct browser_disasm_line *disasm_line__browser(struct disasm_lin
48 return (struct browser_disasm_line *)(dl + 1); 54 return (struct browser_disasm_line *)(dl + 1);
49} 55}
50 56
51static bool disasm_line__filter(struct ui_browser *browser, void *entry) 57static bool disasm_line__filter(struct ui_browser *browser __used, void *entry)
52{ 58{
53 struct annotate_browser *ab = container_of(browser, struct annotate_browser, b); 59 if (annotate_browser__opts.hide_src_code) {
54
55 if (ab->hide_src_code) {
56 struct disasm_line *dl = list_entry(entry, struct disasm_line, node); 60 struct disasm_line *dl = list_entry(entry, struct disasm_line, node);
57 return dl->offset == -1; 61 return dl->offset == -1;
58 } 62 }
@@ -79,30 +83,30 @@ static int annotate_browser__set_jumps_percent_color(struct annotate_browser *br
79 return ui_browser__set_color(&browser->b, color); 83 return ui_browser__set_color(&browser->b, color);
80} 84}
81 85
82static void annotate_browser__write(struct ui_browser *self, void *entry, int row) 86static void annotate_browser__write(struct ui_browser *browser, void *entry, int row)
83{ 87{
84 struct annotate_browser *ab = container_of(self, struct annotate_browser, b); 88 struct annotate_browser *ab = container_of(browser, struct annotate_browser, b);
85 struct disasm_line *dl = list_entry(entry, struct disasm_line, node); 89 struct disasm_line *dl = list_entry(entry, struct disasm_line, node);
86 struct browser_disasm_line *bdl = disasm_line__browser(dl); 90 struct browser_disasm_line *bdl = disasm_line__browser(dl);
87 bool current_entry = ui_browser__is_current_entry(self, row); 91 bool current_entry = ui_browser__is_current_entry(browser, row);
88 bool change_color = (!ab->hide_src_code && 92 bool change_color = (!annotate_browser__opts.hide_src_code &&
89 (!current_entry || (self->use_navkeypressed && 93 (!current_entry || (browser->use_navkeypressed &&
90 !self->navkeypressed))); 94 !browser->navkeypressed)));
91 int width = self->width, printed; 95 int width = browser->width, printed;
92 char bf[256]; 96 char bf[256];
93 97
94 if (dl->offset != -1 && bdl->percent != 0.0) { 98 if (dl->offset != -1 && bdl->percent != 0.0) {
95 ui_browser__set_percent_color(self, bdl->percent, current_entry); 99 ui_browser__set_percent_color(browser, bdl->percent, current_entry);
96 slsmg_printf("%6.2f ", bdl->percent); 100 slsmg_printf("%6.2f ", bdl->percent);
97 } else { 101 } else {
98 ui_browser__set_percent_color(self, 0, current_entry); 102 ui_browser__set_percent_color(browser, 0, current_entry);
99 slsmg_write_nstring(" ", 7); 103 slsmg_write_nstring(" ", 7);
100 } 104 }
101 105
102 SLsmg_write_char(' '); 106 SLsmg_write_char(' ');
103 107
104 /* The scroll bar isn't being used */ 108 /* The scroll bar isn't being used */
105 if (!self->navkeypressed) 109 if (!browser->navkeypressed)
106 width += 1; 110 width += 1;
107 111
108 if (!*dl->line) 112 if (!*dl->line)
@@ -116,14 +120,14 @@ static void annotate_browser__write(struct ui_browser *self, void *entry, int ro
116 u64 addr = dl->offset; 120 u64 addr = dl->offset;
117 int color = -1; 121 int color = -1;
118 122
119 if (!ab->use_offset) 123 if (!annotate_browser__opts.use_offset)
120 addr += ab->start; 124 addr += ab->start;
121 125
122 if (!ab->use_offset) { 126 if (!annotate_browser__opts.use_offset) {
123 printed = scnprintf(bf, sizeof(bf), "%" PRIx64 ": ", addr); 127 printed = scnprintf(bf, sizeof(bf), "%" PRIx64 ": ", addr);
124 } else { 128 } else {
125 if (bdl->jump_sources) { 129 if (bdl->jump_sources) {
126 if (ab->show_nr_jumps) { 130 if (annotate_browser__opts.show_nr_jumps) {
127 int prev; 131 int prev;
128 printed = scnprintf(bf, sizeof(bf), "%*d ", 132 printed = scnprintf(bf, sizeof(bf), "%*d ",
129 ab->jumps_width, 133 ab->jumps_width,
@@ -131,7 +135,7 @@ static void annotate_browser__write(struct ui_browser *self, void *entry, int ro
131 prev = annotate_browser__set_jumps_percent_color(ab, bdl->jump_sources, 135 prev = annotate_browser__set_jumps_percent_color(ab, bdl->jump_sources,
132 current_entry); 136 current_entry);
133 slsmg_write_nstring(bf, printed); 137 slsmg_write_nstring(bf, printed);
134 ui_browser__set_color(self, prev); 138 ui_browser__set_color(browser, prev);
135 } 139 }
136 140
137 printed = scnprintf(bf, sizeof(bf), "%*" PRIx64 ": ", 141 printed = scnprintf(bf, sizeof(bf), "%*" PRIx64 ": ",
@@ -143,19 +147,19 @@ static void annotate_browser__write(struct ui_browser *self, void *entry, int ro
143 } 147 }
144 148
145 if (change_color) 149 if (change_color)
146 color = ui_browser__set_color(self, HE_COLORSET_ADDR); 150 color = ui_browser__set_color(browser, HE_COLORSET_ADDR);
147 slsmg_write_nstring(bf, printed); 151 slsmg_write_nstring(bf, printed);
148 if (change_color) 152 if (change_color)
149 ui_browser__set_color(self, color); 153 ui_browser__set_color(browser, color);
150 if (dl->ins && dl->ins->ops->scnprintf) { 154 if (dl->ins && dl->ins->ops->scnprintf) {
151 if (ins__is_jump(dl->ins)) { 155 if (ins__is_jump(dl->ins)) {
152 bool fwd = dl->ops.target.offset > (u64)dl->offset; 156 bool fwd = dl->ops.target.offset > (u64)dl->offset;
153 157
154 ui_browser__write_graph(self, fwd ? SLSMG_DARROW_CHAR : 158 ui_browser__write_graph(browser, fwd ? SLSMG_DARROW_CHAR :
155 SLSMG_UARROW_CHAR); 159 SLSMG_UARROW_CHAR);
156 SLsmg_write_char(' '); 160 SLsmg_write_char(' ');
157 } else if (ins__is_call(dl->ins)) { 161 } else if (ins__is_call(dl->ins)) {
158 ui_browser__write_graph(self, SLSMG_RARROW_CHAR); 162 ui_browser__write_graph(browser, SLSMG_RARROW_CHAR);
159 SLsmg_write_char(' '); 163 SLsmg_write_char(' ');
160 } else { 164 } else {
161 slsmg_write_nstring(" ", 2); 165 slsmg_write_nstring(" ", 2);
@@ -164,12 +168,12 @@ static void annotate_browser__write(struct ui_browser *self, void *entry, int ro
164 if (strcmp(dl->name, "retq")) { 168 if (strcmp(dl->name, "retq")) {
165 slsmg_write_nstring(" ", 2); 169 slsmg_write_nstring(" ", 2);
166 } else { 170 } else {
167 ui_browser__write_graph(self, SLSMG_LARROW_CHAR); 171 ui_browser__write_graph(browser, SLSMG_LARROW_CHAR);
168 SLsmg_write_char(' '); 172 SLsmg_write_char(' ');
169 } 173 }
170 } 174 }
171 175
172 disasm_line__scnprintf(dl, bf, sizeof(bf), !ab->use_offset); 176 disasm_line__scnprintf(dl, bf, sizeof(bf), !annotate_browser__opts.use_offset);
173 slsmg_write_nstring(bf, width - 10 - printed); 177 slsmg_write_nstring(bf, width - 10 - printed);
174 } 178 }
175 179
@@ -184,7 +188,7 @@ static void annotate_browser__draw_current_jump(struct ui_browser *browser)
184 struct browser_disasm_line *btarget, *bcursor; 188 struct browser_disasm_line *btarget, *bcursor;
185 unsigned int from, to; 189 unsigned int from, to;
186 190
187 if (!cursor->ins || !ins__is_jump(cursor->ins) || 191 if (!cursor || !cursor->ins || !ins__is_jump(cursor->ins) ||
188 !disasm_line__has_offset(cursor)) 192 !disasm_line__has_offset(cursor))
189 return; 193 return;
190 194
@@ -195,7 +199,7 @@ static void annotate_browser__draw_current_jump(struct ui_browser *browser)
195 bcursor = disasm_line__browser(cursor); 199 bcursor = disasm_line__browser(cursor);
196 btarget = disasm_line__browser(target); 200 btarget = disasm_line__browser(target);
197 201
198 if (ab->hide_src_code) { 202 if (annotate_browser__opts.hide_src_code) {
199 from = bcursor->idx_asm; 203 from = bcursor->idx_asm;
200 to = btarget->idx_asm; 204 to = btarget->idx_asm;
201 } else { 205 } else {
@@ -209,10 +213,9 @@ static void annotate_browser__draw_current_jump(struct ui_browser *browser)
209 213
210static unsigned int annotate_browser__refresh(struct ui_browser *browser) 214static unsigned int annotate_browser__refresh(struct ui_browser *browser)
211{ 215{
212 struct annotate_browser *ab = container_of(browser, struct annotate_browser, b);
213 int ret = ui_browser__list_head_refresh(browser); 216 int ret = ui_browser__list_head_refresh(browser);
214 217
215 if (ab->jump_arrows) 218 if (annotate_browser__opts.jump_arrows)
216 annotate_browser__draw_current_jump(browser); 219 annotate_browser__draw_current_jump(browser);
217 220
218 ui_browser__set_color(browser, HE_COLORSET_NORMAL); 221 ui_browser__set_color(browser, HE_COLORSET_NORMAL);
@@ -272,27 +275,27 @@ static void disasm_rb_tree__insert(struct rb_root *root, struct browser_disasm_l
272 rb_insert_color(&bdl->rb_node, root); 275 rb_insert_color(&bdl->rb_node, root);
273} 276}
274 277
275static void annotate_browser__set_top(struct annotate_browser *self, 278static void annotate_browser__set_top(struct annotate_browser *browser,
276 struct disasm_line *pos, u32 idx) 279 struct disasm_line *pos, u32 idx)
277{ 280{
278 unsigned back; 281 unsigned back;
279 282
280 ui_browser__refresh_dimensions(&self->b); 283 ui_browser__refresh_dimensions(&browser->b);
281 back = self->b.height / 2; 284 back = browser->b.height / 2;
282 self->b.top_idx = self->b.index = idx; 285 browser->b.top_idx = browser->b.index = idx;
283 286
284 while (self->b.top_idx != 0 && back != 0) { 287 while (browser->b.top_idx != 0 && back != 0) {
285 pos = list_entry(pos->node.prev, struct disasm_line, node); 288 pos = list_entry(pos->node.prev, struct disasm_line, node);
286 289
287 if (disasm_line__filter(&self->b, &pos->node)) 290 if (disasm_line__filter(&browser->b, &pos->node))
288 continue; 291 continue;
289 292
290 --self->b.top_idx; 293 --browser->b.top_idx;
291 --back; 294 --back;
292 } 295 }
293 296
294 self->b.top = pos; 297 browser->b.top = pos;
295 self->b.navkeypressed = true; 298 browser->b.navkeypressed = true;
296} 299}
297 300
298static void annotate_browser__set_rb_top(struct annotate_browser *browser, 301static void annotate_browser__set_rb_top(struct annotate_browser *browser,
@@ -300,10 +303,14 @@ static void annotate_browser__set_rb_top(struct annotate_browser *browser,
300{ 303{
301 struct browser_disasm_line *bpos; 304 struct browser_disasm_line *bpos;
302 struct disasm_line *pos; 305 struct disasm_line *pos;
306 u32 idx;
303 307
304 bpos = rb_entry(nd, struct browser_disasm_line, rb_node); 308 bpos = rb_entry(nd, struct browser_disasm_line, rb_node);
305 pos = ((struct disasm_line *)bpos) - 1; 309 pos = ((struct disasm_line *)bpos) - 1;
306 annotate_browser__set_top(browser, pos, bpos->idx); 310 idx = bpos->idx;
311 if (annotate_browser__opts.hide_src_code)
312 idx = bpos->idx_asm;
313 annotate_browser__set_top(browser, pos, idx);
307 browser->curr_hot = nd; 314 browser->curr_hot = nd;
308} 315}
309 316
@@ -343,12 +350,12 @@ static bool annotate_browser__toggle_source(struct annotate_browser *browser)
343 dl = list_entry(browser->b.top, struct disasm_line, node); 350 dl = list_entry(browser->b.top, struct disasm_line, node);
344 bdl = disasm_line__browser(dl); 351 bdl = disasm_line__browser(dl);
345 352
346 if (browser->hide_src_code) { 353 if (annotate_browser__opts.hide_src_code) {
347 if (bdl->idx_asm < offset) 354 if (bdl->idx_asm < offset)
348 offset = bdl->idx; 355 offset = bdl->idx;
349 356
350 browser->b.nr_entries = browser->nr_entries; 357 browser->b.nr_entries = browser->nr_entries;
351 browser->hide_src_code = false; 358 annotate_browser__opts.hide_src_code = false;
352 browser->b.seek(&browser->b, -offset, SEEK_CUR); 359 browser->b.seek(&browser->b, -offset, SEEK_CUR);
353 browser->b.top_idx = bdl->idx - offset; 360 browser->b.top_idx = bdl->idx - offset;
354 browser->b.index = bdl->idx; 361 browser->b.index = bdl->idx;
@@ -363,7 +370,7 @@ static bool annotate_browser__toggle_source(struct annotate_browser *browser)
363 offset = bdl->idx_asm; 370 offset = bdl->idx_asm;
364 371
365 browser->b.nr_entries = browser->nr_asm_entries; 372 browser->b.nr_entries = browser->nr_asm_entries;
366 browser->hide_src_code = true; 373 annotate_browser__opts.hide_src_code = true;
367 browser->b.seek(&browser->b, -offset, SEEK_CUR); 374 browser->b.seek(&browser->b, -offset, SEEK_CUR);
368 browser->b.top_idx = bdl->idx_asm - offset; 375 browser->b.top_idx = bdl->idx_asm - offset;
369 browser->b.index = bdl->idx_asm; 376 browser->b.index = bdl->idx_asm;
@@ -372,6 +379,12 @@ static bool annotate_browser__toggle_source(struct annotate_browser *browser)
372 return true; 379 return true;
373} 380}
374 381
382static void annotate_browser__init_asm_mode(struct annotate_browser *browser)
383{
384 ui_browser__reset_index(&browser->b);
385 browser->b.nr_entries = browser->nr_asm_entries;
386}
387
375static bool annotate_browser__callq(struct annotate_browser *browser, 388static bool annotate_browser__callq(struct annotate_browser *browser,
376 int evidx, void (*timer)(void *arg), 389 int evidx, void (*timer)(void *arg),
377 void *arg, int delay_secs) 390 void *arg, int delay_secs)
@@ -574,33 +587,46 @@ bool annotate_browser__continue_search_reverse(struct annotate_browser *browser,
574 return __annotate_browser__search_reverse(browser); 587 return __annotate_browser__search_reverse(browser);
575} 588}
576 589
577static int annotate_browser__run(struct annotate_browser *self, int evidx, 590static void annotate_browser__update_addr_width(struct annotate_browser *browser)
591{
592 if (annotate_browser__opts.use_offset)
593 browser->target_width = browser->min_addr_width;
594 else
595 browser->target_width = browser->max_addr_width;
596
597 browser->addr_width = browser->target_width;
598
599 if (annotate_browser__opts.show_nr_jumps)
600 browser->addr_width += browser->jumps_width + 1;
601}
602
603static int annotate_browser__run(struct annotate_browser *browser, int evidx,
578 void(*timer)(void *arg), 604 void(*timer)(void *arg),
579 void *arg, int delay_secs) 605 void *arg, int delay_secs)
580{ 606{
581 struct rb_node *nd = NULL; 607 struct rb_node *nd = NULL;
582 struct map_symbol *ms = self->b.priv; 608 struct map_symbol *ms = browser->b.priv;
583 struct symbol *sym = ms->sym; 609 struct symbol *sym = ms->sym;
584 const char *help = "Press 'h' for help on key bindings"; 610 const char *help = "Press 'h' for help on key bindings";
585 int key; 611 int key;
586 612
587 if (ui_browser__show(&self->b, sym->name, help) < 0) 613 if (ui_browser__show(&browser->b, sym->name, help) < 0)
588 return -1; 614 return -1;
589 615
590 annotate_browser__calc_percent(self, evidx); 616 annotate_browser__calc_percent(browser, evidx);
591 617
592 if (self->curr_hot) { 618 if (browser->curr_hot) {
593 annotate_browser__set_rb_top(self, self->curr_hot); 619 annotate_browser__set_rb_top(browser, browser->curr_hot);
594 self->b.navkeypressed = false; 620 browser->b.navkeypressed = false;
595 } 621 }
596 622
597 nd = self->curr_hot; 623 nd = browser->curr_hot;
598 624
599 while (1) { 625 while (1) {
600 key = ui_browser__run(&self->b, delay_secs); 626 key = ui_browser__run(&browser->b, delay_secs);
601 627
602 if (delay_secs != 0) { 628 if (delay_secs != 0) {
603 annotate_browser__calc_percent(self, evidx); 629 annotate_browser__calc_percent(browser, evidx);
604 /* 630 /*
605 * Current line focus got out of the list of most active 631 * Current line focus got out of the list of most active
606 * lines, NULL it so that if TAB|UNTAB is pressed, we 632 * lines, NULL it so that if TAB|UNTAB is pressed, we
@@ -622,21 +648,21 @@ static int annotate_browser__run(struct annotate_browser *self, int evidx,
622 if (nd != NULL) { 648 if (nd != NULL) {
623 nd = rb_prev(nd); 649 nd = rb_prev(nd);
624 if (nd == NULL) 650 if (nd == NULL)
625 nd = rb_last(&self->entries); 651 nd = rb_last(&browser->entries);
626 } else 652 } else
627 nd = self->curr_hot; 653 nd = browser->curr_hot;
628 break; 654 break;
629 case K_UNTAB: 655 case K_UNTAB:
630 if (nd != NULL) 656 if (nd != NULL)
631 nd = rb_next(nd); 657 nd = rb_next(nd);
632 if (nd == NULL) 658 if (nd == NULL)
633 nd = rb_first(&self->entries); 659 nd = rb_first(&browser->entries);
634 else 660 else
635 nd = self->curr_hot; 661 nd = browser->curr_hot;
636 break; 662 break;
637 case K_F1: 663 case K_F1:
638 case 'h': 664 case 'h':
639 ui_browser__help_window(&self->b, 665 ui_browser__help_window(&browser->b,
640 "UP/DOWN/PGUP\n" 666 "UP/DOWN/PGUP\n"
641 "PGDN/SPACE Navigate\n" 667 "PGDN/SPACE Navigate\n"
642 "q/ESC/CTRL+C Exit\n\n" 668 "q/ESC/CTRL+C Exit\n\n"
@@ -652,57 +678,62 @@ static int annotate_browser__run(struct annotate_browser *self, int evidx,
652 "? Search previous string\n"); 678 "? Search previous string\n");
653 continue; 679 continue;
654 case 'H': 680 case 'H':
655 nd = self->curr_hot; 681 nd = browser->curr_hot;
656 break; 682 break;
657 case 's': 683 case 's':
658 if (annotate_browser__toggle_source(self)) 684 if (annotate_browser__toggle_source(browser))
659 ui_helpline__puts(help); 685 ui_helpline__puts(help);
660 continue; 686 continue;
661 case 'o': 687 case 'o':
662 self->use_offset = !self->use_offset; 688 annotate_browser__opts.use_offset = !annotate_browser__opts.use_offset;
663 if (self->use_offset) 689 annotate_browser__update_addr_width(browser);
664 self->target_width = self->min_addr_width;
665 else
666 self->target_width = self->max_addr_width;
667update_addr_width:
668 self->addr_width = self->target_width;
669 if (self->show_nr_jumps)
670 self->addr_width += self->jumps_width + 1;
671 continue; 690 continue;
672 case 'j': 691 case 'j':
673 self->jump_arrows = !self->jump_arrows; 692 annotate_browser__opts.jump_arrows = !annotate_browser__opts.jump_arrows;
674 continue; 693 continue;
675 case 'J': 694 case 'J':
676 self->show_nr_jumps = !self->show_nr_jumps; 695 annotate_browser__opts.show_nr_jumps = !annotate_browser__opts.show_nr_jumps;
677 goto update_addr_width; 696 annotate_browser__update_addr_width(browser);
697 continue;
678 case '/': 698 case '/':
679 if (annotate_browser__search(self, delay_secs)) { 699 if (annotate_browser__search(browser, delay_secs)) {
680show_help: 700show_help:
681 ui_helpline__puts(help); 701 ui_helpline__puts(help);
682 } 702 }
683 continue; 703 continue;
684 case 'n': 704 case 'n':
685 if (self->searching_backwards ? 705 if (browser->searching_backwards ?
686 annotate_browser__continue_search_reverse(self, delay_secs) : 706 annotate_browser__continue_search_reverse(browser, delay_secs) :
687 annotate_browser__continue_search(self, delay_secs)) 707 annotate_browser__continue_search(browser, delay_secs))
688 goto show_help; 708 goto show_help;
689 continue; 709 continue;
690 case '?': 710 case '?':
691 if (annotate_browser__search_reverse(self, delay_secs)) 711 if (annotate_browser__search_reverse(browser, delay_secs))
692 goto show_help; 712 goto show_help;
693 continue; 713 continue;
714 case 'D': {
715 static int seq;
716 ui_helpline__pop();
717 ui_helpline__fpush("%d: nr_ent=%d, height=%d, idx=%d, top_idx=%d, nr_asm_entries=%d",
718 seq++, browser->b.nr_entries,
719 browser->b.height,
720 browser->b.index,
721 browser->b.top_idx,
722 browser->nr_asm_entries);
723 }
724 continue;
694 case K_ENTER: 725 case K_ENTER:
695 case K_RIGHT: 726 case K_RIGHT:
696 if (self->selection == NULL) 727 if (browser->selection == NULL)
697 ui_helpline__puts("Huh? No selection. Report to linux-kernel@vger.kernel.org"); 728 ui_helpline__puts("Huh? No selection. Report to linux-kernel@vger.kernel.org");
698 else if (self->selection->offset == -1) 729 else if (browser->selection->offset == -1)
699 ui_helpline__puts("Actions are only available for assembly lines."); 730 ui_helpline__puts("Actions are only available for assembly lines.");
700 else if (!self->selection->ins) { 731 else if (!browser->selection->ins) {
701 if (strcmp(self->selection->name, "retq")) 732 if (strcmp(browser->selection->name, "retq"))
702 goto show_sup_ins; 733 goto show_sup_ins;
703 goto out; 734 goto out;
704 } else if (!(annotate_browser__jump(self) || 735 } else if (!(annotate_browser__jump(browser) ||
705 annotate_browser__callq(self, evidx, timer, arg, delay_secs))) { 736 annotate_browser__callq(browser, evidx, timer, arg, delay_secs))) {
706show_sup_ins: 737show_sup_ins:
707 ui_helpline__puts("Actions are only available for 'callq', 'retq' & jump instructions."); 738 ui_helpline__puts("Actions are only available for 'callq', 'retq' & jump instructions.");
708 } 739 }
@@ -717,10 +748,10 @@ show_sup_ins:
717 } 748 }
718 749
719 if (nd != NULL) 750 if (nd != NULL)
720 annotate_browser__set_rb_top(self, nd); 751 annotate_browser__set_rb_top(browser, nd);
721 } 752 }
722out: 753out:
723 ui_browser__hide(&self->b); 754 ui_browser__hide(&browser->b);
724 return key; 755 return key;
725} 756}
726 757
@@ -797,8 +828,6 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx,
797 .priv = &ms, 828 .priv = &ms,
798 .use_navkeypressed = true, 829 .use_navkeypressed = true,
799 }, 830 },
800 .use_offset = true,
801 .jump_arrows = true,
802 }; 831 };
803 int ret = -1; 832 int ret = -1;
804 833
@@ -855,6 +884,12 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx,
855 browser.b.nr_entries = browser.nr_entries; 884 browser.b.nr_entries = browser.nr_entries;
856 browser.b.entries = &notes->src->source, 885 browser.b.entries = &notes->src->source,
857 browser.b.width += 18; /* Percentage */ 886 browser.b.width += 18; /* Percentage */
887
888 if (annotate_browser__opts.hide_src_code)
889 annotate_browser__init_asm_mode(&browser);
890
891 annotate_browser__update_addr_width(&browser);
892
858 ret = annotate_browser__run(&browser, evidx, timer, arg, delay_secs); 893 ret = annotate_browser__run(&browser, evidx, timer, arg, delay_secs);
859 list_for_each_entry_safe(pos, n, &notes->src->source, node) { 894 list_for_each_entry_safe(pos, n, &notes->src->source, node) {
860 list_del(&pos->node); 895 list_del(&pos->node);
@@ -865,3 +900,52 @@ out_free_offsets:
865 free(browser.offsets); 900 free(browser.offsets);
866 return ret; 901 return ret;
867} 902}
903
904#define ANNOTATE_CFG(n) \
905 { .name = #n, .value = &annotate_browser__opts.n, }
906
907/*
908 * Keep the entries sorted, they are bsearch'ed
909 */
910static struct annotate__config {
911 const char *name;
912 bool *value;
913} annotate__configs[] = {
914 ANNOTATE_CFG(hide_src_code),
915 ANNOTATE_CFG(jump_arrows),
916 ANNOTATE_CFG(show_nr_jumps),
917 ANNOTATE_CFG(use_offset),
918};
919
920#undef ANNOTATE_CFG
921
922static int annotate_config__cmp(const void *name, const void *cfgp)
923{
924 const struct annotate__config *cfg = cfgp;
925
926 return strcmp(name, cfg->name);
927}
928
929static int annotate__config(const char *var, const char *value, void *data __used)
930{
931 struct annotate__config *cfg;
932 const char *name;
933
934 if (prefixcmp(var, "annotate.") != 0)
935 return 0;
936
937 name = var + 9;
938 cfg = bsearch(name, annotate__configs, ARRAY_SIZE(annotate__configs),
939 sizeof(struct annotate__config), annotate_config__cmp);
940
941 if (cfg == NULL)
942 return -1;
943
944 *cfg->value = perf_config_bool(name, value);
945 return 0;
946}
947
948void annotate_browser__init(void)
949{
950 perf_config(annotate__config, NULL);
951}
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index a372a4b02635..53f6697d014e 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -26,21 +26,21 @@ struct hist_browser {
26 bool has_symbols; 26 bool has_symbols;
27}; 27};
28 28
29static int hists__browser_title(struct hists *self, char *bf, size_t size, 29static int hists__browser_title(struct hists *hists, char *bf, size_t size,
30 const char *ev_name); 30 const char *ev_name);
31 31
32static void hist_browser__refresh_dimensions(struct hist_browser *self) 32static void hist_browser__refresh_dimensions(struct hist_browser *browser)
33{ 33{
34 /* 3 == +/- toggle symbol before actual hist_entry rendering */ 34 /* 3 == +/- toggle symbol before actual hist_entry rendering */
35 self->b.width = 3 + (hists__sort_list_width(self->hists) + 35 browser->b.width = 3 + (hists__sort_list_width(browser->hists) +
36 sizeof("[k]")); 36 sizeof("[k]"));
37} 37}
38 38
39static void hist_browser__reset(struct hist_browser *self) 39static void hist_browser__reset(struct hist_browser *browser)
40{ 40{
41 self->b.nr_entries = self->hists->nr_entries; 41 browser->b.nr_entries = browser->hists->nr_entries;
42 hist_browser__refresh_dimensions(self); 42 hist_browser__refresh_dimensions(browser);
43 ui_browser__reset_index(&self->b); 43 ui_browser__reset_index(&browser->b);
44} 44}
45 45
46static char tree__folded_sign(bool unfolded) 46static char tree__folded_sign(bool unfolded)
@@ -48,32 +48,32 @@ static char tree__folded_sign(bool unfolded)
48 return unfolded ? '-' : '+'; 48 return unfolded ? '-' : '+';
49} 49}
50 50
51static char map_symbol__folded(const struct map_symbol *self) 51static char map_symbol__folded(const struct map_symbol *ms)
52{ 52{
53 return self->has_children ? tree__folded_sign(self->unfolded) : ' '; 53 return ms->has_children ? tree__folded_sign(ms->unfolded) : ' ';
54} 54}
55 55
56static char hist_entry__folded(const struct hist_entry *self) 56static char hist_entry__folded(const struct hist_entry *he)
57{ 57{
58 return map_symbol__folded(&self->ms); 58 return map_symbol__folded(&he->ms);
59} 59}
60 60
61static char callchain_list__folded(const struct callchain_list *self) 61static char callchain_list__folded(const struct callchain_list *cl)
62{ 62{
63 return map_symbol__folded(&self->ms); 63 return map_symbol__folded(&cl->ms);
64} 64}
65 65
66static void map_symbol__set_folding(struct map_symbol *self, bool unfold) 66static void map_symbol__set_folding(struct map_symbol *ms, bool unfold)
67{ 67{
68 self->unfolded = unfold ? self->has_children : false; 68 ms->unfolded = unfold ? ms->has_children : false;
69} 69}
70 70
71static int callchain_node__count_rows_rb_tree(struct callchain_node *self) 71static int callchain_node__count_rows_rb_tree(struct callchain_node *node)
72{ 72{
73 int n = 0; 73 int n = 0;
74 struct rb_node *nd; 74 struct rb_node *nd;
75 75
76 for (nd = rb_first(&self->rb_root); nd; nd = rb_next(nd)) { 76 for (nd = rb_first(&node->rb_root); nd; nd = rb_next(nd)) {
77 struct callchain_node *child = rb_entry(nd, struct callchain_node, rb_node); 77 struct callchain_node *child = rb_entry(nd, struct callchain_node, rb_node);
78 struct callchain_list *chain; 78 struct callchain_list *chain;
79 char folded_sign = ' '; /* No children */ 79 char folded_sign = ' '; /* No children */
@@ -123,23 +123,23 @@ static int callchain__count_rows(struct rb_root *chain)
123 return n; 123 return n;
124} 124}
125 125
126static bool map_symbol__toggle_fold(struct map_symbol *self) 126static bool map_symbol__toggle_fold(struct map_symbol *ms)
127{ 127{
128 if (!self) 128 if (!ms)
129 return false; 129 return false;
130 130
131 if (!self->has_children) 131 if (!ms->has_children)
132 return false; 132 return false;
133 133
134 self->unfolded = !self->unfolded; 134 ms->unfolded = !ms->unfolded;
135 return true; 135 return true;
136} 136}
137 137
138static void callchain_node__init_have_children_rb_tree(struct callchain_node *self) 138static void callchain_node__init_have_children_rb_tree(struct callchain_node *node)
139{ 139{
140 struct rb_node *nd = rb_first(&self->rb_root); 140 struct rb_node *nd = rb_first(&node->rb_root);
141 141
142 for (nd = rb_first(&self->rb_root); nd; nd = rb_next(nd)) { 142 for (nd = rb_first(&node->rb_root); nd; nd = rb_next(nd)) {
143 struct callchain_node *child = rb_entry(nd, struct callchain_node, rb_node); 143 struct callchain_node *child = rb_entry(nd, struct callchain_node, rb_node);
144 struct callchain_list *chain; 144 struct callchain_list *chain;
145 bool first = true; 145 bool first = true;
@@ -158,49 +158,49 @@ static void callchain_node__init_have_children_rb_tree(struct callchain_node *se
158 } 158 }
159} 159}
160 160
161static void callchain_node__init_have_children(struct callchain_node *self) 161static void callchain_node__init_have_children(struct callchain_node *node)
162{ 162{
163 struct callchain_list *chain; 163 struct callchain_list *chain;
164 164
165 list_for_each_entry(chain, &self->val, list) 165 list_for_each_entry(chain, &node->val, list)
166 chain->ms.has_children = !RB_EMPTY_ROOT(&self->rb_root); 166 chain->ms.has_children = !RB_EMPTY_ROOT(&node->rb_root);
167 167
168 callchain_node__init_have_children_rb_tree(self); 168 callchain_node__init_have_children_rb_tree(node);
169} 169}
170 170
171static void callchain__init_have_children(struct rb_root *self) 171static void callchain__init_have_children(struct rb_root *root)
172{ 172{
173 struct rb_node *nd; 173 struct rb_node *nd;
174 174
175 for (nd = rb_first(self); nd; nd = rb_next(nd)) { 175 for (nd = rb_first(root); nd; nd = rb_next(nd)) {
176 struct callchain_node *node = rb_entry(nd, struct callchain_node, rb_node); 176 struct callchain_node *node = rb_entry(nd, struct callchain_node, rb_node);
177 callchain_node__init_have_children(node); 177 callchain_node__init_have_children(node);
178 } 178 }
179} 179}
180 180
181static void hist_entry__init_have_children(struct hist_entry *self) 181static void hist_entry__init_have_children(struct hist_entry *he)
182{ 182{
183 if (!self->init_have_children) { 183 if (!he->init_have_children) {
184 self->ms.has_children = !RB_EMPTY_ROOT(&self->sorted_chain); 184 he->ms.has_children = !RB_EMPTY_ROOT(&he->sorted_chain);
185 callchain__init_have_children(&self->sorted_chain); 185 callchain__init_have_children(&he->sorted_chain);
186 self->init_have_children = true; 186 he->init_have_children = true;
187 } 187 }
188} 188}
189 189
190static bool hist_browser__toggle_fold(struct hist_browser *self) 190static bool hist_browser__toggle_fold(struct hist_browser *browser)
191{ 191{
192 if (map_symbol__toggle_fold(self->selection)) { 192 if (map_symbol__toggle_fold(browser->selection)) {
193 struct hist_entry *he = self->he_selection; 193 struct hist_entry *he = browser->he_selection;
194 194
195 hist_entry__init_have_children(he); 195 hist_entry__init_have_children(he);
196 self->hists->nr_entries -= he->nr_rows; 196 browser->hists->nr_entries -= he->nr_rows;
197 197
198 if (he->ms.unfolded) 198 if (he->ms.unfolded)
199 he->nr_rows = callchain__count_rows(&he->sorted_chain); 199 he->nr_rows = callchain__count_rows(&he->sorted_chain);
200 else 200 else
201 he->nr_rows = 0; 201 he->nr_rows = 0;
202 self->hists->nr_entries += he->nr_rows; 202 browser->hists->nr_entries += he->nr_rows;
203 self->b.nr_entries = self->hists->nr_entries; 203 browser->b.nr_entries = browser->hists->nr_entries;
204 204
205 return true; 205 return true;
206 } 206 }
@@ -209,12 +209,12 @@ static bool hist_browser__toggle_fold(struct hist_browser *self)
209 return false; 209 return false;
210} 210}
211 211
212static int callchain_node__set_folding_rb_tree(struct callchain_node *self, bool unfold) 212static int callchain_node__set_folding_rb_tree(struct callchain_node *node, bool unfold)
213{ 213{
214 int n = 0; 214 int n = 0;
215 struct rb_node *nd; 215 struct rb_node *nd;
216 216
217 for (nd = rb_first(&self->rb_root); nd; nd = rb_next(nd)) { 217 for (nd = rb_first(&node->rb_root); nd; nd = rb_next(nd)) {
218 struct callchain_node *child = rb_entry(nd, struct callchain_node, rb_node); 218 struct callchain_node *child = rb_entry(nd, struct callchain_node, rb_node);
219 struct callchain_list *chain; 219 struct callchain_list *chain;
220 bool has_children = false; 220 bool has_children = false;
@@ -263,37 +263,37 @@ static int callchain__set_folding(struct rb_root *chain, bool unfold)
263 return n; 263 return n;
264} 264}
265 265
266static void hist_entry__set_folding(struct hist_entry *self, bool unfold) 266static void hist_entry__set_folding(struct hist_entry *he, bool unfold)
267{ 267{
268 hist_entry__init_have_children(self); 268 hist_entry__init_have_children(he);
269 map_symbol__set_folding(&self->ms, unfold); 269 map_symbol__set_folding(&he->ms, unfold);
270 270
271 if (self->ms.has_children) { 271 if (he->ms.has_children) {
272 int n = callchain__set_folding(&self->sorted_chain, unfold); 272 int n = callchain__set_folding(&he->sorted_chain, unfold);
273 self->nr_rows = unfold ? n : 0; 273 he->nr_rows = unfold ? n : 0;
274 } else 274 } else
275 self->nr_rows = 0; 275 he->nr_rows = 0;
276} 276}
277 277
278static void hists__set_folding(struct hists *self, bool unfold) 278static void hists__set_folding(struct hists *hists, bool unfold)
279{ 279{
280 struct rb_node *nd; 280 struct rb_node *nd;
281 281
282 self->nr_entries = 0; 282 hists->nr_entries = 0;
283 283
284 for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) { 284 for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) {
285 struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node); 285 struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node);
286 hist_entry__set_folding(he, unfold); 286 hist_entry__set_folding(he, unfold);
287 self->nr_entries += 1 + he->nr_rows; 287 hists->nr_entries += 1 + he->nr_rows;
288 } 288 }
289} 289}
290 290
291static void hist_browser__set_folding(struct hist_browser *self, bool unfold) 291static void hist_browser__set_folding(struct hist_browser *browser, bool unfold)
292{ 292{
293 hists__set_folding(self->hists, unfold); 293 hists__set_folding(browser->hists, unfold);
294 self->b.nr_entries = self->hists->nr_entries; 294 browser->b.nr_entries = browser->hists->nr_entries;
295 /* Go to the start, we may be way after valid entries after a collapse */ 295 /* Go to the start, we may be way after valid entries after a collapse */
296 ui_browser__reset_index(&self->b); 296 ui_browser__reset_index(&browser->b);
297} 297}
298 298
299static void ui_browser__warn_lost_events(struct ui_browser *browser) 299static void ui_browser__warn_lost_events(struct ui_browser *browser)
@@ -305,64 +305,64 @@ static void ui_browser__warn_lost_events(struct ui_browser *browser)
305 "Or reduce the sampling frequency."); 305 "Or reduce the sampling frequency.");
306} 306}
307 307
308static int hist_browser__run(struct hist_browser *self, const char *ev_name, 308static int hist_browser__run(struct hist_browser *browser, const char *ev_name,
309 void(*timer)(void *arg), void *arg, int delay_secs) 309 void(*timer)(void *arg), void *arg, int delay_secs)
310{ 310{
311 int key; 311 int key;
312 char title[160]; 312 char title[160];
313 313
314 self->b.entries = &self->hists->entries; 314 browser->b.entries = &browser->hists->entries;
315 self->b.nr_entries = self->hists->nr_entries; 315 browser->b.nr_entries = browser->hists->nr_entries;
316 316
317 hist_browser__refresh_dimensions(self); 317 hist_browser__refresh_dimensions(browser);
318 hists__browser_title(self->hists, title, sizeof(title), ev_name); 318 hists__browser_title(browser->hists, title, sizeof(title), ev_name);
319 319
320 if (ui_browser__show(&self->b, title, 320 if (ui_browser__show(&browser->b, title,
321 "Press '?' for help on key bindings") < 0) 321 "Press '?' for help on key bindings") < 0)
322 return -1; 322 return -1;
323 323
324 while (1) { 324 while (1) {
325 key = ui_browser__run(&self->b, delay_secs); 325 key = ui_browser__run(&browser->b, delay_secs);
326 326
327 switch (key) { 327 switch (key) {
328 case K_TIMER: 328 case K_TIMER:
329 timer(arg); 329 timer(arg);
330 ui_browser__update_nr_entries(&self->b, self->hists->nr_entries); 330 ui_browser__update_nr_entries(&browser->b, browser->hists->nr_entries);
331 331
332 if (self->hists->stats.nr_lost_warned != 332 if (browser->hists->stats.nr_lost_warned !=
333 self->hists->stats.nr_events[PERF_RECORD_LOST]) { 333 browser->hists->stats.nr_events[PERF_RECORD_LOST]) {
334 self->hists->stats.nr_lost_warned = 334 browser->hists->stats.nr_lost_warned =
335 self->hists->stats.nr_events[PERF_RECORD_LOST]; 335 browser->hists->stats.nr_events[PERF_RECORD_LOST];
336 ui_browser__warn_lost_events(&self->b); 336 ui_browser__warn_lost_events(&browser->b);
337 } 337 }
338 338
339 hists__browser_title(self->hists, title, sizeof(title), ev_name); 339 hists__browser_title(browser->hists, title, sizeof(title), ev_name);
340 ui_browser__show_title(&self->b, title); 340 ui_browser__show_title(&browser->b, title);
341 continue; 341 continue;
342 case 'D': { /* Debug */ 342 case 'D': { /* Debug */
343 static int seq; 343 static int seq;
344 struct hist_entry *h = rb_entry(self->b.top, 344 struct hist_entry *h = rb_entry(browser->b.top,
345 struct hist_entry, rb_node); 345 struct hist_entry, rb_node);
346 ui_helpline__pop(); 346 ui_helpline__pop();
347 ui_helpline__fpush("%d: nr_ent=(%d,%d), height=%d, idx=%d, fve: idx=%d, row_off=%d, nrows=%d", 347 ui_helpline__fpush("%d: nr_ent=(%d,%d), height=%d, idx=%d, fve: idx=%d, row_off=%d, nrows=%d",
348 seq++, self->b.nr_entries, 348 seq++, browser->b.nr_entries,
349 self->hists->nr_entries, 349 browser->hists->nr_entries,
350 self->b.height, 350 browser->b.height,
351 self->b.index, 351 browser->b.index,
352 self->b.top_idx, 352 browser->b.top_idx,
353 h->row_offset, h->nr_rows); 353 h->row_offset, h->nr_rows);
354 } 354 }
355 break; 355 break;
356 case 'C': 356 case 'C':
357 /* Collapse the whole world. */ 357 /* Collapse the whole world. */
358 hist_browser__set_folding(self, false); 358 hist_browser__set_folding(browser, false);
359 break; 359 break;
360 case 'E': 360 case 'E':
361 /* Expand the whole world. */ 361 /* Expand the whole world. */
362 hist_browser__set_folding(self, true); 362 hist_browser__set_folding(browser, true);
363 break; 363 break;
364 case K_ENTER: 364 case K_ENTER:
365 if (hist_browser__toggle_fold(self)) 365 if (hist_browser__toggle_fold(browser))
366 break; 366 break;
367 /* fall thru */ 367 /* fall thru */
368 default: 368 default:
@@ -370,23 +370,23 @@ static int hist_browser__run(struct hist_browser *self, const char *ev_name,
370 } 370 }
371 } 371 }
372out: 372out:
373 ui_browser__hide(&self->b); 373 ui_browser__hide(&browser->b);
374 return key; 374 return key;
375} 375}
376 376
377static char *callchain_list__sym_name(struct callchain_list *self, 377static char *callchain_list__sym_name(struct callchain_list *cl,
378 char *bf, size_t bfsize) 378 char *bf, size_t bfsize)
379{ 379{
380 if (self->ms.sym) 380 if (cl->ms.sym)
381 return self->ms.sym->name; 381 return cl->ms.sym->name;
382 382
383 snprintf(bf, bfsize, "%#" PRIx64, self->ip); 383 snprintf(bf, bfsize, "%#" PRIx64, cl->ip);
384 return bf; 384 return bf;
385} 385}
386 386
387#define LEVEL_OFFSET_STEP 3 387#define LEVEL_OFFSET_STEP 3
388 388
389static int hist_browser__show_callchain_node_rb_tree(struct hist_browser *self, 389static int hist_browser__show_callchain_node_rb_tree(struct hist_browser *browser,
390 struct callchain_node *chain_node, 390 struct callchain_node *chain_node,
391 u64 total, int level, 391 u64 total, int level,
392 unsigned short row, 392 unsigned short row,
@@ -444,21 +444,21 @@ static int hist_browser__show_callchain_node_rb_tree(struct hist_browser *self,
444 } 444 }
445 445
446 color = HE_COLORSET_NORMAL; 446 color = HE_COLORSET_NORMAL;
447 width = self->b.width - (offset + extra_offset + 2); 447 width = browser->b.width - (offset + extra_offset + 2);
448 if (ui_browser__is_current_entry(&self->b, row)) { 448 if (ui_browser__is_current_entry(&browser->b, row)) {
449 self->selection = &chain->ms; 449 browser->selection = &chain->ms;
450 color = HE_COLORSET_SELECTED; 450 color = HE_COLORSET_SELECTED;
451 *is_current_entry = true; 451 *is_current_entry = true;
452 } 452 }
453 453
454 ui_browser__set_color(&self->b, color); 454 ui_browser__set_color(&browser->b, color);
455 ui_browser__gotorc(&self->b, row, 0); 455 ui_browser__gotorc(&browser->b, row, 0);
456 slsmg_write_nstring(" ", offset + extra_offset); 456 slsmg_write_nstring(" ", offset + extra_offset);
457 slsmg_printf("%c ", folded_sign); 457 slsmg_printf("%c ", folded_sign);
458 slsmg_write_nstring(str, width); 458 slsmg_write_nstring(str, width);
459 free(alloc_str); 459 free(alloc_str);
460 460
461 if (++row == self->b.height) 461 if (++row == browser->b.height)
462 goto out; 462 goto out;
463do_next: 463do_next:
464 if (folded_sign == '+') 464 if (folded_sign == '+')
@@ -467,11 +467,11 @@ do_next:
467 467
468 if (folded_sign == '-') { 468 if (folded_sign == '-') {
469 const int new_level = level + (extra_offset ? 2 : 1); 469 const int new_level = level + (extra_offset ? 2 : 1);
470 row += hist_browser__show_callchain_node_rb_tree(self, child, new_total, 470 row += hist_browser__show_callchain_node_rb_tree(browser, child, new_total,
471 new_level, row, row_offset, 471 new_level, row, row_offset,
472 is_current_entry); 472 is_current_entry);
473 } 473 }
474 if (row == self->b.height) 474 if (row == browser->b.height)
475 goto out; 475 goto out;
476 node = next; 476 node = next;
477 } 477 }
@@ -479,7 +479,7 @@ out:
479 return row - first_row; 479 return row - first_row;
480} 480}
481 481
482static int hist_browser__show_callchain_node(struct hist_browser *self, 482static int hist_browser__show_callchain_node(struct hist_browser *browser,
483 struct callchain_node *node, 483 struct callchain_node *node,
484 int level, unsigned short row, 484 int level, unsigned short row,
485 off_t *row_offset, 485 off_t *row_offset,
@@ -488,7 +488,7 @@ static int hist_browser__show_callchain_node(struct hist_browser *self,
488 struct callchain_list *chain; 488 struct callchain_list *chain;
489 int first_row = row, 489 int first_row = row,
490 offset = level * LEVEL_OFFSET_STEP, 490 offset = level * LEVEL_OFFSET_STEP,
491 width = self->b.width - offset; 491 width = browser->b.width - offset;
492 char folded_sign = ' '; 492 char folded_sign = ' ';
493 493
494 list_for_each_entry(chain, &node->val, list) { 494 list_for_each_entry(chain, &node->val, list) {
@@ -503,26 +503,26 @@ static int hist_browser__show_callchain_node(struct hist_browser *self,
503 } 503 }
504 504
505 color = HE_COLORSET_NORMAL; 505 color = HE_COLORSET_NORMAL;
506 if (ui_browser__is_current_entry(&self->b, row)) { 506 if (ui_browser__is_current_entry(&browser->b, row)) {
507 self->selection = &chain->ms; 507 browser->selection = &chain->ms;
508 color = HE_COLORSET_SELECTED; 508 color = HE_COLORSET_SELECTED;
509 *is_current_entry = true; 509 *is_current_entry = true;
510 } 510 }
511 511
512 s = callchain_list__sym_name(chain, ipstr, sizeof(ipstr)); 512 s = callchain_list__sym_name(chain, ipstr, sizeof(ipstr));
513 ui_browser__gotorc(&self->b, row, 0); 513 ui_browser__gotorc(&browser->b, row, 0);
514 ui_browser__set_color(&self->b, color); 514 ui_browser__set_color(&browser->b, color);
515 slsmg_write_nstring(" ", offset); 515 slsmg_write_nstring(" ", offset);
516 slsmg_printf("%c ", folded_sign); 516 slsmg_printf("%c ", folded_sign);
517 slsmg_write_nstring(s, width - 2); 517 slsmg_write_nstring(s, width - 2);
518 518
519 if (++row == self->b.height) 519 if (++row == browser->b.height)
520 goto out; 520 goto out;
521 } 521 }
522 522
523 if (folded_sign == '-') 523 if (folded_sign == '-')
524 row += hist_browser__show_callchain_node_rb_tree(self, node, 524 row += hist_browser__show_callchain_node_rb_tree(browser, node,
525 self->hists->stats.total_period, 525 browser->hists->stats.total_period,
526 level + 1, row, 526 level + 1, row,
527 row_offset, 527 row_offset,
528 is_current_entry); 528 is_current_entry);
@@ -530,7 +530,7 @@ out:
530 return row - first_row; 530 return row - first_row;
531} 531}
532 532
533static int hist_browser__show_callchain(struct hist_browser *self, 533static int hist_browser__show_callchain(struct hist_browser *browser,
534 struct rb_root *chain, 534 struct rb_root *chain,
535 int level, unsigned short row, 535 int level, unsigned short row,
536 off_t *row_offset, 536 off_t *row_offset,
@@ -542,31 +542,31 @@ static int hist_browser__show_callchain(struct hist_browser *self,
542 for (nd = rb_first(chain); nd; nd = rb_next(nd)) { 542 for (nd = rb_first(chain); nd; nd = rb_next(nd)) {
543 struct callchain_node *node = rb_entry(nd, struct callchain_node, rb_node); 543 struct callchain_node *node = rb_entry(nd, struct callchain_node, rb_node);
544 544
545 row += hist_browser__show_callchain_node(self, node, level, 545 row += hist_browser__show_callchain_node(browser, node, level,
546 row, row_offset, 546 row, row_offset,
547 is_current_entry); 547 is_current_entry);
548 if (row == self->b.height) 548 if (row == browser->b.height)
549 break; 549 break;
550 } 550 }
551 551
552 return row - first_row; 552 return row - first_row;
553} 553}
554 554
555static int hist_browser__show_entry(struct hist_browser *self, 555static int hist_browser__show_entry(struct hist_browser *browser,
556 struct hist_entry *entry, 556 struct hist_entry *entry,
557 unsigned short row) 557 unsigned short row)
558{ 558{
559 char s[256]; 559 char s[256];
560 double percent; 560 double percent;
561 int printed = 0; 561 int printed = 0;
562 int width = self->b.width - 6; /* The percentage */ 562 int width = browser->b.width - 6; /* The percentage */
563 char folded_sign = ' '; 563 char folded_sign = ' ';
564 bool current_entry = ui_browser__is_current_entry(&self->b, row); 564 bool current_entry = ui_browser__is_current_entry(&browser->b, row);
565 off_t row_offset = entry->row_offset; 565 off_t row_offset = entry->row_offset;
566 566
567 if (current_entry) { 567 if (current_entry) {
568 self->he_selection = entry; 568 browser->he_selection = entry;
569 self->selection = &entry->ms; 569 browser->selection = &entry->ms;
570 } 570 }
571 571
572 if (symbol_conf.use_callchain) { 572 if (symbol_conf.use_callchain) {
@@ -575,11 +575,11 @@ static int hist_browser__show_entry(struct hist_browser *self,
575 } 575 }
576 576
577 if (row_offset == 0) { 577 if (row_offset == 0) {
578 hist_entry__snprintf(entry, s, sizeof(s), self->hists); 578 hist_entry__snprintf(entry, s, sizeof(s), browser->hists);
579 percent = (entry->period * 100.0) / self->hists->stats.total_period; 579 percent = (entry->period * 100.0) / browser->hists->stats.total_period;
580 580
581 ui_browser__set_percent_color(&self->b, percent, current_entry); 581 ui_browser__set_percent_color(&browser->b, percent, current_entry);
582 ui_browser__gotorc(&self->b, row, 0); 582 ui_browser__gotorc(&browser->b, row, 0);
583 if (symbol_conf.use_callchain) { 583 if (symbol_conf.use_callchain) {
584 slsmg_printf("%c ", folded_sign); 584 slsmg_printf("%c ", folded_sign);
585 width -= 2; 585 width -= 2;
@@ -588,11 +588,11 @@ static int hist_browser__show_entry(struct hist_browser *self,
588 slsmg_printf(" %5.2f%%", percent); 588 slsmg_printf(" %5.2f%%", percent);
589 589
590 /* The scroll bar isn't being used */ 590 /* The scroll bar isn't being used */
591 if (!self->b.navkeypressed) 591 if (!browser->b.navkeypressed)
592 width += 1; 592 width += 1;
593 593
594 if (!current_entry || !self->b.navkeypressed) 594 if (!current_entry || !browser->b.navkeypressed)
595 ui_browser__set_color(&self->b, HE_COLORSET_NORMAL); 595 ui_browser__set_color(&browser->b, HE_COLORSET_NORMAL);
596 596
597 if (symbol_conf.show_nr_samples) { 597 if (symbol_conf.show_nr_samples) {
598 slsmg_printf(" %11u", entry->nr_events); 598 slsmg_printf(" %11u", entry->nr_events);
@@ -610,12 +610,12 @@ static int hist_browser__show_entry(struct hist_browser *self,
610 } else 610 } else
611 --row_offset; 611 --row_offset;
612 612
613 if (folded_sign == '-' && row != self->b.height) { 613 if (folded_sign == '-' && row != browser->b.height) {
614 printed += hist_browser__show_callchain(self, &entry->sorted_chain, 614 printed += hist_browser__show_callchain(browser, &entry->sorted_chain,
615 1, row, &row_offset, 615 1, row, &row_offset,
616 &current_entry); 616 &current_entry);
617 if (current_entry) 617 if (current_entry)
618 self->he_selection = entry; 618 browser->he_selection = entry;
619 } 619 }
620 620
621 return printed; 621 return printed;
@@ -631,22 +631,22 @@ static void ui_browser__hists_init_top(struct ui_browser *browser)
631 } 631 }
632} 632}
633 633
634static unsigned int hist_browser__refresh(struct ui_browser *self) 634static unsigned int hist_browser__refresh(struct ui_browser *browser)
635{ 635{
636 unsigned row = 0; 636 unsigned row = 0;
637 struct rb_node *nd; 637 struct rb_node *nd;
638 struct hist_browser *hb = container_of(self, struct hist_browser, b); 638 struct hist_browser *hb = container_of(browser, struct hist_browser, b);
639 639
640 ui_browser__hists_init_top(self); 640 ui_browser__hists_init_top(browser);
641 641
642 for (nd = self->top; nd; nd = rb_next(nd)) { 642 for (nd = browser->top; nd; nd = rb_next(nd)) {
643 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); 643 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
644 644
645 if (h->filtered) 645 if (h->filtered)
646 continue; 646 continue;
647 647
648 row += hist_browser__show_entry(hb, h, row); 648 row += hist_browser__show_entry(hb, h, row);
649 if (row == self->height) 649 if (row == browser->height)
650 break; 650 break;
651 } 651 }
652 652
@@ -679,27 +679,27 @@ static struct rb_node *hists__filter_prev_entries(struct rb_node *nd)
679 return NULL; 679 return NULL;
680} 680}
681 681
682static void ui_browser__hists_seek(struct ui_browser *self, 682static void ui_browser__hists_seek(struct ui_browser *browser,
683 off_t offset, int whence) 683 off_t offset, int whence)
684{ 684{
685 struct hist_entry *h; 685 struct hist_entry *h;
686 struct rb_node *nd; 686 struct rb_node *nd;
687 bool first = true; 687 bool first = true;
688 688
689 if (self->nr_entries == 0) 689 if (browser->nr_entries == 0)
690 return; 690 return;
691 691
692 ui_browser__hists_init_top(self); 692 ui_browser__hists_init_top(browser);
693 693
694 switch (whence) { 694 switch (whence) {
695 case SEEK_SET: 695 case SEEK_SET:
696 nd = hists__filter_entries(rb_first(self->entries)); 696 nd = hists__filter_entries(rb_first(browser->entries));
697 break; 697 break;
698 case SEEK_CUR: 698 case SEEK_CUR:
699 nd = self->top; 699 nd = browser->top;
700 goto do_offset; 700 goto do_offset;
701 case SEEK_END: 701 case SEEK_END:
702 nd = hists__filter_prev_entries(rb_last(self->entries)); 702 nd = hists__filter_prev_entries(rb_last(browser->entries));
703 first = false; 703 first = false;
704 break; 704 break;
705 default: 705 default:
@@ -710,7 +710,7 @@ static void ui_browser__hists_seek(struct ui_browser *self,
710 * Moves not relative to the first visible entry invalidates its 710 * Moves not relative to the first visible entry invalidates its
711 * row_offset: 711 * row_offset:
712 */ 712 */
713 h = rb_entry(self->top, struct hist_entry, rb_node); 713 h = rb_entry(browser->top, struct hist_entry, rb_node);
714 h->row_offset = 0; 714 h->row_offset = 0;
715 715
716 /* 716 /*
@@ -738,7 +738,7 @@ do_offset:
738 } else { 738 } else {
739 h->row_offset += offset; 739 h->row_offset += offset;
740 offset = 0; 740 offset = 0;
741 self->top = nd; 741 browser->top = nd;
742 break; 742 break;
743 } 743 }
744 } 744 }
@@ -746,7 +746,7 @@ do_offset:
746 if (nd == NULL) 746 if (nd == NULL)
747 break; 747 break;
748 --offset; 748 --offset;
749 self->top = nd; 749 browser->top = nd;
750 } while (offset != 0); 750 } while (offset != 0);
751 } else if (offset < 0) { 751 } else if (offset < 0) {
752 while (1) { 752 while (1) {
@@ -759,7 +759,7 @@ do_offset:
759 } else { 759 } else {
760 h->row_offset += offset; 760 h->row_offset += offset;
761 offset = 0; 761 offset = 0;
762 self->top = nd; 762 browser->top = nd;
763 break; 763 break;
764 } 764 }
765 } else { 765 } else {
@@ -769,7 +769,7 @@ do_offset:
769 } else { 769 } else {
770 h->row_offset = h->nr_rows + offset; 770 h->row_offset = h->nr_rows + offset;
771 offset = 0; 771 offset = 0;
772 self->top = nd; 772 browser->top = nd;
773 break; 773 break;
774 } 774 }
775 } 775 }
@@ -779,7 +779,7 @@ do_offset:
779 if (nd == NULL) 779 if (nd == NULL)
780 break; 780 break;
781 ++offset; 781 ++offset;
782 self->top = nd; 782 browser->top = nd;
783 if (offset == 0) { 783 if (offset == 0) {
784 /* 784 /*
785 * Last unfiltered hist_entry, check if it is 785 * Last unfiltered hist_entry, check if it is
@@ -794,7 +794,7 @@ do_offset:
794 first = false; 794 first = false;
795 } 795 }
796 } else { 796 } else {
797 self->top = nd; 797 browser->top = nd;
798 h = rb_entry(nd, struct hist_entry, rb_node); 798 h = rb_entry(nd, struct hist_entry, rb_node);
799 h->row_offset = 0; 799 h->row_offset = 0;
800 } 800 }
@@ -802,46 +802,46 @@ do_offset:
802 802
803static struct hist_browser *hist_browser__new(struct hists *hists) 803static struct hist_browser *hist_browser__new(struct hists *hists)
804{ 804{
805 struct hist_browser *self = zalloc(sizeof(*self)); 805 struct hist_browser *browser = zalloc(sizeof(*browser));
806 806
807 if (self) { 807 if (browser) {
808 self->hists = hists; 808 browser->hists = hists;
809 self->b.refresh = hist_browser__refresh; 809 browser->b.refresh = hist_browser__refresh;
810 self->b.seek = ui_browser__hists_seek; 810 browser->b.seek = ui_browser__hists_seek;
811 self->b.use_navkeypressed = true; 811 browser->b.use_navkeypressed = true;
812 if (sort__branch_mode == 1) 812 if (sort__branch_mode == 1)
813 self->has_symbols = sort_sym_from.list.next != NULL; 813 browser->has_symbols = sort_sym_from.list.next != NULL;
814 else 814 else
815 self->has_symbols = sort_sym.list.next != NULL; 815 browser->has_symbols = sort_sym.list.next != NULL;
816 } 816 }
817 817
818 return self; 818 return browser;
819} 819}
820 820
821static void hist_browser__delete(struct hist_browser *self) 821static void hist_browser__delete(struct hist_browser *browser)
822{ 822{
823 free(self); 823 free(browser);
824} 824}
825 825
826static struct hist_entry *hist_browser__selected_entry(struct hist_browser *self) 826static struct hist_entry *hist_browser__selected_entry(struct hist_browser *browser)
827{ 827{
828 return self->he_selection; 828 return browser->he_selection;
829} 829}
830 830
831static struct thread *hist_browser__selected_thread(struct hist_browser *self) 831static struct thread *hist_browser__selected_thread(struct hist_browser *browser)
832{ 832{
833 return self->he_selection->thread; 833 return browser->he_selection->thread;
834} 834}
835 835
836static int hists__browser_title(struct hists *self, char *bf, size_t size, 836static int hists__browser_title(struct hists *hists, char *bf, size_t size,
837 const char *ev_name) 837 const char *ev_name)
838{ 838{
839 char unit; 839 char unit;
840 int printed; 840 int printed;
841 const struct dso *dso = self->dso_filter; 841 const struct dso *dso = hists->dso_filter;
842 const struct thread *thread = self->thread_filter; 842 const struct thread *thread = hists->thread_filter;
843 unsigned long nr_samples = self->stats.nr_events[PERF_RECORD_SAMPLE]; 843 unsigned long nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE];
844 u64 nr_events = self->stats.total_period; 844 u64 nr_events = hists->stats.total_period;
845 845
846 nr_samples = convert_unit(nr_samples, &unit); 846 nr_samples = convert_unit(nr_samples, &unit);
847 printed = scnprintf(bf, size, 847 printed = scnprintf(bf, size,
@@ -849,9 +849,9 @@ static int hists__browser_title(struct hists *self, char *bf, size_t size,
849 nr_samples, unit, ev_name, nr_events); 849 nr_samples, unit, ev_name, nr_events);
850 850
851 851
852 if (self->uid_filter_str) 852 if (hists->uid_filter_str)
853 printed += snprintf(bf + printed, size - printed, 853 printed += snprintf(bf + printed, size - printed,
854 ", UID: %s", self->uid_filter_str); 854 ", UID: %s", hists->uid_filter_str);
855 if (thread) 855 if (thread)
856 printed += scnprintf(bf + printed, size - printed, 856 printed += scnprintf(bf + printed, size - printed,
857 ", Thread: %s(%d)", 857 ", Thread: %s(%d)",
@@ -879,8 +879,8 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
879 void(*timer)(void *arg), void *arg, 879 void(*timer)(void *arg), void *arg,
880 int delay_secs) 880 int delay_secs)
881{ 881{
882 struct hists *self = &evsel->hists; 882 struct hists *hists = &evsel->hists;
883 struct hist_browser *browser = hist_browser__new(self); 883 struct hist_browser *browser = hist_browser__new(hists);
884 struct branch_info *bi; 884 struct branch_info *bi;
885 struct pstack *fstack; 885 struct pstack *fstack;
886 char *options[16]; 886 char *options[16];
@@ -946,8 +946,8 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
946 "Please enter the name of symbol you want to see", 946 "Please enter the name of symbol you want to see",
947 buf, "ENTER: OK, ESC: Cancel", 947 buf, "ENTER: OK, ESC: Cancel",
948 delay_secs * 2) == K_ENTER) { 948 delay_secs * 2) == K_ENTER) {
949 self->symbol_filter_str = *buf ? buf : NULL; 949 hists->symbol_filter_str = *buf ? buf : NULL;
950 hists__filter_by_symbol(self); 950 hists__filter_by_symbol(hists);
951 hist_browser__reset(browser); 951 hist_browser__reset(browser);
952 } 952 }
953 continue; 953 continue;
@@ -1128,7 +1128,7 @@ zoom_out_dso:
1128 sort_dso.elide = true; 1128 sort_dso.elide = true;
1129 pstack__push(fstack, &browser->hists->dso_filter); 1129 pstack__push(fstack, &browser->hists->dso_filter);
1130 } 1130 }
1131 hists__filter_by_dso(self); 1131 hists__filter_by_dso(hists);
1132 hist_browser__reset(browser); 1132 hist_browser__reset(browser);
1133 } else if (choice == zoom_thread) { 1133 } else if (choice == zoom_thread) {
1134zoom_thread: 1134zoom_thread:
@@ -1146,7 +1146,7 @@ zoom_out_thread:
1146 sort_thread.elide = true; 1146 sort_thread.elide = true;
1147 pstack__push(fstack, &browser->hists->thread_filter); 1147 pstack__push(fstack, &browser->hists->thread_filter);
1148 } 1148 }
1149 hists__filter_by_thread(self); 1149 hists__filter_by_thread(hists);
1150 hist_browser__reset(browser); 1150 hist_browser__reset(browser);
1151 } 1151 }
1152 } 1152 }
diff --git a/tools/perf/ui/setup.c b/tools/perf/ui/setup.c
index 9f5f888f73e3..791fb15ce350 100644
--- a/tools/perf/ui/setup.c
+++ b/tools/perf/ui/setup.c
@@ -22,6 +22,7 @@ void setup_browser(bool fallback_to_pager)
22 break; 22 break;
23 /* fall through */ 23 /* fall through */
24 default: 24 default:
25 use_browser = 0;
25 if (fallback_to_pager) 26 if (fallback_to_pager)
26 setup_pager(); 27 setup_pager();
27 break; 28 break;
diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c
index 0deac6a14b65..6faa3a18bfbd 100644
--- a/tools/perf/util/config.c
+++ b/tools/perf/util/config.c
@@ -120,7 +120,7 @@ static char *parse_value(void)
120 120
121static inline int iskeychar(int c) 121static inline int iskeychar(int c)
122{ 122{
123 return isalnum(c) || c == '-'; 123 return isalnum(c) || c == '-' || c == '_';
124} 124}
125 125
126static int get_value(config_fn_t fn, void *data, char *name, unsigned int len) 126static int get_value(config_fn_t fn, void *data, char *name, unsigned int len)
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 57e4ce57bbcc..91d19138f3ec 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -15,6 +15,7 @@
15#include "cpumap.h" 15#include "cpumap.h"
16#include "thread_map.h" 16#include "thread_map.h"
17#include "target.h" 17#include "target.h"
18#include "../../include/linux/perf_event.h"
18 19
19#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) 20#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))
20#define GROUP_FD(group_fd, cpu) (*(int *)xyarray__entry(group_fd, cpu, 0)) 21#define GROUP_FD(group_fd, cpu) (*(int *)xyarray__entry(group_fd, cpu, 0))
@@ -64,6 +65,95 @@ struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr, int idx)
64 return evsel; 65 return evsel;
65} 66}
66 67
68static const char *perf_evsel__hw_names[PERF_COUNT_HW_MAX] = {
69 "cycles",
70 "instructions",
71 "cache-references",
72 "cache-misses",
73 "branches",
74 "branch-misses",
75 "bus-cycles",
76 "stalled-cycles-frontend",
77 "stalled-cycles-backend",
78 "ref-cycles",
79};
80
81const char *__perf_evsel__hw_name(u64 config)
82{
83 if (config < PERF_COUNT_HW_MAX && perf_evsel__hw_names[config])
84 return perf_evsel__hw_names[config];
85
86 return "unknown-hardware";
87}
88
89static int perf_evsel__hw_name(struct perf_evsel *evsel, char *bf, size_t size)
90{
91 int colon = 0;
92 struct perf_event_attr *attr = &evsel->attr;
93 int r = scnprintf(bf, size, "%s", __perf_evsel__hw_name(attr->config));
94 bool exclude_guest_default = false;
95
96#define MOD_PRINT(context, mod) do { \
97 if (!attr->exclude_##context) { \
98 if (!colon) colon = r++; \
99 r += scnprintf(bf + r, size - r, "%c", mod); \
100 } } while(0)
101
102 if (attr->exclude_kernel || attr->exclude_user || attr->exclude_hv) {
103 MOD_PRINT(kernel, 'k');
104 MOD_PRINT(user, 'u');
105 MOD_PRINT(hv, 'h');
106 exclude_guest_default = true;
107 }
108
109 if (attr->precise_ip) {
110 if (!colon)
111 colon = r++;
112 r += scnprintf(bf + r, size - r, "%.*s", attr->precise_ip, "ppp");
113 exclude_guest_default = true;
114 }
115
116 if (attr->exclude_host || attr->exclude_guest == exclude_guest_default) {
117 MOD_PRINT(host, 'H');
118 MOD_PRINT(guest, 'G');
119 }
120#undef MOD_PRINT
121 if (colon)
122 bf[colon] = ':';
123 return r;
124}
125
126int perf_evsel__name(struct perf_evsel *evsel, char *bf, size_t size)
127{
128 int ret;
129
130 switch (evsel->attr.type) {
131 case PERF_TYPE_RAW:
132 ret = scnprintf(bf, size, "raw 0x%" PRIx64, evsel->attr.config);
133 break;
134
135 case PERF_TYPE_HARDWARE:
136 ret = perf_evsel__hw_name(evsel, bf, size);
137 break;
138 default:
139 /*
140 * FIXME
141 *
142 * This is the minimal perf_evsel__name so that we can
143 * reconstruct event names taking into account event modifiers.
144 *
145 * The old event_name uses it now for raw anr hw events, so that
146 * we don't drag all the parsing stuff into the python binding.
147 *
148 * On the next devel cycle the rest of the event naming will be
149 * brought here.
150 */
151 return 0;
152 }
153
154 return ret;
155}
156
67void perf_evsel__config(struct perf_evsel *evsel, struct perf_record_opts *opts, 157void perf_evsel__config(struct perf_evsel *evsel, struct perf_record_opts *opts,
68 struct perf_evsel *first) 158 struct perf_evsel *first)
69{ 159{
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 3d6b3e4cb66b..4ba8b564e6f4 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -83,6 +83,9 @@ void perf_evsel__config(struct perf_evsel *evsel,
83 struct perf_record_opts *opts, 83 struct perf_record_opts *opts,
84 struct perf_evsel *first); 84 struct perf_evsel *first);
85 85
86const char* __perf_evsel__hw_name(u64 config);
87int perf_evsel__name(struct perf_evsel *evsel, char *bf, size_t size);
88
86int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads); 89int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads);
87int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads); 90int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads);
88int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus); 91int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus);
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index fac7d59309b8..05dbc8b3c767 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -62,19 +62,6 @@ static struct event_symbol event_symbols[] = {
62#define PERF_EVENT_TYPE(config) __PERF_EVENT_FIELD(config, TYPE) 62#define PERF_EVENT_TYPE(config) __PERF_EVENT_FIELD(config, TYPE)
63#define PERF_EVENT_ID(config) __PERF_EVENT_FIELD(config, EVENT) 63#define PERF_EVENT_ID(config) __PERF_EVENT_FIELD(config, EVENT)
64 64
65static const char *hw_event_names[PERF_COUNT_HW_MAX] = {
66 "cycles",
67 "instructions",
68 "cache-references",
69 "cache-misses",
70 "branches",
71 "branch-misses",
72 "bus-cycles",
73 "stalled-cycles-frontend",
74 "stalled-cycles-backend",
75 "ref-cycles",
76};
77
78static const char *sw_event_names[PERF_COUNT_SW_MAX] = { 65static const char *sw_event_names[PERF_COUNT_SW_MAX] = {
79 "cpu-clock", 66 "cpu-clock",
80 "task-clock", 67 "task-clock",
@@ -300,6 +287,16 @@ const char *event_name(struct perf_evsel *evsel)
300 u64 config = evsel->attr.config; 287 u64 config = evsel->attr.config;
301 int type = evsel->attr.type; 288 int type = evsel->attr.type;
302 289
290 if (type == PERF_TYPE_RAW || type == PERF_TYPE_HARDWARE) {
291 /*
292 * XXX minimal fix, see comment on perf_evsen__name, this static buffer
293 * will go away together with event_name in the next devel cycle.
294 */
295 static char bf[128];
296 perf_evsel__name(evsel, bf, sizeof(bf));
297 return bf;
298 }
299
303 if (evsel->name) 300 if (evsel->name)
304 return evsel->name; 301 return evsel->name;
305 302
@@ -317,9 +314,7 @@ const char *__event_name(int type, u64 config)
317 314
318 switch (type) { 315 switch (type) {
319 case PERF_TYPE_HARDWARE: 316 case PERF_TYPE_HARDWARE:
320 if (config < PERF_COUNT_HW_MAX && hw_event_names[config]) 317 return __perf_evsel__hw_name(config);
321 return hw_event_names[config];
322 return "unknown-hardware";
323 318
324 case PERF_TYPE_HW_CACHE: { 319 case PERF_TYPE_HW_CACHE: {
325 u8 cache_type, cache_op, cache_result; 320 u8 cache_type, cache_op, cache_result;
diff --git a/tools/perf/util/thread_map.c b/tools/perf/util/thread_map.c
index 84d9bd782004..9b5f856cc280 100644
--- a/tools/perf/util/thread_map.c
+++ b/tools/perf/util/thread_map.c
@@ -188,28 +188,27 @@ static struct thread_map *thread_map__new_by_pid_str(const char *pid_str)
188 nt = realloc(threads, (sizeof(*threads) + 188 nt = realloc(threads, (sizeof(*threads) +
189 sizeof(pid_t) * total_tasks)); 189 sizeof(pid_t) * total_tasks));
190 if (nt == NULL) 190 if (nt == NULL)
191 goto out_free_threads; 191 goto out_free_namelist;
192 192
193 threads = nt; 193 threads = nt;
194 194
195 if (threads) { 195 for (i = 0; i < items; i++) {
196 for (i = 0; i < items; i++) 196 threads->map[j++] = atoi(namelist[i]->d_name);
197 threads->map[j++] = atoi(namelist[i]->d_name);
198 threads->nr = total_tasks;
199 }
200
201 for (i = 0; i < items; i++)
202 free(namelist[i]); 197 free(namelist[i]);
198 }
199 threads->nr = total_tasks;
203 free(namelist); 200 free(namelist);
204
205 if (!threads)
206 break;
207 } 201 }
208 202
209out: 203out:
210 strlist__delete(slist); 204 strlist__delete(slist);
211 return threads; 205 return threads;
212 206
207out_free_namelist:
208 for (i = 0; i < items; i++)
209 free(namelist[i]);
210 free(namelist);
211
213out_free_threads: 212out_free_threads:
214 free(threads); 213 free(threads);
215 threads = NULL; 214 threads = NULL;