Annotation of researchv10no/cmd/prof.c, revision 1.1

1.1     ! root        1: #include "sys/types.h"
        !             2: #include "sys/stat.h"
        !             3: #include "a.out.h"
        !             4: /* it wouldn't be better to get this out of sys/param.h */
        !             5: #define HZ 60
        !             6: 
        !             7: typedef unsigned short Prof;   /* what the counts are stored in! */
        !             8: /* a mon.out consists of a phdr, cnt structs pcnt, and the rest are
        !             9:        Profs of pc clicks */
        !            10: struct phdr {
        !            11:        char    *lopc, *hipc;   /* void *? */
        !            12:        int     cnt;
        !            13: };
        !            14: struct phdr hsv;
        !            15: struct pcnt {
        !            16:        char *  value;
        !            17:        long    calls;
        !            18: };
        !            19: char flags[128];
        !            20: char *xfile, *file;
        !            21: struct nlist *names;
        !            22: char *strings, *pbuf;
        !            23: Prof *accum;
        !            24: int accumsz;
        !            25: typedef struct {
        !            26:        char *loc;
        !            27:        char *name;
        !            28:        long calls;
        !            29:        long clicks;
        !            30:        unsigned char type;
        !            31: } sym;
        !            32: int nsym;
        !            33: sym *syms, nilsym;
        !            34: long lopct, hipct;     /* plot stuff */
        !            35: double rscale, roffset;
        !            36: 
        !            37: main(argc, argv)
        !            38: char **argv;
        !            39: {      int c;
        !            40:        extern int optind;
        !            41:        extern char **optarg;
        !            42:        char *p;
        !            43:        
        !            44:        while((c = getopt(argc, argv, "alnsvz")) != -1)
        !            45:        switch(c) {
        !            46:        case 'l': case 'n': case 's': case 'z':
        !            47:                flags[c] = 1;
        !            48:                continue;
        !            49:        case 'v':
        !            50:                flags['v'] = 1;
        !            51:                p = argv[optind];
        !            52:                if(*p != '-' || p[1] > '9' || p[1] < '0')
        !            53:                        continue;
        !            54:                lopct = atoi(p+1);
        !            55:                p = argv[++optind];
        !            56:                if(*p != '-' || p[1] > '9' || p[1] < '0')
        !            57:                        continue;
        !            58:                hipct = atoi(p+1);
        !            59:                optind++;
        !            60:                continue;
        !            61:        case '?':
        !            62:                fatal("usage: %s -[alnsz] files\n", argv[0]);
        !            63:        }
        !            64:        if(optind < argc)
        !            65:                xfile = argv[optind++];
        !            66:        else
        !            67:                xfile = "a.out";
        !            68:        readsyms();
        !            69:        if(optind >= argc)
        !            70:                doit("mon.out");
        !            71:        else
        !            72:                for(; optind < argc; optind++)
        !            73:                        doit(argv[optind]);
        !            74:        output();
        !            75:        exit(0);
        !            76: }
        !            77: 
        !            78: doit(s)
        !            79: char *s;
        !            80: {      struct stat stb;
        !            81:        int fd;
        !            82: 
        !            83:        file = s;
        !            84:        fd = open(s, 0);
        !            85:        if(fd < 0)
        !            86:                fatal("couldn't open %s\n", s);
        !            87:        fstat(fd, &stb);
        !            88:        pbuf = (char *) malloc(stb.st_size);
        !            89:        if(pbuf == 0)
        !            90:                fatal("couldn't alloc %d bytes for %s\n", stb.st_size, s);
        !            91:        if(read(fd, pbuf, stb.st_size) != stb.st_size)
        !            92:                fatal("read of %s failed\n", s);
        !            93:        if(stb.st_size <= sizeof(struct phdr))
        !            94:                fatal("%s not a mon.out\n");
        !            95:        close(fd);
        !            96:        addcalls();
        !            97:        addclicks(stb.st_size);
        !            98:        free(pbuf);
        !            99: }
        !           100: 
        !           101: addclicks(top)
        !           102: {      int i, n, cnt, j;
        !           103:        char *x;
        !           104:        Prof *p;
        !           105:        struct phdr *h;
        !           106:        double scale;   /* the kernel uses 16 bit fractions */
        !           107: 
        !           108:        h = (struct phdr *)pbuf;
        !           109:        n = ((struct phdr *)pbuf)->cnt;
        !           110:        p = (Prof *) (pbuf + sizeof(struct phdr) + n * sizeof(struct pcnt));
        !           111:        top -= sizeof(struct phdr) + n * sizeof(struct pcnt);
        !           112:        cnt = top/sizeof(Prof); /* number of counters */
        !           113:        if(flags['s'] && !accumsz) {
        !           114:                accum = (Prof *) malloc(cnt*sizeof(Prof));
        !           115:                (void) memset(accum, 0, cnt*sizeof(Prof));
        !           116:                accumsz = cnt;
        !           117:                hsv = *h;
        !           118:        }       /* we assume h is fixed across the files */
        !           119:        scale = (h->hipc-h->lopc)/(double)cnt;
        !           120:        /* in mcrt0.s it's 8 */
        !           121:        for(j = i = 0; i < cnt; i++) {
        !           122:                x = (char *)(h->lopc + (int)(scale*i));
        !           123:                while(j < nsym && syms[j+1].loc < x)
        !           124:                        j++;
        !           125:                if(j > nsym)
        !           126:                        fatal("cnts out of range %s\n", file);
        !           127:                syms[j].clicks += p[i];
        !           128:        }
        !           129:        if(flags['s'])
        !           130:        for(i = 0; i < accumsz; i++) {
        !           131:                n = accum[i] + p[i];
        !           132:                accum[i] = n;
        !           133:                if(n != accum[i]) {
        !           134:                        mesg("overflow in accumulating counts, -s ignored\n");
        !           135:                        flags['s'] = 0;
        !           136:                        return;
        !           137:                }
        !           138:        }
        !           139: }
        !           140: 
        !           141: addcalls()
        !           142: {      int n, i;
        !           143:        struct pcnt *p;
        !           144: 
        !           145:        p = (struct pcnt *)(pbuf + sizeof(struct phdr));
        !           146:        n = ((struct phdr *)pbuf)->cnt;
        !           147:        for(i = 0; i < n; i++, p++)
        !           148:                addcall(p->value, p->calls);
        !           149: }
        !           150: 
        !           151: addcall(x, n)
        !           152: char *x;
        !           153: {      int i;
        !           154:        for(i = 0; i < nsym && syms[i+1].loc < x; i++)
        !           155:                ;
        !           156:        if(i >= nsym) {
        !           157:                mesg("cntr out of range (%s), ignored\n", file);
        !           158:                return;
        !           159:        }
        !           160:        if(syms[i+1].loc == x)
        !           161:                syms[i+1].calls += n;
        !           162:        else
        !           163:                syms[i].calls += n;
        !           164: }
        !           165: 
        !           166: symnum(a, b)
        !           167: register sym *a, *b;
        !           168: {
        !           169:        return(a->loc - b->loc);
        !           170: }
        !           171: 
        !           172: readsyms()
        !           173: {      int fd, n, i, j;
        !           174:        struct exec x;
        !           175:        struct stat stb;
        !           176:        struct nlist *np;
        !           177: 
        !           178:        fd = open(xfile, 0);
        !           179:        if(fd < 0)
        !           180:                fatal("couldn't read %s\n", xfile);
        !           181:        if(read(fd, (char *)&x, sizeof(x)) != sizeof(x))
        !           182:                fatal("can't read header of %s\n", xfile);
        !           183:        if(!x.a_syms)
        !           184:                fatal("%s has no symbol table\n", xfile);
        !           185: 
        !           186:        /* read the symbol table in */
        !           187:        lseek(fd, N_SYMOFF(x), 0);
        !           188:        names = (struct nlist *) malloc(x.a_syms);
        !           189:        read(fd, (char *)names, x.a_syms);
        !           190:        nsym = N_STROFF(x) - N_SYMOFF(x);
        !           191:        nsym /= sizeof(struct nlist);   /* over estimated */
        !           192: 
        !           193:        /* read the wretched strings in */
        !           194:        lseek(fd, N_STROFF(x), 0);
        !           195:        fstat(fd, &stb);
        !           196:        n = stb.st_size - N_STROFF(x);
        !           197:        strings = (char *) malloc(n);
        !           198:        if(read(fd, strings, n) != n)
        !           199:                fatal("couldn't read string table from %s (%d)\n", xfile, n);
        !           200: 
        !           201:        /* copy the text symbols into the symbol table */
        !           202:        syms = (sym *) malloc(nsym * sizeof(sym));
        !           203:        for(i = 0, np = names; np < names + nsym; np++) {
        !           204:                if((np->n_type & N_TYPE) != N_TEXT)
        !           205:                        continue;
        !           206:                if(np->n_type & N_STAB)
        !           207:                        continue;
        !           208:                syms[i] = nilsym;
        !           209:                syms[i].type = np->n_type;
        !           210:                syms[i].loc = (char *)np->n_value;
        !           211:                syms[i].name = strings + np->n_un.n_strx;
        !           212:                i++;
        !           213:        }
        !           214:        nsym = i;
        !           215:        qsort((char *)syms, nsym, sizeof(sym), symnum);
        !           216: 
        !           217:        /* now decide which of the ones with the same loc we like */
        !           218:        for(i = 0; i < nsym; i = j) {
        !           219:                for(j = i+1; j < nsym; j++)
        !           220:                        if(syms[i].loc != syms[j].loc)
        !           221:                                break;
        !           222:                choose(i, j);
        !           223:        }
        !           224:        /* and squash it down */
        !           225:        for(i = j = 0; i < nsym; i++)
        !           226:                if(syms[i].type)
        !           227:                        syms[j++] = syms[i];
        !           228:        nsym = j;
        !           229:        syms[nsym].loc = (char *)0x8fffffff;    /* a very big end */
        !           230:        close(fd);
        !           231: }
        !           232: 
        !           233: /* the expert system */
        !           234: choose(i, j)
        !           235: {      int n;
        !           236:        if(j-i <= 1)
        !           237:                return;
        !           238:        /* if there is an external text one, take it */
        !           239:        for(n = i; n < j; n++)
        !           240:                if(syms[n].type & N_EXT)
        !           241:                        goto found;
        !           242:        /* if there is one that starts with _, take it */
        !           243:        for(n = i; n < j; n++)
        !           244:                if(syms[n].name[0] == '_')
        !           245:                        goto found;
        !           246:        /* if there is one without a . in it, take it */
        !           247:        for(n = i; n < j; n++)
        !           248:                if(!strchr(syms[n].name, '.'))
        !           249:                        goto found;
        !           250:        /* first must be right, or at least ok */
        !           251:        n = i;
        !           252: found:
        !           253:        for(; i < j; i++)
        !           254:                if(i != n)
        !           255:                        syms[i].type = 0;
        !           256: }
        !           257: 
        !           258: char ebuf[256];
        !           259: mesg(s, a, b, c, d, e, f)
        !           260: char *s;
        !           261: {
        !           262:        sprintf(ebuf, s, a, b, c, d, e, f);
        !           263:        write(2, ebuf, strlen(ebuf));
        !           264: }
        !           265: 
        !           266: fatal(s, a, b, c, d, e, f)
        !           267: char *s;
        !           268: {
        !           269:        mesg(s, a, b, c, d, e, f);
        !           270:        exit(1);
        !           271: }
        !           272: 
        !           273: symcalls(a, b)
        !           274: register sym *a, *b;
        !           275: {
        !           276:        return(b->calls - a->calls);
        !           277: }
        !           278: 
        !           279: symcnt(a, b)
        !           280: register sym *a, *b;
        !           281: {
        !           282:        return(b->clicks - a->clicks);  /* largest first */
        !           283: }
        !           284: 
        !           285: output()
        !           286: {      int i, tot, fd;
        !           287:        double x, y;
        !           288: 
        !           289:        if(flags['v']) {
        !           290:                plotout();
        !           291:                return;
        !           292:        }
        !           293:        for(tot = i = 0; i < nsym; i++)
        !           294:                tot += syms[i].clicks;
        !           295:        if(tot == 0)
        !           296:                tot = 1;
        !           297:        if(flags['n'])
        !           298:                qsort((char *)syms, nsym, sizeof(sym), symcalls);
        !           299:        else if(!flags['l'])
        !           300:                qsort((char *)syms, nsym, sizeof(sym), symcnt);
        !           301:        printf("  %%   Time\tCalls\tName\n");
        !           302:        for(i = 0; i < nsym; i++) {
        !           303:                if(!syms[i].calls && !syms[i].clicks && !flags['z'])
        !           304:                        continue;
        !           305:                x = syms[i].clicks;
        !           306:                x /= HZ;
        !           307:                y = syms[i].clicks/(double)tot;
        !           308:                printf("%4.1f%8.3f %8d\t%s\n", (y*100), x, syms[i].calls,
        !           309:                        syms[i].name);
        !           310:        }
        !           311:        if(!flags['s'])
        !           312:                return;
        !           313:        fd = creat("mon.sum", 0666);
        !           314:        if(fd < 0)
        !           315:                fatal("can't create mon.sum\n");
        !           316:        hsv.cnt = nsym;
        !           317:        if(write(fd, (char *)&hsv, sizeof(hsv)) != sizeof(hsv))
        !           318:                fatal("write failed\n");
        !           319:        for(i = 0; i < nsym; i++) {     /* this is very inefficient */
        !           320:                write(fd, (char *)&syms[i].loc, 4);     /* 4! */
        !           321:                write(fd, (char *)&syms[i].calls, 4);
        !           322:        }
        !           323:        if(write(fd, (char *)accum, accumsz*sizeof(Prof)) != accumsz*sizeof(Prof))
        !           324:                fatal("write failed\n");
        !           325:        close(fd);
        !           326: }
        !           327: 
        !           328: /* most of this is witchcraft */
        !           329: plotout()
        !           330: {      int i;
        !           331: /*     double lastx, lasty;
        !           332:        if(lopct >= 100 || lopct < 0)
        !           333:                lopct = 0;
        !           334:        if(hipct > 100 || hipct <= 0)
        !           335:                hipct = 100;
        !           336:        rscale = 100./(hipct-lopct);
        !           337:        roffset = 2040.+40.8*lopct*rscale;
        !           338:        openpl();
        !           339:        erase();
        !           340:        range(-2048, -2048, 2048, 2048);
        !           341:        line(-2040, -2040, -2040, 2040);
        !           342:        for(i = 0; i < 11; i++)
        !           343:                line(-2040, 2040-i*408, 0, 2040-i*408);
        !           344:        */
        !           345: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.