Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / tools / perf / ui / tui / setup.c
diff --git a/kernel/tools/perf/ui/tui/setup.c b/kernel/tools/perf/ui/tui/setup.c
new file mode 100644 (file)
index 0000000..b77e1d7
--- /dev/null
@@ -0,0 +1,174 @@
+#include <signal.h>
+#include <stdbool.h>
+#ifdef HAVE_BACKTRACE_SUPPORT
+#include <execinfo.h>
+#endif
+
+#include "../../util/cache.h"
+#include "../../util/debug.h"
+#include "../browser.h"
+#include "../helpline.h"
+#include "../ui.h"
+#include "../util.h"
+#include "../libslang.h"
+#include "../keysyms.h"
+#include "tui.h"
+
+static volatile int ui__need_resize;
+
+extern struct perf_error_ops perf_tui_eops;
+extern bool tui_helpline__set;
+
+extern void hist_browser__init_hpp(void);
+
+void ui__refresh_dimensions(bool force)
+{
+       if (force || ui__need_resize) {
+               ui__need_resize = 0;
+               pthread_mutex_lock(&ui__lock);
+               SLtt_get_screen_size();
+               SLsmg_reinit_smg();
+               pthread_mutex_unlock(&ui__lock);
+       }
+}
+
+static void ui__sigwinch(int sig __maybe_unused)
+{
+       ui__need_resize = 1;
+}
+
+static void ui__setup_sigwinch(void)
+{
+       static bool done;
+
+       if (done)
+               return;
+
+       done = true;
+       pthread__unblock_sigwinch();
+       signal(SIGWINCH, ui__sigwinch);
+}
+
+int ui__getch(int delay_secs)
+{
+       struct timeval timeout, *ptimeout = delay_secs ? &timeout : NULL;
+       fd_set read_set;
+       int err, key;
+
+       ui__setup_sigwinch();
+
+       FD_ZERO(&read_set);
+       FD_SET(0, &read_set);
+
+       if (delay_secs) {
+               timeout.tv_sec = delay_secs;
+               timeout.tv_usec = 0;
+       }
+
+        err = select(1, &read_set, NULL, NULL, ptimeout);
+
+       if (err == 0)
+               return K_TIMER;
+
+       if (err == -1) {
+               if (errno == EINTR)
+                       return K_RESIZE;
+               return K_ERROR;
+       }
+
+       key = SLang_getkey();
+       if (key != K_ESC)
+               return key;
+
+       FD_ZERO(&read_set);
+       FD_SET(0, &read_set);
+       timeout.tv_sec = 0;
+       timeout.tv_usec = 20;
+        err = select(1, &read_set, NULL, NULL, &timeout);
+       if (err == 0)
+               return K_ESC;
+
+       SLang_ungetkey(key);
+       return SLkp_getkey();
+}
+
+#ifdef HAVE_BACKTRACE_SUPPORT
+static void ui__signal_backtrace(int sig)
+{
+       void *stackdump[32];
+       size_t size;
+
+       ui__exit(false);
+       psignal(sig, "perf");
+
+       printf("-------- backtrace --------\n");
+       size = backtrace(stackdump, ARRAY_SIZE(stackdump));
+       backtrace_symbols_fd(stackdump, size, STDOUT_FILENO);
+
+       exit(0);
+}
+#else
+# define ui__signal_backtrace  ui__signal
+#endif
+
+static void ui__signal(int sig)
+{
+       ui__exit(false);
+       psignal(sig, "perf");
+       exit(0);
+}
+
+int ui__init(void)
+{
+       int err;
+
+       SLutf8_enable(-1);
+       SLtt_get_terminfo();
+       SLtt_get_screen_size();
+
+       err = SLsmg_init_smg();
+       if (err < 0)
+               goto out;
+       err = SLang_init_tty(0, 0, 0);
+       if (err < 0)
+               goto out;
+
+       err = SLkp_init();
+       if (err < 0) {
+               pr_err("TUI initialization failed.\n");
+               goto out;
+       }
+
+       SLkp_define_keysym((char *)"^(kB)", SL_KEY_UNTAB);
+
+       ui_helpline__init();
+       ui_browser__init();
+       tui_progress__init();
+
+       signal(SIGSEGV, ui__signal_backtrace);
+       signal(SIGFPE, ui__signal_backtrace);
+       signal(SIGINT, ui__signal);
+       signal(SIGQUIT, ui__signal);
+       signal(SIGTERM, ui__signal);
+
+       perf_error__register(&perf_tui_eops);
+
+       hist_browser__init_hpp();
+out:
+       return err;
+}
+
+void ui__exit(bool wait_for_ok)
+{
+       if (wait_for_ok && tui_helpline__set)
+               ui__question_window("Fatal Error",
+                                   ui_helpline__last_msg,
+                                   "Press any key...", 0);
+
+       SLtt_set_cursor_visibility(1);
+       SLsmg_refresh();
+       SLsmg_reset_smg();
+       SLang_reset_tty();
+
+       perf_error__unregister(&perf_tui_eops);
+}