Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.sbin/tprof mainly fixes around display.



details:   https://anonhg.NetBSD.org/src/rev/6075f4a2b215
branches:  trunk
changeset: 372567:6075f4a2b215
user:      ryo <ryo%NetBSD.org@localhost>
date:      Fri Dec 09 01:56:40 2022 +0000

description:
mainly fixes around display.

- use terminfo
- dynamically adjust column widths
- mode can be changed while running

diffstat:

 usr.sbin/tprof/Makefile    |    6 +-
 usr.sbin/tprof/tprof.8     |   17 +-
 usr.sbin/tprof/tprof_top.c |  610 ++++++++++++++++++++++++++++++++------------
 3 files changed, 457 insertions(+), 176 deletions(-)

diffs (truncated from 966 to 300 lines):

diff -r aee5ce392b42 -r 6075f4a2b215 usr.sbin/tprof/Makefile
--- a/usr.sbin/tprof/Makefile   Fri Dec 09 01:55:46 2022 +0000
+++ b/usr.sbin/tprof/Makefile   Fri Dec 09 01:56:40 2022 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: Makefile,v 1.12 2022/12/01 00:43:27 ryo Exp $
+#      $NetBSD: Makefile,v 1.13 2022/12/09 01:56:40 ryo Exp $
 
 .PATH: ${.CURDIR}/arch
 
@@ -21,11 +21,15 @@
 LDADD+= -lpthread
 LDADD+= -lm
 LDADD+= -lelf
+LDADD+= -lterminfo
 LDADD+= -lutil
 DPADD+= ${LIBPTHREAD}
 DPADD+= ${LIBM}
 DPADD+= ${LIBELF}
+DPADD+= ${LIBTERMINFO}
 DPADD+= ${LIBUTIL}
 
+COPTS.tprof_top.c = -Wno-format-nonliteral
+
 .include <bsd.own.mk>
 .include <bsd.prog.mk>
diff -r aee5ce392b42 -r 6075f4a2b215 usr.sbin/tprof/tprof.8
--- a/usr.sbin/tprof/tprof.8    Fri Dec 09 01:55:46 2022 +0000
+++ b/usr.sbin/tprof/tprof.8    Fri Dec 09 01:56:40 2022 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: tprof.8,v 1.20 2022/12/09 01:55:46 ryo Exp $
+.\"    $NetBSD: tprof.8,v 1.21 2022/12/09 01:56:40 ryo Exp $
 .\"
 .\" Copyright (c)2011 YAMAMOTO Takashi,
 .\" All rights reserved.
@@ -166,6 +166,21 @@
 .It Fl u
 Userland processes are also included in the profiling.
 .El
+.Pp
+While
+.Nm
+.Ar top
+is running, it accepts commands from the terminal.
+These commands are currently recognized:
+.Bl -tag -width XXcommandsX -offset indent
+.It Ic a
+toggle accumurative mode.
+.It Ic q
+quit
+.Nm .
+.It Ic z
+clear accumulated data.
+.El
 .El
 .Sh EXAMPLES
 The following command profiles the system during 20 seconds and writes the
diff -r aee5ce392b42 -r 6075f4a2b215 usr.sbin/tprof/tprof_top.c
--- a/usr.sbin/tprof/tprof_top.c        Fri Dec 09 01:55:46 2022 +0000
+++ b/usr.sbin/tprof/tprof_top.c        Fri Dec 09 01:56:40 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tprof_top.c,v 1.3 2022/12/09 01:55:46 ryo Exp $        */
+/*     $NetBSD: tprof_top.c,v 1.4 2022/12/09 01:56:40 ryo Exp $        */
 
 /*-
  * Copyright (c) 2022 Ryo Shimizu <ryo%nerv.org@localhost>
@@ -28,15 +28,17 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: tprof_top.c,v 1.3 2022/12/09 01:55:46 ryo Exp $");
+__RCSID("$NetBSD: tprof_top.c,v 1.4 2022/12/09 01:56:40 ryo Exp $");
 #endif /* not lint */
 
 #include <sys/param.h>
 #include <sys/types.h>
+#include <sys/ioctl.h>
 #include <sys/rbtree.h>
-#include <sys/ioctl.h>
+#include <sys/select.h>
 #include <sys/time.h>
 
+#include <assert.h>
 #include <err.h>
 #include <errno.h>
 #include <fcntl.h>
@@ -46,6 +48,8 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <term.h>
+#include <termios.h>
 #include <unistd.h>
 #include <util.h>
 
@@ -57,6 +61,9 @@
 #define SAMPLE_MODE_INSTANTANEOUS      1
 #define SAMPLE_MODE_NUM                        2
 
