121963Sdist /* 221963Sdist * Copyright (c) 1983 Regents of the University of California. 3*34199Sbostic * All rights reserved. 4*34199Sbostic * 5*34199Sbostic * Redistribution and use in source and binary forms are permitted 6*34199Sbostic * provided that this notice is preserved and that due credit is given 7*34199Sbostic * to the University of California at Berkeley. The name of the University 8*34199Sbostic * may not be used to endorse or promote products derived from this 9*34199Sbostic * software without specific prior written permission. This software 10*34199Sbostic * is provided ``as is'' without express or implied warranty. 1121963Sdist */ 1221963Sdist 134515Speter #ifndef lint 14*34199Sbostic static char sccsid[] = "@(#)printgprof.c 5.4 (Berkeley) 05/05/88"; 15*34199Sbostic #endif /* not lint */ 164515Speter 174562Speter #include "gprof.h" 184515Speter 194753Speter printprof() 204753Speter { 214753Speter register nltype *np; 224753Speter nltype **sortednlp; 2333227Sbostic int index, timecmp(); 244753Speter 254753Speter actime = 0.0; 2616853Smckusick printf( "\f\n" ); 274753Speter flatprofheader(); 284753Speter /* 294753Speter * Sort the symbol table in by time 304753Speter */ 314753Speter sortednlp = (nltype **) calloc( nname , sizeof(nltype *) ); 324753Speter if ( sortednlp == (nltype **) 0 ) { 334753Speter fprintf( stderr , "[printprof] ran out of memory for time sorting\n" ); 344753Speter } 354753Speter for ( index = 0 ; index < nname ; index += 1 ) { 364753Speter sortednlp[ index ] = &nl[ index ]; 374753Speter } 384753Speter qsort( sortednlp , nname , sizeof(nltype *) , timecmp ); 394753Speter for ( index = 0 ; index < nname ; index += 1 ) { 404753Speter np = sortednlp[ index ]; 414753Speter flatprofline( np ); 424753Speter } 434753Speter actime = 0.0; 4416853Smckusick cfree( sortednlp ); 454753Speter } 464753Speter 474753Speter timecmp( npp1 , npp2 ) 484753Speter nltype **npp1, **npp2; 494753Speter { 504856Speter double timediff; 514856Speter long calldiff; 524753Speter 534856Speter timediff = (*npp2) -> time - (*npp1) -> time; 544856Speter if ( timediff > 0.0 ) 554753Speter return 1 ; 564856Speter if ( timediff < 0.0 ) 574753Speter return -1; 584856Speter calldiff = (*npp2) -> ncall - (*npp1) -> ncall; 594856Speter if ( calldiff > 0 ) 604856Speter return 1; 614856Speter if ( calldiff < 0 ) 624856Speter return -1; 634753Speter return( strcmp( (*npp1) -> name , (*npp2) -> name ) ); 644753Speter } 654753Speter 664753Speter /* 674753Speter * header for flatprofline 684753Speter */ 694753Speter flatprofheader() 704753Speter { 714753Speter 724854Speter if ( bflag ) { 7310285Speter printblurb( FLAT_BLURB ); 744854Speter } 7516853Smckusick printf( "\ngranularity: each sample hit covers %d byte(s)" , 7616853Smckusick (long) scale * sizeof(UNIT) ); 7716853Smckusick if ( totime > 0.0 ) { 7816853Smckusick printf( " for %.2f%% of %.2f seconds\n\n" , 7916853Smckusick 100.0/totime , totime / hz ); 8016853Smckusick } else { 8116853Smckusick printf( " no time accumulated\n\n" ); 8216853Smckusick /* 8316853Smckusick * this doesn't hurt sinc eall the numerators will be zero. 8416853Smckusick */ 8516853Smckusick totime = 1.0; 8616853Smckusick } 8716853Smckusick printf( "%5.5s %10.10s %8.8s %8.8s %8.8s %8.8s %-8.8s\n" , 8816853Smckusick "% " , "cumulative" , "self " , "" , "self " , "total " , "" ); 8916853Smckusick printf( "%5.5s %10.10s %8.8s %8.8s %8.8s %8.8s %-8.8s\n" , 9016853Smckusick "time" , "seconds " , "seconds" , "calls" , 9116853Smckusick "ms/call" , "ms/call" , "name" ); 924753Speter } 934753Speter 944753Speter flatprofline( np ) 954753Speter register nltype *np; 964753Speter { 974753Speter 984854Speter if ( zflag == 0 && np -> ncall == 0 && np -> time == 0 ) { 994753Speter return; 1004753Speter } 1014753Speter actime += np -> time; 10216853Smckusick printf( "%5.1f %10.2f %8.2f" , 10310248Speter 100 * np -> time / totime , actime / hz , np -> time / hz ); 1044753Speter if ( np -> ncall != 0 ) { 10516853Smckusick printf( " %8d %8.2f %8.2f " , np -> ncall , 10616853Smckusick 1000 * np -> time / hz / np -> ncall , 10716853Smckusick 1000 * ( np -> time + np -> childtime ) / hz / np -> ncall ); 1084753Speter } else { 10916853Smckusick printf( " %8.8s %8.8s %8.8s " , "" , "" , "" ); 1104753Speter } 11116853Smckusick printname( np ); 11216853Smckusick printf( "\n" ); 1134753Speter } 1144753Speter 1154753Speter gprofheader() 1164753Speter { 1174854Speter 1184854Speter if ( bflag ) { 11910285Speter printblurb( CALLG_BLURB ); 1204854Speter } 1217172Speter printf( "\ngranularity: each sample hit covers %d byte(s)" , 1227172Speter (long) scale * sizeof(UNIT) ); 1237225Speter if ( printtime > 0.0 ) { 1247225Speter printf( " for %.2f%% of %.2f seconds\n\n" , 12510248Speter 100.0/printtime , printtime / hz ); 1267225Speter } else { 1277225Speter printf( " no time propagated\n\n" ); 1287225Speter /* 1297225Speter * this doesn't hurt, since all the numerators will be 0.0 1307225Speter */ 1317225Speter printtime = 1.0; 1327225Speter } 1334753Speter printf( "%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s %-8.8s\n" , 13430799Sbostic "" , "" , "" , "" , "called" , "total" , "parents"); 1354753Speter printf( "%-6.6s %5.5s %7.7s %11.11s %7.7s+%-7.7s %-8.8s\t%5.5s\n" , 1364753Speter "index" , "%time" , "self" , "descendents" , 1374753Speter "called" , "self" , "name" , "index" ); 1384753Speter printf( "%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s %-8.8s\n" , 13930799Sbostic "" , "" , "" , "" , "called" , "total" , "children"); 1404753Speter printf( "\n" ); 1414753Speter } 1424753Speter 1434753Speter gprofline( np ) 1444753Speter register nltype *np; 1454753Speter { 1464753Speter char kirkbuffer[ BUFSIZ ]; 1474753Speter 1484753Speter sprintf( kirkbuffer , "[%d]" , np -> index ); 1494753Speter printf( "%-6.6s %5.1f %7.2f %11.2f" , 1504753Speter kirkbuffer , 1517222Speter 100 * ( np -> propself + np -> propchild ) / printtime , 15210248Speter np -> propself / hz , 15310248Speter np -> propchild / hz ); 1544753Speter if ( ( np -> ncall + np -> selfcalls ) != 0 ) { 1554753Speter printf( " %7d" , np -> ncall ); 1564753Speter if ( np -> selfcalls != 0 ) { 1574753Speter printf( "+%-7d " , np -> selfcalls ); 1584753Speter } else { 1594753Speter printf( " %7.7s " , "" ); 1604753Speter } 1614753Speter } else { 1624753Speter printf( " %7.7s %7.7s " , "" , "" ); 1634753Speter } 1644753Speter printname( np ); 1654753Speter printf( "\n" ); 1664753Speter } 1674753Speter 16816853Smckusick printgprof(timesortnlp) 16916853Smckusick nltype **timesortnlp; 1704515Speter { 1714515Speter int index; 1724515Speter nltype *parentp; 1734515Speter 1744515Speter /* 17516853Smckusick * Print out the structured profiling list 1764515Speter */ 1774753Speter gprofheader(); 1787129Speter for ( index = 0 ; index < nname + ncycle ; index ++ ) { 1794515Speter parentp = timesortnlp[ index ]; 1804854Speter if ( zflag == 0 && 1814515Speter parentp -> ncall == 0 && 1824515Speter parentp -> selfcalls == 0 && 1837222Speter parentp -> propself == 0 && 1847222Speter parentp -> propchild == 0 ) { 1854515Speter continue; 1864515Speter } 1877172Speter if ( ! parentp -> printflag ) { 1887172Speter continue; 1897172Speter } 1904515Speter if ( parentp -> name == 0 && parentp -> cycleno != 0 ) { 1914515Speter /* 1924515Speter * cycle header 1934515Speter */ 1944753Speter printcycle( parentp ); 1954753Speter printmembers( parentp ); 1964515Speter } else { 1974515Speter printparents( parentp ); 1984753Speter gprofline( parentp ); 1994515Speter printchildren( parentp ); 2004515Speter } 2014515Speter printf( "\n" ); 2024753Speter printf( "-----------------------------------------------\n" ); 2034753Speter printf( "\n" ); 2044515Speter } 20516853Smckusick cfree( timesortnlp ); 2064515Speter } 2074515Speter 2084856Speter /* 2097222Speter * sort by decreasing propagated time 2104856Speter * if times are equal, but one is a cycle header, 2114856Speter * say that's first (e.g. less, i.e. -1). 2124856Speter * if one's name doesn't have an underscore and the other does, 2134856Speter * say the one is first. 2144856Speter * all else being equal, sort by names. 2154856Speter */ 2164856Speter int 2174856Speter totalcmp( npp1 , npp2 ) 2184856Speter nltype **npp1; 2194856Speter nltype **npp2; 2204856Speter { 2214856Speter register nltype *np1 = *npp1; 2224856Speter register nltype *np2 = *npp2; 2234856Speter double diff; 2244856Speter 2257222Speter diff = ( np1 -> propself + np1 -> propchild ) 2267222Speter - ( np2 -> propself + np2 -> propchild ); 2274856Speter if ( diff < 0.0 ) 2284856Speter return 1; 2294856Speter if ( diff > 0.0 ) 2304856Speter return -1; 2314856Speter if ( np1 -> name == 0 && np1 -> cycleno != 0 ) 2324856Speter return -1; 2334856Speter if ( np2 -> name == 0 && np2 -> cycleno != 0 ) 2344856Speter return 1; 2354856Speter if ( np1 -> name == 0 ) 2364856Speter return -1; 2374856Speter if ( np2 -> name == 0 ) 2384856Speter return 1; 2394856Speter if ( *(np1 -> name) != '_' && *(np2 -> name) == '_' ) 2404856Speter return -1; 2414856Speter if ( *(np1 -> name) == '_' && *(np2 -> name) != '_' ) 2424856Speter return 1; 2437222Speter if ( np1 -> ncall > np2 -> ncall ) 2447222Speter return -1; 2457222Speter if ( np1 -> ncall < np2 -> ncall ) 2467222Speter return 1; 2474856Speter return strcmp( np1 -> name , np2 -> name ); 2484856Speter } 2494856Speter 2504515Speter printparents( childp ) 2514515Speter nltype *childp; 2524515Speter { 2534515Speter nltype *parentp; 2544515Speter arctype *arcp; 2554515Speter nltype *cycleheadp; 2564515Speter 2574515Speter if ( childp -> cyclehead != 0 ) { 2584515Speter cycleheadp = childp -> cyclehead; 2594515Speter } else { 2604515Speter cycleheadp = childp; 2614515Speter } 2624515Speter if ( childp -> parents == 0 ) { 2634753Speter printf( "%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s <spontaneous>\n" , 2644515Speter "" , "" , "" , "" , "" , "" ); 2654515Speter return; 2664515Speter } 2674515Speter sortparents( childp ); 2684515Speter for ( arcp = childp -> parents ; arcp ; arcp = arcp -> arc_parentlist ) { 2694515Speter parentp = arcp -> arc_parentp; 2704515Speter if ( childp == parentp || 2714515Speter ( childp->cycleno != 0 && parentp->cycleno == childp->cycleno ) ) { 2724515Speter /* 2734753Speter * selfcall or call among siblings 2744515Speter */ 2754753Speter printf( "%6.6s %5.5s %7.7s %11.11s %7d %7.7s " , 2764515Speter "" , "" , "" , "" , 2774515Speter arcp -> arc_count , "" ); 2784515Speter printname( parentp ); 2794515Speter printf( "\n" ); 2804515Speter } else { 2814515Speter /* 2824515Speter * regular parent of child 2834515Speter */ 2844753Speter printf( "%6.6s %5.5s %7.2f %11.2f %7d/%-7d " , 2854753Speter "" , "" , 28610248Speter arcp -> arc_time / hz , arcp -> arc_childtime / hz , 2874515Speter arcp -> arc_count , cycleheadp -> ncall ); 2884515Speter printname( parentp ); 2894515Speter printf( "\n" ); 2904515Speter } 2914515Speter } 2924515Speter } 2934515Speter 2944515Speter printchildren( parentp ) 2954515Speter nltype *parentp; 2964515Speter { 2974515Speter nltype *childp; 2984515Speter arctype *arcp; 2994515Speter 3004515Speter sortchildren( parentp ); 3014515Speter arcp = parentp -> children; 3024515Speter for ( arcp = parentp -> children ; arcp ; arcp = arcp -> arc_childlist ) { 3034515Speter childp = arcp -> arc_childp; 3044515Speter if ( childp == parentp || 3054515Speter ( childp->cycleno != 0 && childp->cycleno == parentp->cycleno ) ) { 3064515Speter /* 3074515Speter * self call or call to sibling 3084515Speter */ 3094753Speter printf( "%6.6s %5.5s %7.7s %11.11s %7d %7.7s " , 3104753Speter "" , "" , "" , "" , arcp -> arc_count , "" ); 3114515Speter printname( childp ); 3124515Speter printf( "\n" ); 3134515Speter } else { 3144515Speter /* 3154515Speter * regular child of parent 3164515Speter */ 3174753Speter printf( "%6.6s %5.5s %7.2f %11.2f %7d/%-7d " , 3184753Speter "" , "" , 31910248Speter arcp -> arc_time / hz , arcp -> arc_childtime / hz , 3204515Speter arcp -> arc_count , childp -> cyclehead -> ncall ); 3214515Speter printname( childp ); 3224515Speter printf( "\n" ); 3234515Speter } 3244515Speter } 3254515Speter } 3264515Speter 3274515Speter printname( selfp ) 3284515Speter nltype *selfp; 3294515Speter { 3304515Speter 3314515Speter if ( selfp -> name != 0 ) { 3324753Speter printf( "%s" , selfp -> name ); 3334515Speter # ifdef DEBUG 3344515Speter if ( debug & DFNDEBUG ) { 3354515Speter printf( "{%d} " , selfp -> toporder ); 3364515Speter } 3377222Speter if ( debug & PROPDEBUG ) { 3387222Speter printf( "%5.2f%% " , selfp -> propfraction ); 3397222Speter } 3404515Speter # endif DEBUG 3414515Speter } 3424842Speter if ( selfp -> cycleno != 0 ) { 34316853Smckusick printf( " <cycle %d>" , selfp -> cycleno ); 3444842Speter } 3454753Speter if ( selfp -> index != 0 ) { 3467172Speter if ( selfp -> printflag ) { 3477172Speter printf( " [%d]" , selfp -> index ); 3487172Speter } else { 3497172Speter printf( " (%d)" , selfp -> index ); 3507172Speter } 3514753Speter } 3524515Speter } 3534515Speter 3544515Speter sortchildren( parentp ) 3554515Speter nltype *parentp; 3564515Speter { 3574515Speter arctype *arcp; 3584515Speter arctype *detachedp; 3594515Speter arctype sorted; 3604515Speter arctype *prevp; 3614515Speter 3624515Speter /* 3634515Speter * unlink children from parent, 3644515Speter * then insertion sort back on to sorted's children. 3654515Speter * *arcp the arc you have detached and are inserting. 3664515Speter * *detachedp the rest of the arcs to be sorted. 3674515Speter * sorted arc list onto which you insertion sort. 3684515Speter * *prevp arc before the arc you are comparing. 3694515Speter */ 3704515Speter sorted.arc_childlist = 0; 37111798Speter for ( (arcp = parentp -> children)&&(detachedp = arcp -> arc_childlist); 3724515Speter arcp ; 37311798Speter (arcp = detachedp)&&(detachedp = detachedp -> arc_childlist)) { 3744515Speter /* 3754515Speter * consider *arcp as disconnected 3764515Speter * insert it into sorted 3774515Speter */ 3784515Speter for ( prevp = &sorted ; 3794515Speter prevp -> arc_childlist ; 3804515Speter prevp = prevp -> arc_childlist ) { 3814515Speter if ( arccmp( arcp , prevp -> arc_childlist ) != LESSTHAN ) { 3824515Speter break; 3834515Speter } 3844515Speter } 3854515Speter arcp -> arc_childlist = prevp -> arc_childlist; 3864515Speter prevp -> arc_childlist = arcp; 3874515Speter } 3884515Speter /* 3894515Speter * reattach sorted children to parent 3904515Speter */ 3914515Speter parentp -> children = sorted.arc_childlist; 3924515Speter } 3934515Speter 3944515Speter sortparents( childp ) 3954515Speter nltype *childp; 3964515Speter { 3974515Speter arctype *arcp; 3984515Speter arctype *detachedp; 3994515Speter arctype sorted; 4004515Speter arctype *prevp; 4014515Speter 4024515Speter /* 4034515Speter * unlink parents from child, 4044515Speter * then insertion sort back on to sorted's parents. 4054515Speter * *arcp the arc you have detached and are inserting. 4064515Speter * *detachedp the rest of the arcs to be sorted. 4074515Speter * sorted arc list onto which you insertion sort. 4084515Speter * *prevp arc before the arc you are comparing. 4094515Speter */ 4104515Speter sorted.arc_parentlist = 0; 41111798Speter for ( (arcp = childp -> parents)&&(detachedp = arcp -> arc_parentlist); 4124515Speter arcp ; 41311798Speter (arcp = detachedp)&&(detachedp = detachedp -> arc_parentlist)) { 4144515Speter /* 4154515Speter * consider *arcp as disconnected 4164515Speter * insert it into sorted 4174515Speter */ 4184515Speter for ( prevp = &sorted ; 4194515Speter prevp -> arc_parentlist ; 4204515Speter prevp = prevp -> arc_parentlist ) { 4214515Speter if ( arccmp( arcp , prevp -> arc_parentlist ) != GREATERTHAN ) { 4224515Speter break; 4234515Speter } 4244515Speter } 4254515Speter arcp -> arc_parentlist = prevp -> arc_parentlist; 4264515Speter prevp -> arc_parentlist = arcp; 4274515Speter } 4284515Speter /* 4294515Speter * reattach sorted arcs to child 4304515Speter */ 4314515Speter childp -> parents = sorted.arc_parentlist; 4324515Speter } 4334515Speter 4344515Speter /* 4354753Speter * print a cycle header 4364753Speter */ 4374753Speter printcycle( cyclep ) 4384753Speter nltype *cyclep; 4394753Speter { 4404753Speter char kirkbuffer[ BUFSIZ ]; 4414753Speter 4424753Speter sprintf( kirkbuffer , "[%d]" , cyclep -> index ); 4434753Speter printf( "%-6.6s %5.1f %7.2f %11.2f %7d" , 4444753Speter kirkbuffer , 4457222Speter 100 * ( cyclep -> propself + cyclep -> propchild ) / printtime , 44610248Speter cyclep -> propself / hz , 44710248Speter cyclep -> propchild / hz , 4484753Speter cyclep -> ncall ); 4494753Speter if ( cyclep -> selfcalls != 0 ) { 4504753Speter printf( "+%-7d" , cyclep -> selfcalls ); 4514753Speter } else { 4524753Speter printf( " %7.7s" , "" ); 4534753Speter } 4544753Speter printf( " <cycle %d as a whole>\t[%d]\n" , 4554753Speter cyclep -> cycleno , cyclep -> index ); 4564753Speter } 4574753Speter 4584753Speter /* 4594753Speter * print the members of a cycle 4604753Speter */ 4614753Speter printmembers( cyclep ) 4624753Speter nltype *cyclep; 4634753Speter { 4644753Speter nltype *memberp; 4654753Speter 4664753Speter sortmembers( cyclep ); 4674753Speter for ( memberp = cyclep -> cnext ; memberp ; memberp = memberp -> cnext ) { 4684753Speter printf( "%6.6s %5.5s %7.2f %11.2f %7d" , 46910248Speter "" , "" , memberp -> propself / hz , memberp -> propchild / hz , 4704753Speter memberp -> ncall ); 4714753Speter if ( memberp -> selfcalls != 0 ) { 4724753Speter printf( "+%-7d" , memberp -> selfcalls ); 4734753Speter } else { 4744753Speter printf( " %7.7s" , "" ); 4754753Speter } 4764753Speter printf( " " ); 4774753Speter printname( memberp ); 4784753Speter printf( "\n" ); 4794753Speter } 4804753Speter } 4814753Speter 4824753Speter /* 4834753Speter * sort members of a cycle 4844753Speter */ 4854753Speter sortmembers( cyclep ) 4864753Speter nltype *cyclep; 4874753Speter { 4884753Speter nltype *todo; 4894753Speter nltype *doing; 4904753Speter nltype *prev; 4914753Speter 4924753Speter /* 4934753Speter * detach cycle members from cyclehead, 4944753Speter * and insertion sort them back on. 4954753Speter */ 4964753Speter todo = cyclep -> cnext; 4974753Speter cyclep -> cnext = 0; 49811798Speter for ( (doing = todo)&&(todo = doing -> cnext); 4994753Speter doing ; 50011798Speter (doing = todo )&&(todo = doing -> cnext )){ 5014753Speter for ( prev = cyclep ; prev -> cnext ; prev = prev -> cnext ) { 5024753Speter if ( membercmp( doing , prev -> cnext ) == GREATERTHAN ) { 5034753Speter break; 5044753Speter } 5054753Speter } 5064753Speter doing -> cnext = prev -> cnext; 5074753Speter prev -> cnext = doing; 5084753Speter } 5094753Speter } 5104753Speter 5114753Speter /* 5127222Speter * major sort is on propself + propchild, 5134753Speter * next is sort on ncalls + selfcalls. 5144753Speter */ 5154842Speter int 5164753Speter membercmp( this , that ) 5174753Speter nltype *this; 5184753Speter nltype *that; 5194753Speter { 5207222Speter double thistime = this -> propself + this -> propchild; 5217222Speter double thattime = that -> propself + that -> propchild; 5224753Speter long thiscalls = this -> ncall + this -> selfcalls; 5234753Speter long thatcalls = that -> ncall + that -> selfcalls; 5244753Speter 5254753Speter if ( thistime > thattime ) { 5264753Speter return GREATERTHAN; 5274753Speter } 5284753Speter if ( thistime < thattime ) { 5294753Speter return LESSTHAN; 5304753Speter } 5314753Speter if ( thiscalls > thatcalls ) { 5324753Speter return GREATERTHAN; 5334753Speter } 5344753Speter if ( thiscalls < thatcalls ) { 5354753Speter return LESSTHAN; 5364753Speter } 5374753Speter return EQUALTO; 5384753Speter } 5394753Speter /* 5404515Speter * compare two arcs to/from the same child/parent. 5414515Speter * - if one arc is a self arc, it's least. 5424515Speter * - if one arc is within a cycle, it's less than. 5434515Speter * - if both arcs are within a cycle, compare arc counts. 5444515Speter * - if neither arc is within a cycle, compare with 5457222Speter * arc_time + arc_childtime as major key 5464515Speter * arc count as minor key 5474515Speter */ 5484515Speter int 5494515Speter arccmp( thisp , thatp ) 5504515Speter arctype *thisp; 5514515Speter arctype *thatp; 5524515Speter { 5534515Speter nltype *thisparentp = thisp -> arc_parentp; 5544515Speter nltype *thischildp = thisp -> arc_childp; 5554515Speter nltype *thatparentp = thatp -> arc_parentp; 5564515Speter nltype *thatchildp = thatp -> arc_childp; 5574515Speter double thistime; 5584515Speter double thattime; 5594515Speter 5604515Speter # ifdef DEBUG 5614515Speter if ( debug & TIMEDEBUG ) { 5624515Speter printf( "[arccmp] " ); 5634515Speter printname( thisparentp ); 5644515Speter printf( " calls " ); 5654515Speter printname ( thischildp ); 5664515Speter printf( " %f + %f %d/%d\n" , 5674515Speter thisp -> arc_time , thisp -> arc_childtime , 5684515Speter thisp -> arc_count , thischildp -> ncall ); 5694515Speter printf( "[arccmp] " ); 5704515Speter printname( thatparentp ); 5714515Speter printf( " calls " ); 5724515Speter printname( thatchildp ); 5734515Speter printf( " %f + %f %d/%d\n" , 5744515Speter thatp -> arc_time , thatp -> arc_childtime , 5754515Speter thatp -> arc_count , thatchildp -> ncall ); 5764515Speter printf( "\n" ); 5774515Speter } 5784515Speter # endif DEBUG 5794515Speter if ( thisparentp == thischildp ) { 5804515Speter /* this is a self call */ 5814515Speter return LESSTHAN; 5824515Speter } 5834515Speter if ( thatparentp == thatchildp ) { 5844515Speter /* that is a self call */ 5854515Speter return GREATERTHAN; 5864515Speter } 5874515Speter if ( thisparentp -> cycleno != 0 && thischildp -> cycleno != 0 && 5884515Speter thisparentp -> cycleno == thischildp -> cycleno ) { 5894515Speter /* this is a call within a cycle */ 5904515Speter if ( thatparentp -> cycleno != 0 && thatchildp -> cycleno != 0 && 5914515Speter thatparentp -> cycleno == thatchildp -> cycleno ) { 5924515Speter /* that is a call within the cycle, too */ 5934515Speter if ( thisp -> arc_count < thatp -> arc_count ) { 5944515Speter return LESSTHAN; 5954515Speter } 5964515Speter if ( thisp -> arc_count > thatp -> arc_count ) { 5974515Speter return GREATERTHAN; 5984515Speter } 5994515Speter return EQUALTO; 6004515Speter } else { 6014515Speter /* that isn't a call within the cycle */ 6024515Speter return LESSTHAN; 6034515Speter } 6044515Speter } else { 6054515Speter /* this isn't a call within a cycle */ 6064515Speter if ( thatparentp -> cycleno != 0 && thatchildp -> cycleno != 0 && 6074515Speter thatparentp -> cycleno == thatchildp -> cycleno ) { 6084515Speter /* that is a call within a cycle */ 6094515Speter return GREATERTHAN; 6104515Speter } else { 6114515Speter /* neither is a call within a cycle */ 6124515Speter thistime = thisp -> arc_time + thisp -> arc_childtime; 6134515Speter thattime = thatp -> arc_time + thatp -> arc_childtime; 6144515Speter if ( thistime < thattime ) 6154515Speter return LESSTHAN; 6164515Speter if ( thistime > thattime ) 6174515Speter return GREATERTHAN; 6184515Speter if ( thisp -> arc_count < thatp -> arc_count ) 6194515Speter return LESSTHAN; 6204515Speter if ( thisp -> arc_count > thatp -> arc_count ) 6214515Speter return GREATERTHAN; 6224515Speter return EQUALTO; 6234515Speter } 6244515Speter } 6254515Speter } 6264854Speter 6274854Speter printblurb( blurbname ) 6284854Speter char *blurbname; 6294854Speter { 6304854Speter FILE *blurbfile; 6314854Speter int input; 6324854Speter 63310285Speter blurbfile = fopen( blurbname , "r" ); 6344854Speter if ( blurbfile == NULL ) { 63510285Speter perror( blurbname ); 6364854Speter return; 6374854Speter } 6384854Speter while ( ( input = getc( blurbfile ) ) != EOF ) { 6394854Speter putchar( input ); 6404854Speter } 6414854Speter fclose( blurbfile ); 6424854Speter } 64316853Smckusick 64416853Smckusick int 64516853Smckusick namecmp( npp1 , npp2 ) 64616853Smckusick nltype **npp1, **npp2; 64716853Smckusick { 64816853Smckusick return( strcmp( (*npp1) -> name , (*npp2) -> name ) ); 64916853Smckusick } 65016853Smckusick 65116853Smckusick printindex() 65216853Smckusick { 65316853Smckusick nltype **namesortnlp; 65416853Smckusick register nltype *nlp; 65516853Smckusick int index, nnames, todo, i, j; 65616853Smckusick char peterbuffer[ BUFSIZ ]; 65716853Smckusick 65816853Smckusick /* 65916853Smckusick * Now, sort regular function name alphbetically 66016853Smckusick * to create an index. 66116853Smckusick */ 66216853Smckusick namesortnlp = (nltype **) calloc( nname + ncycle , sizeof(nltype *) ); 66316853Smckusick if ( namesortnlp == (nltype **) 0 ) { 66416853Smckusick fprintf( stderr , "%s: ran out of memory for sorting\n" , whoami ); 66516853Smckusick } 66616853Smckusick for ( index = 0 , nnames = 0 ; index < nname ; index++ ) { 66716853Smckusick if ( zflag == 0 && nl[index].ncall == 0 && nl[index].time == 0 ) 66816853Smckusick continue; 66916853Smckusick namesortnlp[nnames++] = &nl[index]; 67016853Smckusick } 67116853Smckusick qsort( namesortnlp , nnames , sizeof(nltype *) , namecmp ); 67216853Smckusick for ( index = 1 , todo = nnames ; index <= ncycle ; index++ ) { 67316853Smckusick namesortnlp[todo++] = &cyclenl[index]; 67416853Smckusick } 67516853Smckusick printf( "\f\nIndex by function name\n\n" ); 67616853Smckusick index = ( todo + 2 ) / 3; 67716853Smckusick for ( i = 0; i < index ; i++ ) { 67816853Smckusick for ( j = i; j < todo ; j += index ) { 67916853Smckusick nlp = namesortnlp[ j ]; 68016853Smckusick if ( nlp -> printflag ) { 68116853Smckusick sprintf( peterbuffer , "[%d]" , nlp -> index ); 68216853Smckusick } else { 68316853Smckusick sprintf( peterbuffer , "(%d)" , nlp -> index ); 68416853Smckusick } 68516853Smckusick if ( j < nnames ) { 68616853Smckusick printf( "%6.6s %-19.19s" , peterbuffer , nlp -> name ); 68716853Smckusick } else { 68816853Smckusick printf( "%6.6s " , peterbuffer ); 68916853Smckusick sprintf( peterbuffer , "<cycle %d>" , nlp -> cycleno ); 69016853Smckusick printf( "%-19.19s" , peterbuffer ); 69116853Smckusick } 69216853Smckusick } 69316853Smckusick printf( "\n" ); 69416853Smckusick } 69516853Smckusick cfree( namesortnlp ); 69616853Smckusick } 697