Annotation of 42BSD/lib/libc/vax/csu/gmon.c, revision 1.1.1.1

1.1       root        1: static char *sccsid = "@(#)gmon.c      4.13 (Berkeley) 7/26/83";
                      2: 
                      3: #ifdef DEBUG
                      4: #include <stdio.h>
                      5: #endif DEBUG
                      6: 
                      7: #include "gmon.h"
                      8: 
                      9:     /*
                     10:      * froms is actually a bunch of unsigned shorts indexing tos
                     11:      */
                     12: static int             profiling = 3;
                     13: static unsigned short  *froms;
                     14: static struct tostruct *tos = 0;
                     15: static long            tolimit = 0;
                     16: static char            *s_lowpc = 0;
                     17: static char            *s_highpc = 0;
                     18: static unsigned long   s_textsize = 0;
                     19: 
                     20: static int     ssiz;
                     21: static char    *sbuf;
                     22: static int     s_scale;
                     23:     /* see profil(2) where this is describe (incorrectly) */
                     24: #define                SCALE_1_TO_1    0x10000L
                     25: 
                     26: #define        MSG "No space for monitor buffer(s)\n"
                     27: 
                     28: monstartup(lowpc, highpc)
                     29:     char       *lowpc;
                     30:     char       *highpc;
                     31: {
                     32:     int                        monsize;
                     33:     char               *buffer;
                     34:     char               *sbrk();
                     35:     extern char                *minbrk;
                     36: 
                     37:        /*
                     38:         *      round lowpc and highpc to multiples of the density we're using
                     39:         *      so the rest of the scaling (here and in gprof) stays in ints.
                     40:         */
                     41:     lowpc = (char *)
                     42:            ROUNDDOWN((unsigned)lowpc, HISTFRACTION*sizeof(HISTCOUNTER));
                     43:     s_lowpc = lowpc;
                     44:     highpc = (char *)
                     45:            ROUNDUP((unsigned)highpc, HISTFRACTION*sizeof(HISTCOUNTER));
                     46:     s_highpc = highpc;
                     47:     s_textsize = highpc - lowpc;
                     48:     monsize = (s_textsize / HISTFRACTION) + sizeof(struct phdr);
                     49:     buffer = sbrk( monsize );
                     50:     if ( buffer == (char *) -1 ) {
                     51:        write( 2 , MSG , sizeof(MSG) );
                     52:        return;
                     53:     }
                     54:     froms = (unsigned short *) sbrk( s_textsize / HASHFRACTION );
                     55:     if ( froms == (unsigned short *) -1 ) {
                     56:        write( 2 , MSG , sizeof(MSG) );
                     57:        froms = 0;
                     58:        return;
                     59:     }
                     60:     tolimit = s_textsize * ARCDENSITY / 100;
                     61:     if ( tolimit < MINARCS ) {
                     62:        tolimit = MINARCS;
                     63:     } else if ( tolimit > 65534 ) {
                     64:        tolimit = 65534;
                     65:     }
                     66:     tos = (struct tostruct *) sbrk( tolimit * sizeof( struct tostruct ) );
                     67:     if ( tos == (struct tostruct *) -1 ) {
                     68:        write( 2 , MSG , sizeof(MSG) );
                     69:        froms = 0;
                     70:        tos = 0;
                     71:        return;
                     72:     }
                     73:     minbrk = sbrk(0);
                     74:     tos[0].link = 0;
                     75:     monitor( lowpc , highpc , buffer , monsize , tolimit );
                     76: }
                     77: 
                     78: _mcleanup()
                     79: {
                     80:     int                        fd;
                     81:     int                        fromindex;
                     82:     int                        endfrom;
                     83:     char               *frompc;
                     84:     int                        toindex;
                     85:     struct rawarc      rawarc;
                     86: 
                     87:     fd = creat( "gmon.out" , 0666 );
                     88:     if ( fd < 0 ) {
                     89:        perror( "mcount: gmon.out" );
                     90:        return;
                     91:     }
                     92: #   ifdef DEBUG
                     93:        fprintf( stderr , "[mcleanup] sbuf 0x%x ssiz %d\n" , sbuf , ssiz );
                     94: #   endif DEBUG
                     95:     write( fd , sbuf , ssiz );
                     96:     endfrom = s_textsize / (HASHFRACTION * sizeof(*froms));
                     97:     for ( fromindex = 0 ; fromindex < endfrom ; fromindex++ ) {
                     98:        if ( froms[fromindex] == 0 ) {
                     99:            continue;
                    100:        }
                    101:        frompc = s_lowpc + (fromindex * HASHFRACTION * sizeof(*froms));
                    102:        for (toindex=froms[fromindex]; toindex!=0; toindex=tos[toindex].link) {
                    103: #          ifdef DEBUG
                    104:                fprintf( stderr ,
                    105:                        "[mcleanup] frompc 0x%x selfpc 0x%x count %d\n" ,
                    106:                        frompc , tos[toindex].selfpc , tos[toindex].count );
                    107: #          endif DEBUG
                    108:            rawarc.raw_frompc = (unsigned long) frompc;
                    109:            rawarc.raw_selfpc = (unsigned long) tos[toindex].selfpc;
                    110:            rawarc.raw_count = tos[toindex].count;
                    111:            write( fd , &rawarc , sizeof rawarc );
                    112:        }
                    113:     }
                    114:     close( fd );
                    115: }
                    116: 
                    117: asm(".text");
                    118: asm(".align 2");
                    119: asm("#the beginning of mcount()");
                    120: asm(".data");
                    121: mcount()
                    122: {
                    123:        register char                   *selfpc;        /* r11 => r5 */
                    124:        register unsigned short         *frompcindex;   /* r10 => r4 */
                    125:        register struct tostruct        *top;           /* r9  => r3 */
                    126:        register struct tostruct        *prevtop;       /* r8  => r2 */
                    127:        register long                   toindex;        /* r7  => r1 */
                    128: 
                    129: #ifdef lint
                    130:        selfpc = (char *)0;
                    131:        frompcindex = 0;
                    132: #else not lint
                    133:        /*
                    134:         *      find the return address for mcount,
                    135:         *      and the return address for mcount's caller.
                    136:         */
                    137:        asm("   .text");                /* make sure we're in text space */
                    138:        asm("   movl (sp), r11");       /* selfpc = ... (jsb frame) */
                    139:        asm("   movl 16(fp), r10");     /* frompcindex =     (calls frame) */
                    140: #endif not lint
                    141:        /*
                    142:         *      check that we are profiling
                    143:         *      and that we aren't recursively invoked.
                    144:         */
                    145:        if (profiling) {
                    146:                goto out;
                    147:        }
                    148:        profiling++;
                    149:        /*
                    150:         *      check that frompcindex is a reasonable pc value.
                    151:         *      for example:    signal catchers get called from the stack,
                    152:         *                      not from text space.  too bad.
                    153:         */
                    154:        frompcindex = (unsigned short *)((long)frompcindex - (long)s_lowpc);
                    155:        if ((unsigned long)frompcindex > s_textsize) {
                    156:                goto done;
                    157:        }
                    158:        frompcindex =
                    159:            &froms[((long)frompcindex) / (HASHFRACTION * sizeof(*froms))];
                    160:        toindex = *frompcindex;
                    161:        if (toindex == 0) {
                    162:                /*
                    163:                 *      first time traversing this arc
                    164:                 */
                    165:                toindex = ++tos[0].link;
                    166:                if (toindex >= tolimit) {
                    167:                        goto overflow;
                    168:                }
                    169:                *frompcindex = toindex;
                    170:                top = &tos[toindex];
                    171:                top->selfpc = selfpc;
                    172:                top->count = 1;
                    173:                top->link = 0;
                    174:                goto done;
                    175:        }
                    176:        top = &tos[toindex];
                    177:        if (top->selfpc == selfpc) {
                    178:                /*
                    179:                 *      arc at front of chain; usual case.
                    180:                 */
                    181:                top->count++;
                    182:                goto done;
                    183:        }
                    184:        /*
                    185:         *      have to go looking down chain for it.
                    186:         *      top points to what we are looking at,
                    187:         *      prevtop points to previous top.
                    188:         *      we know it is not at the head of the chain.
                    189:         */
                    190:        for (; /* goto done */; ) {
                    191:                if (top->link == 0) {
                    192:                        /*
                    193:                         *      top is end of the chain and none of the chain
                    194:                         *      had top->selfpc == selfpc.
                    195:                         *      so we allocate a new tostruct
                    196:                         *      and link it to the head of the chain.
                    197:                         */
                    198:                        toindex = ++tos[0].link;
                    199:                        if (toindex >= tolimit) {
                    200:                                goto overflow;
                    201:                        }
                    202:                        top = &tos[toindex];
                    203:                        top->selfpc = selfpc;
                    204:                        top->count = 1;
                    205:                        top->link = *frompcindex;
                    206:                        *frompcindex = toindex;
                    207:                        goto done;
                    208:                }
                    209:                /*
                    210:                 *      otherwise, check the next arc on the chain.
                    211:                 */
                    212:                prevtop = top;
                    213:                top = &tos[top->link];
                    214:                if (top->selfpc == selfpc) {
                    215:                        /*
                    216:                         *      there it is.
                    217:                         *      increment its count
                    218:                         *      move it to the head of the chain.
                    219:                         */
                    220:                        top->count++;
                    221:                        toindex = prevtop->link;
                    222:                        prevtop->link = top->link;
                    223:                        top->link = *frompcindex;
                    224:                        *frompcindex = toindex;
                    225:                        goto done;
                    226:                }
                    227: 
                    228:        }
                    229: done:
                    230:        profiling--;
                    231:        /* and fall through */
                    232: out:
                    233:        asm("   rsb");
                    234: 
                    235: overflow:
                    236:        profiling++; /* halt further profiling */
                    237: #   define     TOLIMIT "mcount: tos overflow\n"
                    238:        write(2, TOLIMIT, sizeof(TOLIMIT));
                    239:        goto out;
                    240: }
                    241: asm(".text");
                    242: asm("#the end of mcount()");
                    243: asm(".data");
                    244: 
                    245: /*VARARGS1*/
                    246: monitor( lowpc , highpc , buf , bufsiz , nfunc )
                    247:     char       *lowpc;
                    248:     char       *highpc;
                    249:     char       *buf;   /* declared ``short buffer[]'' in monitor(3) */
                    250:     int                bufsiz;
                    251:     int                nfunc;  /* not used, available for compatability only */
                    252: {
                    253:     register o;
                    254: 
                    255:     if ( lowpc == 0 ) {
                    256:        moncontrol(0);
                    257:        _mcleanup();
                    258:        return;
                    259:     }
                    260:     sbuf = buf;
                    261:     ssiz = bufsiz;
                    262:     ( (struct phdr *) buf ) -> lpc = lowpc;
                    263:     ( (struct phdr *) buf ) -> hpc = highpc;
                    264:     ( (struct phdr *) buf ) -> ncnt = ssiz;
                    265:     bufsiz -= sizeof(struct phdr);
                    266:     if ( bufsiz <= 0 )
                    267:        return;
                    268:     o = highpc - lowpc;
                    269:     if( bufsiz < o )
                    270:        s_scale = ( (float) bufsiz / o ) * SCALE_1_TO_1;
                    271:     else
                    272:        s_scale = SCALE_1_TO_1;
                    273:     moncontrol(1);
                    274: }
                    275: 
                    276: /*
                    277:  * Control profiling
                    278:  *     profiling is what mcount checks to see if
                    279:  *     all the data structures are ready.
                    280:  */
                    281: moncontrol(mode)
                    282:     int mode;
                    283: {
                    284:     if (mode) {
                    285:        /* start */
                    286:        profil(sbuf + sizeof(struct phdr), ssiz - sizeof(struct phdr),
                    287:                s_lowpc, s_scale);
                    288:        profiling = 0;
                    289:     } else {
                    290:        /* stop */
                    291:        profil((char *)0, 0, 0, 0);
                    292:        profiling = 3;
                    293:     }
                    294: }

unix.superglobalmegacorp.com

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