temp files should be protected; bug report 4.3BSD/usr.bin/186
[unix-history] / usr / src / usr.bin / gprof / arcs.c
index d7b745a..6c135c7 100644 (file)
@@ -1,6 +1,23 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
 #ifndef lint
 #ifndef lint
-    static     char *sccsid = "@(#)arcs.c      1.9 (Berkeley) %G%";
-#endif lint
+static char sccsid[] = "@(#)arcs.c     5.5 (Berkeley) %G%";
+#endif /* not lint */
 
 #include "gprof.h"
 
 
 #include "gprof.h"
 
@@ -68,9 +85,10 @@ topcmp( npp1 , npp2 )
     return (*npp1) -> toporder - (*npp2) -> toporder;
 }
 
     return (*npp1) -> toporder - (*npp2) -> toporder;
 }
 
+nltype **
 doarcs()
 {
 doarcs()
 {
-    nltype     *parentp;
+    nltype     *parentp, **timesortnlp;
     arctype    *arcp;
     long       index;
 
     arctype    *arcp;
     long       index;
 
@@ -93,20 +111,21 @@ doarcs()
        parentp -> propself = 0.0;
        parentp -> propchild = 0.0;
        parentp -> printflag = FALSE;
        parentp -> propself = 0.0;
        parentp -> propchild = 0.0;
        parentp -> printflag = FALSE;
-       parentp -> toporder = 0;
+       parentp -> toporder = DFN_NAN;
        parentp -> cycleno = 0;
        parentp -> cyclehead = parentp;
        parentp -> cnext = 0;
        if ( cflag ) {
        parentp -> cycleno = 0;
        parentp -> cyclehead = parentp;
        parentp -> cnext = 0;
        if ( cflag ) {
-           findcalls( parentp , parentp -> value , (parentp+1) -> value );
+           findcall( parentp , parentp -> value , (parentp+1) -> value );
        }
     }
        /*
         *      topologically order things
        }
     }
        /*
         *      topologically order things
-        *      from each of the roots of the call graph
+        *      if any node is unnumbered,
+        *          number it and any of its descendents.
         */
     for ( parentp = nl ; parentp < npe ; parentp++ ) {
         */
     for ( parentp = nl ; parentp < npe ; parentp++ ) {
-       if ( parentp -> parents == 0 ) {
+       if ( parentp -> toporder == DFN_NAN ) {
            dfn( parentp );
        }
     }
            dfn( parentp );
        }
     }
@@ -149,7 +168,26 @@ doarcs()
         *      propogate children times up to parents.
         */
     dotime();
         *      propogate children times up to parents.
         */
     dotime();
-    printgprof();
+       /*
+        *      Now, sort by propself + propchild.
+        *      sorting both the regular function names
+        *      and cycle headers.
+        */
+    timesortnlp = (nltype **) calloc( nname + ncycle , sizeof(nltype *) );
+    if ( timesortnlp == (nltype **) 0 ) {
+       fprintf( stderr , "%s: ran out of memory for sorting\n" , whoami );
+    }
+    for ( index = 0 ; index < nname ; index++ ) {
+       timesortnlp[index] = &nl[index];
+    }
+    for ( index = 1 ; index <= ncycle ; index++ ) {
+       timesortnlp[nname+index-1] = &cyclenl[index];
+    }
+    qsort( timesortnlp , nname + ncycle , sizeof(nltype *) , totalcmp );
+    for ( index = 0 ; index < nname + ncycle ; index++ ) {
+       timesortnlp[ index ] -> index = index + 1;
+    }
+    return( timesortnlp );
 }
 
 dotime()
 }
 
 dotime()