+#define LINESTR        "-------------------------------------------------------------"
+#define SYMBOL_LEN                     32      /* symbol and event name */
+
 struct sample_elm {
        struct rb_node node;
        uint64_t addr;
@@ -80,9 +87,14 @@
 static int opt_showcounter = 0;
 
 /* for display */
+static char *term;
 static struct winsize win;
 static int nontty;
+static struct termios termios_save;
+static bool termios_saved;
 static long top_interval = 1;
+static bool do_redraw;
+static u_int nshow;
 
 /* for profiling and counting samples */
 static sig_atomic_t sigalrm;
@@ -95,6 +107,8 @@
 struct ptrarray sample_list[SAMPLE_MODE_NUM];
 static u_int sample_n_kern[SAMPLE_MODE_NUM];
 static u_int sample_n_user[SAMPLE_MODE_NUM];
+static u_int sample_event_width = 7;
+static u_int *sample_cpu_width;                                        /* [ncpu] */
 static uint32_t *sample_n_kern_per_cpu[SAMPLE_MODE_NUM];       /* [ncpu] */
 static uint32_t *sample_n_user_per_cpu[SAMPLE_MODE_NUM];       /* [ncpu] */
 static uint64_t *sample_n_per_event[SAMPLE_MODE_NUM];          /* [nevent] */
@@ -127,43 +141,145 @@
        return cycleevent;
 }
 
-/* XXX: use terminfo or curses */
 static void
-cursor_address(u_int x, u_int y)
+reset_cursor_pos(void)
 {
-       if (nontty)
+       int i;
+       char *p;
+
+       if (nontty || term == NULL)
                return;
-       printf("\e[%u;%uH", y - 1, x - 1);
+
+       printf("\r");
+
+       /* cursor_up * n */
+       if ((p = tigetstr("cuu")) != NULL) {
+               printf("%s", tparm(p, win.ws_row - 1, 0, 0, 0, 0, 0, 0, 0, 0));
+       } else if ((p = tigetstr("cuu1")) != NULL) {
+               for (i = win.ws_row - 1; i > 0; i--)
+                       printf("%s", p);
+       }
 }
 
 static void
-cursor_home(void)
+clr_to_eol(void)
 {
-       if (nontty)
+       char *p;
+
+       if (nontty || term == NULL)
                return;
-       printf("\e[H");
+
+       if ((p = tigetstr("el")) != NULL)
+               printf("%s", p);
+}
+
+/* newline, and clearing to end of line if needed */
+static void
+lim_newline(int *lim)
+{
+       if (*lim >= 1)
+               clr_to_eol();
+
+       printf("\n");
+       *lim = win.ws_col;
 }
 
-static void
-cls_eol(void)
+static int
+lim_printf(int *lim, const char *fmt, ...)
 {
-       if (nontty)
-               return;
-       printf("\e[K");
-}
+       va_list ap;
+       size_t written;
+       char *p;
+
+       if (*lim <= 0)
+               return 0;
+
+       p = alloca(*lim + 1);
 
-static void
-cls_eos(void)
-{
-       if (nontty)
-               return;
-       printf("\e[J");
+       va_start(ap, fmt);
+       vsnprintf(p, *lim + 1, fmt, ap);
+       va_end(ap);
+
+       written = strlen(p);
+       if (written == 0) {
+               *lim = 0;
+               return 0;
+       }
+
+       fwrite(p, written, 1, stdout);
+       *lim -= written;
+
+       return written;
 }
 
 static void
 sigwinch_handler(int signo)
 {
+       char *p;
+
+       win.ws_col = tigetnum("lines");
+       win.ws_row = tigetnum("cols");
+
        nontty = ioctl(STDOUT_FILENO, TIOCGWINSZ, &win);
+       if (nontty != 0) {
+               nontty = !isatty(STDOUT_FILENO);
+               win.ws_col = 65535;
+               win.ws_row = 65535;
+       }
+
+       if ((p = getenv("LINES")) != NULL)
+               win.ws_row = strtoul(p, NULL, 0);
+       if ((p = getenv("COLUMNS")) != NULL)
+               win.ws_col = strtoul(p, NULL, 0);
+
+       do_redraw = true;
+}
+
+static void
+tty_setup(void)
+{
+       struct termios termios;
+
+       term = getenv("TERM");
+       if (term != NULL)
+               setupterm(term, 0, NULL);
+
+       sigwinch_handler(0);
+
+       if (tcgetattr(STDOUT_FILENO, &termios_save) == 0) {
+               termios_saved = true;
+
+               /* stty cbreak */
+               termios = termios_save;
+               termios.c_iflag |= BRKINT|IXON|IMAXBEL;
+               termios.c_oflag |= OPOST;
+               termios.c_lflag |= ISIG|IEXTEN;
+               termios.c_lflag &= ~(ICANON|ECHO);
+               tcsetattr(STDOUT_FILENO, TCSADRAIN, &termios);
+       }
+}
+
+static void
+tty_restore(void)
+{
+       if (termios_saved) {
+               tcsetattr(STDOUT_FILENO, TCSADRAIN, &termios_save);
+               termios_saved = false;
+       }
+}
+
+static void
+sigtstp_handler(int signo)
+{
+       tty_restore();
+
+       signal(SIGWINCH, SIG_DFL);
+       signal(SIGINT, SIG_DFL);
+       signal(SIGQUIT, SIG_DFL);
+       signal(SIGTERM, SIG_DFL);
+       signal(SIGTSTP, SIG_DFL);
+       kill(0, SIGTSTP);
+       nshow = 0;
 }
 
 static void
@@ -173,6 +289,30 @@
 }
 
 static void
+die(int signo)
+{
+       tty_restore();



Home | Main Index | Thread Index | Old Index