Allow sub-second interval timings for iostat and vmstat.

e.g.
vmstat -w.5
iostat -w.5

Reviewed by:	jhb
Approved by:	scottl (mentor)
Obtained from:	Yahoo Inc.
MFC after:	2 weeks
This commit is contained in:
Sean Bruno 2010-05-21 17:10:52 +00:00
parent 14765ad2e0
commit 8b10473d30
4 changed files with 29 additions and 12 deletions

View File

@ -209,6 +209,9 @@ seconds between each display.
If no repeat
.Ar wait
interval is specified, the default is 1 second.
The
.Nm
command will accept and honor a non-integer number of seconds.
.It Fl z
Report on memory used by the kernel zone allocator,
.Xr uma 9 ,

View File

@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$");
#include <sys/ioctl.h>
#include <sys/resource.h>
#include <sys/sysctl.h>
#include <sys/time.h>
#include <sys/vmmeter.h>
#include <sys/pcpu.h>
@ -181,6 +182,7 @@ main(int argc, char *argv[])
{
int c, todo;
unsigned int interval;
float f;
int reps;
char *memf, *nlistf;
char errbuf[_POSIX2_LINE_MAX];
@ -243,7 +245,9 @@ main(int argc, char *argv[])
#endif
break;
case 'w':
interval = atoi(optarg);
/* Convert to milliseconds. */
f = atof(optarg);
interval = f * 1000;
break;
case 'z':
todo |= ZMEMSTAT;
@ -298,7 +302,8 @@ main(int argc, char *argv[])
#define BACKWARD_COMPATIBILITY
#ifdef BACKWARD_COMPATIBILITY
if (*argv) {
interval = atoi(*argv);
f = atof(*argv);
interval = f * 1000;
if (*++argv)
reps = atoi(*argv);
}
@ -308,7 +313,7 @@ main(int argc, char *argv[])
if (!reps)
reps = -1;
} else if (reps)
interval = 1;
interval = 1 * 1000;
if (todo & FORKSTAT)
doforkst();
@ -652,9 +657,11 @@ dovmstat(unsigned int interval, int reps)
size_t size;
int ncpus, maxid;
u_long cpumask;
int rate_adj;
uptime = getuptime();
halfuptime = uptime / 2;
rate_adj = 1;
/*
* If the user stops the program (control-Z) and then resumes it,
@ -766,7 +773,7 @@ dovmstat(unsigned int interval, int reps)
(void)printf("%2d %1d %1d",
total.t_rq - 1, total.t_dw + total.t_pw, total.t_sw);
#define vmstat_pgtok(a) ((a) * (sum.v_page_size >> 10))
#define rate(x) (((x) + halfuptime) / uptime) /* round */
#define rate(x) (((x) * rate_adj + halfuptime) / uptime) /* round */
if (hflag) {
printf(" ");
prthuman(total.t_avm * (u_int64_t)sum.v_page_size, 7);
@ -806,15 +813,16 @@ dovmstat(unsigned int interval, int reps)
break;
osum = sum;
uptime = interval;
rate_adj = 1000;
/*
* We round upward to avoid losing low-frequency events
* (i.e., >= 1 per interval but < 1 per second).
* (i.e., >= 1 per interval but < 1 per millisecond).
*/
if (interval != 1)
halfuptime = (uptime + 1) / 2;
else
halfuptime = 0;
(void)sleep(interval);
(void)usleep(interval * 1000);
}
}

View File

@ -239,6 +239,9 @@ seconds between each display.
If no repeat
.Ar count
is specified, the default is infinity.
The
.Nm
command will accept and honor a non-integer number of seconds.
.It Fl x
Show extended disk statistics.
Each disk is displayed on a line of its own with all available statistics.

View File

@ -184,6 +184,7 @@ main(int argc, char **argv)
long select_generation;
char **specified_devices;
devstat_select_mode select_mode;
float f;
int havelast = 0;
matches = NULL;
@ -239,9 +240,10 @@ main(int argc, char **argv)
break;
case 'w':
wflag++;
waittime = atoi(optarg);
f = atof(optarg);
waittime = f * 1000;
if (waittime < 1)
errx(1, "wait time is < 1");
errx(1, "wait time is < 1ms");
break;
case 'x':
xflag++;
@ -378,12 +380,13 @@ main(int argc, char **argv)
* Look for the traditional wait time and count arguments.
*/
if (*argv) {
waittime = atoi(*argv);
f = atof(*argv);
waittime = f * 1000;
/* Let the user know he goofed, but keep going anyway */
if (wflag != 0)
warnx("discarding previous wait interval, using"
" %d instead", waittime);
" %g instead", waittime / 1000.0);
wflag++;
if (*++argv) {
@ -401,7 +404,7 @@ main(int argc, char **argv)
* to an interval of 1 second.
*/
if ((wflag == 0) && (cflag > 0))
waittime = 1;
waittime = 1 * 1000;
/*
* If the user specified a wait time, but not a count, we want to
@ -602,7 +605,7 @@ main(int argc, char **argv)
if (count >= 0 && --count <= 0)
break;
sleep(waittime);
usleep(waittime * 1000);
havelast = 1;
}