date and time created 81/10/15 13:47:22 by peter
authorPeter B. Kessler <peter@ucbvax.Berkeley.EDU>
Fri, 16 Oct 1981 05:47:22 +0000 (21:47 -0800)
committerPeter B. Kessler <peter@ucbvax.Berkeley.EDU>
Fri, 16 Oct 1981 05:47:22 +0000 (21:47 -0800)
SCCS-vsn: usr.bin/gprof/printgprof.c 1.1

usr/src/usr.bin/gprof/printgprof.c [new file with mode: 0644]

diff --git a/usr/src/usr.bin/gprof/printgprof.c b/usr/src/usr.bin/gprof/printgprof.c
new file mode 100644 (file)
index 0000000..2acb78f
--- /dev/null
@@ -0,0 +1,324 @@
+#ifndef lint
+    static     char *sccsid = "@(#)printgprof.c        1.1 (Berkeley) %G%";
+#endif lint
+
+#include "dprof.h"
+
+printdprof()
+{
+    nltype     **timesortnlp;
+    int                index;
+    nltype     *parentp;
+    nltype     *childp;
+
+       /*
+        *      Now, sort by time + childtime.
+        *      include the cycle headers hiding out past nl[nname].
+        */
+    timesortnlp = (nltype **) calloc( nname+1+cyclemax , sizeof(nltype *) );
+    if ( timesortnlp == (nltype **) 0 ) {
+       fprintf( stderr , "[doarcs] ran out of memory for sorting\n" );
+    }
+    for ( index = 0 ; index < nname+1+cyclemax ; index++ ) {
+       timesortnlp[index] = &nl[index];
+    }
+    qsort( timesortnlp , nname+1+cyclemax , sizeof(nltype *) , totalcmp );
+    for ( index = 0 ; index < nname+1+cyclemax ; index++ ) {
+       timesortnlp[ index ] -> index = index + 1;
+    }
+       /*
+        *      Now, print out the structured profiling list
+        */
+    actime = 0.0;
+    printf( "\f" );
+    putprofheader();
+    for ( index = 0 ; index < nname + 1 + cyclemax ; index ++ ) {
+       parentp = timesortnlp[ index ];
+       if ( zflg == 0 &&
+            parentp -> ncall == 0 &&
+            parentp -> selfcalls == 0 &&
+            parentp -> time == 0 &&
+            parentp -> childtime == 0 ) {
+           continue;
+       }
+       if ( parentp -> name == 0 && parentp -> cycleno != 0 ) {
+               /*
+                *      cycle header
+                */
+           putprofline( parentp , 0 );
+           for ( childp = parentp->cnext ; childp ; childp = childp->cnext ) {
+               putprofline( childp , 0 );
+           }
+       } else {
+           printparents( parentp );
+           putprofline( parentp , 1 );
+           printchildren( parentp );
+       }
+       printf( "\n" );
+    }
+    actime = 0.0;
+}
+
+printparents( childp )
+    nltype     *childp;
+{
+    nltype     *parentp;
+    arctype    *arcp;
+    nltype     *cycleheadp;
+
+    if ( childp -> cyclehead != 0 ) {
+       cycleheadp = childp -> cyclehead;
+    } else {
+       cycleheadp = childp;
+    }
+    if ( childp -> parents == 0 ) {
+       printf( "\t%5.5s %7.7s %7.7s %7.7s %7.7s %7.7s      <spontaneous>\n" ,
+               "" , "" , "" , "" , "" , "" );
+       return;
+    }
+    sortparents( childp );
+    for ( arcp = childp -> parents ; arcp ; arcp = arcp -> arc_parentlist ) {
+       parentp = arcp -> arc_parentp;
+       if ( childp == parentp ||
+            ( childp->cycleno != 0 && parentp->cycleno == childp->cycleno ) ) {
+               /*
+                *      selfcall or call amoung siblings
+                */
+           printf( "\t%5.5s %7.7s %7.7s %7.7s %7d %7.7s      " ,
+                   "" , "" , "" , "" ,
+                   arcp -> arc_count , "" );
+           printname( parentp );
+           printf( "\n" );
+       } else {
+               /*
+                *      regular parent of child
+                */
+           printf( "\t%5.5s %7.7s %7.1f %7.1f %7d/%-7d      " , "" , "" ,
+                   arcp -> arc_time / HZ , arcp -> arc_childtime / HZ ,
+                   arcp -> arc_count , cycleheadp -> ncall );
+           printname( parentp );
+           printf( "\n" );
+       }
+    }
+}
+
+printchildren( parentp )
+    nltype     *parentp;
+{
+    nltype     *childp;
+    arctype    *arcp;
+
+    sortchildren( parentp );
+    arcp = parentp -> children;
+    for ( arcp = parentp -> children ; arcp ; arcp = arcp -> arc_childlist ) {
+       childp = arcp -> arc_childp;
+       if ( childp == parentp ||
+           ( childp->cycleno != 0 && childp->cycleno == parentp->cycleno ) ) {
+               /*
+                *      self call or call to sibling
+                */
+           printf( "\t%5.5s %7.7s %7.7s %7.7s %7d %7.7s      " ,
+                   "" , "" , "" , "" ,
+                   arcp -> arc_count , "" );
+           printname( childp );
+           printf( "\n" );
+       } else {
+               /*
+                *      regular child of parent
+                */
+           printf( "\t%5.5s %7.7s %7.1f %7.1f %7d/%-7d      " , "" , "" ,
+                   arcp -> arc_time / HZ , arcp -> arc_childtime / HZ ,
+                   arcp -> arc_count , childp -> cyclehead -> ncall );
+           printname( childp );
+           printf( "\n" );
+       }
+    }
+}
+
+printname( selfp )
+    nltype     *selfp;
+{
+
+    if ( selfp -> name != 0 ) {
+       printf( "%s\t" , selfp -> name );
+       if ( selfp -> index != 0 ) {
+           printf( "[%d] " , selfp -> index );
+       }
+#      ifdef DEBUG
+           if ( debug & DFNDEBUG ) {
+               printf( "{%d} " , selfp -> toporder );
+           }
+#      endif DEBUG
+    }
+    if ( selfp -> cycleno != 0 ) {
+       printf( "<cycle %d>" , selfp -> cycleno );
+    }
+}
+
+sortchildren( parentp )
+    nltype     *parentp;
+{
+    arctype    *arcp;
+    arctype    *detachedp;
+    arctype    sorted;
+    arctype    *prevp;
+
+       /*
+        *      unlink children from parent,
+        *      then insertion sort back on to sorted's children.
+        *          *arcp       the arc you have detached and are inserting.
+        *          *detachedp  the rest of the arcs to be sorted.
+        *          sorted      arc list onto which you insertion sort.
+        *          *prevp      arc before the arc you are comparing.
+        */
+    sorted.arc_childlist = 0;
+    for (   arcp = parentp -> children , detachedp = arcp -> arc_childlist ;
+           arcp ;
+           arcp = detachedp , detachedp = detachedp -> arc_childlist ) {
+           /*
+            *  consider *arcp as disconnected
+            *  insert it into sorted
+            */
+       for (   prevp = &sorted ;
+               prevp -> arc_childlist ;
+               prevp = prevp -> arc_childlist ) {
+           if ( arccmp( arcp , prevp -> arc_childlist ) != LESSTHAN ) {
+               break;
+           }
+       }
+       arcp -> arc_childlist = prevp -> arc_childlist;
+       prevp -> arc_childlist = arcp;
+    }
+       /*
+        *      reattach sorted children to parent
+        */
+    parentp -> children = sorted.arc_childlist;
+}
+
+sortparents( childp )
+    nltype     *childp;
+{
+    arctype    *arcp;
+    arctype    *detachedp;
+    arctype    sorted;
+    arctype    *prevp;
+
+       /*
+        *      unlink parents from child,
+        *      then insertion sort back on to sorted's parents.
+        *          *arcp       the arc you have detached and are inserting.
+        *          *detachedp  the rest of the arcs to be sorted.
+        *          sorted      arc list onto which you insertion sort.
+        *          *prevp      arc before the arc you are comparing.
+        */
+    sorted.arc_parentlist = 0;
+    for (   arcp = childp -> parents , detachedp = arcp -> arc_parentlist ;
+           arcp ;
+           arcp = detachedp , detachedp = detachedp -> arc_parentlist ) {
+           /*
+            *  consider *arcp as disconnected
+            *  insert it into sorted
+            */
+       for (   prevp = &sorted ;
+               prevp -> arc_parentlist ;
+               prevp = prevp -> arc_parentlist ) {
+           if ( arccmp( arcp , prevp -> arc_parentlist ) != GREATERTHAN ) {
+               break;
+           }
+       }
+       arcp -> arc_parentlist = prevp -> arc_parentlist;
+       prevp -> arc_parentlist = arcp;
+    }
+       /*
+        *      reattach sorted arcs to child
+        */
+    childp -> parents = sorted.arc_parentlist;
+}
+
+    /*
+     * compare two arcs to/from the same child/parent.
+     * - if one arc is a self arc, it's least.
+     * - if one arc is within a cycle, it's less than.
+     * - if both arcs are within a cycle, compare arc counts.
+     * - if neither arc is within a cycle, compare with
+     *         time + childtime as major key
+     *         arc count as minor key
+     */
+int
+arccmp( thisp , thatp )
+    arctype    *thisp;
+    arctype    *thatp;
+{
+    nltype     *thisparentp = thisp -> arc_parentp;
+    nltype     *thischildp = thisp -> arc_childp;
+    nltype     *thatparentp = thatp -> arc_parentp;
+    nltype     *thatchildp = thatp -> arc_childp;
+    double     thistime;
+    double     thattime;
+
+#   ifdef DEBUG
+       if ( debug & TIMEDEBUG ) {
+           printf( "[arccmp] " );
+           printname( thisparentp );
+           printf( " calls " );
+           printname ( thischildp );
+           printf( " %f + %f %d/%d\n" ,
+                   thisp -> arc_time , thisp -> arc_childtime ,
+                   thisp -> arc_count , thischildp -> ncall );
+           printf( "[arccmp] " );
+           printname( thatparentp );
+           printf( " calls " );
+           printname( thatchildp );
+           printf( " %f + %f %d/%d\n" ,
+                   thatp -> arc_time , thatp -> arc_childtime ,
+                   thatp -> arc_count , thatchildp -> ncall );
+           printf( "\n" );
+       }
+#   endif DEBUG
+    if ( thisparentp == thischildp ) {
+           /* this is a self call */
+       return LESSTHAN;
+    }
+    if ( thatparentp == thatchildp ) {
+           /* that is a self call */
+       return GREATERTHAN;
+    }
+    if ( thisparentp -> cycleno != 0 && thischildp -> cycleno != 0 &&
+       thisparentp -> cycleno == thischildp -> cycleno ) {
+           /* this is a call within a cycle */
+       if ( thatparentp -> cycleno != 0 && thatchildp -> cycleno != 0 &&
+           thatparentp -> cycleno == thatchildp -> cycleno ) {
+               /* that is a call within the cycle, too */
+           if ( thisp -> arc_count < thatp -> arc_count ) {
+               return LESSTHAN;
+           }
+           if ( thisp -> arc_count > thatp -> arc_count ) {
+               return GREATERTHAN;
+           }
+           return EQUALTO;
+       } else {
+               /* that isn't a call within the cycle */
+           return LESSTHAN;
+       }
+    } else {
+           /* this isn't a call within a cycle */
+       if ( thatparentp -> cycleno != 0 && thatchildp -> cycleno != 0 &&
+           thatparentp -> cycleno == thatchildp -> cycleno ) {
+               /* that is a call within a cycle */
+           return GREATERTHAN;
+       } else {
+               /* neither is a call within a cycle */
+           thistime = thisp -> arc_time + thisp -> arc_childtime;
+           thattime = thatp -> arc_time + thatp -> arc_childtime;
+           if ( thistime < thattime )
+               return LESSTHAN;
+           if ( thistime > thattime )
+               return GREATERTHAN;
+           if ( thisp -> arc_count < thatp -> arc_count )
+               return LESSTHAN;
+           if ( thisp -> arc_count > thatp -> arc_count )
+               return GREATERTHAN;
+           return EQUALTO;
+       }
+    }
+}