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