Linux Perf
setup.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0
2 #include <errno.h>
3 #include <signal.h>
4 #include <stdbool.h>
5 #include <linux/kernel.h>
6 #ifdef HAVE_BACKTRACE_SUPPORT
7 #include <execinfo.h>
8 #endif
9 
10 #include "../../util/cache.h"
11 #include "../../util/debug.h"
12 #include "../../util/util.h"
13 #include "../browser.h"
14 #include "../helpline.h"
15 #include "../ui.h"
16 #include "../util.h"
17 #include "../libslang.h"
18 #include "../keysyms.h"
19 #include "tui.h"
20 
21 static volatile int ui__need_resize;
22 
23 extern struct perf_error_ops perf_tui_eops;
24 extern bool tui_helpline__set;
25 
26 extern void hist_browser__init_hpp(void);
27 
29 {
30  if (force || ui__need_resize) {
31  ui__need_resize = 0;
32  pthread_mutex_lock(&ui__lock);
33  SLtt_get_screen_size();
34  SLsmg_reinit_smg();
35  pthread_mutex_unlock(&ui__lock);
36  }
37 }
38 
39 static void ui__sigwinch(int sig __maybe_unused)
40 {
41  ui__need_resize = 1;
42 }
43 
44 static void ui__setup_sigwinch(void)
45 {
46  static bool done;
47 
48  if (done)
49  return;
50 
51  done = true;
53  signal(SIGWINCH, ui__sigwinch);
54 }
55 
56 int ui__getch(int delay_secs)
57 {
58  struct timeval timeout, *ptimeout = delay_secs ? &timeout : NULL;
59  fd_set read_set;
60  int err, key;
61 
63 
64  FD_ZERO(&read_set);
65  FD_SET(0, &read_set);
66 
67  if (delay_secs) {
68  timeout.tv_sec = delay_secs;
69  timeout.tv_usec = 0;
70  }
71 
72  err = select(1, &read_set, NULL, NULL, ptimeout);
73 
74  if (err == 0)
75  return K_TIMER;
76 
77  if (err == -1) {
78  if (errno == EINTR)
79  return K_RESIZE;
80  return K_ERROR;
81  }
82 
83  key = SLang_getkey();
84  if (key != K_ESC)
85  return key;
86 
87  FD_ZERO(&read_set);
88  FD_SET(0, &read_set);
89  timeout.tv_sec = 0;
90  timeout.tv_usec = 20;
91  err = select(1, &read_set, NULL, NULL, &timeout);
92  if (err == 0)
93  return K_ESC;
94 
95  SLang_ungetkey(key);
96  return SLkp_getkey();
97 }
98 
99 #ifdef HAVE_BACKTRACE_SUPPORT
100 static void ui__signal_backtrace(int sig)
101 {
102  void *stackdump[32];
103  size_t size;
104 
105  ui__exit(false);
106  psignal(sig, "perf");
107 
108  printf("-------- backtrace --------\n");
109  size = backtrace(stackdump, ARRAY_SIZE(stackdump));
110  backtrace_symbols_fd(stackdump, size, STDOUT_FILENO);
111 
112  exit(0);
113 }
114 #else
115 # define ui__signal_backtrace ui__signal
116 #endif
117 
118 static void ui__signal(int sig)
119 {
120  ui__exit(false);
121  psignal(sig, "perf");
122  exit(0);
123 }
124 
125 int ui__init(void)
126 {
127  int err;
128 
129  SLutf8_enable(-1);
130  SLtt_get_terminfo();
131  SLtt_get_screen_size();
132 
133  err = SLsmg_init_smg();
134  if (err < 0)
135  goto out;
136  err = SLang_init_tty(-1, 0, 0);
137  if (err < 0)
138  goto out;
139 
140  err = SLkp_init();
141  if (err < 0) {
142  pr_err("TUI initialization failed.\n");
143  goto out;
144  }
145 
146  SLkp_define_keysym((char *)"^(kB)", SL_KEY_UNTAB);
147 
148  signal(SIGSEGV, ui__signal_backtrace);
149  signal(SIGFPE, ui__signal_backtrace);
150  signal(SIGINT, ui__signal);
151  signal(SIGQUIT, ui__signal);
152  signal(SIGTERM, ui__signal);
153 
155 
159 
161 out:
162  return err;
163 }
164 
165 void ui__exit(bool wait_for_ok)
166 {
167  if (wait_for_ok && tui_helpline__set)
168  ui__question_window("Fatal Error",
170  "Press any key...", 0);
171 
172  SLtt_set_cursor_visibility(1);
173  SLsmg_refresh();
174  SLsmg_reset_smg();
175  SLang_reset_tty();
176 
178 }
#define K_TIMER
Definition: keysyms.h:24
bool tui_helpline__set
Definition: helpline.c:13
void ui__refresh_dimensions(bool force)
Definition: setup.c:28
#define K_ESC
Definition: keysyms.h:10
size_t size
Definition: evsel.c:60
int ui__getch(int delay_secs)
Definition: setup.c:56
int int err
Definition: 5sec.c:44
#define ui__signal_backtrace
Definition: setup.c:115
static bool force
Definition: builtin-diff.c:68
pthread_mutex_t ui__lock
Definition: setup.c:10
static void ui__setup_sigwinch(void)
Definition: setup.c:44
#define pr_err(fmt,...)
Definition: json.h:21
static void ui__sigwinch(int sig __maybe_unused)
Definition: setup.c:39
int perf_error__unregister(struct perf_error_ops *eops)
Definition: util.c:78
const char * key
Definition: bpf-loader.c:196
void hist_browser__init_hpp(void)
Definition: hists.c:1210
static void ui__signal(int sig)
Definition: setup.c:118
char ui_helpline__last_msg[]
Definition: helpline.c:12
void pthread__unblock_sigwinch(void)
Definition: perf.c:414
int perf_error__register(struct perf_error_ops *eops)
Definition: util.c:63
void tui_progress__init(void)
Definition: progress.c:85
#define SL_KEY_UNTAB
Definition: libslang.h:31
void ui__exit(bool wait_for_ok)
Definition: setup.c:165
int ui__init(void)
Definition: setup.c:125
int ui__question_window(const char *title, const char *text, const char *exit_msg, int delay_secs)
Definition: util.c:165
void ui_helpline__init(void)
Definition: helpline.c:58
static volatile int ui__need_resize
Definition: setup.c:21
struct perf_error_ops perf_tui_eops
Definition: util.c:254
void ui_browser__init(void)
Definition: browser.c:783
#define K_ERROR
Definition: keysyms.h:25
static bool done
Definition: futex-hash.c:35
#define K_RESIZE
Definition: keysyms.h:26