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 dnel...@allantgroup.com
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 )
_______________________________________________ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "freebsd-hackers-unsubscr...@freebsd.org"