Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 17 May 2014 03:54:52 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r266293 - head/usr.bin/procstat
Message-ID:  <201405170354.s4H3sqgI062328@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Sat May 17 03:54:51 2014
New Revision: 266293
URL: http://svnweb.freebsd.org/changeset/base/266293

Log:
  - Add support for dumping current resource usage for processes via a new -r
    flag to procstat.
  - Add an -H flag to request information about threads rather than processes
    when dumping statistics.  Currently it is only used for -r to display
    resource usage for individual threads instead of the entire process.
  
  Reviewed by:	kib (older version without -H)
  MFC after:	1 month

Added:
  head/usr.bin/procstat/procstat_rusage.c   (contents, props changed)
Modified:
  head/usr.bin/procstat/Makefile
  head/usr.bin/procstat/procstat.1
  head/usr.bin/procstat/procstat.c
  head/usr.bin/procstat/procstat.h

Modified: head/usr.bin/procstat/Makefile
==============================================================================
--- head/usr.bin/procstat/Makefile	Sat May 17 03:49:29 2014	(r266292)
+++ head/usr.bin/procstat/Makefile	Sat May 17 03:54:51 2014	(r266293)
@@ -11,6 +11,7 @@ SRCS=	procstat.c		\
 	procstat_files.c	\
 	procstat_kstack.c	\
 	procstat_rlimit.c	\
+	procstat_rusage.c	\
 	procstat_sigs.c		\
 	procstat_threads.c	\
 	procstat_vm.c

Modified: head/usr.bin/procstat/procstat.1
==============================================================================
--- head/usr.bin/procstat/procstat.1	Sat May 17 03:49:29 2014	(r266292)
+++ head/usr.bin/procstat/procstat.1	Sat May 17 03:54:51 2014	(r266293)
@@ -25,7 +25,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd February 11, 2014
+.Dd May 16, 2014
 .Dt PROCSTAT 1
 .Os
 .Sh NAME
@@ -33,11 +33,9 @@
 .Nd get detailed process information
 .Sh SYNOPSIS
 .Nm
-.Op Fl h
-.Op Fl n
-.Op Fl C
+.Op Fl CHhn
 .Op Fl w Ar interval
-.Op Fl b | c | e | f | i | j | k | l | s | t | v | x
+.Op Fl b | c | e | f | i | j | k | l | r | s | t | v | x
 .Op Fl a | Ar pid | Ar core ...
 .Sh DESCRIPTION
 The
@@ -73,6 +71,8 @@ If the flag is repeated, function offset
 printed.
 .It Fl l
 Display resource limits for the process.
+.It Fl r
+Display resource usage information for the process.
 .It Fl s
 Display security credential information for the process.
 .It Fl t
@@ -102,6 +102,13 @@ The
 flag requests the printing of additional capability information in the file
 descriptor view.
 .Pp
+The
+.Fl H
+flag may be used to request per-thread statistics rather than per-process
+statistics for some options.
+For those options, the second field in the table will list the thread ID
+to which the row of information corresponds.
+.Pp
 Some information, such as VM and file descriptor information, is available
 only to the owner of a process or the superuser.
 .Ss Binary Information

Modified: head/usr.bin/procstat/procstat.c
==============================================================================
--- head/usr.bin/procstat/procstat.c	Sat May 17 03:49:29 2014	(r266292)
+++ head/usr.bin/procstat/procstat.c	Sat May 17 03:54:51 2014	(r266293)
@@ -39,18 +39,19 @@
 
 #include "procstat.h"
 
