Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 8 Mar 2009 20:21:37 -0500
From:      Dan Nelson <dnelson@allantgroup.com>
To:        Jay Loden <freebsd@jayloden.com>
Cc:        freebsd-hackers@freebsd.org
Subject:   Re: CPU user/kernel time given the PID
Message-ID:  <20090309012137.GG3398@dan.emsphone.com>
In-Reply-To: <49B463D7.9010401@jayloden.com>
References:  <200903082156.n28Lup7e085565@lurza.secnetix.de> <49B463D7.9010401@jayloden.com>

next in thread | previous in thread | raw e-mail | index | archive | help

--Kj7319i9nmIyA2yE
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

In the last episode (Mar 08), Jay Loden said:
> Oliver Fromme wrote:
> > ps(1) and top(1) both use ki_pctcpu, see the getpcpu() function in
> > src/bin/ps/print.c and format_next_process() in
> > src/usr.bin/top/machine.c
> 
> Hi Oliver, thanks for the reply. I noticed the same after some digging
> through the source code for ps and top.  While CPU usage % is a useful
> number also, I was hoping to be able to get CPU time(s).  Possibly that
> information simply isn't available on FreeBSD like it is for other OSes.

I was wondering why you were having so much trouble finding what you were
looking for, and then I realized I have a patch that I have never submitted
a PR for: the addition of "systime" and "usertime" ps keywords :) It simply
reads the rusage struct, and returns the same values that getrusage() does.

-- 
	Dan Nelson
	dnelson@allantgroup.com

--Kj7319i9nmIyA2yE
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="ps.diff"

Index: extern.h
===================================================================
RCS file: /home/ncvs/src/bin/ps/extern.h,v
retrieving revision 1.37
diff -u -p -r1.37 extern.h
--- extern.h	23 Jun 2004 23:48:09 -0000	1.37
+++ extern.h	7 Jan 2005 06:46:15 -0000
@@ -78,11 +78,13 @@ int	 s_uname(KINFO *);
 void	 showkey(void);
 void	 started(KINFO *, VARENT *);
 void	 state(KINFO *, VARENT *);
+void	 systime(KINFO *, VARENT *);
 void	 tdev(KINFO *, VARENT *);
 void	 tname(KINFO *, VARENT *);
 void	 ucomm(KINFO *, VARENT *);
 void	 uname(KINFO *, VARENT *);
 void	 upr(KINFO *, VARENT *);
+void	 usertime(KINFO *, VARENT *);
 void	 vsize(KINFO *, VARENT *);
 void	 wchan(KINFO *, VARENT *);
 __END_DECLS
Index: keyword.c
===================================================================
RCS file: /home/ncvs/src/bin/ps/keyword.c,v
retrieving revision 1.76
diff -u -p -r1.76 keyword.c
--- keyword.c	6 Apr 2006 03:24:31 -0000	1.76
+++ keyword.c	2 Mar 2007 17:23:10 -0000
@@ -185,6 +185,7 @@ static VAR var[] = {
 		UINT, UIDFMT, 0},
 	{"svuid", "SVUID", NULL, 0, kvar, NULL, UIDLEN, KOFF(ki_svuid),
 		UINT, UIDFMT, 0},
+	{"systime", "SYSTIME", NULL, USER, systime, NULL, 9, 0, CHAR, NULL, 0},
 	{"tdev", "TDEV", NULL, 0, tdev, NULL, 4, 0, CHAR, NULL, 0},
 	{"time", "TIME", NULL, USER, cputime, NULL, 9, 0, CHAR, NULL, 0},
 	{"tpgid", "TPGID", NULL, 0, kvar, NULL, 4, KOFF(ki_tpgid), UINT,
@@ -203,6 +204,7 @@ static VAR var[] = {
 		"lx", 0},
 	{"user", "USER", NULL, LJUST|DSIZ, uname, s_uname, USERLEN, 0, CHAR,
 		NULL, 0},
+	{"usertime", "USERTIME", NULL, USER, usertime, NULL, 9, 0, CHAR, NULL, 0},
 	{"usrpri", "", "upr", 0, NULL, NULL, 0, 0, CHAR, NULL, 0},
 	{"vsize", "", "vsz", 0, NULL, NULL, 0, 0, CHAR, NULL, 0},
 	{"vsz", "VSZ", NULL, 0, vsize, NULL, 5, 0, CHAR, NULL, 0},
Index: print.c
===================================================================
RCS file: /home/ncvs/src/bin/ps/print.c,v
retrieving revision 1.95
diff -u -p -r1.95 print.c
--- print.c	17 Sep 2007 05:27:18 -0000	1.95
+++ print.c	11 Oct 2007 19:54:02 -0000
@@ -551,6 +551,79 @@ cputime(KINFO *k, VARENT *ve)
 }
 
 void
