Loading tools/perf/builtin-top.c +20 −5 Original line number Original line Diff line number Diff line Loading @@ -304,7 +304,7 @@ static void print_sym_table(void) hists__collapse_resort_threaded(&top.sym_evsel->hists); hists__collapse_resort_threaded(&top.sym_evsel->hists); hists__output_resort_threaded(&top.sym_evsel->hists); hists__output_resort_threaded(&top.sym_evsel->hists); hists__decay_entries(&top.sym_evsel->hists); hists__decay_entries_threaded(&top.sym_evsel->hists); hists__output_recalc_col_len(&top.sym_evsel->hists, winsize.ws_row - 3); hists__output_recalc_col_len(&top.sym_evsel->hists, winsize.ws_row - 3); putchar('\n'); putchar('\n'); hists__fprintf(&top.sym_evsel->hists, NULL, false, false, hists__fprintf(&top.sym_evsel->hists, NULL, false, false, Loading Loading @@ -555,7 +555,7 @@ static void perf_top__sort_new_samples(void *arg) hists__collapse_resort_threaded(&t->sym_evsel->hists); hists__collapse_resort_threaded(&t->sym_evsel->hists); hists__output_resort_threaded(&t->sym_evsel->hists); hists__output_resort_threaded(&t->sym_evsel->hists); hists__decay_entries(&t->sym_evsel->hists); hists__decay_entries_threaded(&t->sym_evsel->hists); hists__output_recalc_col_len(&t->sym_evsel->hists, winsize.ws_row - 3); hists__output_recalc_col_len(&t->sym_evsel->hists, winsize.ws_row - 3); } } Loading Loading @@ -585,16 +585,31 @@ static void *display_thread(void *arg __used) tc.c_cc[VMIN] = 0; tc.c_cc[VMIN] = 0; tc.c_cc[VTIME] = 0; tc.c_cc[VTIME] = 0; pthread__unblock_sigwinch(); repeat: repeat: delay_msecs = top.delay_secs * 1000; delay_msecs = top.delay_secs * 1000; tcsetattr(0, TCSANOW, &tc); tcsetattr(0, TCSANOW, &tc); /* trash return*/ /* trash return*/ getc(stdin); getc(stdin); do { while (1) { print_sym_table(); print_sym_table(); } while (!poll(&stdin_poll, 1, delay_msecs) == 1); /* * Either timeout expired or we got an EINTR due to SIGWINCH, * refresh screen in both cases. */ switch (poll(&stdin_poll, 1, delay_msecs)) { case 0: continue; case -1: if (errno == EINTR) continue; /* Fall trhu */ default: goto process_hotkey; } } process_hotkey: c = getc(stdin); c = getc(stdin); tcsetattr(0, TCSAFLUSH, &save); tcsetattr(0, TCSAFLUSH, &save); Loading tools/perf/perf.c +24 −0 Original line number Original line Diff line number Diff line Loading @@ -427,6 +427,24 @@ static void get_debugfs_mntpt(void) debugfs_mntpt[0] = '\0'; debugfs_mntpt[0] = '\0'; } } static void pthread__block_sigwinch(void) { sigset_t set; sigemptyset(&set); sigaddset(&set, SIGWINCH); pthread_sigmask(SIG_BLOCK, &set, NULL); } void pthread__unblock_sigwinch(void) { sigset_t set; sigemptyset(&set); sigaddset(&set, SIGWINCH); pthread_sigmask(SIG_UNBLOCK, &set, NULL); } int main(int argc, const char **argv) int main(int argc, const char **argv) { { const char *cmd; const char *cmd; Loading Loading @@ -480,6 +498,12 @@ int main(int argc, const char **argv) * time. * time. */ */ setup_path(); setup_path(); /* * Block SIGWINCH notifications so that the thread that wants it can * unblock and get syscalls like select interrupted instead of waiting * forever while the signal goes to some other non interested thread. */ pthread__block_sigwinch(); while (1) { while (1) { static int done_help; static int done_help; Loading tools/perf/perf.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -183,4 +183,6 @@ struct ip_callchain { extern bool perf_host, perf_guest; extern bool perf_host, perf_guest; extern const char perf_version_string[]; extern const char perf_version_string[]; void pthread__unblock_sigwinch(void); #endif #endif tools/perf/util/header.c +1 −1 Original line number Original line Diff line number Diff line Loading @@ -1289,7 +1289,7 @@ int build_id_cache__remove_s(const char *sbuild_id, const char *debugdir) if (access(linkname, F_OK)) if (access(linkname, F_OK)) goto out_free; goto out_free; if (readlink(linkname, filename, size) < 0) if (readlink(linkname, filename, size - 1) < 0) goto out_free; goto out_free; if (unlink(linkname)) if (unlink(linkname)) Loading tools/perf/util/hist.c +20 −4 Original line number Original line Diff line number Diff line Loading @@ -100,13 +100,15 @@ static void hist_entry__decay(struct hist_entry *he) static bool hists__decay_entry(struct hists *hists, struct hist_entry *he) static bool hists__decay_entry(struct hists *hists, struct hist_entry *he) { { if (he->period == 0) return true; hists->stats.total_period -= he->period; hists->stats.total_period -= he->period; hist_entry__decay(he); hist_entry__decay(he); hists->stats.total_period += he->period; hists->stats.total_period += he->period; return he->period == 0; return he->period == 0; } } void hists__decay_entries(struct hists *hists) static void __hists__decay_entries(struct hists *hists, bool threaded) { { struct rb_node *next = rb_first(&hists->entries); struct rb_node *next = rb_first(&hists->entries); struct hist_entry *n; struct hist_entry *n; Loading @@ -114,11 +116,15 @@ void hists__decay_entries(struct hists *hists) while (next) { while (next) { n = rb_entry(next, struct hist_entry, rb_node); n = rb_entry(next, struct hist_entry, rb_node); next = rb_next(&n->rb_node); next = rb_next(&n->rb_node); /* if (hists__decay_entry(hists, n)) { * We may be annotating this, for instance, so keep it here in * case some it gets new samples, we'll eventually free it when * the user stops browsing and it agains gets fully decayed. */ if (hists__decay_entry(hists, n) && !n->used) { rb_erase(&n->rb_node, &hists->entries); rb_erase(&n->rb_node, &hists->entries); if (sort__need_collapse) if (sort__need_collapse || threaded) rb_erase(&n->rb_node_in, &hists->entries_collapsed); rb_erase(&n->rb_node_in, &hists->entries_collapsed); hist_entry__free(n); hist_entry__free(n); Loading @@ -127,6 +133,16 @@ void hists__decay_entries(struct hists *hists) } } } } void hists__decay_entries(struct hists *hists) { return __hists__decay_entries(hists, false); } void hists__decay_entries_threaded(struct hists *hists) { return __hists__decay_entries(hists, true); } /* /* * histogram, sorted on item, collects periods * histogram, sorted on item, collects periods */ */ Loading Loading
tools/perf/builtin-top.c +20 −5 Original line number Original line Diff line number Diff line Loading @@ -304,7 +304,7 @@ static void print_sym_table(void) hists__collapse_resort_threaded(&top.sym_evsel->hists); hists__collapse_resort_threaded(&top.sym_evsel->hists); hists__output_resort_threaded(&top.sym_evsel->hists); hists__output_resort_threaded(&top.sym_evsel->hists); hists__decay_entries(&top.sym_evsel->hists); hists__decay_entries_threaded(&top.sym_evsel->hists); hists__output_recalc_col_len(&top.sym_evsel->hists, winsize.ws_row - 3); hists__output_recalc_col_len(&top.sym_evsel->hists, winsize.ws_row - 3); putchar('\n'); putchar('\n'); hists__fprintf(&top.sym_evsel->hists, NULL, false, false, hists__fprintf(&top.sym_evsel->hists, NULL, false, false, Loading Loading @@ -555,7 +555,7 @@ static void perf_top__sort_new_samples(void *arg) hists__collapse_resort_threaded(&t->sym_evsel->hists); hists__collapse_resort_threaded(&t->sym_evsel->hists); hists__output_resort_threaded(&t->sym_evsel->hists); hists__output_resort_threaded(&t->sym_evsel->hists); hists__decay_entries(&t->sym_evsel->hists); hists__decay_entries_threaded(&t->sym_evsel->hists); hists__output_recalc_col_len(&t->sym_evsel->hists, winsize.ws_row - 3); hists__output_recalc_col_len(&t->sym_evsel->hists, winsize.ws_row - 3); } } Loading Loading @@ -585,16 +585,31 @@ static void *display_thread(void *arg __used) tc.c_cc[VMIN] = 0; tc.c_cc[VMIN] = 0; tc.c_cc[VTIME] = 0; tc.c_cc[VTIME] = 0; pthread__unblock_sigwinch(); repeat: repeat: delay_msecs = top.delay_secs * 1000; delay_msecs = top.delay_secs * 1000; tcsetattr(0, TCSANOW, &tc); tcsetattr(0, TCSANOW, &tc); /* trash return*/ /* trash return*/ getc(stdin); getc(stdin); do { while (1) { print_sym_table(); print_sym_table(); } while (!poll(&stdin_poll, 1, delay_msecs) == 1); /* * Either timeout expired or we got an EINTR due to SIGWINCH, * refresh screen in both cases. */ switch (poll(&stdin_poll, 1, delay_msecs)) { case 0: continue; case -1: if (errno == EINTR) continue; /* Fall trhu */ default: goto process_hotkey; } } process_hotkey: c = getc(stdin); c = getc(stdin); tcsetattr(0, TCSAFLUSH, &save); tcsetattr(0, TCSAFLUSH, &save); Loading
tools/perf/perf.c +24 −0 Original line number Original line Diff line number Diff line Loading @@ -427,6 +427,24 @@ static void get_debugfs_mntpt(void) debugfs_mntpt[0] = '\0'; debugfs_mntpt[0] = '\0'; } } static void pthread__block_sigwinch(void) { sigset_t set; sigemptyset(&set); sigaddset(&set, SIGWINCH); pthread_sigmask(SIG_BLOCK, &set, NULL); } void pthread__unblock_sigwinch(void) { sigset_t set; sigemptyset(&set); sigaddset(&set, SIGWINCH); pthread_sigmask(SIG_UNBLOCK, &set, NULL); } int main(int argc, const char **argv) int main(int argc, const char **argv) { { const char *cmd; const char *cmd; Loading Loading @@ -480,6 +498,12 @@ int main(int argc, const char **argv) * time. * time. */ */ setup_path(); setup_path(); /* * Block SIGWINCH notifications so that the thread that wants it can * unblock and get syscalls like select interrupted instead of waiting * forever while the signal goes to some other non interested thread. */ pthread__block_sigwinch(); while (1) { while (1) { static int done_help; static int done_help; Loading
tools/perf/perf.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -183,4 +183,6 @@ struct ip_callchain { extern bool perf_host, perf_guest; extern bool perf_host, perf_guest; extern const char perf_version_string[]; extern const char perf_version_string[]; void pthread__unblock_sigwinch(void); #endif #endif
tools/perf/util/header.c +1 −1 Original line number Original line Diff line number Diff line Loading @@ -1289,7 +1289,7 @@ int build_id_cache__remove_s(const char *sbuild_id, const char *debugdir) if (access(linkname, F_OK)) if (access(linkname, F_OK)) goto out_free; goto out_free; if (readlink(linkname, filename, size) < 0) if (readlink(linkname, filename, size - 1) < 0) goto out_free; goto out_free; if (unlink(linkname)) if (unlink(linkname)) Loading
tools/perf/util/hist.c +20 −4 Original line number Original line Diff line number Diff line Loading @@ -100,13 +100,15 @@ static void hist_entry__decay(struct hist_entry *he) static bool hists__decay_entry(struct hists *hists, struct hist_entry *he) static bool hists__decay_entry(struct hists *hists, struct hist_entry *he) { { if (he->period == 0) return true; hists->stats.total_period -= he->period; hists->stats.total_period -= he->period; hist_entry__decay(he); hist_entry__decay(he); hists->stats.total_period += he->period; hists->stats.total_period += he->period; return he->period == 0; return he->period == 0; } } void hists__decay_entries(struct hists *hists) static void __hists__decay_entries(struct hists *hists, bool threaded) { { struct rb_node *next = rb_first(&hists->entries); struct rb_node *next = rb_first(&hists->entries); struct hist_entry *n; struct hist_entry *n; Loading @@ -114,11 +116,15 @@ void hists__decay_entries(struct hists *hists) while (next) { while (next) { n = rb_entry(next, struct hist_entry, rb_node); n = rb_entry(next, struct hist_entry, rb_node); next = rb_next(&n->rb_node); next = rb_next(&n->rb_node); /* if (hists__decay_entry(hists, n)) { * We may be annotating this, for instance, so keep it here in * case some it gets new samples, we'll eventually free it when * the user stops browsing and it agains gets fully decayed. */ if (hists__decay_entry(hists, n) && !n->used) { rb_erase(&n->rb_node, &hists->entries); rb_erase(&n->rb_node, &hists->entries); if (sort__need_collapse) if (sort__need_collapse || threaded) rb_erase(&n->rb_node_in, &hists->entries_collapsed); rb_erase(&n->rb_node_in, &hists->entries_collapsed); hist_entry__free(n); hist_entry__free(n); Loading @@ -127,6 +133,16 @@ void hists__decay_entries(struct hists *hists) } } } } void hists__decay_entries(struct hists *hists) { return __hists__decay_entries(hists, false); } void hists__decay_entries_threaded(struct hists *hists) { return __hists__decay_entries(hists, true); } /* /* * histogram, sorted on item, collects periods * histogram, sorted on item, collects periods */ */ Loading