+/*
+ * 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
- 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"
return (*npp1) -> toporder - (*npp2) -> toporder;
}
+nltype **
doarcs()
{
- nltype *parentp;
+ nltype *parentp, **timesortnlp;
arctype *arcp;
long index;
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 ) {
- findcalls( parentp , parentp -> value , (parentp+1) -> value );
+ findcall( parentp , parentp -> value , (parentp+1) -> value );
}
}
/*
* 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++ ) {
- if ( parentp -> parents == 0 ) {
+ if ( parentp -> toporder == DFN_NAN ) {
dfn( parentp );
}
}
* 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()
*/
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];
- 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 -> 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 */
int cycle;
nltype *cyclenlp;
nltype *childp;
- arctype *arcp;
- nltype *parentp;
for ( cycle = 1 ; cycle <= ncycle ; cycle += 1 ) {
cyclenlp = &cyclenl[ cycle ];
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
}
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 -> 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 {
/*
}
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 ) {