+systime(KINFO *k, VARENT *ve)
+{
+	VAR *v;
+	long secs;
+	long psecs;	/* "parts" of a second. first micro, then centi */
+	char obuff[128];
+	static char decimal_point;
+
+	if (decimal_point == '\0')
+		decimal_point = localeconv()->decimal_point[0];
+	v = ve->var;
+	if (!k->ki_valid) {
+		secs = 0;
+		psecs = 0;
+	} else {
+		/*
+		 * This counts time spent handling interrupts.  We could
+		 * fix this, but it is not 100% trivial (and interrupt
+		 * time fractions only work on the sparc anyway).	XXX
+		 */
+		secs = k->ki_p->ki_rusage.ru_stime.tv_sec;
+		psecs = k->ki_p->ki_rusage.ru_stime.tv_usec;
+		if (sumrusage) {
+			secs += k->ki_p->ki_childstime.tv_sec;
+			psecs += k->ki_p->ki_childstime.tv_usec;
+		}
+		/*
+		 * round and scale to 100's
+		 */
+		psecs = (psecs + 5000) / 10000;
+		secs += psecs / 100;
+		psecs = psecs % 100;
+	}
+	(void)snprintf(obuff, sizeof(obuff), "%3ld:%02ld%c%02ld",
+	    secs / 60, secs % 60, decimal_point, psecs);
+	(void)printf("%*s", v->width, obuff);
+}
+
+void
+usertime(KINFO *k, VARENT *ve)
+{
+	VAR *v;
+	long secs;
+	long psecs;	/* "parts" of a second. first micro, then centi */
+	char obuff[128];
+	static char decimal_point;
+
+	if (decimal_point == '\0')
+		decimal_point = localeconv()->decimal_point[0];
+	v = ve->var;
+	if (!k->ki_valid) {
+		secs = 0;
+		psecs = 0;
+	} else {
+		secs = k->ki_p->ki_rusage.ru_utime.tv_sec;
+		psecs = k->ki_p->ki_rusage.ru_utime.tv_usec;
+		if (sumrusage) {
+			secs += k->ki_p->ki_childutime.tv_sec;
+			psecs += k->ki_p->ki_childutime.tv_usec;
+		}
+		/*
+		 * round and scale to 100's
+		 */
+		psecs = (psecs + 5000) / 10000;
+		secs += psecs / 100;
+		psecs = psecs % 100;
+	}
+	(void)snprintf(obuff, sizeof(obuff), "%3ld:%02ld%c%02ld",
+	    secs / 60, secs % 60, decimal_point, psecs);
+	(void)printf("%*s", v->width, obuff);
+}
+
+void
 elapsed(KINFO *k, VARENT *ve)
 {
 	VAR *v;
Index: ps.1
===================================================================
RCS file: /home/ncvs/src/bin/ps/ps.1,v
retrieving revision 1.89
diff -u -p -r1.89 ps.1
--- ps.1	17 Sep 2006 17:40:06 -0000	1.89
+++ ps.1	2 Mar 2007 17:23:11 -0000
@@ -571,6 +571,8 @@ symbolic process state (alias
 saved gid from a setgid executable
 .It Cm svuid
 saved UID from a setuid executable
+.It Cm systime
+accumulated system CPU time
 .It Cm tdev
 control terminal device number
 .It Cm time
@@ -599,6 +601,8 @@ scheduling priority on return from syste
 .Cm usrpri )
 .It Cm user
 user name (from UID)
+.It Cm usertime
+accumulated user CPU time
 .It Cm vsz
 virtual size in Kbytes (alias
 .Cm vsize )

--Kj7319i9nmIyA2yE--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20090309012137.GG3398>