try to make display narrower
[unix-history] / usr / src / lib / libc / gmon / gmon.c
index 2223057..76a6d61 100644 (file)
@@ -1,4 +1,12 @@
-static char *sccsid = "@(#)gmon.c      4.8 (Berkeley) %G%";
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)gmon.c     5.4 (Berkeley) %G%";
+#endif LIBC_SCCS and not lint
 
 #ifdef DEBUG
 #include <stdio.h>
 
 #ifdef DEBUG
 #include <stdio.h>
@@ -9,16 +17,19 @@ static       char *sccsid = "@(#)gmon.c      4.8 (Berkeley) %G%";
     /*
      * froms is actually a bunch of unsigned shorts indexing tos
      */
     /*
      * froms is actually a bunch of unsigned shorts indexing tos
      */
+static int             profiling = 3;
 static unsigned short  *froms;
 static struct tostruct *tos = 0;
 static long            tolimit = 0;
 static char            *s_lowpc = 0;
 static char            *s_highpc = 0;
 static unsigned long   s_textsize = 0;
 static unsigned short  *froms;
 static struct tostruct *tos = 0;
 static long            tolimit = 0;
 static char            *s_lowpc = 0;
 static char            *s_highpc = 0;
 static unsigned long   s_textsize = 0;
-static char            *minsbrk = 0;
 
 static int     ssiz;
 
 static int     ssiz;
-static int     *sbuf;
+static char    *sbuf;
+static int     s_scale;
+    /* see profil(2) where this is describe (incorrectly) */
+#define                SCALE_1_TO_1    0x10000L
 
 #define        MSG "No space for monitor buffer(s)\n"
 
 
 #define        MSG "No space for monitor buffer(s)\n"
 
@@ -29,7 +40,7 @@ monstartup(lowpc, highpc)
     int                        monsize;
     char               *buffer;
     char               *sbrk();
     int                        monsize;
     char               *buffer;
     char               *sbrk();
-    unsigned long      limit;
+    extern char                *minbrk;
 
        /*
         *      round lowpc and highpc to multiples of the density we're using
 
        /*
         *      round lowpc and highpc to multiples of the density we're using
@@ -45,36 +56,30 @@ monstartup(lowpc, highpc)
     monsize = (s_textsize / HISTFRACTION) + sizeof(struct phdr);
     buffer = sbrk( monsize );
     if ( buffer == (char *) -1 ) {
     monsize = (s_textsize / HISTFRACTION) + sizeof(struct phdr);
     buffer = sbrk( monsize );
     if ( buffer == (char *) -1 ) {
-       write( 2 , MSG , sizeof(MSG) );
+       write( 2 , MSG , sizeof(MSG) - 1 );
        return;
     }
        return;
     }
-    froms = (unsigned short *) sbrk( s_textsize );
+    froms = (unsigned short *) sbrk( s_textsize / HASHFRACTION );
     if ( froms == (unsigned short *) -1 ) {
     if ( froms == (unsigned short *) -1 ) {
-       write( 2 , MSG , sizeof(MSG) );
+       write( 2 , MSG , sizeof(MSG) - 1 );
        froms = 0;
        return;
     }
        froms = 0;
        return;
     }
-    limit = s_textsize * ARCDENSITY / 100;
-    if ( limit < MINARCS ) {
-       limit = MINARCS;
-    } else if ( limit > 65534 ) {
-       limit = 65534;
+    tolimit = s_textsize * ARCDENSITY / 100;
+    if ( tolimit < MINARCS ) {
+       tolimit = MINARCS;
+    } else if ( tolimit > 65534 ) {
+       tolimit = 65534;
     }
     }
-    tos = (struct tostruct *) sbrk( limit * sizeof( struct tostruct ) );
+    tos = (struct tostruct *) sbrk( tolimit * sizeof( struct tostruct ) );
     if ( tos == (struct tostruct *) -1 ) {
     if ( tos == (struct tostruct *) -1 ) {
-       write( 2 , MSG , sizeof(MSG) );
+       write( 2 , MSG , sizeof(MSG) - 1 );
        froms = 0;
        tos = 0;
        return;
     }
        froms = 0;
        tos = 0;
        return;
     }
-    minsbrk = sbrk(0);
+    minbrk = sbrk(0);
     tos[0].link = 0;
     tos[0].link = 0;
-       /*
-        *      tolimit is what mcount checks to see if
-        *      all the data structures are ready!!!
-        *      make sure it won't overflow.
-        */
-    tolimit = limit;
     monitor( lowpc , highpc , buffer , monsize , tolimit );
 }
 
     monitor( lowpc , highpc , buffer , monsize , tolimit );
 }
 
