aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2013-01-30 11:25:53 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2013-01-31 11:07:42 -0500
commit11859e821761e9738c4d8a0e7d6ca1cc2e0d37e8 (patch)
tree952564a6f569dd284a3194d6d3a455fe6da2dde1 /tools/perf
parent152fefa921535665f95840c08062844ab2f5593e (diff)
perf top: Stop using exit()
Just return to the perf main() routine so that an unified exit path can be followed and resources released, helping in finding memory leaks. Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Namhyung Kim <namhyung@gmail.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-ro8oeodo96490nrhcph57atr@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/builtin-top.c56
1 files changed, 33 insertions, 23 deletions
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 7978c8117b7f..903e4f4a3047 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -68,6 +68,8 @@
68#include <linux/unistd.h> 68#include <linux/unistd.h>
69#include <linux/types.h> 69#include <linux/types.h>
70 70
71static volatile int done;
72
71static void perf_top__update_print_entries(struct perf_top *top) 73static void perf_top__update_print_entries(struct perf_top *top)
72{ 74{
73 if (top->print_entries > 9) 75 if (top->print_entries > 9)
@@ -431,8 +433,10 @@ static int perf_top__key_mapped(struct perf_top *top, int c)
431 return 0; 433 return 0;
432} 434}
433 435
434static void perf_top__handle_keypress(struct perf_top *top, int c) 436static bool perf_top__handle_keypress(struct perf_top *top, int c)
435{ 437{
438 bool ret = true;
439
436 if (!perf_top__key_mapped(top, c)) { 440 if (!perf_top__key_mapped(top, c)) {
437 struct pollfd stdin_poll = { .fd = 0, .events = POLLIN }; 441 struct pollfd stdin_poll = { .fd = 0, .events = POLLIN };
438 struct termios tc, save; 442 struct termios tc, save;
@@ -453,7 +457,7 @@ static void perf_top__handle_keypress(struct perf_top *top, int c)
453 457
454 tcsetattr(0, TCSAFLUSH, &save); 458 tcsetattr(0, TCSAFLUSH, &save);
455 if (!perf_top__key_mapped(top, c)) 459 if (!perf_top__key_mapped(top, c))
456 return; 460 return ret;
457 } 461 }
458 462
459 switch (c) { 463 switch (c) {
@@ -515,7 +519,8 @@ static void perf_top__handle_keypress(struct perf_top *top, int c)
515 printf("exiting.\n"); 519 printf("exiting.\n");
516 if (top->dump_symtab) 520 if (top->dump_symtab)
517 perf_session__fprintf_dsos(top->session, stderr); 521 perf_session__fprintf_dsos(top->session, stderr);
518 exit(0); 522 ret = false;
523 break;
519 case 's': 524 case 's':
520 perf_top__prompt_symbol(top, "Enter details symbol"); 525 perf_top__prompt_symbol(top, "Enter details symbol");
521 break; 526 break;
@@ -538,6 +543,8 @@ static void perf_top__handle_keypress(struct perf_top *top, int c)
538 default: 543 default:
539 break; 544 break;
540 } 545 }
546
547 return ret;
541} 548}
542 549
543static void perf_top__sort_new_samples(void *arg) 550static void perf_top__sort_new_samples(void *arg)
@@ -579,8 +586,7 @@ static void *display_thread_tui(void *arg)
579 perf_evlist__tui_browse_hists(top->evlist, help, &hbt, 586 perf_evlist__tui_browse_hists(top->evlist, help, &hbt,
580 &top->session->header.env); 587 &top->session->header.env);
581 588
582 exit_browser(0); 589 done = 1;
583 exit(0);
584 return NULL; 590 return NULL;
585} 591}
586 592
@@ -604,7 +610,7 @@ repeat:
604 /* trash return*/ 610 /* trash return*/
605 getc(stdin); 611 getc(stdin);
606 612
607 while (1) { 613 while (!done) {
608 perf_top__print_sym_table(top); 614 perf_top__print_sym_table(top);
609 /* 615 /*
610 * Either timeout expired or we got an EINTR due to SIGWINCH, 616 * Either timeout expired or we got an EINTR due to SIGWINCH,
@@ -618,15 +624,14 @@ repeat:
618 continue; 624 continue;
619 /* Fall trhu */ 625 /* Fall trhu */
620 default: 626 default:
621 goto process_hotkey; 627 c = getc(stdin);
628 tcsetattr(0, TCSAFLUSH, &save);
629
630 if (perf_top__handle_keypress(top, c))
631 goto repeat;
632 done = 1;
622 } 633 }
623 } 634 }
624process_hotkey:
625 c = getc(stdin);
626 tcsetattr(0, TCSAFLUSH, &save);
627
628 perf_top__handle_keypress(top, c);
629 goto repeat;
630 635
631 return NULL; 636 return NULL;
632} 637}
@@ -705,7 +710,7 @@ static void perf_event__process_sample(struct perf_tool *tool,
705 } 710 }
706 711
707 if (!machine) { 712 if (!machine) {
708 pr_err("%u unprocessable samples recorded.\n", 713 pr_err("%u unprocessable samples recorded.\r",
709 top->session->stats.nr_unprocessable_samples++); 714 top->session->stats.nr_unprocessable_samples++);
710 return; 715 return;
711 } 716 }
@@ -868,7 +873,7 @@ static void perf_top__mmap_read(struct perf_top *top)
868 perf_top__mmap_read_idx(top, i); 873 perf_top__mmap_read_idx(top, i);
869} 874}
870 875
871static void perf_top__start_counters(struct perf_top *top) 876static int perf_top__start_counters(struct perf_top *top)
872{ 877{
873 char msg[512]; 878 char msg[512];
874 struct perf_evsel *counter; 879 struct perf_evsel *counter;
@@ -900,11 +905,10 @@ try_again:
900 goto out_err; 905 goto out_err;
901 } 906 }
902 907
903 return; 908 return 0;
904 909
905out_err: 910out_err:
906 exit_browser(0); 911 return -1;
907 exit(0);
908} 912}
909 913
910static int perf_top__setup_sample_type(struct perf_top *top) 914static int perf_top__setup_sample_type(struct perf_top *top)
@@ -948,7 +952,11 @@ static int __cmd_top(struct perf_top *top)
948 else 952 else
949 perf_event__synthesize_threads(&top->tool, perf_event__process, 953 perf_event__synthesize_threads(&top->tool, perf_event__process,
950 &top->session->machines.host); 954 &top->session->machines.host);
951 perf_top__start_counters(top); 955
956 ret = perf_top__start_counters(top);
957 if (ret)
958 goto out_delete;
959
952 top->session->evlist = top->evlist; 960 top->session->evlist = top->evlist;
953 perf_session__set_id_hdr_size(top->session); 961 perf_session__set_id_hdr_size(top->session);
954 962
@@ -968,10 +976,11 @@ static int __cmd_top(struct perf_top *top)
968 976
969 perf_top__mmap_read(top); 977 perf_top__mmap_read(top);
970 978
979 ret = -1;
971 if (pthread_create(&thread, NULL, (use_browser > 0 ? display_thread_tui : 980 if (pthread_create(&thread, NULL, (use_browser > 0 ? display_thread_tui :
972 display_thread), top)) { 981 display_thread), top)) {
973 ui__error("Could not create display thread.\n"); 982 ui__error("Could not create display thread.\n");
974 exit(-1); 983 goto out_delete;
975 } 984 }
976 985
977 if (top->realtime_prio) { 986 if (top->realtime_prio) {
@@ -980,11 +989,11 @@ static int __cmd_top(struct perf_top *top)
980 param.sched_priority = top->realtime_prio; 989 param.sched_priority = top->realtime_prio;
981 if (sched_setscheduler(0, SCHED_FIFO, &param)) { 990 if (sched_setscheduler(0, SCHED_FIFO, &param)) {
982 ui__error("Could not set realtime priority.\n"); 991 ui__error("Could not set realtime priority.\n");
983 exit(-1); 992 goto out_delete;
984 } 993 }
985 } 994 }
986 995
987 while (1) { 996 while (!done) {
988 u64 hits = top->samples; 997 u64 hits = top->samples;
989 998
990 perf_top__mmap_read(top); 999 perf_top__mmap_read(top);
@@ -993,11 +1002,12 @@ static int __cmd_top(struct perf_top *top)
993 ret = poll(top->evlist->pollfd, top->evlist->nr_fds, 100); 1002 ret = poll(top->evlist->pollfd, top->evlist->nr_fds, 100);
994 } 1003 }
995 1004
1005 ret = 0;
996out_delete: 1006out_delete:
997 perf_session__delete(top->session); 1007 perf_session__delete(top->session);
998 top->session = NULL; 1008 top->session = NULL;
999 1009
1000 return 0; 1010 return ret;
1001} 1011}
1002 1012
1003static int 1013static int