summaryrefslogtreecommitdiffstats
path: root/usr.bin
diff options
context:
space:
mode:
authorwill <will@FreeBSD.org>2015-01-23 16:15:55 +0000
committerwill <will@FreeBSD.org>2015-01-23 16:15:55 +0000
commit8f871060e6f2ddfcf4177c91739c3d7f14e15994 (patch)
tree45527ad69fb7fa74b37916c16ab60246f9174841 /usr.bin
parent46dec2e356b14245e929050c1768dc109e8abc64 (diff)
downloadFreeBSD-src-8f871060e6f2ddfcf4177c91739c3d7f14e15994.zip
FreeBSD-src-8f871060e6f2ddfcf4177c91739c3d7f14e15994.tar.gz
Make "vmstat -i" respect the -c <count> and -i <interval> options together.
Submitted by: asomers MFC after: 1 week Sponsored by: Spectra Logic MFSpectraBSD: 1066735 on 2014/06/04
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/vmstat/vmstat.c141
1 files changed, 106 insertions, 35 deletions
diff --git a/usr.bin/vmstat/vmstat.c b/usr.bin/vmstat/vmstat.c
index 760dce8..a54a0dd 100644
--- a/usr.bin/vmstat/vmstat.c
+++ b/usr.bin/vmstat/vmstat.c
@@ -148,7 +148,7 @@ static void cpustats(void);
static void pcpustats(int, u_long, int);
static void devstats(void);
static void doforkst(void);
-static void dointr(void);
+static void dointr(unsigned int, int);
static void dosum(void);
static void dovmstat(unsigned int, int);
static void domemstat_malloc(void);
@@ -325,7 +325,7 @@ retry_nlist:
dotimes();
#endif
if (todo & INTRSTAT)
- dointr();
+ dointr(interval, reps);
if (todo & VMSTAT)
dovmstat(interval, reps);
exit(0);
@@ -1165,61 +1165,132 @@ pcpustats(int ncpus, u_long cpumask, int maxid)
}
}
-static void
-dointr(void)
+static unsigned int
+read_intrcnts(unsigned long **intrcnts)
{
- unsigned long *intrcnt, uptime;
- uint64_t inttotal;
- size_t clen, inamlen, intrcntlen, istrnamlen;
- unsigned int i, nintr;
- char *intrname, *tintrname;
+ size_t intrcntlen;
- uptime = getuptime();
if (kd != NULL) {
kread(X_SINTRCNT, &intrcntlen, sizeof(intrcntlen));
- kread(X_SINTRNAMES, &inamlen, sizeof(inamlen));
- if ((intrcnt = malloc(intrcntlen)) == NULL ||
- (intrname = malloc(inamlen)) == NULL)
+ if ((*intrcnts = malloc(intrcntlen)) == NULL)
err(1, "malloc()");
- kread(X_INTRCNT, intrcnt, intrcntlen);
- kread(X_INTRNAMES, intrname, inamlen);
+ kread(X_INTRCNT, *intrcnts, intrcntlen);
} else {
- for (intrcnt = NULL, intrcntlen = 1024; ; intrcntlen *= 2) {
- if ((intrcnt = reallocf(intrcnt, intrcntlen)) == NULL)
+ for (*intrcnts = NULL, intrcntlen = 1024; ; intrcntlen *= 2) {
+ *intrcnts = reallocf(*intrcnts, intrcntlen);
+ if (*intrcnts == NULL)
err(1, "reallocf()");
if (mysysctl("hw.intrcnt",
- intrcnt, &intrcntlen, NULL, 0) == 0)
+ *intrcnts, &intrcntlen, NULL, 0) == 0)
break;
}
- for (intrname = NULL, inamlen = 1024; ; inamlen *= 2) {
- if ((intrname = reallocf(intrname, inamlen)) == NULL)
+ }
+
+ return (intrcntlen / sizeof(unsigned long));
+}
+
+static void
+print_intrcnts(unsigned long *intrcnts, unsigned long *old_intrcnts,
+ char *intrnames, unsigned int nintr,
+ size_t istrnamlen, unsigned long long period)
+{
+ unsigned long *intrcnt, *old_intrcnt;
+ uint64_t inttotal, old_inttotal, total_count, total_rate;
+ char* intrname;
+ unsigned int i;
+
+ inttotal = 0;
+ old_inttotal = 0;
+ intrname = intrnames;
+ for (i = 0, intrcnt=intrcnts, old_intrcnt=old_intrcnts; i < nintr; i++) {
+ if (intrname[0] != '\0' && (*intrcnt != 0 || aflag)) {
+ unsigned long count, rate;
+
+ count = *intrcnt - *old_intrcnt;
+ rate = (count * 1000 + period/2) / period;
+ (void)printf("%-*s %20lu %10lu\n", (int)istrnamlen,
+ intrname, count, rate);
+ }
+ intrname += strlen(intrname) + 1;
+ inttotal += *intrcnt++;
+ old_inttotal += *old_intrcnt++;
+ }
+ total_count = inttotal - old_inttotal;
+ total_rate = (total_count * 1000 + period/2) / period;
+ (void)printf("%-*s %20" PRIu64 " %10" PRIu64 "\n", (int)istrnamlen,
+ "Total", total_count, total_rate);
+}
+
+static void
+dointr(unsigned int interval, int reps)
+{
+ unsigned long *intrcnts;
+ unsigned long long uptime, period;
+ unsigned long *old_intrcnts = NULL;
+ size_t clen, inamlen, istrnamlen;
+ unsigned int rep;
+ char *intrnames, *intrname;
+
+ uptime = getuptime();
+
+ /* Get the names of each interrupt source */
+ if (kd != NULL) {
+ kread(X_SINTRNAMES, &inamlen, sizeof(inamlen));
+ if ((intrnames = malloc(inamlen)) == NULL)
+ err(1, "malloc()");
+ kread(X_INTRNAMES, intrnames, inamlen);
+ } else {
+ for (intrnames = NULL, inamlen = 1024; ; inamlen *= 2) {
+ if ((intrnames = reallocf(intrnames, inamlen)) == NULL)
err(1, "reallocf()");
if (mysysctl("hw.intrnames",
- intrname, &inamlen, NULL, 0) == 0)
+ intrnames, &inamlen, NULL, 0) == 0)
break;
}
}
- nintr = intrcntlen / sizeof(unsigned long);
- tintrname = intrname;
+
+ /* Determine the length of the longest interrupt name */
+ intrname = intrnames;
istrnamlen = strlen("interrupt");
- for (i = 0; i < nintr; i++) {
- clen = strlen(tintrname);
+ while(*intrname != '\0') {
+ clen = strlen(intrname);
if (clen > istrnamlen)
istrnamlen = clen;
- tintrname += clen + 1;
+ intrname += strlen(intrname) + 1;
}
(void)printf("%-*s %20s %10s\n", (int)istrnamlen, "interrupt", "total",
"rate");
- inttotal = 0;
- for (i = 0; i < nintr; i++) {
- if (intrname[0] != '\0' && (*intrcnt != 0 || aflag))
- (void)printf("%-*s %20lu %10lu\n", (int)istrnamlen,
- intrname, *intrcnt, *intrcnt / uptime);
- intrname += strlen(intrname) + 1;
- inttotal += *intrcnt++;
+
+ /*
+ * Loop reps times printing differential interrupt counts. If reps is
+ * zero, then run just once, printing total counts
+ */
+ period = uptime * 1000;
+ while(1) {
+ char *intrname;
+ unsigned int nintr;
+
+ nintr = read_intrcnts(&intrcnts);
+ /*
+ * Initialize old_intrcnts to 0 for the first pass, so
+ * print_intrcnts will print total interrupts since boot
+ */
+ if (old_intrcnts == NULL) {
+ old_intrcnts = calloc(nintr, sizeof(unsigned long));
+ if (old_intrcnts == NULL)
+ err(1, "calloc()");
+ }
+
+ print_intrcnts(intrcnts, old_intrcnts, intrnames, nintr,
+ istrnamlen, period);
+
+ free(old_intrcnts);
+ old_intrcnts = intrcnts;
+ if (reps >= 0 && --reps <= 0)
+ break;
+ usleep(interval * 1000);
+ period = interval;
}
- (void)printf("%-*s %20" PRIu64 " %10" PRIu64 "\n", (int)istrnamlen,
- "Total", inttotal, inttotal / uptime);
}
static void
OpenPOWER on IntegriCloud