Source-Changes-HG archive

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

[src/trunk]: src/usr.sbin/tprof the "scale" option can be specified in the ev...



details:   https://anonhg.NetBSD.org/src/rev/8d757ade1cb9
branches:  trunk
changeset: 372652:8d757ade1cb9
user:      ryo <ryo%NetBSD.org@localhost>
date:      Fri Dec 16 08:02:04 2022 +0000

description:
the "scale" option can be specified in the event name even in "tprof monitor"

diffstat:

 usr.sbin/tprof/tprof.8     |   30 +++++-----
 usr.sbin/tprof/tprof.c     |  118 +++++++++++++++++++++++++++++++++++++-------
 usr.sbin/tprof/tprof.h     |    7 ++-
 usr.sbin/tprof/tprof_top.c |   48 ++---------------
 4 files changed, 127 insertions(+), 76 deletions(-)

diffs (truncated from 323 to 300 lines):

diff -r 13d41c637178 -r 8d757ade1cb9 usr.sbin/tprof/tprof.8
--- a/usr.sbin/tprof/tprof.8    Fri Dec 16 08:00:47 2022 +0000
+++ b/usr.sbin/tprof/tprof.8    Fri Dec 16 08:02:04 2022 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: tprof.8,v 1.23 2022/12/16 08:00:47 ryo Exp $
+.\"    $NetBSD: tprof.8,v 1.24 2022/12/16 08:02:04 ryo Exp $
 .\"
 .\" Copyright (c)2011 YAMAMOTO Takashi,
 .\" All rights reserved.
@@ -66,7 +66,7 @@
 Display a list of performance counter events available on the system.
 .It monitor Xo
 .Fl e
-.Ar name[:option]
+.Ar name[:option][,scale]
 .Op Fl e Ar ...
 .Op Fl o Ar outfile
 .Ar command
@@ -83,6 +83,18 @@
 .Ar k
 (kernel). If omitted, it is assumed that both are specified.
 The collected samples are written into the file
+.Ar scale
+specifies the ratio of the speed to the cycle counter, or the counter until
+overflow.
+The counter reset value on overflow used for profiling is calculated from the
+speed of the cycle counter by default, but for some events this value may be
+too large (counter increasing too slowly) to be sufficient for profiling.
+For example, to specify an event that increases about 1000 times slower than
+the cycle counter, specify
+.Dq Pa -e event,1000 .
+Also, if
+.Dq Pa -e event,=200
+is specified, profiling is performed every time the counter is increased by 200.
 .Ar outfile
 if specified.
 The default is
@@ -133,7 +145,7 @@
 .It top Xo
 .Oo
 .Fl e
-.Ar name[,value]
+.Ar name[,scale]
 .Op Fl e Ar ...
 .Oc
 .Op Fl i Ar interval
@@ -142,18 +154,6 @@
 Displays profiling results in real-time.
 .Ar name
 specifies the name of the event to count.
-.Ar value
-specifies the ratio of the speed to the cycle counter, or the counter until
-overflow.
-The counter reset value on overflow used for profiling is calculated from the
-speed of the cycle counter by default, but for some events this value may be
-too large (counter increasing too slowly) to be sufficient for profiling.
-For example, to specify an event that increases about 1000 times slower than
-the cycle counter, specify
-.Dq Pa -e event,1000 .
-Also, if 
-.Dq Pa -e event,=200
-is specified, profiling is performed every time the counter is increased by 200.
 .Bl -tag -width XXintervalX -offset indent
 .It Fl i Ar interval
 set the update interval in seconds. The default value is 1.
diff -r 13d41c637178 -r 8d757ade1cb9 usr.sbin/tprof/tprof.c
--- a/usr.sbin/tprof/tprof.c    Fri Dec 16 08:00:47 2022 +0000
+++ b/usr.sbin/tprof/tprof.c    Fri Dec 16 08:02:04 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tprof.c,v 1.17 2022/12/05 05:02:45 ryo Exp $   */
+/*     $NetBSD: tprof.c,v 1.18 2022/12/16 08:02:04 ryo Exp $   */
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -57,7 +57,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: tprof.c,v 1.17 2022/12/05 05:02:45 ryo Exp $");
+__RCSID("$NetBSD: tprof.c,v 1.18 2022/12/16 08:02:04 ryo Exp $");
 #endif /* not lint */
 
 #include <sys/atomic.h>
