121963Sdist /*
2*62017Sbostic * Copyright (c) 1983, 1993
3*62017Sbostic * The Regents of the University of California. All rights reserved.
434199Sbostic *
542683Sbostic * %sccs.include.redist.c%
621963Sdist */
721963Sdist
84515Speter #ifndef lint
9*62017Sbostic static char sccsid[] = "@(#)printgprof.c 8.1 (Berkeley) 06/06/93";
1034199Sbostic #endif /* not lint */
114515Speter
124562Speter #include "gprof.h"
1337801Sbostic #include "pathnames.h"
144515Speter
printprof()154753Speter printprof()
164753Speter {
174753Speter register nltype *np;
184753Speter nltype **sortednlp;
1933227Sbostic int index, timecmp();
204753Speter
214753Speter actime = 0.0;
2216853Smckusick printf( "\f\n" );
234753Speter flatprofheader();
244753Speter /*
254753Speter * Sort the symbol table in by time
264753Speter */
274753Speter sortednlp = (nltype **) calloc( nname , sizeof(nltype *) );
284753Speter if ( sortednlp == (nltype **) 0 ) {
294753Speter fprintf( stderr , "[printprof] ran out of memory for time sorting\n" );
304753Speter }
314753Speter for ( index = 0 ; index < nname ; index += 1 ) {
324753Speter sortednlp[ index ] = &nl[ index ];
334753Speter }
344753Speter qsort( sortednlp , nname , sizeof(nltype *) , timecmp );
354753Speter for ( index = 0 ; index < nname ; index += 1 ) {
364753Speter np = sortednlp[ index ];
374753Speter flatprofline( np );
384753Speter }
394753Speter actime = 0.0;
4057658Sbostic free( sortednlp );
414753Speter }
424753Speter
timecmp(npp1,npp2)434753Speter timecmp( npp1 , npp2 )
444753Speter nltype **npp1, **npp2;
454753Speter {
464856Speter double timediff;
474856Speter long calldiff;
484753Speter
494856Speter timediff = (*npp2) -> time - (*npp1) -> time;
504856Speter if ( timediff > 0.0 )
514753Speter return 1 ;
524856Speter if ( timediff < 0.0 )
534753Speter return -1;
544856Speter calldiff = (*npp2) -> ncall - (*npp1) -> ncall;
554856Speter if ( calldiff > 0 )
564856Speter return 1;
574856Speter if ( calldiff < 0 )
584856Speter return -1;
594753Speter return( strcmp( (*npp1) -> name , (*npp2) -> name ) );
604753Speter }
614753Speter
624753Speter /*
634753Speter * header for flatprofline
644753Speter */
flatprofheader()654753Speter flatprofheader()
664753Speter {
674753Speter
684854Speter if ( bflag ) {
6937801Sbostic printblurb( _PATH_FLAT_BLURB );
704854Speter }
7116853Smckusick printf( "\ngranularity: each sample hit covers %d byte(s)" ,
7216853Smckusick (long) scale * sizeof(UNIT) );
7316853Smckusick if ( totime > 0.0 ) {
7416853Smckusick printf( " for %.2f%% of %.2f seconds\n\n" ,
7516853Smckusick 100.0/totime , totime / hz );
7616853Smckusick } else {
7716853Smckusick printf( " no time accumulated\n\n" );
7816853Smckusick /*
7916853Smckusick * this doesn't hurt sinc eall the numerators will be zero.
8016853Smckusick */
8116853Smckusick totime = 1.0;
8216853Smckusick }
8316853Smckusick printf( "%5.5s %10.10s %8.8s %8.8s %8.8s %8.8s %-8.8s\n" ,
8416853Smckusick "% " , "cumulative" , "self " , "" , "self " , "total " , "" );
8516853Smckusick printf( "%5.5s %10.10s %8.8s %8.8s %8.8s %8.8s %-8.8s\n" ,
8616853Smckusick "time" , "seconds " , "seconds" , "calls" ,
8716853Smckusick "ms/call" , "ms/call" , "name" );
884753Speter }
894753Speter
flatprofline(np)904753Speter flatprofline( np )
914753Speter register nltype *np;
924753Speter {
934753Speter
944854Speter if ( zflag == 0 && np -> ncall == 0 && np -> time == 0 ) {
954753Speter return;
964753Speter }
974753Speter actime += np -> time;
9816853Smckusick printf( "%5.1f %10.2f %8.2f" ,
9910248Speter 100 * np -> time / totime , actime / hz , np -> time / hz );
1004753Speter if ( np -> ncall != 0 ) {
10116853Smckusick printf( " %8d %8.2f %8.2f " , np -> ncall ,
10216853Smckusick 1000 * np -> time / hz / np -> ncall ,
10316853Smckusick 1000 * ( np -> time + np -> childtime ) / hz / np -> ncall );
1044753Speter } else {
10516853Smckusick printf( " %8.8s %8.8s %8.8s " , "" , "" , "" );
1064753Speter }
10716853Smckusick printname( np );
10816853Smckusick printf( "\n" );
1094753Speter }
1104753Speter
gprofheader()1114753Speter gprofheader()
1124753Speter {
1134854Speter
1144854Speter if ( bflag ) {
11537801Sbostic printblurb( _PATH_CALLG_BLURB );
1164854Speter }
1177172Speter printf( "\ngranularity: each sample hit covers %d byte(s)" ,
1187172Speter (long) scale * sizeof(UNIT) );
1197225Speter if ( printtime > 0.0 ) {
1207225Speter printf( " for %.2f%% of %.2f seconds\n\n" ,
12110248Speter 100.0/printtime , printtime / hz );
1227225Speter } else {
1237225Speter printf( " no time propagated\n\n" );
1247225Speter /*
1257225Speter * this doesn't hurt, since all the numerators will be 0.0
1267225Speter */
1277225Speter printtime = 1.0;
1287225Speter }
1294753Speter printf( "%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s %-8.8s\n" ,
13030799Sbostic "" , "" , "" , "" , "called" , "total" , "parents");
1314753Speter printf( "%-6.6s %5.5s %7.7s %11.11s %7.7s+%-7.7s %-8.8s\t%5.5s\n" ,
1324753Speter "index" , "%time" , "self" , "descendents" ,
1334753Speter "called" , "self" , "name" , "index" );
1344753Speter printf( "%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s %-8.8s\n" ,
13530799Sbostic "" , "" , "" , "" , "called" , "total" , "children");
1364753Speter printf( "\n" );
1374753Speter }
1384753Speter
gprofline(np)1394753Speter gprofline( np )
1404753Speter register nltype *np;
1414753Speter {
1424753Speter char kirkbuffer[ BUFSIZ ];
1434753Speter
1444753Speter sprintf( kirkbuffer , "[%d]" , np -> index );
1454753Speter printf( "%-6.6s %5.1f %7.2f %11.2f" ,
1464753Speter kirkbuffer ,
1477222Speter 100 * ( np -> propself + np -> propchild ) / printtime ,
14810248Speter np -> propself / hz ,
14910248Speter np -> propchild / hz );
1504753Speter if ( ( np -> ncall + np -> selfcalls ) != 0 ) {
15152649Smckusick printf( " %7d" , np -> npropcall );
1524753Speter if ( np -> selfcalls != 0 ) {
1534753Speter printf( "+%-7d " , np -> selfcalls );
1544753Speter } else {
1554753Speter printf( " %7.7s " , "" );
1564753Speter }
1574753Speter } else {
1584753Speter printf( " %7.7s %7.7s " , "" , "" );
1594753Speter }
1604753Speter printname( np );
1614753Speter printf( "\n" );
1624753Speter }
1634753Speter
printgprof(timesortnlp)16416853Smckusick printgprof(timesortnlp)
16516853Smckusick nltype **timesortnlp;
1664515Speter {
1674515Speter int index;
1684515Speter nltype *parentp;
1694515Speter
1704515Speter /*
17116853Smckusick * Print out the structured profiling list
1724515Speter */
1734753Speter gprofheader();
1747129Speter for ( index = 0 ; index < nname + ncycle ; index ++ ) {
1754515Speter parentp = timesortnlp[ index ];
1764854Speter if ( zflag == 0 &&
1774515Speter parentp -> ncall == 0 &&
1784515Speter parentp -> selfcalls == 0 &&
1797222Speter parentp -> propself == 0 &&
1807222Speter parentp -> propchild == 0 ) {
1814515Speter continue;
1824515Speter }
1837172Speter if ( ! parentp -> printflag ) {
1847172Speter continue;
1857172Speter }
1864515Speter if ( parentp -> name == 0 && parentp -> cycleno != 0 ) {
1874515Speter /*
1884515Speter * cycle header
1894515Speter */
1904753Speter printcycle( parentp );
1914753Speter printmembers( parentp );
1924515Speter } else {
1934515Speter printparents( parentp );
1944753Speter gprofline( parentp );
1954515Speter printchildren( parentp );
1964515Speter }
1974515Speter printf( "\n" );
1984753Speter printf( "-----------------------------------------------\n" );
1994753Speter printf( "\n" );
2004515Speter }
20157658Sbostic free( timesortnlp );
2024515Speter }
2034515Speter
2044856Speter /*
2057222Speter * sort by decreasing propagated time
2064856Speter * if times are equal, but one is a cycle header,
2074856Speter * say that's first (e.g. less, i.e. -1).
2084856Speter * if one's name doesn't have an underscore and the other does,
2094856Speter * say the one is first.
2104856Speter * all else being equal, sort by names.
2114856Speter */
2124856Speter int
totalcmp(npp1,npp2)2134856Speter totalcmp( npp1 , npp2 )
2144856Speter nltype **npp1;
2154856Speter nltype **npp2;
2164856Speter {
2174856Speter register nltype *np1 = *npp1;
2184856Speter register nltype *np2 = *npp2;
2194856Speter double diff;
2204856Speter
2217222Speter diff = ( np1 -> propself + np1 -> propchild )
2227222Speter - ( np2 -> propself + np2 -> propchild );
2234856Speter if ( diff < 0.0 )
2244856Speter return 1;
2254856Speter if ( diff > 0.0 )
2264856Speter return -1;
2274856Speter if ( np1 -> name == 0 && np1 -> cycleno != 0 )
2284856Speter return -1;
2294856Speter if ( np2 -> name == 0 && np2 -> cycleno != 0 )
2304856Speter return 1;
2314856Speter if ( np1 -> name == 0 )
2324856Speter return -1;
2334856Speter if ( np2 -> name == 0 )
2344856Speter return 1;
2354856Speter if ( *(np1 -> name) != '_' && *(np2 -> name) == '_' )
2364856Speter return -1;
2374856Speter if ( *(np1 -> name) == '_' && *(np2 -> name) != '_' )
2384856Speter return 1;
2397222Speter if ( np1 -> ncall > np2 -> ncall )
2407222Speter return -1;
2417222Speter if ( np1 -> ncall < np2 -> ncall )
2427222Speter return 1;
2434856Speter return strcmp( np1 -> name , np2 -> name );
2444856Speter }
2454856Speter
printparents(childp)2464515Speter printparents( childp )
2474515Speter nltype *childp;
2484515Speter {
2494515Speter nltype *parentp;
2504515Speter arctype *arcp;
2514515Speter nltype *cycleheadp;
2524515Speter
2534515Speter if ( childp -> cyclehead != 0 ) {
2544515Speter cycleheadp = childp -> cyclehead;
2554515Speter } else {
2564515Speter cycleheadp = childp;
2574515Speter }
2584515Speter if ( childp -> parents == 0 ) {
2594753Speter printf( "%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s <spontaneous>\n" ,
2604515Speter "" , "" , "" , "" , "" , "" );
2614515Speter return;
2624515Speter }
2634515Speter sortparents( childp );
2644515Speter for ( arcp = childp -> parents ; arcp ; arcp = arcp -> arc_parentlist ) {
2654515Speter parentp = arcp -> arc_parentp;
26652649Smckusick if ( childp == parentp || ( arcp -> arc_flags & DEADARC ) ||
2674515Speter ( childp->cycleno != 0 && parentp->cycleno == childp->cycleno ) ) {
2684515Speter /*
2694753Speter * selfcall or call among siblings
2704515Speter */
2714753Speter printf( "%6.6s %5.5s %7.7s %11.11s %7d %7.7s " ,
2724515Speter "" , "" , "" , "" ,
2734515Speter arcp -> arc_count , "" );
2744515Speter printname( parentp );
2754515Speter printf( "\n" );
2764515Speter } else {
2774515Speter /*
2784515Speter * regular parent of child
2794515Speter */
2804753Speter printf( "%6.6s %5.5s %7.2f %11.2f %7d/%-7d " ,
2814753Speter "" , "" ,
28210248Speter arcp -> arc_time / hz , arcp -> arc_childtime / hz ,
28352649Smckusick arcp -> arc_count , cycleheadp -> npropcall );
2844515Speter printname( parentp );
2854515Speter printf( "\n" );
2864515Speter }
2874515Speter }
2884515Speter }
2894515Speter
printchildren(parentp)2904515Speter printchildren( parentp )
2914515Speter nltype *parentp;
2924515Speter {
2934515Speter nltype *childp;
2944515Speter arctype *arcp;
2954515Speter
2964515Speter sortchildren( parentp );
2974515Speter arcp = parentp -> children;
2984515Speter for ( arcp = parentp -> children ; arcp ; arcp = arcp -> arc_childlist ) {
2994515Speter childp = arcp -> arc_childp;
30052649Smckusick if ( childp == parentp || ( arcp -> arc_flags & DEADARC ) ||
3014515Speter ( childp->cycleno != 0 && childp->cycleno == parentp->cycleno ) ) {
3024515Speter /*
3034515Speter * self call or call to sibling
3044515Speter */
3054753Speter printf( "%6.6s %5.5s %7.7s %11.11s %7d %7.7s " ,
3064753Speter "" , "" , "" , "" , arcp -> arc_count , "" );
3074515Speter printname( childp );
3084515Speter printf( "\n" );
3094515Speter } else {
3104515Speter /*
3114515Speter * regular child of parent
3124515Speter */
3134753Speter printf( "%6.6s %5.5s %7.2f %11.2f %7d/%-7d " ,
3144753Speter "" , "" ,
31510248Speter arcp -> arc_time / hz , arcp -> arc_childtime / hz ,
31652649Smckusick arcp -> arc_count , childp -> cyclehead -> npropcall );
3174515Speter printname( childp );
3184515Speter printf( "\n" );
3194515Speter }
3204515Speter }
3214515Speter }
3224515Speter
printname(selfp)3234515Speter printname( selfp )
3244515Speter nltype *selfp;
3254515Speter {
3264515Speter
3274515Speter if ( selfp -> name != 0 ) {
3284753Speter printf( "%s" , selfp -> name );
3294515Speter # ifdef DEBUG
3304515Speter if ( debug & DFNDEBUG ) {
3314515Speter printf( "{%d} " , selfp -> toporder );
3324515Speter }
3337222Speter if ( debug & PROPDEBUG ) {
3347222Speter printf( "%5.2f%% " , selfp -> propfraction );
3357222Speter }
3364515Speter # endif DEBUG
3374515Speter }
3384842Speter if ( selfp -> cycleno != 0 ) {
33916853Smckusick printf( " <cycle %d>" , selfp -> cycleno );
3404842Speter }
3414753Speter if ( selfp -> index != 0 ) {
3427172Speter if ( selfp -> printflag ) {
3437172Speter printf( " [%d]" , selfp -> index );
3447172Speter } else {
3457172Speter printf( " (%d)" , selfp -> index );
3467172Speter }
3474753Speter }
3484515Speter }
3494515Speter
sortchildren(parentp)3504515Speter sortchildren( parentp )
3514515Speter nltype *parentp;
3524515Speter {
3534515Speter arctype *arcp;
3544515Speter arctype *detachedp;
3554515Speter arctype sorted;
3564515Speter arctype *prevp;
3574515Speter
3584515Speter /*
3594515Speter * unlink children from parent,
3604515Speter * then insertion sort back on to sorted's children.
3614515Speter * *arcp the arc you have detached and are inserting.
3624515Speter * *detachedp the rest of the arcs to be sorted.
3634515Speter * sorted arc list onto which you insertion sort.
3644515Speter * *prevp arc before the arc you are comparing.
3654515Speter */
3664515Speter sorted.arc_childlist = 0;
36711798Speter for ( (arcp = parentp -> children)&&(detachedp = arcp -> arc_childlist);
3684515Speter arcp ;
36911798Speter (arcp = detachedp)&&(detachedp = detachedp -> arc_childlist)) {
3704515Speter /*
3714515Speter * consider *arcp as disconnected
3724515Speter * insert it into sorted
3734515Speter */
3744515Speter for ( prevp = &sorted ;
3754515Speter prevp -> arc_childlist ;
3764515Speter prevp = prevp -> arc_childlist ) {
3774515Speter if ( arccmp( arcp , prevp -> arc_childlist ) != LESSTHAN ) {
3784515Speter break;
3794515Speter }
3804515Speter }
3814515Speter arcp -> arc_childlist = prevp -> arc_childlist;
3824515Speter prevp -> arc_childlist = arcp;
3834515Speter }
3844515Speter /*
3854515Speter * reattach sorted children to parent
3864515Speter */
3874515Speter parentp -> children = sorted.arc_childlist;
3884515Speter }
3894515Speter
sortparents(childp)3904515Speter sortparents( childp )
3914515Speter nltype *childp;
3924515Speter {
3934515Speter arctype *arcp;
3944515Speter arctype *detachedp;
3954515Speter arctype sorted;
3964515Speter arctype *prevp;
3974515Speter
3984515Speter /*
3994515Speter * unlink parents from child,
4004515Speter * then insertion sort back on to sorted's parents.
4014515Speter * *arcp the arc you have detached and are inserting.
4024515Speter * *detachedp the rest of the arcs to be sorted.
4034515Speter * sorted arc list onto which you insertion sort.
4044515Speter * *prevp arc before the arc you are comparing.
4054515Speter */
4064515Speter sorted.arc_parentlist = 0;
40711798Speter for ( (arcp = childp -> parents)&&(detachedp = arcp -> arc_parentlist);
4084515Speter arcp ;
40911798Speter (arcp = detachedp)&&(detachedp = detachedp -> arc_parentlist)) {
4104515Speter /*
4114515Speter * consider *arcp as disconnected
4124515Speter * insert it into sorted
4134515Speter */
4144515Speter for ( prevp = &sorted ;
4154515Speter prevp -> arc_parentlist ;
4164515Speter prevp = prevp -> arc_parentlist ) {
4174515Speter if ( arccmp( arcp , prevp -> arc_parentlist ) != GREATERTHAN ) {
4184515Speter break;
4194515Speter }
4204515Speter }
4214515Speter arcp -> arc_parentlist = prevp -> arc_parentlist;
4224515Speter prevp -> arc_parentlist = arcp;
4234515Speter }
4244515Speter /*
4254515Speter * reattach sorted arcs to child
4264515Speter */
4274515Speter childp -> parents = sorted.arc_parentlist;
4284515Speter }
4294515Speter
4304515Speter /*
4314753Speter * print a cycle header
4324753Speter */
printcycle(cyclep)4334753Speter printcycle( cyclep )
4344753Speter nltype *cyclep;
4354753Speter {
4364753Speter char kirkbuffer[ BUFSIZ ];
4374753Speter
4384753Speter sprintf( kirkbuffer , "[%d]" , cyclep -> index );
4394753Speter printf( "%-6.6s %5.1f %7.2f %11.2f %7d" ,
4404753Speter kirkbuffer ,
4417222Speter 100 * ( cyclep -> propself + cyclep -> propchild ) / printtime ,
44210248Speter cyclep -> propself / hz ,
44310248Speter cyclep -> propchild / hz ,
44452649Smckusick cyclep -> npropcall );
4454753Speter if ( cyclep -> selfcalls != 0 ) {
4464753Speter printf( "+%-7d" , cyclep -> selfcalls );
4474753Speter } else {
4484753Speter printf( " %7.7s" , "" );
4494753Speter }
4504753Speter printf( " <cycle %d as a whole>\t[%d]\n" ,
4514753Speter cyclep -> cycleno , cyclep -> index );
4524753Speter }
4534753Speter
4544753Speter /*
4554753Speter * print the members of a cycle
4564753Speter */
printmembers(cyclep)4574753Speter printmembers( cyclep )
4584753Speter nltype *cyclep;
4594753Speter {
4604753Speter nltype *memberp;
4614753Speter
4624753Speter sortmembers( cyclep );
4634753Speter for ( memberp = cyclep -> cnext ; memberp ; memberp = memberp -> cnext ) {
4644753Speter printf( "%6.6s %5.5s %7.2f %11.2f %7d" ,
46510248Speter "" , "" , memberp -> propself / hz , memberp -> propchild / hz ,
46652649Smckusick memberp -> npropcall );
4674753Speter if ( memberp -> selfcalls != 0 ) {
4684753Speter printf( "+%-7d" , memberp -> selfcalls );
4694753Speter } else {
4704753Speter printf( " %7.7s" , "" );
4714753Speter }
4724753Speter printf( " " );
4734753Speter printname( memberp );
4744753Speter printf( "\n" );
4754753Speter }
4764753Speter }
4774753Speter
4784753Speter /*
4794753Speter * sort members of a cycle
4804753Speter */
sortmembers(cyclep)4814753Speter sortmembers( cyclep )
4824753Speter nltype *cyclep;
4834753Speter {
4844753Speter nltype *todo;
4854753Speter nltype *doing;
4864753Speter nltype *prev;
4874753Speter
4884753Speter /*
4894753Speter * detach cycle members from cyclehead,
4904753Speter * and insertion sort them back on.
4914753Speter */
4924753Speter todo = cyclep -> cnext;
4934753Speter cyclep -> cnext = 0;
49411798Speter for ( (doing = todo)&&(todo = doing -> cnext);
4954753Speter doing ;
49611798Speter (doing = todo )&&(todo = doing -> cnext )){
4974753Speter for ( prev = cyclep ; prev -> cnext ; prev = prev -> cnext ) {
4984753Speter if ( membercmp( doing , prev -> cnext ) == GREATERTHAN ) {
4994753Speter break;
5004753Speter }
5014753Speter }
5024753Speter doing -> cnext = prev -> cnext;
5034753Speter prev -> cnext = doing;
5044753Speter }
5054753Speter }
5064753Speter
5074753Speter /*
5087222Speter * major sort is on propself + propchild,
5094753Speter * next is sort on ncalls + selfcalls.
5104753Speter */
5114842Speter int
membercmp(this,that)5124753Speter membercmp( this , that )
5134753Speter nltype *this;
5144753Speter nltype *that;
5154753Speter {
5167222Speter double thistime = this -> propself + this -> propchild;
5177222Speter double thattime = that -> propself + that -> propchild;
5184753Speter long thiscalls = this -> ncall + this -> selfcalls;
5194753Speter long thatcalls = that -> ncall + that -> selfcalls;
5204753Speter
5214753Speter if ( thistime > thattime ) {
5224753Speter return GREATERTHAN;
5234753Speter }
5244753Speter if ( thistime < thattime ) {
5254753Speter return LESSTHAN;
5264753Speter }
5274753Speter if ( thiscalls > thatcalls ) {
5284753Speter return GREATERTHAN;
5294753Speter }
5304753Speter if ( thiscalls < thatcalls ) {
5314753Speter return LESSTHAN;
5324753Speter }
5334753Speter return EQUALTO;
5344753Speter }
5354753Speter /*
5364515Speter * compare two arcs to/from the same child/parent.
5374515Speter * - if one arc is a self arc, it's least.
5384515Speter * - if one arc is within a cycle, it's less than.
5394515Speter * - if both arcs are within a cycle, compare arc counts.
5404515Speter * - if neither arc is within a cycle, compare with
5417222Speter * arc_time + arc_childtime as major key
5424515Speter * arc count as minor key
5434515Speter */
5444515Speter int
arccmp(thisp,thatp)5454515Speter arccmp( thisp , thatp )
5464515Speter arctype *thisp;
5474515Speter arctype *thatp;
5484515Speter {
5494515Speter nltype *thisparentp = thisp -> arc_parentp;
5504515Speter nltype *thischildp = thisp -> arc_childp;
5514515Speter nltype *thatparentp = thatp -> arc_parentp;
5524515Speter nltype *thatchildp = thatp -> arc_childp;
5534515Speter double thistime;
5544515Speter double thattime;
5554515Speter
5564515Speter # ifdef DEBUG
5574515Speter if ( debug & TIMEDEBUG ) {
5584515Speter printf( "[arccmp] " );
5594515Speter printname( thisparentp );
5604515Speter printf( " calls " );
5614515Speter printname ( thischildp );
5624515Speter printf( " %f + %f %d/%d\n" ,
5634515Speter thisp -> arc_time , thisp -> arc_childtime ,
5644515Speter thisp -> arc_count , thischildp -> ncall );
5654515Speter printf( "[arccmp] " );
5664515Speter printname( thatparentp );
5674515Speter printf( " calls " );
5684515Speter printname( thatchildp );
5694515Speter printf( " %f + %f %d/%d\n" ,
5704515Speter thatp -> arc_time , thatp -> arc_childtime ,
5714515Speter thatp -> arc_count , thatchildp -> ncall );
5724515Speter printf( "\n" );
5734515Speter }
5744515Speter # endif DEBUG
5754515Speter if ( thisparentp == thischildp ) {
5764515Speter /* this is a self call */
5774515Speter return LESSTHAN;
5784515Speter }
5794515Speter if ( thatparentp == thatchildp ) {
5804515Speter /* that is a self call */
5814515Speter return GREATERTHAN;
5824515Speter }
5834515Speter if ( thisparentp -> cycleno != 0 && thischildp -> cycleno != 0 &&
5844515Speter thisparentp -> cycleno == thischildp -> cycleno ) {
5854515Speter /* this is a call within a cycle */
5864515Speter if ( thatparentp -> cycleno != 0 && thatchildp -> cycleno != 0 &&
5874515Speter thatparentp -> cycleno == thatchildp -> cycleno ) {
5884515Speter /* that is a call within the cycle, too */
5894515Speter if ( thisp -> arc_count < thatp -> arc_count ) {
5904515Speter return LESSTHAN;
5914515Speter }
5924515Speter if ( thisp -> arc_count > thatp -> arc_count ) {
5934515Speter return GREATERTHAN;
5944515Speter }
5954515Speter return EQUALTO;
5964515Speter } else {
5974515Speter /* that isn't a call within the cycle */
5984515Speter return LESSTHAN;
5994515Speter }
6004515Speter } else {
6014515Speter /* this isn't a call within a cycle */
6024515Speter if ( thatparentp -> cycleno != 0 && thatchildp -> cycleno != 0 &&
6034515Speter thatparentp -> cycleno == thatchildp -> cycleno ) {
6044515Speter /* that is a call within a cycle */
6054515Speter return GREATERTHAN;
6064515Speter } else {
6074515Speter /* neither is a call within a cycle */
6084515Speter thistime = thisp -> arc_time + thisp -> arc_childtime;
6094515Speter thattime = thatp -> arc_time + thatp -> arc_childtime;
6104515Speter if ( thistime < thattime )
6114515Speter return LESSTHAN;
6124515Speter if ( thistime > thattime )
6134515Speter return GREATERTHAN;
6144515Speter if ( thisp -> arc_count < thatp -> arc_count )
6154515Speter return LESSTHAN;
6164515Speter if ( thisp -> arc_count > thatp -> arc_count )
6174515Speter return GREATERTHAN;
6184515Speter return EQUALTO;
6194515Speter }
6204515Speter }
6214515Speter }
6224854Speter
printblurb(blurbname)6234854Speter printblurb( blurbname )
6244854Speter char *blurbname;
6254854Speter {
6264854Speter FILE *blurbfile;
6274854Speter int input;
6284854Speter
62910285Speter blurbfile = fopen( blurbname , "r" );
6304854Speter if ( blurbfile == NULL ) {
63110285Speter perror( blurbname );
6324854Speter return;
6334854Speter }
6344854Speter while ( ( input = getc( blurbfile ) ) != EOF ) {
6354854Speter putchar( input );
6364854Speter }
6374854Speter fclose( blurbfile );
6384854Speter }
63916853Smckusick
64016853Smckusick int
namecmp(npp1,npp2)64116853Smckusick namecmp( npp1 , npp2 )
64216853Smckusick nltype **npp1, **npp2;
64316853Smckusick {
64416853Smckusick return( strcmp( (*npp1) -> name , (*npp2) -> name ) );
64516853Smckusick }
64616853Smckusick
printindex()64716853Smckusick printindex()
64816853Smckusick {
64916853Smckusick nltype **namesortnlp;
65016853Smckusick register nltype *nlp;
65116853Smckusick int index, nnames, todo, i, j;
65216853Smckusick char peterbuffer[ BUFSIZ ];
65316853Smckusick
65416853Smckusick /*
65516853Smckusick * Now, sort regular function name alphbetically
65616853Smckusick * to create an index.
65716853Smckusick */
65816853Smckusick namesortnlp = (nltype **) calloc( nname + ncycle , sizeof(nltype *) );
65916853Smckusick if ( namesortnlp == (nltype **) 0 ) {
66016853Smckusick fprintf( stderr , "%s: ran out of memory for sorting\n" , whoami );
66116853Smckusick }
66216853Smckusick for ( index = 0 , nnames = 0 ; index < nname ; index++ ) {
66316853Smckusick if ( zflag == 0 && nl[index].ncall == 0 && nl[index].time == 0 )
66416853Smckusick continue;
66516853Smckusick namesortnlp[nnames++] = &nl[index];
66616853Smckusick }
66716853Smckusick qsort( namesortnlp , nnames , sizeof(nltype *) , namecmp );
66816853Smckusick for ( index = 1 , todo = nnames ; index <= ncycle ; index++ ) {
66916853Smckusick namesortnlp[todo++] = &cyclenl[index];
67016853Smckusick }
67116853Smckusick printf( "\f\nIndex by function name\n\n" );
67216853Smckusick index = ( todo + 2 ) / 3;
67316853Smckusick for ( i = 0; i < index ; i++ ) {
67416853Smckusick for ( j = i; j < todo ; j += index ) {
67516853Smckusick nlp = namesortnlp[ j ];
67616853Smckusick if ( nlp -> printflag ) {
67716853Smckusick sprintf( peterbuffer , "[%d]" , nlp -> index );
67816853Smckusick } else {
67916853Smckusick sprintf( peterbuffer , "(%d)" , nlp -> index );
68016853Smckusick }
68116853Smckusick if ( j < nnames ) {
68216853Smckusick printf( "%6.6s %-19.19s" , peterbuffer , nlp -> name );
68316853Smckusick } else {
68416853Smckusick printf( "%6.6s " , peterbuffer );
68516853Smckusick sprintf( peterbuffer , "<cycle %d>" , nlp -> cycleno );
68616853Smckusick printf( "%-19.19s" , peterbuffer );
68716853Smckusick }
68816853Smckusick }
68916853Smckusick printf( "\n" );
69016853Smckusick }
69157658Sbostic free( namesortnlp );
69216853Smckusick }
693