-static int aflag, bflag, cflag, eflag, fflag, iflag, jflag, kflag, lflag, sflag;
-static int tflag, vflag, xflag;
-int	hflag, nflag, Cflag;
+static int aflag, bflag, cflag, eflag, fflag, iflag, jflag, kflag, lflag, rflag;
+static int sflag, tflag, vflag, xflag;
+int	hflag, nflag, Cflag, Hflag;
 
 static void
 usage(void)
 {
 
-	fprintf(stderr, "usage: procstat [-h] [-C] [-M core] [-N system] "
+	fprintf(stderr, "usage: procstat [-CHhn] [-M core] [-N system] "
 	    "[-w interval] \n");
 	fprintf(stderr, "                [-b | -c | -e | -f | -i | -j | -k | "
-	    "-l | -s | -t | -v | -x] [-a | pid | core ...]\n");
+	    "-l | -r | -s | -t | -v | -x]\n");
+	fprintf(stderr, "                [-a | pid | core ...]\n");
 	exit(EX_USAGE);
 }
 
@@ -74,6 +75,8 @@ procstat(struct procstat *prstat, struct
 		procstat_kstack(prstat, kipp, kflag);
 	else if (lflag)
 		procstat_rlimit(prstat, kipp);
+	else if (rflag)
+		procstat_rusage(prstat, kipp);
 	else if (sflag)
 		procstat_cred(prstat, kipp);
 	else if (tflag)
@@ -125,12 +128,16 @@ main(int argc, char *argv[])
 
 	interval = 0;
 	memf = nlistf = NULL;
-	while ((ch = getopt(argc, argv, "CN:M:abcefijklhstvw:x")) != -1) {
+	while ((ch = getopt(argc, argv, "CHN:M:abcefijklhrstvw:x")) != -1) {
 		switch (ch) {
 		case 'C':
 			Cflag++;
 			break;
 
+		case 'H':
+			Hflag++;
+			break;
+
 		case 'M':
 			memf = optarg;
 			break;
@@ -181,6 +188,10 @@ main(int argc, char *argv[])
 			hflag++;
 			break;
 
+		case 'r':
+			rflag++;
+			break;
+
 		case 's':
 			sflag++;
 			break;
@@ -217,7 +228,7 @@ main(int argc, char *argv[])
 
 	/* We require that either 0 or 1 mode flags be set. */
 	tmp = bflag + cflag + eflag + fflag + iflag + jflag + (kflag ? 1 : 0) +
-	    lflag + sflag + tflag + vflag + xflag;
+	    lflag + rflag + sflag + tflag + vflag + xflag;
 	if (!(tmp == 0 || tmp == 1))
 		usage();
 

Modified: head/usr.bin/procstat/procstat.h
==============================================================================
--- head/usr.bin/procstat/procstat.h	Sat May 17 03:49:29 2014	(r266292)
+++ head/usr.bin/procstat/procstat.h	Sat May 17 03:54:51 2014	(r266293)
@@ -29,7 +29,7 @@
 #ifndef PROCSTAT_H
 #define	PROCSTAT_H
 
-extern int	hflag, nflag, Cflag;
+extern int	hflag, nflag, Cflag, Hflag;
 
 struct kinfo_proc;
 void	kinfo_proc_sort(struct kinfo_proc *kipp, int count);
@@ -44,6 +44,7 @@ void	procstat_files(struct procstat *prs
 void	procstat_kstack(struct procstat *prstat, struct kinfo_proc *kipp,
     int kflag);
 void	procstat_rlimit(struct procstat *prstat, struct kinfo_proc *kipp);
+void	procstat_rusage(struct procstat *prstat, struct kinfo_proc *kipp);
 void	procstat_sigs(struct procstat *prstat, struct kinfo_proc *kipp);
 void	procstat_threads(struct procstat *prstat, struct kinfo_proc *kipp);
 void	procstat_threads_sigs(struct procstat *prstat, struct kinfo_proc *kipp);

Added: head/usr.bin/procstat/procstat_rusage.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/usr.bin/procstat/procstat_rusage.c	Sat May 17 03:54:51 2014	(r266293)
@@ -0,0 +1,160 @@
+/*-
+ * Copyright (c) 2012 Advanced Computing Technologies LLC
+ * Written by: John H. Baldwin <jhb@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <sys/user.h>
+
+#include <libprocstat.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <libutil.h>
+
+#include "procstat.h"
+
+static struct {
+	const char *ri_name;
+	bool	ri_humanize;
+	int	ri_scale;
+} rusage_info[] = {
+	{ "maximum RSS", true, 1 },
+	{ "integral shared memory", true, 1 },
+	{ "integral unshared data", true, 1 },
+	{ "integral unshared stack", true, 1 },
+	{ "page reclaims", false, 0 },
+	{ "page faults", false, 0 },
+	{ "swaps", false, 0 },
+	{ "block reads", false, 0 },
+	{ "block writes", false, 0 },
+	{ "messages sent", false, 0 },
+	{ "messages received", false, 0 },
+	{ "signals received", false, 0 },
+	{ "voluntary context switches", false, 0 },
+	{ "involuntary context switches", false, 0 }
+};
+
+/* xxx days hh:mm:ss.uuuuuu */
+static const char *
+format_time(struct timeval *tv)
+{
+	static char buffer[32];
+	int days, hours, minutes, seconds, used;
+
+	minutes = tv->tv_sec / 60;
+	seconds = tv->tv_sec % 60;
+	hours = minutes / 60;
+	minutes %= 60;
+	days = hours / 24;
+	hours %= 24;
+	used = 0;
+	if (days == 1)
+		used += snprintf(buffer, sizeof(buffer), "1 day ");
+	else if (days > 0)
+		used += snprintf(buffer, sizeof(buffer), "%u days ", days);
+	
+	snprintf(buffer + used, sizeof(buffer) - used, "%02u:%02u:%02u.%06u   ",
+	    hours, minutes, seconds, (unsigned int)tv->tv_usec);
+	return (buffer);
+}
+
+static const char *
+format_value(long value, bool humanize, int scale)
+{
+	static char buffer[14];
+
+	if (scale != 0)
+		value <<= scale * 10;
+	if (humanize)
+		humanize_number(buffer, sizeof(buffer), value, "B",
+		    scale, HN_DECIMAL);
+	else
+		snprintf(buffer, sizeof(buffer), "%ld   ", value);
+	return (buffer);
+}
+
+static void
+print_prefix(struct kinfo_proc *kipp)
+{
+
+	printf("%5d ", kipp->ki_pid);
+	if (Hflag)
+		printf("%6d ", kipp->ki_tid);
+	printf("%-16s ", kipp->ki_comm);
+}
+
+static void
+print_rusage(struct kinfo_proc *kipp)
+{
+	long *lp;
+	unsigned int i;
+
+	print_prefix(kipp);
+	printf("%-14s %32s\n", "user time",
+	    format_time(&kipp->ki_rusage.ru_utime));
+	print_prefix(kipp);
+	printf("%-14s %32s\n", "system time",
+	    format_time(&kipp->ki_rusage.ru_stime));
+	lp = &kipp->ki_rusage.ru_maxrss;
+	for (i = 0; i < nitems(rusage_info); i++) {
+		print_prefix(kipp);
+		printf("%-32s %14s\n", rusage_info[i].ri_name,
+		    format_value(*lp, rusage_info[i].ri_humanize,
+			rusage_info[i].ri_scale));
+		lp++;
+	}
+}
+
+void
+procstat_rusage(struct procstat *procstat, struct kinfo_proc *kipp)
+{
+	struct kinfo_proc *kip;
+	unsigned int count, i;
+
+	if (!hflag) {
+		printf("%5s ", "PID");
+		if (Hflag)
+			printf("%6s ", "TID");
+		printf("%-16s %-32s %14s\n", "COMM", "TYPE", "VALUE        ");
+	}
+
+	if (!Hflag) {
+		print_rusage(kipp);
+		return;
+	}
+
+	kip = procstat_getprocs(procstat, KERN_PROC_PID | KERN_PROC_INC_THREAD,
+	    kipp->ki_pid, &count);
+	if (kip == NULL)
+		return;
+	kinfo_proc_sort(kip, count);
+	for (i = 0; i < count; i++)
+		print_rusage(&kip[i]);
+	procstat_freeprocs(procstat, kip);
+}



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