@@ -264,6 +264,97 @@
        tprof_event_list();
 }
 
+int
+tprof_parse_event(tprof_param_t *param, const char *str, uint32_t flags,
+    const char **eventnamep, char **errmsgp)
+{
+       double d;
+       uint64_t n;
+       int error = 0;
+       char *p, *event = NULL, *opt = NULL, *scale = NULL;
+       bool allow_option, allow_scale;
+       static char errmsgbuf[128];
+
+       allow_option = flags & TPROF_PARSE_EVENT_F_ALLOWOPTION;
+       allow_scale = flags & TPROF_PARSE_EVENT_F_ALLOWSCALE;
+
+       p = estrdup(str);
+       event = p;
+       if (allow_option) {
+               opt = strchr(p, ':');
+               if (opt != NULL) {
+                       *opt++ = '\0';
+                       p = opt;
+               }
+       }
+       if (allow_scale) {
+               scale = strchr(p, ',');
+               if (scale != NULL)
+                       *scale++ = '\0';
+       }
+
+       tprof_event_lookup(event, param);
+
+       if (opt != NULL) {
+               while (*opt != '\0') {
+                       switch (*opt) {
+                       case 'u':
+                               param->p_flags |= TPROF_PARAM_USER;
+                               break;
+                       case 'k':
+                               param->p_flags |= TPROF_PARAM_KERN;
+                               break;
+                       default:
+                               error = -1;
+                               snprintf(errmsgbuf, sizeof(errmsgbuf),
+                                   "invalid option: '%c'", *opt);
+                               goto done;
+                       }
+               }
+       } else if (allow_option) {
+               param->p_flags |= TPROF_PARAM_USER;
+               param->p_flags |= TPROF_PARAM_KERN;
+       }
+
+       if (scale != NULL) {
+               if (*scale == '=') {
+                       scale++;
+                       n = strtoull(scale, &p, 0);
+                       if (*p != '\0') {
+                               error = -1;
+                       } else {
+                               param->p_value2 = n;
+                               param->p_flags |=
+                                   TPROF_PARAM_VALUE2_TRIGGERCOUNT;
+                       }
+               } else {
+                       if (strncasecmp("0x", scale, 2) == 0)
+                               d = strtol(scale, &p, 0);
+                       else
+                               d = strtod(scale, &p);
+                       if (*p != '\0' || d <= 0) {
+                               error = -1;
+                       } else {
+                               param->p_value2 = 0x100000000ULL / d;
+                               param->p_flags |= TPROF_PARAM_VALUE2_SCALE;
+                       }
+               }
+
+               if (error != 0) {
+                       snprintf(errmsgbuf, sizeof(errmsgbuf),
+                           "invalid scale: %s", scale);
+                       goto done;
+               }
+       }
+
+ done:
+       if (eventnamep != NULL)
+               *eventnamep = event;
+       if (error != 0 && errmsgp != NULL)
+               *errmsgp = errmsgbuf;
+       return error;
+}
+
 static void
 tprof_monitor_common(bool do_profile, int argc, char **argv)
 {
@@ -273,7 +364,7 @@
        pid_t pid;
        pthread_t pt;
        int ret, ch, i;
-       char *tokens[2], *p;
+       char *p, *errmsg;
        tprof_countermask_t mask = TPROF_COUNTERMASK_ALL;
 
        memset(params, 0, sizeof(params));
@@ -290,23 +381,12 @@
                                    optarg);
                        break;
                case 'e':
