14515Speter #ifndef lint 2*16853Smckusick static char *sccsid = "@(#)printgprof.c 1.15 (Berkeley) 08/07/84"; 34515Speter #endif lint 44515Speter 54562Speter #include "gprof.h" 64515Speter 74753Speter printprof() 84753Speter { 94753Speter register nltype *np; 104753Speter nltype **sortednlp; 114753Speter int index; 124753Speter 134753Speter actime = 0.0; 14*16853Smckusick printf( "\f\n" ); 154753Speter flatprofheader(); 164753Speter /* 174753Speter * Sort the symbol table in by time 184753Speter */ 194753Speter sortednlp = (nltype **) calloc( nname , sizeof(nltype *) ); 204753Speter if ( sortednlp == (nltype **) 0 ) { 214753Speter fprintf( stderr , "[printprof] ran out of memory for time sorting\n" ); 224753Speter } 234753Speter for ( index = 0 ; index < nname ; index += 1 ) { 244753Speter sortednlp[ index ] = &nl[ index ]; 254753Speter } 264753Speter qsort( sortednlp , nname , sizeof(nltype *) , timecmp ); 274753Speter for ( index = 0 ; index < nname ; index += 1 ) { 284753Speter np = sortednlp[ index ]; 294753Speter flatprofline( np ); 304753Speter } 314753Speter actime = 0.0; 32*16853Smckusick cfree( sortednlp ); 334753Speter } 344753Speter 354753Speter timecmp( npp1 , npp2 ) 364753Speter nltype **npp1, **npp2; 374753Speter { 384856Speter double timediff; 394856Speter long calldiff; 404753Speter 414856Speter timediff = (*npp2) -> time - (*npp1) -> time; 424856Speter if ( timediff > 0.0 ) 434753Speter return 1 ; 444856Speter if ( timediff < 0.0 ) 454753Speter return -1; 464856Speter calldiff = (*npp2) -> ncall - (*npp1) -> ncall; 474856Speter if ( calldiff > 0 ) 484856Speter return 1; 494856Speter if ( calldiff < 0 ) 504856Speter return -1; 514753Speter return( strcmp( (*npp1) -> name , (*npp2) -> name ) ); 524753Speter } 534753Speter 544753Speter /* 554753Speter * header for flatprofline 564753Speter */ 574753Speter flatprofheader() 584753Speter { 594753Speter 604854Speter if ( bflag ) { 6110285Speter printblurb( FLAT_BLURB ); 624854Speter } 63*16853Smckusick printf( "\ngranularity: each sample hit covers %d byte(s)" , 64*16853Smckusick (long) scale * sizeof(UNIT) ); 65*16853Smckusick if ( totime > 0.0 ) { 66*16853Smckusick printf( " for %.2f%% of %.2f seconds\n\n" , 67*16853Smckusick 100.0/totime , totime / hz ); 68*16853Smckusick } else { 69*16853Smckusick printf( " no time accumulated\n\n" ); 70*16853Smckusick /* 71*16853Smckusick * this doesn't hurt sinc eall the numerators will be zero. 72*16853Smckusick */ 73*16853Smckusick totime = 1.0; 74*16853Smckusick } 75*16853Smckusick printf( "%5.5s %10.10s %8.8s %8.8s %8.8s %8.8s %-8.8s\n" , 76*16853Smckusick "% " , "cumulative" , "self " , "" , "self " , "total " , "" ); 77*16853Smckusick printf( "%5.5s %10.10s %8.8s %8.8s %8.8s %8.8s %-8.8s\n" , 78*16853Smckusick "time" , "seconds " , "seconds" , "calls" , 79*16853Smckusick "ms/call" , "ms/call" , "name" ); 804753Speter } 814753Speter 824753Speter flatprofline( np ) 834753Speter register nltype *np; 844753Speter { 854753Speter 864854Speter if ( zflag == 0 && np -> ncall == 0 && np -> time == 0 ) { 874753Speter return; 884753Speter } 894753Speter actime += np -> time; 90*16853Smckusick printf( "%5.1f %10.2f %8.2f" , 9110248Speter 100 * np -> time / totime , actime / hz , np -> time / hz ); 924753Speter if ( np -> ncall != 0 ) { 93*16853Smckusick printf( " %8d %8.2f %8.2f " , np -> ncall , 94*16853Smckusick 1000 * np -> time / hz / np -> ncall , 95*16853Smckusick 1000 * ( np -> time + np -> childtime ) / hz / np -> ncall ); 964753Speter } else { 97*16853Smckusick printf( " %8.8s %8.8s %8.8s " , "" , "" , "" ); 984753Speter } 99*16853Smckusick printname( np ); 100*16853Smckusick printf( "\n" ); 1014753Speter } 1024753Speter 1034753Speter gprofheader() 1044753Speter { 1054854Speter 1064854Speter if ( bflag ) { 10710285Speter printblurb( CALLG_BLURB ); 1084854Speter } 1097172Speter printf( "\ngranularity: each sample hit covers %d byte(s)" , 1107172Speter (long) scale * sizeof(UNIT) ); 1117225Speter if ( printtime > 0.0 ) { 1127225Speter printf( " for %.2f%% of %.2f seconds\n\n" , 11310248Speter 100.0/printtime , printtime / hz ); 1147225Speter } else { 1157225Speter printf( " no time propagated\n\n" ); 1167225Speter /* 1177225Speter * this doesn't hurt, since all the numerators will be 0.0 1187225Speter */ 1197225Speter printtime = 1.0; 1207225Speter } 1214753Speter printf( "%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s %-8.8s\n" , 1224753Speter "" , "" , "" , "" , "called" , "total" , "parents" , "" ); 1234753Speter printf( "%-6.6s %5.5s %7.7s %11.11s %7.7s+%-7.7s %-8.8s\t%5.5s\n" , 1244753Speter "index" , "%time" , "self" , "descendents" , 1254753Speter "called" , "self" , "name" , "index" ); 1264753Speter printf( "%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s %-8.8s\n" , 1274753Speter "" , "" , "" , "" , "called" , "total" , "children" , "" ); 1284753Speter printf( "\n" ); 1294753Speter } 1304753Speter 1314753Speter gprofline( np ) 1324753Speter register nltype *np; 1334753Speter { 1344753Speter char kirkbuffer[ BUFSIZ ]; 1354753Speter 1364753Speter sprintf( kirkbuffer , "[%d]" , np -> index ); 1374753Speter printf( "%-6.6s %5.1f %7.2f %11.2f" , 1384753Speter kirkbuffer , 1397222Speter 100 * ( np -> propself + np -> propchild ) / printtime , 14010248Speter np -> propself / hz , 14110248Speter np -> propchild / hz ); 1424753Speter if ( ( np -> ncall + np -> selfcalls ) != 0 ) { 1434753Speter printf( " %7d" , np -> ncall ); 1444753Speter if ( np -> selfcalls != 0 ) { 1454753Speter printf( "+%-7d " , np -> selfcalls ); 1464753Speter } else { 1474753Speter printf( " %7.7s " , "" ); 1484753Speter } 1494753Speter } else { 1504753Speter printf( " %7.7s %7.7s " , "" , "" ); 1514753Speter } 1524753Speter printname( np ); 1534753Speter printf( "\n" ); 1544753Speter } 1554753Speter 156*16853Smckusick printgprof(timesortnlp) 157*16853Smckusick nltype **timesortnlp; 1584515Speter { 1594515Speter int index; 1604515Speter nltype *parentp; 1614515Speter 1624515Speter /* 163*16853Smckusick * Print out the structured profiling list 1644515Speter */ 1654753Speter gprofheader(); 1667129Speter for ( index = 0 ; index < nname + ncycle ; index ++ ) { 1674515Speter parentp = timesortnlp[ index ]; 1684854Speter if ( zflag == 0 && 1694515Speter parentp -> ncall == 0 && 1704515Speter parentp -> selfcalls == 0 && 1717222Speter parentp -> propself == 0 && 1727222Speter parentp -> propchild == 0 ) { 1734515Speter continue; 1744515Speter } 1757172Speter if ( ! parentp -> printflag ) { 1767172Speter continue; 1777172Speter } 1784515Speter if ( parentp -> name == 0 && parentp -> cycleno != 0 ) { 1794515Speter /* 1804515Speter * cycle header 1814515Speter */ 1824753Speter printcycle( parentp ); 1834753Speter printmembers( parentp ); 1844515Speter } else { 1854515Speter printparents( parentp ); 1864753Speter gprofline( parentp ); 1874515Speter printchildren( parentp ); 1884515Speter } 1894515Speter printf( "\n" ); 1904753Speter printf( "-----------------------------------------------\n" ); 1914753Speter printf( "\n" ); 1924515Speter } 193*16853Smckusick cfree( timesortnlp ); 1944515Speter } 1954515Speter 1964856Speter /* 1977222Speter * sort by decreasing propagated time 1984856Speter * if times are equal, but one is a cycle header, 1994856Speter * say that's first (e.g. less, i.e. -1). 2004856Speter * if one's name doesn't have an underscore and the other does, 2014856Speter * say the one is first. 2024856Speter * all else being equal, sort by names. 2034856Speter */ 2044856Speter int 2054856Speter totalcmp( npp1 , npp2 ) 2064856Speter nltype **npp1; 2074856Speter nltype **npp2; 2084856Speter { 2094856Speter register nltype *np1 = *npp1; 2104856Speter register nltype *np2 = *npp2; 2114856Speter double diff; 2124856Speter 2137222Speter diff = ( np1 -> propself + np1 -> propchild ) 2147222Speter - ( np2 -> propself + np2 -> propchild ); 2154856Speter if ( diff < 0.0 ) 2164856Speter return 1; 2174856Speter if ( diff > 0.0 ) 2184856Speter return -1; 2194856Speter if ( np1 -> name == 0 && np1 -> cycleno != 0 ) 2204856Speter return -1; 2214856Speter if ( np2 -> name == 0 && np2 -> cycleno != 0 ) 2224856Speter return 1; 2234856Speter if ( np1 -> name == 0 ) 2244856Speter return -1; 2254856Speter if ( np2 -> name == 0 ) 2264856Speter return 1; 2274856Speter if ( *(np1 -> name) != '_' && *(np2 -> name) == '_' ) 2284856Speter return -1; 2294856Speter if ( *(np1 -> name) == '_' && *(np2 -> name) != '_' ) 2304856Speter return 1; 2317222Speter if ( np1 -> ncall > np2 -> ncall ) 2327222Speter return -1; 2337222Speter if ( np1 -> ncall < np2 -> ncall ) 2347222Speter return 1; 2354856Speter return strcmp( np1 -> name , np2 -> name ); 2364856Speter } 2374856Speter 2384515Speter printparents( childp ) 2394515Speter nltype *childp; 2404515Speter { 2414515Speter nltype *parentp; 2424515Speter arctype *arcp; 2434515Speter nltype *cycleheadp; 2444515Speter 2454515Speter if ( childp -> cyclehead != 0 ) { 2464515Speter cycleheadp = childp -> cyclehead; 2474515Speter } else { 2484515Speter cycleheadp = childp; 2494515Speter } 2504515Speter if ( childp -> parents == 0 ) { 2514753Speter printf( "%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s <spontaneous>\n" , 2524515Speter "" , "" , "" , "" , "" , "" ); 2534515Speter return; 2544515Speter } 2554515Speter sortparents( childp ); 2564515Speter for ( arcp = childp -> parents ; arcp ; arcp = arcp -> arc_parentlist ) { 2574515Speter parentp = arcp -> arc_parentp; 2584515Speter if ( childp == parentp || 2594515Speter ( childp->cycleno != 0 && parentp->cycleno == childp->cycleno ) ) { 2604515Speter /* 2614753Speter * selfcall or call among siblings 2624515Speter */ 2634753Speter printf( "%6.6s %5.5s %7.7s %11.11s %7d %7.7s " , 2644515Speter "" , "" , "" , "" , 2654515Speter arcp -> arc_count , "" ); 2664515Speter printname( parentp ); 2674515Speter printf( "\n" ); 2684515Speter } else { 2694515Speter /* 2704515Speter * regular parent of child 2714515Speter */ 2724753Speter printf( "%6.6s %5.5s %7.2f %11.2f %7d/%-7d " , 2734753Speter "" , "" , 27410248Speter arcp -> arc_time / hz , arcp -> arc_childtime / hz , 2754515Speter arcp -> arc_count , cycleheadp -> ncall ); 2764515Speter printname( parentp ); 2774515Speter printf( "\n" ); 2784515Speter } 2794515Speter } 2804515Speter } 2814515Speter 2824515Speter printchildren( parentp ) 2834515Speter nltype *parentp; 2844515Speter { 2854515Speter nltype *childp; 2864515Speter arctype *arcp; 2874515Speter 2884515Speter sortchildren( parentp ); 2894515Speter arcp = parentp -> children; 2904515Speter for ( arcp = parentp -> children ; arcp ; arcp = arcp -> arc_childlist ) { 2914515Speter childp = arcp -> arc_childp; 2924515Speter if ( childp == parentp || 2934515Speter ( childp->cycleno != 0 && childp->cycleno == parentp->cycleno ) ) { 2944515Speter /* 2954515Speter * self call or call to sibling 2964515Speter */ 2974753Speter printf( "%6.6s %5.5s %7.7s %11.11s %7d %7.7s " , 2984753Speter "" , "" , "" , "" , arcp -> arc_count , "" ); 2994515Speter printname( childp ); 3004515Speter printf( "\n" ); 3014515Speter } else { 3024515Speter /* 3034515Speter * regular child of parent 3044515Speter */ 3054753Speter printf( "%6.6s %5.5s %7.2f %11.2f %7d/%-7d " , 3064753Speter "" , "" , 30710248Speter arcp -> arc_time / hz , arcp -> arc_childtime / hz , 3084515Speter arcp -> arc_count , childp -> cyclehead -> ncall ); 3094515Speter printname( childp ); 3104515Speter printf( "\n" ); 3114515Speter } 3124515Speter } 3134515Speter } 3144515Speter 3154515Speter printname( selfp ) 3164515Speter nltype *selfp; 3174515Speter { 3184515Speter 3194515Speter if ( selfp -> name != 0 ) { 3204753Speter printf( "%s" , selfp -> name ); 3214515Speter # ifdef DEBUG 3224515Speter if ( debug & DFNDEBUG ) { 3234515Speter printf( "{%d} " , selfp -> toporder ); 3244515Speter } 3257222Speter if ( debug & PROPDEBUG ) { 3267222Speter printf( "%5.2f%% " , selfp -> propfraction ); 3277222Speter } 3284515Speter # endif DEBUG 3294515Speter } 3304842Speter if ( selfp -> cycleno != 0 ) { 331*16853Smckusick printf( " <cycle %d>" , selfp -> cycleno ); 3324842Speter } 3334753Speter if ( selfp -> index != 0 ) { 3347172Speter if ( selfp -> printflag ) { 3357172Speter printf( " [%d]" , selfp -> index ); 3367172Speter } else { 3377172Speter printf( " (%d)" , selfp -> index ); 3387172Speter } 3394753Speter } 3404515Speter } 3414515Speter 3424515Speter sortchildren( parentp ) 3434515Speter nltype *parentp; 3444515Speter { 3454515Speter arctype *arcp; 3464515Speter arctype *detachedp; 3474515Speter arctype sorted; 3484515Speter arctype *prevp; 3494515Speter 3504515Speter /* 3514515Speter * unlink children from parent, 3524515Speter * then insertion sort back on to sorted's children. 3534515Speter * *arcp the arc you have detached and are inserting. 3544515Speter * *detachedp the rest of the arcs to be sorted. 3554515Speter * sorted arc list onto which you insertion sort. 3564515Speter * *prevp arc before the arc you are comparing. 3574515Speter */ 3584515Speter sorted.arc_childlist = 0; 35911798Speter for ( (arcp = parentp -> children)&&(detachedp = arcp -> arc_childlist); 3604515Speter arcp ; 36111798Speter (arcp = detachedp)&&(detachedp = detachedp -> arc_childlist)) { 3624515Speter /* 3634515Speter * consider *arcp as disconnected 3644515Speter * insert it into sorted 3654515Speter */ 3664515Speter for ( prevp = &sorted ; 3674515Speter prevp -> arc_childlist ; 3684515Speter prevp = prevp -> arc_childlist ) { 3694515Speter if ( arccmp( arcp , prevp -> arc_childlist ) != LESSTHAN ) { 3704515Speter break; 3714515Speter } 3724515Speter } 3734515Speter arcp -> arc_childlist = prevp -> arc_childlist; 3744515Speter prevp -> arc_childlist = arcp; 3754515Speter } 3764515Speter /* 3774515Speter * reattach sorted children to parent 3784515Speter */ 3794515Speter parentp -> children = sorted.arc_childlist; 3804515Speter } 3814515Speter 3824515Speter sortparents( childp ) 3834515Speter nltype *childp; 3844515Speter { 3854515Speter arctype *arcp; 3864515Speter arctype *detachedp; 3874515Speter arctype sorted; 3884515Speter arctype *prevp; 3894515Speter 3904515Speter /* 3914515Speter * unlink parents from child, 3924515Speter * then insertion sort back on to sorted's parents. 3934515Speter * *arcp the arc you have detached and are inserting. 3944515Speter * *detachedp the rest of the arcs to be sorted. 3954515Speter * sorted arc list onto which you insertion sort. 3964515Speter * *prevp arc before the arc you are comparing. 3974515Speter */ 3984515Speter sorted.arc_parentlist = 0; 39911798Speter for ( (arcp = childp -> parents)&&(detachedp = arcp -> arc_parentlist); 4004515Speter arcp ; 40111798Speter (arcp = detachedp)&&(detachedp = detachedp -> arc_parentlist)) { 4024515Speter /* 4034515Speter * consider *arcp as disconnected 4044515Speter * insert it into sorted 4054515Speter */ 4064515Speter for ( prevp = &sorted ; 4074515Speter prevp -> arc_parentlist ; 4084515Speter prevp = prevp -> arc_parentlist ) { 4094515Speter if ( arccmp( arcp , prevp -> arc_parentlist ) != GREATERTHAN ) { 4104515Speter break; 4114515Speter } 4124515Speter } 4134515Speter arcp -> arc_parentlist = prevp -> arc_parentlist; 4144515Speter prevp -> arc_parentlist = arcp; 4154515Speter } 4164515Speter /* 4174515Speter * reattach sorted arcs to child 4184515Speter */ 4194515Speter childp -> parents = sorted.arc_parentlist; 4204515Speter } 4214515Speter 4224515Speter /* 4234753Speter * print a cycle header 4244753Speter */ 4254753Speter printcycle( cyclep ) 4264753Speter nltype *cyclep; 4274753Speter { 4284753Speter char kirkbuffer[ BUFSIZ ]; 4294753Speter 4304753Speter sprintf( kirkbuffer , "[%d]" , cyclep -> index ); 4314753Speter printf( "%-6.6s %5.1f %7.2f %11.2f %7d" , 4324753Speter kirkbuffer , 4337222Speter 100 * ( cyclep -> propself + cyclep -> propchild ) / printtime , 43410248Speter cyclep -> propself / hz , 43510248Speter cyclep -> propchild / hz , 4364753Speter cyclep -> ncall ); 4374753Speter if ( cyclep -> selfcalls != 0 ) { 4384753Speter printf( "+%-7d" , cyclep -> selfcalls ); 4394753Speter } else { 4404753Speter printf( " %7.7s" , "" ); 4414753Speter } 4424753Speter printf( " <cycle %d as a whole>\t[%d]\n" , 4434753Speter cyclep -> cycleno , cyclep -> index ); 4444753Speter } 4454753Speter 4464753Speter /* 4474753Speter * print the members of a cycle 4484753Speter */ 4494753Speter printmembers( cyclep ) 4504753Speter nltype *cyclep; 4514753Speter { 4524753Speter nltype *memberp; 4534753Speter 4544753Speter sortmembers( cyclep ); 4554753Speter for ( memberp = cyclep -> cnext ; memberp ; memberp = memberp -> cnext ) { 4564753Speter printf( "%6.6s %5.5s %7.2f %11.2f %7d" , 45710248Speter "" , "" , memberp -> propself / hz , memberp -> propchild / hz , 4584753Speter memberp -> ncall ); 4594753Speter if ( memberp -> selfcalls != 0 ) { 4604753Speter printf( "+%-7d" , memberp -> selfcalls ); 4614753Speter } else { 4624753Speter printf( " %7.7s" , "" ); 4634753Speter } 4644753Speter printf( " " ); 4654753Speter printname( memberp ); 4664753Speter printf( "\n" ); 4674753Speter } 4684753Speter } 4694753Speter 4704753Speter /* 4714753Speter * sort members of a cycle 4724753Speter */ 4734753Speter sortmembers( cyclep ) 4744753Speter nltype *cyclep; 4754753Speter { 4764753Speter nltype *todo; 4774753Speter nltype *doing; 4784753Speter nltype *prev; 4794753Speter 4804753Speter /* 4814753Speter * detach cycle members from cyclehead, 4824753Speter * and insertion sort them back on. 4834753Speter */ 4844753Speter todo = cyclep -> cnext; 4854753Speter cyclep -> cnext = 0; 48611798Speter for ( (doing = todo)&&(todo = doing -> cnext); 4874753Speter doing ; 48811798Speter (doing = todo )&&(todo = doing -> cnext )){ 4894753Speter for ( prev = cyclep ; prev -> cnext ; prev = prev -> cnext ) { 4904753Speter if ( membercmp( doing , prev -> cnext ) == GREATERTHAN ) { 4914753Speter break; 4924753Speter } 4934753Speter } 4944753Speter doing -> cnext = prev -> cnext; 4954753Speter prev -> cnext = doing; 4964753Speter } 4974753Speter } 4984753Speter 4994753Speter /* 5007222Speter * major sort is on propself + propchild, 5014753Speter * next is sort on ncalls + selfcalls. 5024753Speter */ 5034842Speter int 5044753Speter membercmp( this , that ) 5054753Speter nltype *this; 5064753Speter nltype *that; 5074753Speter { 5087222Speter double thistime = this -> propself + this -> propchild; 5097222Speter double thattime = that -> propself + that -> propchild; 5104753Speter long thiscalls = this -> ncall + this -> selfcalls; 5114753Speter long thatcalls = that -> ncall + that -> selfcalls; 5124753Speter 5134753Speter if ( thistime > thattime ) { 5144753Speter return GREATERTHAN; 5154753Speter } 5164753Speter if ( thistime < thattime ) { 5174753Speter return LESSTHAN; 5184753Speter } 5194753Speter if ( thiscalls > thatcalls ) { 5204753Speter return GREATERTHAN; 5214753Speter } 5224753Speter if ( thiscalls < thatcalls ) { 5234753Speter return LESSTHAN; 5244753Speter } 5254753Speter return EQUALTO; 5264753Speter } 5274753Speter /* 5284515Speter * compare two arcs to/from the same child/parent. 5294515Speter * - if one arc is a self arc, it's least. 5304515Speter * - if one arc is within a cycle, it's less than. 5314515Speter * - if both arcs are within a cycle, compare arc counts. 5324515Speter * - if neither arc is within a cycle, compare with 5337222Speter * arc_time + arc_childtime as major key 5344515Speter * arc count as minor key 5354515Speter */ 5364515Speter int 5374515Speter arccmp( thisp , thatp ) 5384515Speter arctype *thisp; 5394515Speter arctype *thatp; 5404515Speter { 5414515Speter nltype *thisparentp = thisp -> arc_parentp; 5424515Speter nltype *thischildp = thisp -> arc_childp; 5434515Speter nltype *thatparentp = thatp -> arc_parentp; 5444515Speter nltype *thatchildp = thatp -> arc_childp; 5454515Speter double thistime; 5464515Speter double thattime; 5474515Speter 5484515Speter # ifdef DEBUG 5494515Speter if ( debug & TIMEDEBUG ) { 5504515Speter printf( "[arccmp] " ); 5514515Speter printname( thisparentp ); 5524515Speter printf( " calls " ); 5534515Speter printname ( thischildp ); 5544515Speter printf( " %f + %f %d/%d\n" , 5554515Speter thisp -> arc_time , thisp -> arc_childtime , 5564515Speter thisp -> arc_count , thischildp -> ncall ); 5574515Speter printf( "[arccmp] " ); 5584515Speter printname( thatparentp ); 5594515Speter printf( " calls " ); 5604515Speter printname( thatchildp ); 5614515Speter printf( " %f + %f %d/%d\n" , 5624515Speter thatp -> arc_time , thatp -> arc_childtime , 5634515Speter thatp -> arc_count , thatchildp -> ncall ); 5644515Speter printf( "\n" ); 5654515Speter } 5664515Speter # endif DEBUG 5674515Speter if ( thisparentp == thischildp ) { 5684515Speter /* this is a self call */ 5694515Speter return LESSTHAN; 5704515Speter } 5714515Speter if ( thatparentp == thatchildp ) { 5724515Speter /* that is a self call */ 5734515Speter return GREATERTHAN; 5744515Speter } 5754515Speter if ( thisparentp -> cycleno != 0 && thischildp -> cycleno != 0 && 5764515Speter thisparentp -> cycleno == thischildp -> cycleno ) { 5774515Speter /* this is a call within a cycle */ 5784515Speter if ( thatparentp -> cycleno != 0 && thatchildp -> cycleno != 0 && 5794515Speter thatparentp -> cycleno == thatchildp -> cycleno ) { 5804515Speter /* that is a call within the cycle, too */ 5814515Speter if ( thisp -> arc_count < thatp -> arc_count ) { 5824515Speter return LESSTHAN; 5834515Speter } 5844515Speter if ( thisp -> arc_count > thatp -> arc_count ) { 5854515Speter return GREATERTHAN; 5864515Speter } 5874515Speter return EQUALTO; 5884515Speter } else { 5894515Speter /* that isn't a call within the cycle */ 5904515Speter return LESSTHAN; 5914515Speter } 5924515Speter } else { 5934515Speter /* this isn't a call within a cycle */ 5944515Speter if ( thatparentp -> cycleno != 0 && thatchildp -> cycleno != 0 && 5954515Speter thatparentp -> cycleno == thatchildp -> cycleno ) { 5964515Speter /* that is a call within a cycle */ 5974515Speter return GREATERTHAN; 5984515Speter } else { 5994515Speter /* neither is a call within a cycle */ 6004515Speter thistime = thisp -> arc_time + thisp -> arc_childtime; 6014515Speter thattime = thatp -> arc_time + thatp -> arc_childtime; 6024515Speter if ( thistime < thattime ) 6034515Speter return LESSTHAN; 6044515Speter if ( thistime > thattime ) 6054515Speter return GREATERTHAN; 6064515Speter if ( thisp -> arc_count < thatp -> arc_count ) 6074515Speter return LESSTHAN; 6084515Speter if ( thisp -> arc_count > thatp -> arc_count ) 6094515Speter return GREATERTHAN; 6104515Speter return EQUALTO; 6114515Speter } 6124515Speter } 6134515Speter } 6144854Speter 6154854Speter printblurb( blurbname ) 6164854Speter char *blurbname; 6174854Speter { 6184854Speter FILE *blurbfile; 6194854Speter int input; 6204854Speter 62110285Speter blurbfile = fopen( blurbname , "r" ); 6224854Speter if ( blurbfile == NULL ) { 62310285Speter perror( blurbname ); 6244854Speter return; 6254854Speter } 6264854Speter while ( ( input = getc( blurbfile ) ) != EOF ) { 6274854Speter putchar( input ); 6284854Speter } 6294854Speter fclose( blurbfile ); 6304854Speter } 631*16853Smckusick 632*16853Smckusick int 633*16853Smckusick namecmp( npp1 , npp2 ) 634*16853Smckusick nltype **npp1, **npp2; 635*16853Smckusick { 636*16853Smckusick return( strcmp( (*npp1) -> name , (*npp2) -> name ) ); 637*16853Smckusick } 638*16853Smckusick 639*16853Smckusick printindex() 640*16853Smckusick { 641*16853Smckusick nltype **namesortnlp; 642*16853Smckusick register nltype *nlp; 643*16853Smckusick int index, nnames, todo, i, j; 644*16853Smckusick char peterbuffer[ BUFSIZ ]; 645*16853Smckusick 646*16853Smckusick /* 647*16853Smckusick * Now, sort regular function name alphbetically 648*16853Smckusick * to create an index. 649*16853Smckusick */ 650*16853Smckusick namesortnlp = (nltype **) calloc( nname + ncycle , sizeof(nltype *) ); 651*16853Smckusick if ( namesortnlp == (nltype **) 0 ) { 652*16853Smckusick fprintf( stderr , "%s: ran out of memory for sorting\n" , whoami ); 653*16853Smckusick } 654*16853Smckusick for ( index = 0 , nnames = 0 ; index < nname ; index++ ) { 655*16853Smckusick if ( zflag == 0 && nl[index].ncall == 0 && nl[index].time == 0 ) 656*16853Smckusick continue; 657*16853Smckusick namesortnlp[nnames++] = &nl[index]; 658*16853Smckusick } 659*16853Smckusick qsort( namesortnlp , nnames , sizeof(nltype *) , namecmp ); 660*16853Smckusick for ( index = 1 , todo = nnames ; index <= ncycle ; index++ ) { 661*16853Smckusick namesortnlp[todo++] = &cyclenl[index]; 662*16853Smckusick } 663*16853Smckusick printf( "\f\nIndex by function name\n\n" ); 664*16853Smckusick index = ( todo + 2 ) / 3; 665*16853Smckusick for ( i = 0; i < index ; i++ ) { 666*16853Smckusick for ( j = i; j < todo ; j += index ) { 667*16853Smckusick nlp = namesortnlp[ j ]; 668*16853Smckusick if ( nlp -> printflag ) { 669*16853Smckusick sprintf( peterbuffer , "[%d]" , nlp -> index ); 670*16853Smckusick } else { 671*16853Smckusick sprintf( peterbuffer , "(%d)" , nlp -> index ); 672*16853Smckusick } 673*16853Smckusick if ( j < nnames ) { 674*16853Smckusick printf( "%6.6s %-19.19s" , peterbuffer , nlp -> name ); 675*16853Smckusick } else { 676*16853Smckusick printf( "%6.6s " , peterbuffer ); 677*16853Smckusick sprintf( peterbuffer , "<cycle %d>" , nlp -> cycleno ); 678*16853Smckusick printf( "%-19.19s" , peterbuffer ); 679*16853Smckusick } 680*16853Smckusick } 681*16853Smckusick printf( "\n" ); 682*16853Smckusick } 683*16853Smckusick cfree( namesortnlp ); 684*16853Smckusick } 685