* Copyright (c) 1983 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
static char sccsid
[] = "@(#)vmstat.c 5.7 (Berkeley) %G%";
* Cursed vmstat -- from Robert Elz.
ut
= open("/etc/utmp", O_RDONLY
);
static struct nlist name
[] = {
struct forkstat Forkstat
;
struct nchstats nchstats
;
#define nchtotal s.nchstats
#define oldnchtotal s1.nchstats
static enum state
{ BOOT
, TIME
, RUN
} state
= TIME
;
* These constants define where the major pieces are laid out
#define PROCSROW 13 /* uses 2 rows and 20 cols */
#define NAMEIROW 20 /* uses 3 rows and 38 cols */
#define GRAPHROW 16 /* uses 3 rows and 51 cols */
#define GENSTATROW 14 /* uses 8 rows and 11 cols */
#define INTSROW 2 /* uses all rows to bottom and 17 cols */
#define STATROW 0 /* uses 1 row and 68 cols */
#define PAGEROW 2 /* uses 11 rows and 26 cols */
#define MEMROW 2 /* uses 4 rows and 31 cols */
#define DISKROW 7 /* uses 5 rows and 35 cols */
if (name
[0].n_type
== 0) {
if (name
[0].n_type
== 0) {
if (dk_ndrive
&& !once
) {
s./**/e = (t *)calloc(dk_ndrive, sizeof (t)); \
s1./**/e = (t *)calloc(dk_ndrive, sizeof (t)); \
s2./**/e = (t *)calloc(dk_ndrive, sizeof (t)); \
z./**/e = (t *)calloc(dk_ndrive, sizeof (t));
nintr
= (name
[X_EINTRCNT
].n_value
-
name
[X_INTRCNT
].n_value
) / sizeof (long);
intrloc
= (long *) calloc(nintr
, sizeof (long));
intrname
= (char **) calloc(nintr
, sizeof (long));
intrnamebuf
= malloc(name
[X_EINTRNAMES
].n_value
-
name
[X_INTRNAMES
].n_value
);
if (intrnamebuf
== 0 || intrname
== 0 || intrloc
== 0) {
error("Out of memory\n");
lseek(kmem
, (long)name
[X_INTRNAMES
].n_value
, L_SET
);
read(kmem
, intrnamebuf
, name
[X_EINTRNAMES
].n_value
-
name
[X_INTRNAMES
].n_value
);
for (cp
= intrnamebuf
, i
= 0; i
< nintr
; i
++) {
nextintsrow
= INTSROW
+ 2;
strcpy(buf
, ctime(&now
));
#define MAXDRIVES 6 /* max # to display */
mvprintw(STATROW
, STATCOL
+ 4, "users Load");
mvprintw(MEMROW
, MEMCOL
, "Mem REAL VIRTUAL");
mvprintw(MEMROW
+ 1, MEMCOL
, " Tot Text Tot Text");
mvprintw(MEMROW
+ 2, MEMCOL
, "Act");
mvprintw(MEMROW
+ 3, MEMCOL
, "All");
mvprintw(MEMROW
+ 1, MEMCOL
+ 28, "Free");
mvprintw(PAGEROW
, PAGECOL
, " PAGING SWAPING ");
mvprintw(PAGEROW
+ 1, PAGECOL
, " in out in out ");
mvprintw(PAGEROW
+ 2, PAGECOL
, "count");
mvprintw(PAGEROW
+ 3, PAGECOL
, "pages");
mvprintw(INTSROW
, INTSCOL
, " Interrupts");
mvprintw(INTSROW
+ 1, INTSCOL
+ 9, "total");
mvprintw(GENSTATROW
, GENSTATCOL
+ 8, "Csw");
mvprintw(GENSTATROW
+ 1, GENSTATCOL
+ 8, "Trp");
mvprintw(GENSTATROW
+ 2, GENSTATCOL
+ 8, "Sys");
mvprintw(GENSTATROW
+ 3, GENSTATCOL
+ 8, "Int");
mvprintw(GENSTATROW
+ 4, GENSTATCOL
+ 8, "Pdm");
mvprintw(GENSTATROW
+ 5, GENSTATCOL
+ 8, "Flt");
mvprintw(GENSTATROW
+ 6, GENSTATCOL
+ 8, "Scn");
mvprintw(GENSTATROW
+ 7, GENSTATCOL
+ 8, "Rev");
mvprintw(PAGEROW
+ 5, PAGECOL
, "Rec It F/S F/F RFL Fre SFr");
mvprintw(PAGEROW
+ 8, PAGECOL
+ 9, " zf");
mvprintw(PAGEROW
+ 9, PAGECOL
+ 9, "nzf");
mvprintw(PAGEROW
+ 10, PAGECOL
+ 9, "%%zf");
mvprintw(PAGEROW
+ 8, PAGECOL
+ 23, " xf");
mvprintw(PAGEROW
+ 9, PAGECOL
+ 23, "nxf");
mvprintw(PAGEROW
+ 10, PAGECOL
+ 23, "%%xf");
mvprintw(GRAPHROW
, GRAPHCOL
,
" . %% Sys . %% User . %% Nice . %% Idle");
mvprintw(PROCSROW
, PROCSCOL
, "Procs r p d s w");
mvprintw(GRAPHROW
+ 1, GRAPHCOL
,
"| | | | | | | | | | |");
mvprintw(NAMEIROW
, NAMEICOL
, "Namei Sys-cache Proc-cache");
mvprintw(NAMEIROW
+ 1, NAMEICOL
,
" Calls hits %% hits %%");
mvprintw(DISKROW
, DISKCOL
, "Discs");
mvprintw(DISKROW
+ 1, DISKCOL
, "seeks");
mvprintw(DISKROW
+ 2, DISKCOL
, "xfers");
mvprintw(DISKROW
+ 3, DISKCOL
, " blks");
mvprintw(DISKROW
+ 4, DISKCOL
, " msps");
for (i
= 0; i
< dk_ndrive
&& j
< MAXDRIVES
; i
++)
mvprintw(DISKROW
, DISKCOL
+ 5 + 5 * j
,
for (i
= 0; i
< nintr
; i
++) {
mvprintw(intrloc
[i
], INTSCOL
+ 9, "%-8.8s", intrname
[i
]);
#define X(fld) {t=s.fld[i]; s.fld[i]-=s1.fld[i]; if(state==TIME) s1.fld[i]=t;}
#define Y(fld) {t = s.fld; s.fld -= s1.fld; if(state == TIME) s1.fld = t;}
#define Z(fld) {t = s.nchstats.fld; s.nchstats.fld -= s1.nchstats.fld; \
if(state == TIME) s1.nchstats.fld = t;}
static char cpuchar
[CPUSTATES
] = { '=' , '>', '-', ' ' };
static char cpuorder
[CPUSTATES
] = { CP_SYS
, CP_USER
, CP_NICE
, CP_IDLE
};
for (i
= 0; i
< dk_ndrive
; i
++) {
X(dk_xfer
); X(dk_seek
); X(dk_wds
); X(dk_time
);
for(i
= 0; i
< CPUSTATES
; i
++) {
if (etime
< 5.0) { /* < 5 ticks - ignore this trash */
if (failcnt
++ >= MAXFAIL
) {
mvprintw(2, 10, "The alternate system clock has died!");
mvprintw(3, 10, "Reverting to ``pigs'' display.");
for (i
= 0; i
< nintr
; i
++) {
if (nextintsrow
== LINES
)
intrloc
[i
] = nextintsrow
++;
mvprintw(intrloc
[i
], INTSCOL
+ 9, "%-8.8s",
l
= (int)((float)s
.intrcnt
[i
]/etime
+ 0.5);
putint(l
, intrloc
[i
], INTSCOL
, 8);
putint(inttotal
, INTSROW
+ 1, INTSCOL
, 8);
Z(ncs_goodhits
); Z(ncs_badhits
); Z(ncs_miss
);
Z(ncs_long
); Z(ncs_pass2
); Z(ncs_2passes
);
s
.nchcount
= nchtotal
.ncs_goodhits
+ nchtotal
.ncs_badhits
+
nchtotal
.ncs_miss
+ nchtotal
.ncs_long
;
s1
.nchcount
= s
.nchcount
;
for (c
= 0; c
< CPUSTATES
; c
++) {
l
= (int) ((f2
+ 1.0) / 2.0) - psiz
;
putfloat(f1
, GRAPHROW
, GRAPHCOL
+ 1, 5, 1, 0);
putfloat(f1
, GRAPHROW
, GRAPHCOL
+ 12 * c
,
move(GRAPHROW
+ 2, psiz
);
putint(ucount(), STATROW
, STATCOL
, 3);
putfloat(avenrun
[0], STATROW
, STATCOL
+ 17, 6, 2, 0);
putfloat(avenrun
[1], STATROW
, STATCOL
+ 23, 6, 2, 0);
putfloat(avenrun
[2], STATROW
, STATCOL
+ 29, 6, 2, 0);
mvaddstr(STATROW
, STATCOL
+ 53, buf
);
putint(total
.t_arm
/2, MEMROW
+ 2, MEMCOL
+ 4, 5);
putint(total
.t_armtxt
/2, MEMROW
+ 2, MEMCOL
+ 9, 5);
putint(total
.t_avm
/2, MEMROW
+ 2, MEMCOL
+ 14, 6);
putint(total
.t_avmtxt
/2, MEMROW
+ 2, MEMCOL
+ 20, 5);
putint(total
.t_rm
/2, MEMROW
+ 3, MEMCOL
+ 4, 5);
putint(total
.t_rmtxt
/2, MEMROW
+ 3, MEMCOL
+ 9, 5);
putint(total
.t_vm
/2, MEMROW
+ 3, MEMCOL
+ 14, 6);
putint(total
.t_vmtxt
/2, MEMROW
+ 3, MEMCOL
+ 20, 5);
putint(total
.t_free
/2, MEMROW
+ 2, MEMCOL
+ 27, 5);
putint(total
.t_rq
, PROCSROW
+ 1, PROCSCOL
+ 5, 3);
putint(total
.t_pw
, PROCSROW
+ 1, PROCSCOL
+ 8, 3);
putint(total
.t_dw
, PROCSROW
+ 1, PROCSCOL
+ 11, 3);
putint(total
.t_sl
, PROCSROW
+ 1, PROCSCOL
+ 14, 3);
putint(total
.t_sw
, PROCSROW
+ 1, PROCSCOL
+ 17, 3);
putrate(rate
.v_swtch
, oldrate
.v_swtch
,
GENSTATROW
, GENSTATCOL
, 7);
putrate(rate
.v_trap
, oldrate
.v_trap
,
GENSTATROW
+ 1, GENSTATCOL
, 7);
putrate(rate
.v_syscall
, oldrate
.v_syscall
,
GENSTATROW
+ 2, GENSTATCOL
, 7);
putrate(rate
.v_intr
, oldrate
.v_intr
,
GENSTATROW
+ 3, GENSTATCOL
, 7);
putrate(rate
.v_pdma
, oldrate
.v_pdma
,
GENSTATROW
+ 4, GENSTATCOL
, 7);
putrate(rate
.v_faults
, oldrate
.v_faults
,
GENSTATROW
+ 5, GENSTATCOL
, 7);
putrate(rate
.v_scan
, oldrate
.v_scan
,
GENSTATROW
+ 6, GENSTATCOL
, 7);
putrate(rate
.v_rev
, oldrate
.v_rev
,
GENSTATROW
+ 7, GENSTATCOL
, 7);
putrate(rate
.v_pgin
, oldrate
.v_pgin
, PAGEROW
+ 2,
putrate(rate
.v_pgout
, oldrate
.v_pgout
, PAGEROW
+ 2,
putrate(rate
.v_swpin
, oldrate
.v_swpin
, PAGEROW
+ 2,
putrate(rate
.v_swpout
, oldrate
.v_swpout
, PAGEROW
+ 2,
putrate(rate
.v_pgpgin
, oldrate
.v_pgpgin
, PAGEROW
+ 3,
putrate(rate
.v_pgpgout
, oldrate
.v_pgpgout
, PAGEROW
+ 3,
putrate(rate
.v_pswpin
, oldrate
.v_pswpin
, PAGEROW
+ 3,
putrate(rate
.v_pswpout
, oldrate
.v_pswpout
, PAGEROW
+ 3,
putrate(rate
.v_pgrec
, oldrate
.v_pgrec
, PAGEROW
+ 6, PAGECOL
, 3);
putrate(rate
.v_intrans
, oldrate
.v_intrans
, PAGEROW
+ 6,
putrate(rate
.v_xsfrec
, oldrate
.v_xsfrec
, PAGEROW
+ 6,
putrate(rate
.v_xifrec
, oldrate
.v_xifrec
, PAGEROW
+ 6,
putrate(rate
.v_pgfrec
, oldrate
.v_pgfrec
, PAGEROW
+ 6,
putrate(rate
.v_dfree
, oldrate
.v_dfree
, PAGEROW
+ 6,
putrate(rate
.v_seqfree
, oldrate
.v_seqfree
, PAGEROW
+ 6,
putrate(rate
.v_zfod
, oldrate
.v_zfod
, PAGEROW
+ 8, PAGECOL
, 8);
putrate(rate
.v_nzfod
, oldrate
.v_nzfod
, PAGEROW
+ 9, PAGECOL
, 8);
putrate(rate
.v_exfod
, oldrate
.v_exfod
, PAGEROW
+ 8,
putrate(rate
.v_nexfod
, oldrate
.v_nexfod
, PAGEROW
+ 9,
( 100.0 * rate
.v_zfod
/ rate
.v_nzfod
)
: rate
.v_nzfod
== oldrate
.v_nzfod
?
( 100.0 * (rate
.v_zfod
-oldrate
.v_zfod
)
/ (rate
.v_nzfod
-oldrate
.v_nzfod
) )
( 100.0 * rate
.v_exfod
/ rate
.v_nexfod
)
: rate
.v_nexfod
== oldrate
.v_nexfod
?
( 100.0 * (rate
.v_exfod
-oldrate
.v_exfod
)
/ (rate
.v_nexfod
-oldrate
.v_nexfod
) )
for (i
= 0; i
< dk_ndrive
&& c
< MAXDRIVES
; i
++)
putint(s
.nchcount
, NAMEIROW
+ 2, NAMEICOL
, 9);
putint(nchtotal
.ncs_goodhits
, NAMEIROW
+ 2, NAMEICOL
+ 9, 9);
#define nz(x) ((x) ? (x) : 1)
putfloat(nchtotal
.ncs_goodhits
* 100.0 / nz(s
.nchcount
),
NAMEIROW
+ 2, NAMEICOL
+ 19, 4, 0, 1);
putint(nchtotal
.ncs_pass2
, NAMEIROW
+ 2, NAMEICOL
+ 23, 9);
putfloat(nchtotal
.ncs_pass2
* 100.0 / nz(s
.nchcount
),
NAMEIROW
+ 2, NAMEICOL
+ 34, 4, 0, 1);
if (prefix(cmd
, "run")) {
if (prefix(cmd
, "boot")) {
if (prefix(cmd
, "time")) {
if (prefix(cmd
, "zero")) {
return (dkcmd(cmd
, args
));
/* calculate number of users on the system */
while (read(ut
, &utmp
, sizeof(utmp
)))
if (utmp
.ut_name
[0] != '\0')
for (i
= 0; i
< CPUSTATES
; i
++)
return (s
.time
[indx
] * 100.0 / t
);
putint((int)((float)r
/etime
+ 0.5), l
, c
, w
);
putfloat(f
, l
, c
, w
, d
, nz
)
sprintf(b
, "%*.*f", w
, d
, f
);
lseek(kmem
, (long)name
[X_CPTIME
].n_value
,L_SET
);
read(kmem
, s
->time
, sizeof s
->time
);
lseek(kmem
, (long)name
[X_SUM
].n_value
, L_SET
);
read(kmem
, &s
->Rate
, sizeof s
->Rate
);
lseek(kmem
, (long)name
[X_RATE
].n_value
,L_SET
);
read(kmem
, &s
->Rate
, sizeof s
->Rate
);
lseek(kmem
, (long)name
[X_TOTAL
].n_value
, L_SET
);
read(kmem
, &s
->Total
, sizeof s
->Total
);
s
->dk_busy
= getw(name
[X_DK_BUSY
].n_value
);
lseek(kmem
, (long)name
[X_DK_TIME
].n_value
, L_SET
);
read(kmem
, s
->dk_time
, dk_ndrive
* sizeof (long));
lseek(kmem
, (long)name
[X_DK_XFER
].n_value
, L_SET
);
read(kmem
, s
->dk_xfer
, dk_ndrive
* sizeof (long));
lseek(kmem
, (long)name
[X_DK_WDS
].n_value
, L_SET
);
read(kmem
, s
->dk_wds
, dk_ndrive
* sizeof (long));
lseek(kmem
, (long)name
[X_DK_SEEK
].n_value
, L_SET
);
read(kmem
, s
->dk_seek
, dk_ndrive
* sizeof (long));
s
->tk_nin
= getw(name
[X_TK_NIN
].n_value
);
s
->tk_nout
= getw(name
[X_TK_NOUT
].n_value
);
lseek(kmem
, (long)name
[X_NCHSTATS
].n_value
, L_SET
);
read(kmem
, &s
->nchstats
, sizeof s
->nchstats
);
lseek(kmem
, (long)name
[X_INTRCNT
].n_value
, L_SET
);
read(kmem
, s
->intrcnt
, nintr
* sizeof (long));
s
->intrcnt
= (long *) malloc(nintr
* sizeof(long));
if (s
->intrcnt
== NULL
) {
fprintf(stderr
, "systat: out of memory\n");
register struct Info
*from
, *to
;
long *time
, *wds
, *seek
, *xfer
;
time
= to
->dk_time
; wds
= to
->dk_wds
; seek
= to
->dk_seek
;
xfer
= to
->dk_xfer
; intrcnt
= to
->intrcnt
;
bcopy(from
->dk_time
, to
->dk_time
= time
, dk_ndrive
* sizeof (long));
bcopy(from
->dk_wds
, to
->dk_wds
= wds
, dk_ndrive
* sizeof (long));
bcopy(from
->dk_seek
, to
->dk_seek
= seek
, dk_ndrive
* sizeof (long));
bcopy(from
->dk_xfer
, to
->dk_xfer
= xfer
, dk_ndrive
* sizeof (long));
bcopy(from
->intrcnt
, to
->intrcnt
= intrcnt
, nintr
* sizeof (int));
double words
, atime
, itime
, xtime
;
words
= s
.dk_wds
[dn
]*32.0; /* number of words transferred */
xtime
= dk_mspw
[dn
]*words
; /* transfer time */
itime
= atime
- xtime
; /* time not transferring */
itime
+= xtime
, xtime
= 0;
xtime
+= itime
, itime
= 0;
putint((int)((float)s
.dk_seek
[dn
]/etime
+0.5), DISKROW
+ 1, c
, 5);
putint((int)((float)s
.dk_xfer
[dn
]/etime
+0.5), DISKROW
+ 2, c
, 5);
putint((int)(words
/etime
/512.0 + 0.5), DISKROW
+ 3, c
, 5);
putfloat(itime
*1000.0/s
.dk_seek
[dn
], DISKROW
+ 4, c
, 5, 1, 1);
putint(0, DISKROW
+ 4, c
, 5);