-                       p = estrdup(optarg);
-                       tokens[0] = strtok(p, ":");
-                       tokens[1] = strtok(NULL, ":");
-                       tprof_event_lookup(tokens[0], &params[nevent]);
-
-                       if (tokens[1] == NULL) {
-                               params[nevent].p_flags |=
-                                   (TPROF_PARAM_USER | TPROF_PARAM_KERN);
-                       } else {
-                               if (strchr(tokens[1], 'u'))
-                                       params[nevent].p_flags |=
-                                           TPROF_PARAM_USER;
-                               if (strchr(tokens[1], 'k'))
-                                       params[nevent].p_flags |=
-                                           TPROF_PARAM_KERN;
+                       if (tprof_parse_event(&params[nevent], optarg,
+                           TPROF_PARSE_EVENT_F_ALLOWOPTION |
+                           (do_profile ? TPROF_PARSE_EVENT_F_ALLOWSCALE : 0),
+                           &eventname[nevent], &errmsg) != 0) {
+                               errx(EXIT_FAILURE, "%s", errmsg);
                        }
-                       eventname[nevent] = tokens[0];
                        eventnamewidth[nevent] = strlen(eventname[nevent]);
                        if (eventnamewidth[nevent] < COUNTER_COLUMNS_WIDTH)
                                eventnamewidth[nevent] = COUNTER_COLUMNS_WIDTH;
diff -r 13d41c637178 -r 8d757ade1cb9 usr.sbin/tprof/tprof.h
--- a/usr.sbin/tprof/tprof.h    Fri Dec 16 08:00:47 2022 +0000
+++ b/usr.sbin/tprof/tprof.h    Fri Dec 16 08:02:04 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tprof.h,v 1.3 2022/12/01 00:43:27 ryo Exp $    */
+/*     $NetBSD: tprof.h,v 1.4 2022/12/16 08:02:04 ryo Exp $    */
 
 /*
  * Copyright (c) 2018 The NetBSD Foundation, Inc.
@@ -38,5 +38,10 @@
 void tprof_event_list(void);
 void tprof_event_lookup(const char *, struct tprof_param *);
 
+int tprof_parse_event(tprof_param_t *, const char *, uint32_t, const char **,
+    char **);
+#define TPROF_PARSE_EVENT_F_ALLOWOPTION        0x00000001
+#define TPROF_PARSE_EVENT_F_ALLOWSCALE 0x00000002
+
 void tprof_analyze(int, char **);
 void tprof_top(int, char **);
diff -r 13d41c637178 -r 8d757ade1cb9 usr.sbin/tprof/tprof_top.c
--- a/usr.sbin/tprof/tprof_top.c        Fri Dec 16 08:00:47 2022 +0000
+++ b/usr.sbin/tprof/tprof_top.c        Fri Dec 16 08:02:04 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: tprof_top.c,v 1.6 2022/12/16 08:00:47 ryo Exp $        */
+/*     $NetBSD: tprof_top.c,v 1.7 2022/12/16 08:02:04 ryo Exp $        */
 
 /*-
  * Copyright (c) 2022 Ryo Shimizu <ryo%nerv.org@localhost>
@@ -28,7 +28,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: tprof_top.c,v 1.6 2022/12/16 08:00:47 ryo Exp $");
+__RCSID("$NetBSD: tprof_top.c,v 1.7 2022/12/16 08:02:04 ryo Exp $");
 #endif /* not lint */
 
 #include <sys/param.h>
@@ -919,33 +919,6 @@
        exit(EXIT_FAILURE);
 }
 
-static int
-parse_event_scale(tprof_param_t *param, const char *str)
-{
-       double d;
-       uint64_t n;
-       char *p;
-
-       if (str[0] == '=') {
-               str++;
-               n = strtoull(str, &p, 0);
-               if (*p != '\0')
-                       return -1;
-               param->p_value2 = n;
-               param->p_flags |= TPROF_PARAM_VALUE2_TRIGGERCOUNT;
-       } else {
-               if (strncasecmp("0x", str, 2) == 0)
-                       d = strtol(str, &p, 0);
-               else
-                       d = strtod(str, &p);
-               if (*p != '\0')
-                       return -1;
-               param->p_value2 = 0x100000000ULL / d;
-               param->p_flags |= TPROF_PARAM_VALUE2_SCALE;
-       }
-       return 0;
-}
-
 __dead void
 tprof_top(int argc, char **argv)
 {
@@ -954,7 +927,7 @@
        ssize_t tprof_bufsize, len;
        u_int i;
        int ch, ret;
-       char *tprof_buf, *tokens[2], *p;
+       char *tprof_buf, *p, *errmsg;
        bool noinput = false;
 
        memset(params, 0, sizeof(params));



Home | Main Index | Thread Index | Old Index