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], ¶ms[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(¶ms[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