@@ -82,6 +87,7 @@ _mcleanup()
 {
     int                        fd;
     int                        fromindex;
 {
     int                        fd;
     int                        fromindex;
+    int                        endfrom;
     char               *frompc;
     int                        toindex;
     struct rawarc      rawarc;
     char               *frompc;
     int                        toindex;
     struct rawarc      rawarc;
@@ -95,11 +101,12 @@ _mcleanup()
        fprintf( stderr , "[mcleanup] sbuf 0x%x ssiz %d\n" , sbuf , ssiz );
 #   endif DEBUG
     write( fd , sbuf , ssiz );
        fprintf( stderr , "[mcleanup] sbuf 0x%x ssiz %d\n" , sbuf , ssiz );
 #   endif DEBUG
     write( fd , sbuf , ssiz );
-    for ( fromindex = 0 ; fromindex < s_textsize>>1 ; fromindex++ ) {
+    endfrom = s_textsize / (HASHFRACTION * sizeof(*froms));
+    for ( fromindex = 0 ; fromindex < endfrom ; fromindex++ ) {
        if ( froms[fromindex] == 0 ) {
            continue;
        }
        if ( froms[fromindex] == 0 ) {
            continue;
        }
-       frompc = s_lowpc + (fromindex<<1);
+       frompc = s_lowpc + (fromindex * HASHFRACTION * sizeof(*froms));
        for (toindex=froms[fromindex]; toindex!=0; toindex=tos[toindex].link) {
 #          ifdef DEBUG
                fprintf( stderr ,
        for (toindex=froms[fromindex]; toindex!=0; toindex=tos[toindex].link) {
 #          ifdef DEBUG
                fprintf( stderr ,
@@ -116,6 +123,7 @@ _mcleanup()
 }
 
 asm(".text");
 }
 
 asm(".text");
+asm(".align 2");
 asm("#the beginning of mcount()");
 asm(".data");
 mcount()
 asm("#the beginning of mcount()");
 asm(".data");
 mcount()
@@ -125,12 +133,7 @@ mcount()
        register struct tostruct        *top;           /* r9  => r3 */
        register struct tostruct        *prevtop;       /* r8  => r2 */
        register long                   toindex;        /* r7  => r1 */
        register struct tostruct        *top;           /* r9  => r3 */
        register struct tostruct        *prevtop;       /* r8  => r2 */
        register long                   toindex;        /* r7  => r1 */
-       static int                      profiling = 0;
 
 
-#ifdef lint
-       selfpc = (char *)0;
-       frompcindex = 0;
-#else not lint
        /*
         *      find the return address for mcount,
         *      and the return address for mcount's caller.
        /*
         *      find the return address for mcount,
         *      and the return address for mcount's caller.
@@ -138,18 +141,14 @@ mcount()
        asm("   .text");                /* make sure we're in text space */
        asm("   movl (sp), r11");       /* selfpc = ... (jsb frame) */
        asm("   movl 16(fp), r10");     /* frompcindex =     (calls frame) */
        asm("   .text");                /* make sure we're in text space */
        asm("   movl (sp), r11");       /* selfpc = ... (jsb frame) */
        asm("   movl 16(fp), r10");     /* frompcindex =     (calls frame) */
-#endif not lint
        /*
         *      check that we are profiling
         *      and that we aren't recursively invoked.
         */
        /*
         *      check that we are profiling
         *      and that we aren't recursively invoked.
         */
-       if (tolimit == 0) {
-               goto out;
-       }
        if (profiling) {
                goto out;
        }
        if (profiling) {
                goto out;
        }
-       profiling = 1;
+       profiling++;
        /*
         *      check that frompcindex is a reasonable pc value.
         *      for example:    signal catchers get called from the stack,
        /*
         *      check that frompcindex is a reasonable pc value.
         *      for example:    signal catchers get called from the stack,
@@ -160,7 +159,7 @@ mcount()
                goto done;
        }
        frompcindex =
                goto done;
        }
        frompcindex =
-           &froms[(((long)frompcindex) + sizeof(*froms) - 1) / sizeof(*froms)];
+           &froms[((long)frompcindex) / (HASHFRACTION * sizeof(*froms))];
        toindex = *frompcindex;
        if (toindex == 0) {
                /*
        toindex = *frompcindex;
        if (toindex == 0) {
                /*
@@ -231,15 +230,15 @@ mcount()
 
        }
 done:
 
        }
 done:
-       profiling = 0;
+       profiling--;
        /* and fall through */
 out:
        asm("   rsb");
 
 overflow:
        /* and fall through */
 out:
        asm("   rsb");
 
 overflow:
-       tolimit = 0;
+       profiling++; /* halt further profiling */
 #   define     TOLIMIT "mcount: tos overflow\n"
 #   define     TOLIMIT "mcount: tos overflow\n"
-       write(2, TOLIMIT, sizeof(TOLIMIT));
+       write(2, TOLIMIT, sizeof(TOLIMIT) - 1);
        goto out;
 }
 asm(".text");
        goto out;
 }
 asm(".text");
@@ -250,13 +249,14 @@ asm(".data");
 monitor( lowpc , highpc , buf , bufsiz , nfunc )
     char       *lowpc;
     char       *highpc;
 monitor( lowpc , highpc , buf , bufsiz , nfunc )
     char       *lowpc;
     char       *highpc;
-    int                *buf, bufsiz;
+    char       *buf;   /* declared ``short buffer[]'' in monitor(3) */
+    int                bufsiz;
     int                nfunc;  /* not used, available for compatability only */
 {
     register o;
 
     if ( lowpc == 0 ) {
     int                nfunc;  /* not used, available for compatability only */
 {
     register o;
 
     if ( lowpc == 0 ) {
-       profil( (char *) 0 , 0 , 0 , 0 );
+       moncontrol(0);
        _mcleanup();
        return;
     }
        _mcleanup();
        return;
     }
@@ -265,36 +265,33 @@ monitor( lowpc , highpc , buf , bufsiz , nfunc )
     ( (struct phdr *) buf ) -> lpc = lowpc;
     ( (struct phdr *) buf ) -> hpc = highpc;
     ( (struct phdr *) buf ) -> ncnt = ssiz;
     ( (struct phdr *) buf ) -> lpc = lowpc;
     ( (struct phdr *) buf ) -> hpc = highpc;
     ( (struct phdr *) buf ) -> ncnt = ssiz;
-    o = sizeof(struct phdr);
-    buf = (int *) ( ( (int) buf ) + o );
-    bufsiz -= o;
+    bufsiz -= sizeof(struct phdr);
     if ( bufsiz <= 0 )
        return;
     if ( bufsiz <= 0 )
        return;
-    o = ( ( (char *) highpc - (char *) lowpc) );
+    o = highpc - lowpc;
     if( bufsiz < o )
     if( bufsiz < o )
-       o = ( (float) bufsiz / o ) * 65536;
+       s_scale = ( (float) bufsiz / o ) * SCALE_1_TO_1;
     else
     else
-       o = 65536;
-    profil( buf , bufsiz , lowpc , o );
+       s_scale = SCALE_1_TO_1;
+    moncontrol(1);
 }
 
 /*
 }
 
 /*
- * This is a stub for the "brk" system call, which we want to
- * catch so that it will not deallocate our data space.
- * (of which the program is not aware)
+ * Control profiling
+ *     profiling is what mcount checks to see if
+ *     all the data structures are ready.
  */
  */
-extern char *curbrk;
-
-brk(addr)
-       char *addr;
+moncontrol(mode)
+    int mode;
 {
 {
-
-       if (addr < minsbrk)
-               addr = minsbrk;
-       asm("   chmk    $17");
-       asm("   jcc     1f");
-       asm("   jmp     cerror");
-asm("1:");
-       curbrk = addr;
-       return (0);
+    if (mode) {
+       /* start */
+       profil(sbuf + sizeof(struct phdr), ssiz - sizeof(struct phdr),
+               s_lowpc, s_scale);
+       profiling = 0;
+    } else {
+       /* stop */
+       profil((char *)0, 0, 0, 0);
+       profiling = 3;
+    }
 }
 }