xref: /original-bsd/usr.sbin/pstat/pstat.c (revision 7a4e9f34)
1 static char *sccsid = "@(#) (Berkeley) 82/05/10";
2 /*
3  * Print system stuff
4  */
5 
6 #define mask(x) (x&0377)
7 #define	clear(x) ((int)x&0x7fffffff)
8 
9 #include <sys/param.h>
10 #include <sys/dir.h>
11 #include <sys/file.h>
12 #include <sys/user.h>
13 #include <sys/proc.h>
14 #include <sys/text.h>
15 #include <sys/inode.h>
16 #include <sys/map.h>
17 #include <sys/tty.h>
18 #include <sys/conf.h>
19 #include <sys/vm.h>
20 #include <nlist.h>
21 #include <sys/pte.h>
22 #define	KERNEL
23 #undef	KERNEL
24 
25 char	*fcore	= "/dev/kmem";
26 char	*fnlist	= "/vmunix";
27 int	fc;
28 
29 struct nlist nl[] = {
30 #define	SINODE	0
31 	{ "_inode" },
32 #define	STEXT	1
33 	{ "_text" },
34 #define	SPROC	2
35 	{ "_proc" },
36 #define	SDZ	3
37 	{ "_dz_tty" },
38 #define	SNDZ	4
39 	{ "_dz_cnt" },
40 #define	SKL	5
41 	{ "_cons" },
42 #define	SFIL	6
43 	{ "_file" },
44 #define	USRPTMA	7
45 	{ "_Usrptmap" },
46 #define	USRPT	8
47 	{ "_usrpt" },
48 #define	SNSWAP	9
49 	{ "_nswap" },
50 #define	SWAPMAP	10
51 	{ "_swapmap" },
52 #define	SDH	11
53 	{ "_dh11" },
54 #define	SNDH	12
55 	{ "_ndh11" },
56 #define	SNPROC	13
57 	{ "_nproc" },
58 #define	SNTEXT	14
59 	{ "_ntext" },
60 #define	SNFILE	15
61 	{ "_nfile" },
62 #define	SNINODE	16
63 	{ "_ninode" },
64 #define	SNSWAPMAP 17
65 	{ "_nswapmap" },
66 #define	SPTY	18
67 	{ "_pt_tty" },
68 	0,
69 };
70 
71 int	inof;
72 int	txtf;
73 int	prcf;
74 int	ttyf;
75 int	usrf;
76 int	mpxf;
77 int	groupf;
78 long	ubase;
79 int	filf;
80 int	swpf;
81 int	totflg;
82 char	partab[1];
83 struct	cdevsw	cdevsw[1];
84 struct	bdevsw	bdevsw[1];
85 int	allflg;
86 int	kflg;
87 struct	pte *Usrptma;
88 struct	pte *usrpt;
89 
90 main(argc, argv)
91 char **argv;
92 {
93 	register char *argp;
94 
95 	argc--, argv++;
96 	while (argc > 0 && **argv == '-') {
97 		argp = *argv++;
98 		argp++;
99 		argc--;
100 		while (*argp++)
101 		switch (argp[-1]) {
102 
103 		case 'T':
104 			totflg++;
105 			break;
106 
107 		case 'a':
108 			allflg++;
109 			break;
110 
111 		case 'i':
112 			inof++;
113 			break;
114 
115 		case 'k':
116 			kflg++;
117 			fcore = "/vmcore";
118 			break;
119 
120 		case 'x':
121 			txtf++;
122 			break;
123 
124 		case 'p':
125 			prcf++;
126 			break;
127 
128 		case 't':
129 			ttyf++;
130 			break;
131 
132 		case 'u':
133 			if (argc == 0)
134 				break;
135 			argc--;
136 			usrf++;
137 			sscanf( *argv++, "%x", &ubase);
138 			break;
139 
140 		case 'f':
141 			filf++;
142 			break;
143 		case 's':
144 			swpf++;
145 			break;
146 		case 'm':
147 			mpxf++;
148 			break;
149 		case 'g':
150 			groupf++;
151 			break;
152 		}
153 	}
154 	if (argc>0)
155 		fcore = argv[0];
156 	if ((fc = open(fcore, 0)) < 0) {
157 		printf("Can't find %s\n", fcore);
158 		exit(1);
159 	}
160 	if (argc>1)
161 		fnlist = argv[1];
162 	nlist(fnlist, nl);
163 	usrpt = (struct pte *)nl[USRPT].n_value;
164 	Usrptma = (struct pte *)nl[USRPTMA].n_value;
165 	if (nl[0].n_type == 0) {
166 		printf("no namelist\n");
167 		exit(1);
168 	}
169 	if (filf||totflg)
170 		dofile();
171 	if (inof||totflg)
172 		doinode();
173 	if (prcf||totflg)
174 		doproc();
175 	if (txtf||totflg)
176 		dotext();
177 	if (ttyf)
178 		dotty();
179 	if (usrf)
180 		dousr();
181 	if (swpf||totflg)
182 		doswap();
183 }
184 
185 doinode()
186 {
187 	register struct inode *ip;
188 	struct inode *xinode, *ainode;
189 	register int nin;
190 	int ninode;
191 
192 	nin = 0;
193 	ninode = getw(nl[SNINODE].n_value);
194 	xinode = (struct inode *)calloc(ninode, sizeof (struct inode));
195 	lseek(fc, (int)(ainode = (struct inode *)getw(nl[SINODE].n_value)), 0);
196 	read(fc, xinode, ninode * sizeof(struct inode));
197 	for (ip = xinode; ip < &xinode[ninode]; ip++)
198 		if (ip->i_count)
199 			nin++;
200 	if (totflg) {
201 		printf("%3d/%3d inodes\n", nin, ninode);
202 		return;
203 	}
204 	printf("%d/%d active inodes\n", nin, ninode);
205 	printf("   LOC    FLAGS  CNT DEVICE   INO  MODE  NLK UID   SIZE/DEV\n");
206 	for (ip = xinode; ip < &xinode[ninode]; ip++) {
207 		if (ip->i_count == 0)
208 			continue;
209 		printf("%8.1x ", ainode + (ip - xinode));
210 		putf(ip->i_flag&ILOCK, 'L');
211 		putf(ip->i_flag&IUPD, 'U');
212 		putf(ip->i_flag&IACC, 'A');
213 		putf(ip->i_flag&IMOUNT, 'M');
214 		putf(ip->i_flag&IWANT, 'W');
215 		putf(ip->i_flag&ITEXT, 'T');
216 		printf("%4d", ip->i_count&0377);
217 		printf("%4d,%3d", major(ip->i_dev), minor(ip->i_dev));
218 		printf("%6d", ip->i_number);
219 		printf("%6x", ip->i_mode & 0xffff);
220 		printf("%4d", ip->i_nlink);
221 		printf("%4d", ip->i_uid);
222 		if ((ip->i_mode&IFMT)==IFBLK || (ip->i_mode&IFMT)==IFCHR)
223 			printf("%6d,%3d", major(ip->i_rdev), minor(ip->i_rdev));
224 		else
225 			printf("%10ld", ip->i_size);
226 		printf("\n");
227 	}
228 	free(xinode);
229 }
230 
231 getw(loc)
232 	off_t loc;
233 {
234 	int word;
235 
236 	if (kflg)
237 		loc &= 0x7fffffff;
238 	lseek(fc, loc, 0);
239 	read(fc, &word, sizeof (word));
240 	if (kflg)
241 		word &= 0x7fffffff;
242 	return (word);
243 }
244 
245 putf(v, n)
246 {
247 	if (v)
248 		printf("%c", n);
249 	else
250 		printf(" ");
251 }
252 
253 dotext()
254 {
255 	register struct text *xp;
256 	int ntext;
257 	struct text *xtext, *atext;
258 	int ntx;
259 
260 	ntx = 0;
261 	ntext = getw(nl[SNTEXT].n_value);
262 	xtext = (struct text *)calloc(ntext, sizeof (struct text));
263 	lseek(fc, (int)(atext = (struct text *)getw(nl[STEXT].n_value)), 0);
264 	read(fc, xtext, ntext * sizeof (struct text));
265 	for (xp = xtext; xp < &xtext[ntext]; xp++)
266 		if (xp->x_iptr!=NULL)
267 			ntx++;
268 	if (totflg) {
269 		printf("%3d/%3d texts\n", ntx, ntext);
270 		return;
271 	}
272 	printf("%d/%d active texts\n", ntx, ntext);
273 	printf("   LOC   FLAGS DADDR      CADDR  RSS SIZE      IPTR  CNT CCNT\n");
274 	for (xp = xtext; xp < &xtext[ntext]; xp++) {
275 		if (xp->x_iptr == NULL)
276 			continue;
277 		printf("%8.1x", atext + (xp - xtext));
278 		printf(" ");
279 		putf(xp->x_flag&XPAGI, 'P');
280 		putf(xp->x_flag&XTRC, 'T');
281 		putf(xp->x_flag&XWRIT, 'W');
282 		putf(xp->x_flag&XLOAD, 'L');
283 		putf(xp->x_flag&XLOCK, 'K');
284 		putf(xp->x_flag&XWANT, 'w');
285 		printf("%5x", xp->x_daddr[0]);
286 		printf("%11x", xp->x_caddr);
287 		printf("%5d", xp->x_rssize);
288 		printf("%5d", xp->x_size);
289 		printf("%10.1x", xp->x_iptr);
290 		printf("%5d", xp->x_count&0377);
291 		printf("%5d", xp->x_ccount);
292 		printf("\n");
293 	}
294 	free(xtext);
295 }
296 
297 doproc()
298 {
299 	struct proc *xproc, *aproc;
300 	int nproc;
301 	register struct proc *pp;
302 	register loc, np;
303 	struct pte apte;
304 
305 	nproc = getw(nl[SNPROC].n_value);
306 	xproc = (struct proc *)calloc(nproc, sizeof (struct proc));
307 	lseek(fc, (int)(aproc = (struct proc *)getw(nl[SPROC].n_value)), 0);
308 	read(fc, xproc, nproc * sizeof (struct proc));
309 	np = 0;
310 	for (pp=xproc; pp < &xproc[nproc]; pp++)
311 		if (pp->p_stat)
312 			np++;
313 	if (totflg) {
314 		printf("%3d/%3d processes\n", np, nproc);
315 		return;
316 	}
317 	printf("%d/%d processes\n", np, nproc);
318 	printf("   LOC    S    F POIP PRI      SIG  UID SLP TIM  CPU  NI   PGRP    PID   PPID    ADDR   RSS SRSS SIZE    WCHAN    LINK   TEXTP CLKT\n");
319 	for (pp=xproc; pp<&xproc[nproc]; pp++) {
320 		if (pp->p_stat==0 && allflg==0)
321 			continue;
322 		printf("%8x", aproc + (pp - xproc));
323 		printf(" %2d", pp->p_stat);
324 		printf(" %4x", pp->p_flag & 0xffff);
325 		printf(" %4d", pp->p_poip);
326 		printf(" %3d", pp->p_pri);
327 		printf(" %8x", pp->p_sig);
328 		printf(" %4d", pp->p_uid);
329 		printf(" %3d", pp->p_slptime);
330 		printf(" %3d", pp->p_time);
331 		printf(" %4d", pp->p_cpu&0377);
332 		printf(" %3d", pp->p_nice);
333 		printf(" %6d", pp->p_pgrp);
334 		printf(" %6d", pp->p_pid);
335 		printf(" %6d", pp->p_ppid);
336 		if (kflg)
337 			pp->p_addr = (struct pte *)clear((int)pp->p_addr);
338 		lseek(fc, (long)(Usrptma+btokmx(pp->p_addr)), 0);
339 		read(fc, &apte, sizeof(apte));
340 		printf(" %8x", ctob(apte.pg_pfnum+1) - sizeof(struct pte) * UPAGES);
341 		printf(" %4x", pp->p_rssize);
342 		printf(" %4x", pp->p_swrss);
343 		printf(" %5x", pp->p_dsize+pp->p_ssize);
344 		printf(" %7x", clear(pp->p_wchan));
345 		printf(" %7x", clear(pp->p_link));
346 		printf(" %7x", clear(pp->p_textp));
347 		printf("    %u", pp->p_clktim);
348 		printf("\n");
349 	}
350 }
351 
352 dotty()
353 {
354 	struct tty dz_tty[128];
355 	int ndz;
356 	register struct tty *tp;
357 	register char *mesg;
358 
359 	printf("1 cons\n");
360 	if (kflg)
361 		nl[SKL].n_value = clear(nl[SKL].n_value);
362 	lseek(fc, (long)nl[SKL].n_value, 0);
363 	read(fc, dz_tty, sizeof(dz_tty[0]));
364 	mesg = " # RAW CAN OUT   MODE    ADDR   DEL COL  STATE   PGRP DISC\n";
365 	printf(mesg);
366 	ttyprt(&dz_tty[0], 0);
367 	if (nl[SNDZ].n_type == 0)
368 		goto dh;
369 	if (kflg) {
370 		nl[SNDZ].n_value = clear(nl[SNDZ].n_value);
371 		nl[SDZ].n_value = clear(nl[SDZ].n_value);
372 	}
373 	lseek(fc, (long)nl[SNDZ].n_value, 0);
374 	read(fc, &ndz, sizeof(ndz));
375 	printf("%d dz lines\n", ndz);
376 	lseek(fc, (long)nl[SDZ].n_value, 0);
377 	read(fc, dz_tty, ndz * sizeof (struct tty));
378 	for (tp = dz_tty; tp < &dz_tty[ndz]; tp++)
379 		ttyprt(tp, tp - dz_tty);
380 dh:
381 	if (nl[SNDH].n_type == 0)
382 		goto pty;
383 	if (kflg) {
384 		nl[SNDH].n_value = clear(nl[SNDH].n_value);
385 		nl[SDH].n_value = clear(nl[SDH].n_value);
386 	}
387 	lseek(fc, (long)nl[SNDH].n_value, 0);
388 	read(fc, &ndz, sizeof(ndz));
389 	printf("%d dh lines\n", ndz);
390 	lseek(fc, (long)nl[SDH].n_value, 0);
391 	read(fc, dz_tty, ndz * sizeof(struct tty));
392 	for (tp = dz_tty; tp < &dz_tty[ndz]; tp++)
393 		ttyprt(tp, tp - dz_tty);
394 pty:
395 	if (nl[SPTY].n_type == 0)
396 		goto pty;
397 	if (kflg) {
398 		nl[SPTY].n_value = clear(nl[SPTY].n_value);
399 	}
400 	printf("32 pty lines\n");
401 	lseek(fc, (long)nl[SPTY].n_value, 0);
402 	read(fc, dz_tty, 32*sizeof(struct tty));
403 	for (tp = dz_tty; tp < &dz_tty[32]; tp++)
404 		ttyprt(tp, tp - dz_tty);
405 }
406 
407 ttyprt(atp, line)
408 struct tty *atp;
409 {
410 	register struct tty *tp;
411 
412 	printf("%2d", line);
413 	tp = atp;
414 	switch (tp->t_line) {
415 
416 /*
417 	case NETLDISC:
418 		if (tp->t_rec)
419 			printf("%4d%4d", 0, tp->t_inbuf);
420 		else
421 			printf("%4d%4d", tp->t_inbuf, 0);
422 		break;
423 */
424 
425 	default:
426 		printf("%4d", tp->t_rawq.c_cc);
427 		printf("%4d", tp->t_canq.c_cc);
428 	}
429 	printf("%4d", tp->t_outq.c_cc);
430 	printf("%8.1o", tp->t_flags);
431 	printf(" %8.1x", tp->t_addr);
432 	printf("%3d", tp->t_delct);
433 	printf("%4d ", tp->t_col);
434 	putf(tp->t_state&TS_TIMEOUT, 'T');
435 	putf(tp->t_state&TS_WOPEN, 'W');
436 	putf(tp->t_state&TS_ISOPEN, 'O');
437 	putf(tp->t_state&TS_CARR_ON, 'C');
438 	putf(tp->t_state&TS_BUSY, 'B');
439 	putf(tp->t_state&TS_ASLEEP, 'A');
440 	putf(tp->t_state&TS_XCLUDE, 'X');
441 /*
442 	putf(tp->t_state&TS_HUPCLS, 'H');
443  */
444 	printf("%6d", tp->t_pgrp);
445 	switch (tp->t_line) {
446 
447 	case NTTYDISC:
448 		printf(" ntty");
449 		break;
450 
451 	case NETLDISC:
452 		printf(" net");
453 		break;
454 	}
455 	printf("\n");
456 }
457 
458 dousr()
459 {
460 	struct user U;
461 	register i, j, *ip;
462 
463 	/* This wins only if PAGSIZ > sizeof (struct user) */
464 	lseek(fc, ubase * NBPG, 0);
465 	read(fc, &U, sizeof(U));
466 	printf("pcb");
467 	ip = (int *)&U.u_pcb;
468 	while (ip < &U.u_arg[0]) {
469 		if ((ip - (int *)&U.u_pcb) % 4 == 0)
470 			printf("\t");
471 		printf("%x ", *ip++);
472 		if ((ip - (int *)&U.u_pcb) % 4 == 0)
473 			printf("\n");
474 	}
475 	if ((ip - (int *)&U.u_pcb) % 4 != 0)
476 		printf("\n");
477 	printf("arg\t");
478 	for (i=0; i<5; i++)
479 		printf(" %.1x", U.u_arg[i]);
480 	printf("\n");
481 	for (i=0; i<sizeof(label_t)/sizeof(int); i++) {
482 		if (i%5==0)
483 			printf("\t");
484 		printf("%9.1x", U.u_ssav[i]);
485 		if (i%5==4)
486 			printf("\n");
487 	}
488 	if (i%5)
489 		printf("\n");
490 	printf("segflg\t%d\nerror %d\n", U.u_segflg, U.u_error);
491 	printf("uids\t%d,%d,%d,%d\n", U.u_uid,U.u_gid,U.u_ruid,U.u_rgid);
492 	printf("procp\t%.1x\n", U.u_procp);
493 	printf("ap\t%.1x\n", U.u_ap);
494 	printf("r_val?\t%.1x %.1x\n", U.u_r.r_val1, U.u_r.r_val2);
495 	printf("base, count, offset %.1x %.1x %ld\n", U.u_base,
496 		U.u_count, U.u_offset);
497 	printf("cdir rdir %.1x %.1x\n", U.u_cdir, U.u_rdir);
498 	printf("dirp %.1x\n", U.u_dirp);
499 	printf("dent %d %.14s\n", U.u_dent.d_ino, U.u_dent.d_name);
500 	printf("pdir %.1o\n", U.u_pdir);
501 	printf("file\t");
502 	for (i=0; i<10; i++)
503 		printf("%9.1x", U.u_ofile[i]);
504 	printf("\n\t");
505 	for (i=10; i<NOFILE; i++)
506 		printf("%9.1x", U.u_ofile[i]);
507 	printf("\n");
508 	printf("pofile\t");
509 	for (i=0; i<10; i++)
510 		printf("%9.1x", U.u_pofile[i]);
511 	printf("\n\t");
512 	for (i=10; i<NOFILE; i++)
513 		printf("%9.1x", U.u_pofile[i]);
514 	printf("\n");
515 	printf("ssav");
516 	for (i=0; i<sizeof(label_t)/sizeof(int); i++) {
517 		if (i%5==0)
518 			printf("\t");
519 		printf("%9.1x", U.u_ssav[i]);
520 		if (i%5==4)
521 			printf("\n");
522 	}
523 	if (i%5)
524 		printf("\n");
525 	printf("sigs\t");
526 	for (i=0; i<NSIG; i++)
527 		printf("%.1x ", U.u_signal[i]);
528 	printf("\n");
529 	printf("code\t%.1x\n", U.u_code);
530 	printf("ar0\t%.1x\n", U.u_ar0);
531 	printf("prof\t%X %X %X %X\n", U.u_prof.pr_base, U.u_prof.pr_size,
532 	    U.u_prof.pr_off, U.u_prof.pr_scale);
533 	printf("\neosys\t%d\n", U.u_eosys);
534 	printf("sep\t%d\n", U.u_sep);
535 	printf("ttyp\t%.1x\n", U.u_ttyp);
536 	printf("ttyd\t%d,%d\n", major(U.u_ttyd), minor(U.u_ttyd));
537 	printf("exdata\t");
538 	ip = (int *)&U.u_exdata;
539 	for (i = 0; i < 8; i++)
540 		printf("%.1D ", *ip++);
541 	printf("\n");
542 	printf("comm %.14s\n", U.u_comm);
543 	printf("start\t%D\n", U.u_start);
544 	printf("acflag\t%D\n", U.u_acflag);
545 	printf("fpflag\t%D\n", U.u_fpflag);
546 	printf("cmask\t%D\n", U.u_cmask);
547 	printf("sizes\t%.1x %.1x %.1x\n", U.u_tsize, U.u_dsize, U.u_ssize);
548 	printf("vm\t");
549 	ip = (int *)&U.u_vm;
550 	for (i = 0; i < sizeof(U.u_vm)/sizeof(int); i++)
551 		printf("%D ", ip[i]);
552 	printf("\n");
553 	ip = (int *)&U.u_cvm;
554 	printf("cvm\t");
555 	for (i = 0; i < sizeof(U.u_vm)/sizeof(int); i++)
556 		printf("%D ", ip[i]);
557 	printf("\n");
558 /*
559 	i =  U.u_stack - &U;
560 	while (U[++i] == 0);
561 	i &= ~07;
562 	while (i < 512) {
563 		printf("%x ", 0140000+2*i);
564 		for (j=0; j<8; j++)
565 			printf("%9x", U[i++]);
566 		printf("\n");
567 	}
568 */
569 }
570 
571 oatoi(s)
572 char *s;
573 {
574 	register v;
575 
576 	v = 0;
577 	while (*s)
578 		v = (v<<3) + *s++ - '0';
579 	return(v);
580 }
581 
582 dofile()
583 {
584 	int nfile;
585 	struct file *xfile, *afile;
586 	register struct file *fp;
587 	register nf;
588 	int loc;
589 
590 	nf = 0;
591 	nfile = getw(nl[SNFILE].n_value);
592 	xfile = (struct file *)calloc(nfile, sizeof (struct file));
593 	lseek(fc, (int)(afile = (struct file *)getw(nl[SFIL].n_value)), 0);
594 	read(fc, xfile, nfile * sizeof (struct file));
595 	for (fp=xfile; fp < &xfile[nfile]; fp++)
596 		if (fp->f_count)
597 			nf++;
598 	if (totflg) {
599 		printf("%3d/%3d files\n", nf, nfile);
600 		return;
601 	}
602 	printf("%d/%d open files\n", nf, nfile);
603 	printf("   LOC   FLG  CNT   INO    OFFS|SOCK\n");
604 	for (fp=xfile,loc=nl[SFIL].n_value; fp < &xfile[nfile]; fp++,loc+=sizeof(xfile[0])) {
605 		if (fp->f_count==0)
606 			continue;
607 		printf("%8x ", loc);
608 		putf(fp->f_flag&FREAD, 'R');
609 		putf(fp->f_flag&FWRITE, 'W');
610 		putf(fp->f_flag&FSOCKET, 'S');
611 		printf("%4d", mask(fp->f_count));
612 		printf("%9.1x", fp->f_inode);
613 		if (fp->f_flag&FSOCKET)
614 			printf("  %x\n", fp->f_socket);
615 		else
616 			printf("  %ld\n", fp->f_offset);
617 	}
618 }
619 
620 doswap()
621 {
622 	struct proc *proc;
623 	int nproc;
624 	struct text *xtext;
625 	int ntext;
626 	struct map *swapmap;
627 	int nswapmap;
628 	register struct proc *pp;
629 	int nswap, used, tused, free;
630 	register struct mapent *me;
631 	register struct text *xp;
632 
633 	nproc = getw(nl[SNPROC].n_value);
634 	proc = (struct proc *)calloc(nproc, sizeof (struct proc));
635 	lseek(fc, getw(nl[SPROC].n_value), 0);
636 	read(fc, proc, nproc * sizeof (struct proc));
637 	nswapmap = getw(nl[SNSWAPMAP].n_value);
638 	swapmap = (struct map *)calloc(nswapmap, sizeof (struct map));
639 	lseek(fc, getw(nl[SWAPMAP].n_value), 0);
640 	read(fc, swapmap, nswapmap * sizeof (struct map));
641 	nswap = getw(nl[SNSWAP].n_value);
642 	free = 0;
643 	for (me = (struct mapent *)(swapmap+1);
644 	    me < (struct mapent *)&swapmap[nswapmap]; me++)
645 		free += me->m_size;
646 	ntext = getw(nl[SNTEXT].n_value);
647 	xtext = (struct text *)calloc(ntext, sizeof (struct text));
648 	lseek(fc, getw(nl[STEXT].n_value), 0);
649 	read(fc, xtext, ntext * sizeof (struct text));
650 	tused = 0;
651 	for (xp = xtext; xp < &xtext[ntext]; xp++)
652 		if (xp->x_iptr!=NULL)
653 			tused += xdsize(xp);
654 	used = tused;
655 	for (pp = proc; pp < &proc[nproc]; pp++) {
656 		if (pp->p_stat == 0 || pp->p_stat == SZOMB)
657 			continue;
658 		if (pp->p_flag & SSYS)
659 			continue;
660 		used += up(pp->p_dsize) + up(pp->p_ssize);
661 		if ((pp->p_flag&SLOAD) == 0)
662 			used += vusize(pp);
663 	}
664 	/* a DMMAX/2 block goes to argmap */
665 	if (totflg) {
666 		printf("%3d/%3d 00k swap\n", used/2/100, (used+free)/2/100);
667 		return;
668 	}
669 	printf("%d used (%d text), %d free, %d missing\n",
670 	    used/2, tused/2, free/2, (nswap - DMMAX/2 - (used + free))/2);
671 }
672 
673 up(size)
674 	register int size;
675 {
676 	register int i, block;
677 
678 	i = 0;
679 	block = DMMIN;
680 	while (i < size) {
681 		i += block;
682 		if (block < DMMAX)
683 			block *= 2;
684 	}
685 	return (i);
686 }
687 
688 vusize(p)
689 struct proc *p;
690 {
691 	register int tsz = p->p_tsize / NPTEPG;
692 
693 	return (clrnd(UPAGES + clrnd(ctopt(p->p_tsize+p->p_dsize+p->p_ssize+UPAGES)) - tsz));
694 }
695 
696 xdsize(xp)
697 struct text *xp;
698 {
699 
700 	if (xp->x_flag & XPAGI)
701 		return (clrnd(xp->x_size + ctopt(xp->x_size)));
702 	return (xp->x_size);
703 }
704 
705