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
This commit is contained in:
parent
9e8ab8f731
commit
961a5dae5c
@ -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 @@ main(int argc, char *argv[])
|
||||
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)
|
||||
break;
|
||||
}
|
||||
for (intrname = NULL, inamlen = 1024; ; inamlen *= 2) {
|
||||
if ((intrname = reallocf(intrname, inamlen)) == NULL)
|
||||
err(1, "reallocf()");
|
||||
if (mysysctl("hw.intrnames",
|
||||
intrname, &inamlen, NULL, 0) == 0)
|
||||
*intrcnts, &intrcntlen, NULL, 0) == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
nintr = intrcntlen / sizeof(unsigned long);
|
||||
tintrname = intrname;
|
||||
|
||||
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",
|
||||
intrnames, &inamlen, NULL, 0) == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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
|
||||
|
Loading…
Reference in New Issue
Block a user