@@ -283,12 +321,12 @@ cyclelink()
         */
     cycle = 0;
     for ( nlp = nl ; nlp < npe ; nlp++ ) {
         */
     cycle = 0;
     for ( nlp = nl ; nlp < npe ; nlp++ ) {
-       if ( nlp -> cyclehead != nlp || nlp -> cnext == 0 ) {
+       if ( !( nlp -> cyclehead == nlp && nlp -> cnext != 0 ) ) {
            continue;
        }
        cycle += 1;
        cyclenlp = &cyclenl[cycle];
            continue;
        }
        cycle += 1;
        cyclenlp = &cyclenl[cycle];
-        cyclenlp -> name = "";         /* the name */
+        cyclenlp -> name = 0;          /* the name */
         cyclenlp -> value = 0;         /* the pc entry point */
         cyclenlp -> time = 0.0;                /* ticks in this routine */
         cyclenlp -> childtime = 0.0;   /* cumulative ticks in children */
         cyclenlp -> value = 0;         /* the pc entry point */
         cyclenlp -> time = 0.0;                /* ticks in this routine */
         cyclenlp -> childtime = 0.0;   /* cumulative ticks in children */
@@ -299,7 +337,7 @@ cyclelink()
        cyclenlp -> propchild = 0.0;    /* how much child time propagates */
        cyclenlp -> printflag = TRUE;   /* should this be printed? */
        cyclenlp -> index = 0;          /* index in the graph list */
        cyclenlp -> propchild = 0.0;    /* how much child time propagates */
        cyclenlp -> printflag = TRUE;   /* should this be printed? */
        cyclenlp -> index = 0;          /* index in the graph list */
-       cyclenlp -> toporder = 0;       /* graph call chain top-sort order */
+       cyclenlp -> toporder = DFN_NAN; /* graph call chain top-sort order */
        cyclenlp -> cycleno = cycle;    /* internal number of cycle on */
        cyclenlp -> cyclehead = cyclenlp;       /* pointer to head of cycle */
        cyclenlp -> cnext = nlp;        /* pointer to next member of cycle */
        cyclenlp -> cycleno = cycle;    /* internal number of cycle on */
        cyclenlp -> cyclehead = cyclenlp;       /* pointer to head of cycle */
        cyclenlp -> cnext = nlp;        /* pointer to next member of cycle */
@@ -343,8 +381,6 @@ cycletime()
     int                        cycle;
     nltype             *cyclenlp;
     nltype             *childp;
     int                        cycle;
     nltype             *cyclenlp;
     nltype             *childp;
-    arctype            *arcp;
-    nltype             *parentp;
 
     for ( cycle = 1 ; cycle <= ncycle ; cycle += 1 ) {
        cyclenlp = &cyclenl[ cycle ];
 
     for ( cycle = 1 ; cycle <= ncycle ; cycle += 1 ) {
        cyclenlp = &cyclenl[ cycle ];
@@ -449,8 +485,8 @@ doflags()
                printname( childp );
                printf( " ends up with printflag %d and propfraction %f\n" ,
                        childp -> printflag , childp -> propfraction );
                printname( childp );
                printf( " ends up with printflag %d and propfraction %f\n" ,
                        childp -> printflag , childp -> propfraction );
-               printf( "time %f propself %f\n" ,
-                       childp -> time , childp -> propself );
+               printf( "time %f propself %f printtime %f\n" ,
+                       childp -> time , childp -> propself , printtime );
            }
 #      endif DEBUG
     }
            }
 #      endif DEBUG
     }
@@ -480,10 +516,20 @@ inheritflags( childp )
        childp -> propfraction = 0.0;
        for (arcp = childp -> parents ; arcp ; arcp = arcp -> arc_parentlist) {
            parentp = arcp -> arc_parentp;
        childp -> propfraction = 0.0;
        for (arcp = childp -> parents ; arcp ; arcp = arcp -> arc_parentlist) {
            parentp = arcp -> arc_parentp;
+           if ( childp == parentp ) {
+               continue;
+           }
            childp -> printflag |= parentp -> printflag;
            childp -> printflag |= parentp -> printflag;
-           childp -> propfraction += parentp -> propfraction
-                                       * ( ( (double) arcp -> arc_count )
-                                         / ( (double) childp -> ncall ) );
+               /*
+                *      if the child was never actually called
+                *      (e.g. this arc is static (and all others are, too))
+                *      no time propagates along this arc.
+                */
+           if ( childp -> ncall ) {
+               childp -> propfraction += parentp -> propfraction
+                                           * ( ( (double) arcp -> arc_count )
+                                             / ( (double) childp -> ncall ) );
+           }
        }
     } else {
            /*
        }
     } else {
            /*
@@ -499,9 +545,16 @@ inheritflags( childp )
                }
                parentp = arcp -> arc_parentp;
                headp -> printflag |= parentp -> printflag;
                }
                parentp = arcp -> arc_parentp;
                headp -> printflag |= parentp -> printflag;
-               headp -> propfraction += parentp -> propfraction
-                                       * ( ( (double) arcp -> arc_count )
-                                         / ( (double) headp -> ncall ) );
+                   /*
+                    *  if the cycle was never actually called
+                    *  (e.g. this arc is static (and all others are, too))
+                    *  no time propagates along this arc.
+                    */
+               if ( headp -> ncall ) {
+                   headp -> propfraction += parentp -> propfraction
+                                           * ( ( (double) arcp -> arc_count )
+                                             / ( (double) headp -> ncall ) );
+               }
            }
        }
        for ( memp = headp ; memp ; memp = memp -> cnext ) {
            }
        }
        for ( memp = headp ; memp ; memp = memp -> cnext ) {