121963Sdist /* 221963Sdist * Copyright (c) 1983 Regents of the University of California. 334199Sbostic * All rights reserved. 434199Sbostic * 5*42683Sbostic * %sccs.include.redist.c% 621963Sdist */ 721963Sdist 84515Speter #ifndef lint 9*42683Sbostic static char sccsid[] = "@(#)printgprof.c 5.7 (Berkeley) 06/01/90"; 1034199Sbostic #endif /* not lint */ 114515Speter 124562Speter #include "gprof.h" 1337801Sbostic #include "pathnames.h" 144515Speter 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; 4016853Smckusick cfree( sortednlp ); 414753Speter } 424753Speter 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 */ 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 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 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 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 ) { 1514753Speter printf( " %7d" , np -> ncall ); 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 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 } 20116853Smckusick cfree( 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 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 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; 2664515Speter if ( childp == parentp || 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 , 2834515Speter arcp -> arc_count , cycleheadp -> ncall ); 2844515Speter printname( parentp ); 2854515Speter printf( "\n" ); 2864515Speter } 2874515Speter } 2884515Speter } 2894515Speter 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; 3004515Speter if ( childp == parentp || 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 , 3164515Speter arcp -> arc_count , childp -> cyclehead -> ncall ); 3174515Speter printname( childp ); 3184515Speter printf( "\n" ); 3194515Speter } 3204515Speter } 3214515Speter } 3224515Speter 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 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 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 */ 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 , 4444753Speter cyclep -> ncall ); 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 */ 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 , 4664753Speter memberp -> ncall ); 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 */ 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 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 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 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 64116853Smckusick namecmp( npp1 , npp2 ) 64216853Smckusick nltype **npp1, **npp2; 64316853Smckusick { 64416853Smckusick return( strcmp( (*npp1) -> name , (*npp2) -> name ) ); 64516853Smckusick } 64616853Smckusick 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 } 69116853Smckusick cfree( namesortnlp ); 69216853Smckusick } 693