|
|
1.1 root 1: #ifndef lint
2: static char *sccsid = "@(#)pstat.c 4.24 (Berkeley) 10/15/83";
3: #endif
4: /*
5: * Print system stuff
6: */
7:
8: #define mask(x) (x&0377)
9: #define clear(x) ((int)x&0x7fffffff)
10:
11: #include <sys/param.h>
12: #include <sys/dir.h>
13: #define KERNEL
14: #include <sys/file.h>
15: #undef KERNEL
16: #include <sys/user.h>
17: #include <sys/proc.h>
18: #include <sys/text.h>
19: #include <sys/inode.h>
20: #include <sys/map.h>
21: #include <sys/ioctl.h>
22: #include <sys/tty.h>
23: #include <sys/conf.h>
24: #include <sys/vm.h>
25: #include <nlist.h>
26: #include <machine/pte.h>
27:
28: char *fcore = "/dev/kmem";
29: char *fnlist = "/vmunix";
30: int fc;
31:
32: struct nlist nl[] = {
33: #define SINODE 0
34: { "_inode" },
35: #define STEXT 1
36: { "_text" },
37: #define SPROC 2
38: { "_proc" },
39: #define SDZ 3
40: { "_dz_tty" },
41: #define SNDZ 4
42: { "_dz_cnt" },
43: #define SKL 5
44: { "_cons" },
45: #define SFIL 6
46: { "_file" },
47: #define USRPTMA 7
48: { "_Usrptmap" },
49: #define USRPT 8
50: { "_usrpt" },
51: #define SWAPMAP 9
52: { "_swapmap" },
53: #define SDH 10
54: { "_dh11" },
55: #define SNDH 11
56: { "_ndh11" },
57: #define SNPROC 12
58: { "_nproc" },
59: #define SNTEXT 13
60: { "_ntext" },
61: #define SNFILE 14
62: { "_nfile" },
63: #define SNINODE 15
64: { "_ninode" },
65: #define SNSWAPMAP 16
66: { "_nswapmap" },
67: #define SPTY 17
68: { "_pt_tty" },
69: #define SDMMIN 18
70: { "_dmmin" },
71: #define SDMMAX 19
72: { "_dmmax" },
73: #define SNSWDEV 20
74: { "_nswdev" },
75: #define SSWDEVT 21
76: { "_swdevt" },
77: { "" }
78: };
79:
80: int inof;
81: int txtf;
82: int prcf;
83: int ttyf;
84: int usrf;
85: long ubase;
86: int filf;
87: int swpf;
88: int totflg;
89: char partab[1];
90: struct cdevsw cdevsw[1];
91: struct bdevsw bdevsw[1];
92: int allflg;
93: int kflg;
94: struct pte *Usrptma;
95: struct pte *usrpt;
96:
97: main(argc, argv)
98: char **argv;
99: {
100: register char *argp;
101: int allflags;
102:
103: argc--, argv++;
104: while (argc > 0 && **argv == '-') {
105: argp = *argv++;
106: argp++;
107: argc--;
108: while (*argp++)
109: switch (argp[-1]) {
110:
111: case 'T':
112: totflg++;
113: break;
114:
115: case 'a':
116: allflg++;
117: break;
118:
119: case 'i':
120: inof++;
121: break;
122:
123: case 'k':
124: kflg++;
125: fcore = "/vmcore";
126: break;
127:
128: case 'x':
129: txtf++;
130: break;
131:
132: case 'p':
133: prcf++;
134: break;
135:
136: case 't':
137: ttyf++;
138: break;
139:
140: case 'u':
141: if (argc == 0)
142: break;
143: argc--;
144: usrf++;
145: sscanf( *argv++, "%x", &ubase);
146: break;
147:
148: case 'f':
149: filf++;
150: break;
151: case 's':
152: swpf++;
153: break;
154: default:
155: usage();
156: exit(1);
157: }
158: }
159: if (argc>1)
160: fcore = argv[1];
161: if ((fc = open(fcore, 0)) < 0) {
162: printf("Can't find %s\n", fcore);
163: exit(1);
164: }
165: if (argc>0)
166: fnlist = argv[0];
167: nlist(fnlist, nl);
168: usrpt = (struct pte *)nl[USRPT].n_value;
169: Usrptma = (struct pte *)nl[USRPTMA].n_value;
170: if (nl[0].n_type == 0) {
171: printf("no namelist\n");
172: exit(1);
173: }
174: allflags = filf | totflg | inof | prcf | txtf | ttyf | usrf | swpf;
175: if (allflags == 0) {
176: printf("pstat: one or more of -[aixptfsu] is required\n");
177: exit(1);
178: }
179: if (filf||totflg)
180: dofile();
181: if (inof||totflg)
182: doinode();
183: if (prcf||totflg)
184: doproc();
185: if (txtf||totflg)
186: dotext();
187: if (ttyf)
188: dotty();
189: if (usrf)
190: dousr();
191: if (swpf||totflg)
192: doswap();
193: }
194:
195: usage()
196: {
197:
198: printf("usage: pstat -[aixptfs] [-u [ubase]] [system] [core]\n");
199: }
200:
201: doinode()
202: {
203: register struct inode *ip;
204: struct inode *xinode, *ainode;
205: register int nin;
206: int ninode;
207:
208: nin = 0;
209: ninode = getw(nl[SNINODE].n_value);
210: xinode = (struct inode *)calloc(ninode, sizeof (struct inode));
211: lseek(fc, (int)(ainode = (struct inode *)getw(nl[SINODE].n_value)), 0);
212: read(fc, xinode, ninode * sizeof(struct inode));
213: for (ip = xinode; ip < &xinode[ninode]; ip++)
214: if (ip->i_count)
215: nin++;
216: if (totflg) {
217: printf("%3d/%3d inodes\n", nin, ninode);
218: return;
219: }
220: printf("%d/%d active inodes\n", nin, ninode);
221: printf(" LOC FLAGS CNT DEVICE RDC WRC INO MODE NLK UID SIZE/DEV\n");
222: for (ip = xinode; ip < &xinode[ninode]; ip++) {
223: if (ip->i_count == 0)
224: continue;
225: printf("%8.1x ", ainode + (ip - xinode));
226: putf(ip->i_flag&ILOCKED, 'L');
227: putf(ip->i_flag&IUPD, 'U');
228: putf(ip->i_flag&IACC, 'A');
229: putf(ip->i_flag&IMOUNT, 'M');
230: putf(ip->i_flag&IWANT, 'W');
231: putf(ip->i_flag&ITEXT, 'T');
232: putf(ip->i_flag&ICHG, 'C');
233: putf(ip->i_flag&ISHLOCK, 'S');
234: putf(ip->i_flag&IEXLOCK, 'E');
235: putf(ip->i_flag&ILWAIT, 'Z');
236: printf("%4d", ip->i_count&0377);
237: printf("%4d,%3d", major(ip->i_dev), minor(ip->i_dev));
238: printf("%4d", ip->i_shlockc&0377);
239: printf("%4d", ip->i_exlockc&0377);
240: printf("%6d", ip->i_number);
241: printf("%6x", ip->i_mode & 0xffff);
242: printf("%4d", ip->i_nlink);
243: printf("%4d", ip->i_uid);
244: if ((ip->i_mode&IFMT)==IFBLK || (ip->i_mode&IFMT)==IFCHR)
245: printf("%6d,%3d", major(ip->i_rdev), minor(ip->i_rdev));
246: else
247: printf("%10ld", ip->i_size);
248: printf("\n");
249: }
250: free(xinode);
251: }
252:
253: getw(loc)
254: off_t loc;
255: {
256: int word;
257:
258: if (kflg)
259: loc &= 0x7fffffff;
260: lseek(fc, loc, 0);
261: read(fc, &word, sizeof (word));
262: if (kflg)
263: word &= 0x7fffffff;
264: return (word);
265: }
266:
267: putf(v, n)
268: {
269: if (v)
270: printf("%c", n);
271: else
272: printf(" ");
273: }
274:
275: dotext()
276: {
277: register struct text *xp;
278: int ntext;
279: struct text *xtext, *atext;
280: int ntx;
281:
282: ntx = 0;
283: ntext = getw(nl[SNTEXT].n_value);
284: xtext = (struct text *)calloc(ntext, sizeof (struct text));
285: lseek(fc, (int)(atext = (struct text *)getw(nl[STEXT].n_value)), 0);
286: read(fc, xtext, ntext * sizeof (struct text));
287: for (xp = xtext; xp < &xtext[ntext]; xp++)
288: if (xp->x_iptr!=NULL)
289: ntx++;
290: if (totflg) {
291: printf("%3d/%3d texts\n", ntx, ntext);
292: return;
293: }
294: printf("%d/%d active texts\n", ntx, ntext);
295: printf(" LOC FLAGS DADDR CADDR RSS SIZE IPTR CNT CCNT\n");
296: for (xp = xtext; xp < &xtext[ntext]; xp++) {
297: if (xp->x_iptr == NULL)
298: continue;
299: printf("%8.1x", atext + (xp - xtext));
300: printf(" ");
301: putf(xp->x_flag&XPAGI, 'P');
302: putf(xp->x_flag&XTRC, 'T');
303: putf(xp->x_flag&XWRIT, 'W');
304: putf(xp->x_flag&XLOAD, 'L');
305: putf(xp->x_flag&XLOCK, 'K');
306: putf(xp->x_flag&XWANT, 'w');
307: printf("%5x", xp->x_daddr[0]);
308: printf("%11x", xp->x_caddr);
309: printf("%5d", xp->x_rssize);
310: printf("%5d", xp->x_size);
311: printf("%10.1x", xp->x_iptr);
312: printf("%5d", xp->x_count&0377);
313: printf("%5d", xp->x_ccount);
314: printf("\n");
315: }
316: free(xtext);
317: }
318:
319: doproc()
320: {
321: struct proc *xproc, *aproc;
322: int nproc;
323: register struct proc *pp;
324: register loc, np;
325: struct pte apte;
326:
327: nproc = getw(nl[SNPROC].n_value);
328: xproc = (struct proc *)calloc(nproc, sizeof (struct proc));
329: lseek(fc, (int)(aproc = (struct proc *)getw(nl[SPROC].n_value)), 0);
330: read(fc, xproc, nproc * sizeof (struct proc));
331: np = 0;
332: for (pp=xproc; pp < &xproc[nproc]; pp++)
333: if (pp->p_stat)
334: np++;
335: if (totflg) {
336: printf("%3d/%3d processes\n", np, nproc);
337: return;
338: }
339: printf("%d/%d processes\n", np, nproc);
340: printf(" LOC S F POIP PRI SIG UID SLP TIM CPU NI PGRP PID PPID ADDR RSS SRSS SIZE WCHAN LINK TEXTP CLKT\n");
341: for (pp=xproc; pp<&xproc[nproc]; pp++) {
342: if (pp->p_stat==0 && allflg==0)
343: continue;
344: printf("%8x", aproc + (pp - xproc));
345: printf(" %2d", pp->p_stat);
346: printf(" %4x", pp->p_flag & 0xffff);
347: printf(" %4d", pp->p_poip);
348: printf(" %3d", pp->p_pri);
349: printf(" %8x", pp->p_sig);
350: printf(" %4d", pp->p_uid);
351: printf(" %3d", pp->p_slptime);
352: printf(" %3d", pp->p_time);
353: printf(" %4d", pp->p_cpu&0377);
354: printf(" %3d", pp->p_nice);
355: printf(" %6d", pp->p_pgrp);
356: printf(" %6d", pp->p_pid);
357: printf(" %6d", pp->p_ppid);
358: if (kflg)
359: pp->p_addr = (struct pte *)clear((int)pp->p_addr);
360: lseek(fc, (long)(Usrptma+btokmx(pp->p_addr)), 0);
361: read(fc, &apte, sizeof(apte));
362: printf(" %8x", ctob(apte.pg_pfnum+1) - sizeof(struct pte) * UPAGES);
363: printf(" %4x", pp->p_rssize);
364: printf(" %4x", pp->p_swrss);
365: printf(" %5x", pp->p_dsize+pp->p_ssize);
366: printf(" %7x", clear(pp->p_wchan));
367: printf(" %7x", clear(pp->p_link));
368: printf(" %7x", clear(pp->p_textp));
369: printf("\n");
370: }
371: }
372:
373: dotty()
374: {
375: struct tty dz_tty[128];
376: int ndz;
377: register struct tty *tp;
378: register char *mesg;
379:
380: printf("1 cons\n");
381: if (kflg)
382: nl[SKL].n_value = clear(nl[SKL].n_value);
383: lseek(fc, (long)nl[SKL].n_value, 0);
384: read(fc, dz_tty, sizeof(dz_tty[0]));
385: mesg = " # RAW CAN OUT MODE ADDR DEL COL STATE PGRP DISC\n";
386: printf(mesg);
387: ttyprt(&dz_tty[0], 0);
388: if (nl[SNDZ].n_type == 0)
389: goto dh;
390: if (kflg) {
391: nl[SNDZ].n_value = clear(nl[SNDZ].n_value);
392: nl[SDZ].n_value = clear(nl[SDZ].n_value);
393: }
394: lseek(fc, (long)nl[SNDZ].n_value, 0);
395: read(fc, &ndz, sizeof(ndz));
396: printf("%d dz lines\n", ndz);
397: lseek(fc, (long)nl[SDZ].n_value, 0);
398: read(fc, dz_tty, ndz * sizeof (struct tty));
399: for (tp = dz_tty; tp < &dz_tty[ndz]; tp++)
400: ttyprt(tp, tp - dz_tty);
401: dh:
402: if (nl[SNDH].n_type == 0)
403: goto pty;
404: if (kflg) {
405: nl[SNDH].n_value = clear(nl[SNDH].n_value);
406: nl[SDH].n_value = clear(nl[SDH].n_value);
407: }
408: lseek(fc, (long)nl[SNDH].n_value, 0);
409: read(fc, &ndz, sizeof(ndz));
410: printf("%d dh lines\n", ndz);
411: lseek(fc, (long)nl[SDH].n_value, 0);
412: read(fc, dz_tty, ndz * sizeof(struct tty));
413: for (tp = dz_tty; tp < &dz_tty[ndz]; tp++)
414: ttyprt(tp, tp - dz_tty);
415: pty:
416: if (nl[SPTY].n_type == 0)
417: goto pty;
418: if (kflg) {
419: nl[SPTY].n_value = clear(nl[SPTY].n_value);
420: }
421: printf("32 pty lines\n");
422: lseek(fc, (long)nl[SPTY].n_value, 0);
423: read(fc, dz_tty, 32*sizeof(struct tty));
424: for (tp = dz_tty; tp < &dz_tty[32]; tp++)
425: ttyprt(tp, tp - dz_tty);
426: }
427:
428: ttyprt(atp, line)
429: struct tty *atp;
430: {
431: register struct tty *tp;
432:
433: printf("%2d", line);
434: tp = atp;
435: switch (tp->t_line) {
436:
437: /*
438: case NETLDISC:
439: if (tp->t_rec)
440: printf("%4d%4d", 0, tp->t_inbuf);
441: else
442: printf("%4d%4d", tp->t_inbuf, 0);
443: break;
444: */
445:
446: default:
447: printf("%4d", tp->t_rawq.c_cc);
448: printf("%4d", tp->t_canq.c_cc);
449: }
450: printf("%4d", tp->t_outq.c_cc);
451: printf("%8.1x", tp->t_flags);
452: printf(" %8.1x", tp->t_addr);
453: printf("%3d", tp->t_delct);
454: printf("%4d ", tp->t_col);
455: putf(tp->t_state&TS_TIMEOUT, 'T');
456: putf(tp->t_state&TS_WOPEN, 'W');
457: putf(tp->t_state&TS_ISOPEN, 'O');
458: putf(tp->t_state&TS_CARR_ON, 'C');
459: putf(tp->t_state&TS_BUSY, 'B');
460: putf(tp->t_state&TS_ASLEEP, 'A');
461: putf(tp->t_state&TS_XCLUDE, 'X');
462: putf(tp->t_state&TS_HUPCLS, 'H');
463: printf("%6d", tp->t_pgrp);
464: switch (tp->t_line) {
465:
466: case NTTYDISC:
467: printf(" ntty");
468: break;
469:
470: case NETLDISC:
471: printf(" net");
472: break;
473: }
474: printf("\n");
475: }
476:
477: dousr()
478: {
479: struct user U;
480: register i, j, *ip;
481:
482: /* This wins only if PAGSIZ > sizeof (struct user) */
483: lseek(fc, ubase * NBPG, 0);
484: read(fc, &U, sizeof(U));
485: printf("pcb");
486: ip = (int *)&U.u_pcb;
487: while (ip < &U.u_arg[0]) {
488: if ((ip - (int *)&U.u_pcb) % 4 == 0)
489: printf("\t");
490: printf("%x ", *ip++);
491: if ((ip - (int *)&U.u_pcb) % 4 == 0)
492: printf("\n");
493: }
494: if ((ip - (int *)&U.u_pcb) % 4 != 0)
495: printf("\n");
496: printf("arg\t");
497: for (i=0; i<5; i++)
498: printf(" %.1x", U.u_arg[i]);
499: printf("\n");
500: for (i=0; i<sizeof(label_t)/sizeof(int); i++) {
501: if (i%5==0)
502: printf("\t");
503: printf("%9.1x", U.u_ssave.val[i]);
504: if (i%5==4)
505: printf("\n");
506: }
507: if (i%5)
508: printf("\n");
509: printf("segflg\t%d\nerror %d\n", U.u_segflg, U.u_error);
510: printf("uids\t%d,%d,%d,%d\n", U.u_uid,U.u_gid,U.u_ruid,U.u_rgid);
511: printf("procp\t%.1x\n", U.u_procp);
512: printf("ap\t%.1x\n", U.u_ap);
513: printf("r_val?\t%.1x %.1x\n", U.u_r.r_val1, U.u_r.r_val2);
514: printf("base, count, offset %.1x %.1x %ld\n", U.u_base,
515: U.u_count, U.u_offset);
516: printf("cdir rdir %.1x %.1x\n", U.u_cdir, U.u_rdir);
517: printf("dirp %.1x\n", U.u_dirp);
518: printf("dent %d %.14s\n", U.u_dent.d_ino, U.u_dent.d_name);
519: printf("pdir %.1o\n", U.u_pdir);
520: printf("file\t");
521: for (i=0; i<10; i++)
522: printf("%9.1x", U.u_ofile[i]);
523: printf("\n\t");
524: for (i=10; i<NOFILE; i++)
525: printf("%9.1x", U.u_ofile[i]);
526: printf("\n");
527: printf("pofile\t");
528: for (i=0; i<10; i++)
529: printf("%9.1x", U.u_pofile[i]);
530: printf("\n\t");
531: for (i=10; i<NOFILE; i++)
532: printf("%9.1x", U.u_pofile[i]);
533: printf("\n");
534: printf("ssave");
535: for (i=0; i<sizeof(label_t)/sizeof(int); i++) {
536: if (i%5==0)
537: printf("\t");
538: printf("%9.1x", U.u_ssave.val[i]);
539: if (i%5==4)
540: printf("\n");
541: }
542: if (i%5)
543: printf("\n");
544: printf("sigs\t");
545: for (i=0; i<NSIG; i++)
546: printf("%.1x ", U.u_signal[i]);
547: printf("\n");
548: printf("code\t%.1x\n", U.u_code);
549: printf("ar0\t%.1x\n", U.u_ar0);
550: printf("prof\t%X %X %X %X\n", U.u_prof.pr_base, U.u_prof.pr_size,
551: U.u_prof.pr_off, U.u_prof.pr_scale);
552: printf("\neosys\t%d\n", U.u_eosys);
553: printf("ttyp\t%.1x\n", U.u_ttyp);
554: printf("ttyd\t%d,%d\n", major(U.u_ttyd), minor(U.u_ttyd));
555: printf("exdata\t");
556: ip = (int *)&U.u_exdata;
557: for (i = 0; i < 8; i++)
558: printf("%.1D ", *ip++);
559: printf("\n");
560: printf("comm %.14s\n", U.u_comm);
561: printf("start\t%D\n", U.u_start);
562: printf("acflag\t%D\n", U.u_acflag);
563: printf("cmask\t%D\n", U.u_cmask);
564: printf("sizes\t%.1x %.1x %.1x\n", U.u_tsize, U.u_dsize, U.u_ssize);
565: printf("ru\t");
566: ip = (int *)&U.u_ru;
567: for (i = 0; i < sizeof(U.u_ru)/sizeof(int); i++)
568: printf("%D ", ip[i]);
569: printf("\n");
570: ip = (int *)&U.u_cru;
571: printf("cru\t");
572: for (i = 0; i < sizeof(U.u_cru)/sizeof(int); i++)
573: printf("%D ", ip[i]);
574: printf("\n");
575: /*
576: i = U.u_stack - &U;
577: while (U[++i] == 0);
578: i &= ~07;
579: while (i < 512) {
580: printf("%x ", 0140000+2*i);
581: for (j=0; j<8; j++)
582: printf("%9x", U[i++]);
583: printf("\n");
584: }
585: */
586: }
587:
588: oatoi(s)
589: char *s;
590: {
591: register v;
592:
593: v = 0;
594: while (*s)
595: v = (v<<3) + *s++ - '0';
596: return(v);
597: }
598:
599: dofile()
600: {
601: int nfile;
602: struct file *xfile, *afile;
603: register struct file *fp;
604: register nf;
605: int loc;
606: static char *dtypes[] = { "???", "inode", "socket" };
607:
608: nf = 0;
609: nfile = getw(nl[SNFILE].n_value);
610: xfile = (struct file *)calloc(nfile, sizeof (struct file));
611: lseek(fc, (int)(afile = (struct file *)getw(nl[SFIL].n_value)), 0);
612: read(fc, xfile, nfile * sizeof (struct file));
613: for (fp=xfile; fp < &xfile[nfile]; fp++)
614: if (fp->f_count)
615: nf++;
616: if (totflg) {
617: printf("%3d/%3d files\n", nf, nfile);
618: return;
619: }
620: printf("%d/%d open files\n", nf, nfile);
621: printf(" LOC TYPE FLG CNT MSG DATA OFFSET\n");
622: for (fp=xfile,loc=(int)afile; fp < &xfile[nfile]; fp++,loc+=sizeof(xfile[0])) {
623: if (fp->f_count==0)
624: continue;
625: printf("%8x ", loc);
626: if (fp->f_type <= DTYPE_SOCKET)
627: printf("%-8.8s", dtypes[fp->f_type]);
628: else
629: printf("8d", fp->f_type);
630: putf(fp->f_flag&FREAD, 'R');
631: putf(fp->f_flag&FWRITE, 'W');
632: putf(fp->f_flag&FAPPEND, 'A');
633: putf(fp->f_flag&FSHLOCK, 'S');
634: putf(fp->f_flag&FEXLOCK, 'X');
635: putf(fp->f_flag&FASYNC, 'I');
636: printf(" %3d", mask(fp->f_count));
637: printf(" %3d", mask(fp->f_msgcount));
638: printf(" %8.1x", fp->f_data);
639: if (fp->f_offset < 0)
640: printf(" %x\n", fp->f_offset);
641: else
642: printf(" %ld\n", fp->f_offset);
643: }
644: }
645:
646: int dmmin, dmmax, nswdev;
647:
648: doswap()
649: {
650: struct proc *proc;
651: int nproc;
652: struct text *xtext;
653: int ntext;
654: struct map *swapmap;
655: int nswapmap;
656: struct swdevt *swdevt, *sw;
657: register struct proc *pp;
658: int nswap, used, tused, free, waste;
659: int db, sb;
660: register struct mapent *me;
661: register struct text *xp;
662: int i, j;
663:
664: nproc = getw(nl[SNPROC].n_value);
665: proc = (struct proc *)calloc(nproc, sizeof (struct proc));
666: ntext = getw(nl[SNTEXT].n_value);
667: xtext = (struct text *)calloc(ntext, sizeof (struct text));
668: nswapmap = getw(nl[SNSWAPMAP].n_value);
669: swapmap = (struct map *)calloc(nswapmap, sizeof (struct map));
670: nswdev = getw(nl[SNSWDEV].n_value);
671: swdevt = (struct swdevt *)calloc(nswdev, sizeof (struct swdevt));
672: lseek(fc, nl[SSWDEVT].n_value, L_SET);
673: read(fc, swdevt, nswdev * sizeof (struct swdevt));
674: lseek(fc, getw(nl[SPROC].n_value), 0);
675: read(fc, proc, nproc * sizeof (struct proc));
676: lseek(fc, getw(nl[STEXT].n_value), 0);
677: read(fc, xtext, ntext * sizeof (struct text));
678: lseek(fc, getw(nl[SWAPMAP].n_value), 0);
679: read(fc, swapmap, nswapmap * sizeof (struct map));
680: swapmap->m_name = "swap";
681: swapmap->m_limit = (struct mapent *)&swapmap[nswapmap];
682: dmmin = getw(nl[SDMMIN].n_value);
683: dmmax = getw(nl[SDMMAX].n_value);
684: nswap = 0;
685: for (sw = swdevt; sw < &swdevt[nswdev]; sw++)
686: nswap += sw->sw_nblks,
687: free = 0;
688: for (me = (struct mapent *)(swapmap+1);
689: me < (struct mapent *)&swapmap[nswapmap]; me++)
690: free += me->m_size;
691: tused = 0;
692: for (xp = xtext; xp < &xtext[ntext]; xp++)
693: if (xp->x_iptr!=NULL) {
694: tused += ctod(xp->x_size);
695: if (xp->x_flag & XPAGI)
696: tused += ctod(ctopt(xp->x_size));
697: }
698: used = tused;
699: waste = 0;
700: for (pp = proc; pp < &proc[nproc]; pp++) {
701: if (pp->p_stat == 0 || pp->p_stat == SZOMB)
702: continue;
703: if (pp->p_flag & SSYS)
704: continue;
705: db = ctod(pp->p_dsize), sb = up(db);
706: used += sb;
707: waste += sb - db;
708: db = ctod(pp->p_ssize), sb = up(db);
709: used += sb;
710: waste += sb - db;
711: if ((pp->p_flag&SLOAD) == 0)
712: used += vusize(pp);
713: }
714: if (totflg) {
715: #define btok(x) ((x) / (1024 / DEV_BSIZE))
716: printf("%3d/%3d 00k swap\n",
717: btok(used/100), btok((used+free)/100));
718: return;
719: }
720: printf("%dk used (%dk text), %dk free, %dk wasted, %dk missing\n",
721: btok(used), btok(tused), btok(free), btok(waste),
722: /* a dmmax/2 block goes to argmap */
723: btok(nswap - dmmax/2 - (used + free)));
724: printf("avail: ");
725: for (i = dmmax; i >= dmmin; i /= 2) {
726: j = 0;
727: while (rmalloc(swapmap, i) != 0)
728: j++;
729: if (j) printf("%d*%dk ", j, btok(i));
730: }
731: free = 0;
732: for (me = (struct mapent *)(swapmap+1);
733: me < (struct mapent *)&swapmap[nswapmap]; me++)
734: free += me->m_size;
735: printf("%d*1k\n", btok(free));
736: }
737:
738: up(size)
739: register int size;
740: {
741: register int i, block;
742:
743: i = 0;
744: block = dmmin;
745: while (i < size) {
746: i += block;
747: if (block < dmmax)
748: block *= 2;
749: }
750: return (i);
751: }
752:
753: /*
754: * Compute number of pages to be allocated to the u. area
755: * and data and stack area page tables, which are stored on the
756: * disk immediately after the u. area.
757: */
758: vusize(p)
759: register struct proc *p;
760: {
761: register int tsz = p->p_tsize / NPTEPG;
762:
763: /*
764: * We do not need page table space on the disk for page
765: * table pages wholly containing text.
766: */
767: return (clrnd(UPAGES +
768: clrnd(ctopt(p->p_tsize+p->p_dsize+p->p_ssize+UPAGES)) - tsz));
769: }
770:
771: /*
772: * Allocate 'size' units from the given
773: * map. Return the base of the allocated space.
774: * In a map, the addresses are increasing and the
775: * list is terminated by a 0 size.
776: *
777: * Algorithm is first-fit.
778: *
779: * This routine knows about the interleaving of the swapmap
780: * and handles that.
781: */
782: long
783: rmalloc(mp, size)
784: register struct map *mp;
785: long size;
786: {
787: register struct mapent *ep = (struct mapent *)(mp+1);
788: register int addr;
789: register struct mapent *bp;
790: swblk_t first, rest;
791:
792: if (size <= 0 || size > dmmax)
793: return (0);
794: /*
795: * Search for a piece of the resource map which has enough
796: * free space to accomodate the request.
797: */
798: for (bp = ep; bp->m_size; bp++) {
799: if (bp->m_size >= size) {
800: /*
801: * If allocating from swapmap,
802: * then have to respect interleaving
803: * boundaries.
804: */
805: if (nswdev > 1 &&
806: (first = dmmax - bp->m_addr%dmmax) < bp->m_size) {
807: if (bp->m_size - first < size)
808: continue;
809: addr = bp->m_addr + first;
810: rest = bp->m_size - first - size;
811: bp->m_size = first;
812: if (rest)
813: rmfree(mp, rest, addr+size);
814: return (addr);
815: }
816: /*
817: * Allocate from the map.
818: * If there is no space left of the piece
819: * we allocated from, move the rest of
820: * the pieces to the left.
821: */
822: addr = bp->m_addr;
823: bp->m_addr += size;
824: if ((bp->m_size -= size) == 0) {
825: do {
826: bp++;
827: (bp-1)->m_addr = bp->m_addr;
828: } while ((bp-1)->m_size = bp->m_size);
829: }
830: if (addr % CLSIZE)
831: return (0);
832: return (addr);
833: }
834: }
835: return (0);
836: }
837:
838: /*
839: * Free the previously allocated space at addr
840: * of size units into the specified map.
841: * Sort addr into map and combine on
842: * one or both ends if possible.
843: */
844: rmfree(mp, size, addr)
845: struct map *mp;
846: long size, addr;
847: {
848: struct mapent *firstbp;
849: register struct mapent *bp;
850: register int t;
851:
852: /*
853: * Both address and size must be
854: * positive, or the protocol has broken down.
855: */
856: if (addr <= 0 || size <= 0)
857: goto badrmfree;
858: /*
859: * Locate the piece of the map which starts after the
860: * returned space (or the end of the map).
861: */
862: firstbp = bp = (struct mapent *)(mp + 1);
863: for (; bp->m_addr <= addr && bp->m_size != 0; bp++)
864: continue;
865: /*
866: * If the piece on the left abuts us,
867: * then we should combine with it.
868: */
869: if (bp > firstbp && (bp-1)->m_addr+(bp-1)->m_size >= addr) {
870: /*
871: * Check no overlap (internal error).
872: */
873: if ((bp-1)->m_addr+(bp-1)->m_size > addr)
874: goto badrmfree;
875: /*
876: * Add into piece on the left by increasing its size.
877: */
878: (bp-1)->m_size += size;
879: /*
880: * If the combined piece abuts the piece on
881: * the right now, compress it in also,
882: * by shifting the remaining pieces of the map over.
883: */
884: if (bp->m_addr && addr+size >= bp->m_addr) {
885: if (addr+size > bp->m_addr)
886: goto badrmfree;
887: (bp-1)->m_size += bp->m_size;
888: while (bp->m_size) {
889: bp++;
890: (bp-1)->m_addr = bp->m_addr;
891: (bp-1)->m_size = bp->m_size;
892: }
893: }
894: goto done;
895: }
896: /*
897: * Don't abut on the left, check for abutting on
898: * the right.
899: */
900: if (addr+size >= bp->m_addr && bp->m_size) {
901: if (addr+size > bp->m_addr)
902: goto badrmfree;
903: bp->m_addr -= size;
904: bp->m_size += size;
905: goto done;
906: }
907: /*
908: * Don't abut at all. Make a new entry
909: * and check for map overflow.
910: */
911: do {
912: t = bp->m_addr;
913: bp->m_addr = addr;
914: addr = t;
915: t = bp->m_size;
916: bp->m_size = size;
917: bp++;
918: } while (size = t);
919: /*
920: * Segment at bp is to be the delimiter;
921: * If there is not room for it
922: * then the table is too full
923: * and we must discard something.
924: */
925: if (bp+1 > mp->m_limit) {
926: /*
927: * Back bp up to last available segment.
928: * which contains a segment already and must
929: * be made into the delimiter.
930: * Discard second to last entry,
931: * since it is presumably smaller than the last
932: * and move the last entry back one.
933: */
934: bp--;
935: printf("%s: rmap ovflo, lost [%d,%d)\n", mp->m_name,
936: (bp-1)->m_addr, (bp-1)->m_addr+(bp-1)->m_size);
937: bp[-1] = bp[0];
938: bp[0].m_size = bp[0].m_addr = 0;
939: }
940: done:
941: return;
942: badrmfree:
943: printf("bad rmfree\n");
944: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.