121963Sdist /* 221963Sdist * Copyright (c) 1983 Regents of the University of California. 334199Sbostic * All rights reserved. 434199Sbostic * 534199Sbostic * Redistribution and use in source and binary forms are permitted 634881Sbostic * provided that the above copyright notice and this paragraph are 734881Sbostic * duplicated in all such forms and that any documentation, 834881Sbostic * advertising materials, and other materials related to such 934881Sbostic * distribution and use acknowledge that the software was developed 1034881Sbostic * by the University of California, Berkeley. The name of the 1134881Sbostic * University may not be used to endorse or promote products derived 1234881Sbostic * from this software without specific prior written permission. 1334881Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1434881Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1534881Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1621963Sdist */ 1721963Sdist 184515Speter #ifndef lint 19*37801Sbostic static char sccsid[] = "@(#)printgprof.c 5.6 (Berkeley) 05/10/89"; 2034199Sbostic #endif /* not lint */ 214515Speter 224562Speter #include "gprof.h" 23*37801Sbostic #include "pathnames.h" 244515Speter 254753Speter printprof() 264753Speter { 274753Speter register nltype *np; 284753Speter nltype **sortednlp; 2933227Sbostic int index, timecmp(); 304753Speter 314753Speter actime = 0.0; 3216853Smckusick printf( "\f\n" ); 334753Speter flatprofheader(); 344753Speter /* 354753Speter * Sort the symbol table in by time 364753Speter */ 374753Speter sortednlp = (nltype **) calloc( nname , sizeof(nltype *) ); 384753Speter if ( sortednlp == (nltype **) 0 ) { 394753Speter fprintf( stderr , "[printprof] ran out of memory for time sorting\n" ); 404753Speter } 414753Speter for ( index = 0 ; index < nname ; index += 1 ) { 424753Speter sortednlp[ index ] = &nl[ index ]; 434753Speter } 444753Speter qsort( sortednlp , nname , sizeof(nltype *) , timecmp ); 454753Speter for ( index = 0 ; index < nname ; index += 1 ) { 464753Speter np = sortednlp[ index ]; 474753Speter flatprofline( np ); 484753Speter } 494753Speter actime = 0.0; 5016853Smckusick cfree( sortednlp ); 514753Speter } 524753Speter 534753Speter timecmp( npp1 , npp2 ) 544753Speter nltype **npp1, **npp2; 554753Speter { 564856Speter double timediff; 574856Speter long calldiff; 584753Speter 594856Speter timediff = (*npp2) -> time - (*npp1) -> time; 604856Speter if ( timediff > 0.0 ) 614753Speter return 1 ; 624856Speter if ( timediff < 0.0 ) 634753Speter return -1; 644856Speter calldiff = (*npp2) -> ncall - (*npp1) -> ncall; 654856Speter if ( calldiff > 0 ) 664856Speter return 1; 674856Speter if ( calldiff < 0 ) 684856Speter return -1; 694753Speter return( strcmp( (*npp1) -> name , (*npp2) -> name ) ); 704753Speter } 714753Speter 724753Speter /* 734753Speter * header for flatprofline 744753Speter */ 754753Speter flatprofheader() 764753Speter { 774753Speter 784854Speter if ( bflag ) { 79*37801Sbostic printblurb( _PATH_FLAT_BLURB ); 804854Speter } 8116853Smckusick printf( "\ngranularity: each sample hit covers %d byte(s)" , 8216853Smckusick (long) scale * sizeof(UNIT) ); 8316853Smckusick if ( totime > 0.0 ) { 8416853Smckusick printf( " for %.2f%% of %.2f seconds\n\n" , 8516853Smckusick 100.0/totime , totime / hz ); 8616853Smckusick } else { 8716853Smckusick printf( " no time accumulated\n\n" ); 8816853Smckusick /* 8916853Smckusick * this doesn't hurt sinc eall the numerators will be zero. 9016853Smckusick */ 9116853Smckusick totime = 1.0; 9216853Smckusick } 9316853Smckusick printf( "%5.5s %10.10s %8.8s %8.8s %8.8s %8.8s %-8.8s\n" , 9416853Smckusick "% " , "cumulative" , "self " , "" , "self " , "total " , "" ); 9516853Smckusick printf( "%5.5s %10.10s %8.8s %8.8s %8.8s %8.8s %-8.8s\n" , 9616853Smckusick "time" , "seconds " , "seconds" , "calls" , 9716853Smckusick "ms/call" , "ms/call" , "name" ); 984753Speter } 994753Speter 1004753Speter flatprofline( np ) 1014753Speter register nltype *np; 1024753Speter { 1034753Speter 1044854Speter if ( zflag == 0 && np -> ncall == 0 && np -> time == 0 ) { 1054753Speter return; 1064753Speter } 1074753Speter actime += np -> time; 10816853Smckusick printf( "%5.1f %10.2f %8.2f" , 10910248Speter 100 * np -> time / totime , actime / hz , np -> time / hz ); 1104753Speter if ( np -> ncall != 0 ) { 11116853Smckusick printf( " %8d %8.2f %8.2f " , np -> ncall , 11216853Smckusick 1000 * np -> time / hz / np -> ncall , 11316853Smckusick 1000 * ( np -> time + np -> childtime ) / hz / np -> ncall ); 1144753Speter } else { 11516853Smckusick printf( " %8.8s %8.8s %8.8s " , "" , "" , "" ); 1164753Speter } 11716853Smckusick printname( np ); 11816853Smckusick printf( "\n" ); 1194753Speter } 1204753Speter 1214753Speter gprofheader() 1224753Speter { 1234854Speter 1244854Speter if ( bflag ) { 125*37801Sbostic printblurb( _PATH_CALLG_BLURB ); 1264854Speter } 1277172Speter printf( "\ngranularity: each sample hit covers %d byte(s)" , 1287172Speter (long) scale * sizeof(UNIT) ); 1297225Speter if ( printtime > 0.0 ) { 1307225Speter printf( " for %.2f%% of %.2f seconds\n\n" , 13110248Speter 100.0/printtime , printtime / hz ); 1327225Speter } else { 1337225Speter printf( " no time propagated\n\n" ); 1347225Speter /* 1357225Speter * this doesn't hurt, since all the numerators will be 0.0 1367225Speter */ 1377225Speter printtime = 1.0; 1387225Speter } 1394753Speter printf( "%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s %-8.8s\n" , 14030799Sbostic "" , "" , "" , "" , "called" , "total" , "parents"); 1414753Speter printf( "%-6.6s %5.5s %7.7s %11.11s %7.7s+%-7.7s %-8.8s\t%5.5s\n" , 1424753Speter "index" , "%time" , "self" , "descendents" , 1434753Speter "called" , "self" , "name" , "index" ); 1444753Speter printf( "%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s %-8.8s\n" , 14530799Sbostic "" , "" , "" , "" , "called" , "total" , "children"); 1464753Speter printf( "\n" ); 1474753Speter } 1484753Speter 1494753Speter gprofline( np ) 1504753Speter register nltype *np; 1514753Speter { 1524753Speter char kirkbuffer[ BUFSIZ ]; 1534753Speter 1544753Speter sprintf( kirkbuffer , "[%d]" , np -> index ); 1554753Speter printf( "%-6.6s %5.1f %7.2f %11.2f" , 1564753Speter kirkbuffer , 1577222Speter 100 * ( np -> propself + np -> propchild ) / printtime , 15810248Speter np -> propself / hz , 15910248Speter np -> propchild / hz ); 1604753Speter if ( ( np -> ncall + np -> selfcalls ) != 0 ) { 1614753Speter printf( " %7d" , np -> ncall ); 1624753Speter if ( np -> selfcalls != 0 ) { 1634753Speter printf( "+%-7d " , np -> selfcalls ); 1644753Speter } else { 1654753Speter printf( " %7.7s " , "" ); 1664753Speter } 1674753Speter } else { 1684753Speter printf( " %7.7s %7.7s " , "" , "" ); 1694753Speter } 1704753Speter printname( np ); 1714753Speter printf( "\n" ); 1724753Speter } 1734753Speter 17416853Smckusick printgprof(timesortnlp) 17516853Smckusick nltype **timesortnlp; 1764515Speter { 1774515Speter int index; 1784515Speter nltype *parentp; 1794515Speter 1804515Speter /* 18116853Smckusick * Print out the structured profiling list 1824515Speter */ 1834753Speter gprofheader(); 1847129Speter for ( index = 0 ; index < nname + ncycle ; index ++ ) { 1854515Speter parentp = timesortnlp[ index ]; 1864854Speter if ( zflag == 0 && 1874515Speter parentp -> ncall == 0 && 1884515Speter parentp -> selfcalls == 0 && 1897222Speter parentp -> propself == 0 && 1907222Speter parentp -> propchild == 0 ) { 1914515Speter continue; 1924515Speter } 1937172Speter if ( ! parentp -> printflag ) { 1947172Speter continue; 1957172Speter } 1964515Speter if ( parentp -> name == 0 && parentp -> cycleno != 0 ) { 1974515Speter /* 1984515Speter * cycle header 1994515Speter */ 2004753Speter printcycle( parentp ); 2014753Speter printmembers( parentp ); 2024515Speter } else { 2034515Speter printparents( parentp ); 2044753Speter gprofline( parentp ); 2054515Speter printchildren( parentp ); 2064515Speter } 2074515Speter printf( "\n" ); 2084753Speter printf( "-----------------------------------------------\n" ); 2094753Speter printf( "\n" ); 2104515Speter } 21116853Smckusick cfree( timesortnlp ); 2124515Speter } 2134515Speter 2144856Speter /* 2157222Speter * sort by decreasing propagated time 2164856Speter * if times are equal, but one is a cycle header, 2174856Speter * say that's first (e.g. less, i.e. -1). 2184856Speter * if one's name doesn't have an underscore and the other does, 2194856Speter * say the one is first. 2204856Speter * all else being equal, sort by names. 2214856Speter */ 2224856Speter int 2234856Speter totalcmp( npp1 , npp2 ) 2244856Speter nltype **npp1; 2254856Speter nltype **npp2; 2264856Speter { 2274856Speter register nltype *np1 = *npp1; 2284856Speter register nltype *np2 = *npp2; 2294856Speter double diff; 2304856Speter 2317222Speter diff = ( np1 -> propself + np1 -> propchild ) 2327222Speter - ( np2 -> propself + np2 -> propchild ); 2334856Speter if ( diff < 0.0 ) 2344856Speter return 1; 2354856Speter if ( diff > 0.0 ) 2364856Speter return -1; 2374856Speter if ( np1 -> name == 0 && np1 -> cycleno != 0 ) 2384856Speter return -1; 2394856Speter if ( np2 -> name == 0 && np2 -> cycleno != 0 ) 2404856Speter return 1; 2414856Speter if ( np1 -> name == 0 ) 2424856Speter return -1; 2434856Speter if ( np2 -> name == 0 ) 2444856Speter return 1; 2454856Speter if ( *(np1 -> name) != '_' && *(np2 -> name) == '_' ) 2464856Speter return -1; 2474856Speter if ( *(np1 -> name) == '_' && *(np2 -> name) != '_' ) 2484856Speter return 1; 2497222Speter if ( np1 -> ncall > np2 -> ncall ) 2507222Speter return -1; 2517222Speter if ( np1 -> ncall < np2 -> ncall ) 2527222Speter return 1; 2534856Speter return strcmp( np1 -> name , np2 -> name ); 2544856Speter } 2554856Speter 2564515Speter printparents( childp ) 2574515Speter nltype *childp; 2584515Speter { 2594515Speter nltype *parentp; 2604515Speter arctype *arcp; 2614515Speter nltype *cycleheadp; 2624515Speter 2634515Speter if ( childp -> cyclehead != 0 ) { 2644515Speter cycleheadp = childp -> cyclehead; 2654515Speter } else { 2664515Speter cycleheadp = childp; 2674515Speter } 2684515Speter if ( childp -> parents == 0 ) { 2694753Speter printf( "%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s <spontaneous>\n" , 2704515Speter "" , "" , "" , "" , "" , "" ); 2714515Speter return; 2724515Speter } 2734515Speter sortparents( childp ); 2744515Speter for ( arcp = childp -> parents ; arcp ; arcp = arcp -> arc_parentlist ) { 2754515Speter parentp = arcp -> arc_parentp; 2764515Speter if ( childp == parentp || 2774515Speter ( childp->cycleno != 0 && parentp->cycleno == childp->cycleno ) ) { 2784515Speter /* 2794753Speter * selfcall or call among siblings 2804515Speter */ 2814753Speter printf( "%6.6s %5.5s %7.7s %11.11s %7d %7.7s " , 2824515Speter "" , "" , "" , "" , 2834515Speter arcp -> arc_count , "" ); 2844515Speter printname( parentp ); 2854515Speter printf( "\n" ); 2864515Speter } else { 2874515Speter /* 2884515Speter * regular parent of child 2894515Speter */ 2904753Speter printf( "%6.6s %5.5s %7.2f %11.2f %7d/%-7d " , 2914753Speter "" , "" , 29210248Speter arcp -> arc_time / hz , arcp -> arc_childtime / hz , 2934515Speter arcp -> arc_count , cycleheadp -> ncall ); 2944515Speter printname( parentp ); 2954515Speter printf( "\n" ); 2964515Speter } 2974515Speter } 2984515Speter } 2994515Speter 3004515Speter printchildren( parentp ) 3014515Speter nltype *parentp; 3024515Speter { 3034515Speter nltype *childp; 3044515Speter arctype *arcp; 3054515Speter 3064515Speter sortchildren( parentp ); 3074515Speter arcp = parentp -> children; 3084515Speter for ( arcp = parentp -> children ; arcp ; arcp = arcp -> arc_childlist ) { 3094515Speter childp = arcp -> arc_childp; 3104515Speter if ( childp == parentp || 3114515Speter ( childp->cycleno != 0 && childp->cycleno == parentp->cycleno ) ) { 3124515Speter /* 3134515Speter * self call or call to sibling 3144515Speter */ 3154753Speter printf( "%6.6s %5.5s %7.7s %11.11s %7d %7.7s " , 3164753Speter "" , "" , "" , "" , arcp -> arc_count , "" ); 3174515Speter printname( childp ); 3184515Speter printf( "\n" ); 3194515Speter } else { 3204515Speter /* 3214515Speter * regular child of parent 3224515Speter */ 3234753Speter printf( "%6.6s %5.5s %7.2f %11.2f %7d/%-7d " , 3244753Speter "" , "" , 32510248Speter arcp -> arc_time / hz , arcp -> arc_childtime / hz , 3264515Speter arcp -> arc_count , childp -> cyclehead -> ncall ); 3274515Speter printname( childp ); 3284515Speter printf( "\n" ); 3294515Speter } 3304515Speter } 3314515Speter } 3324515Speter 3334515Speter printname( selfp ) 3344515Speter nltype *selfp; 3354515Speter { 3364515Speter 3374515Speter if ( selfp -> name != 0 ) { 3384753Speter printf( "%s" , selfp -> name ); 3394515Speter # ifdef DEBUG 3404515Speter if ( debug & DFNDEBUG ) { 3414515Speter printf( "{%d} " , selfp -> toporder ); 3424515Speter } 3437222Speter if ( debug & PROPDEBUG ) { 3447222Speter printf( "%5.2f%% " , selfp -> propfraction ); 3457222Speter } 3464515Speter # endif DEBUG 3474515Speter } 3484842Speter if ( selfp -> cycleno != 0 ) { 34916853Smckusick printf( " <cycle %d>" , selfp -> cycleno ); 3504842Speter } 3514753Speter if ( selfp -> index != 0 ) { 3527172Speter if ( selfp -> printflag ) { 3537172Speter printf( " [%d]" , selfp -> index ); 3547172Speter } else { 3557172Speter printf( " (%d)" , selfp -> index ); 3567172Speter } 3574753Speter } 3584515Speter } 3594515Speter 3604515Speter sortchildren( parentp ) 3614515Speter nltype *parentp; 3624515Speter { 3634515Speter arctype *arcp; 3644515Speter arctype *detachedp; 3654515Speter arctype sorted; 3664515Speter arctype *prevp; 3674515Speter 3684515Speter /* 3694515Speter * unlink children from parent, 3704515Speter * then insertion sort back on to sorted's children. 3714515Speter * *arcp the arc you have detached and are inserting. 3724515Speter * *detachedp the rest of the arcs to be sorted. 3734515Speter * sorted arc list onto which you insertion sort. 3744515Speter * *prevp arc before the arc you are comparing. 3754515Speter */ 3764515Speter sorted.arc_childlist = 0; 37711798Speter for ( (arcp = parentp -> children)&&(detachedp = arcp -> arc_childlist); 3784515Speter arcp ; 37911798Speter (arcp = detachedp)&&(detachedp = detachedp -> arc_childlist)) { 3804515Speter /* 3814515Speter * consider *arcp as disconnected 3824515Speter * insert it into sorted 3834515Speter */ 3844515Speter for ( prevp = &sorted ; 3854515Speter prevp -> arc_childlist ; 3864515Speter prevp = prevp -> arc_childlist ) { 3874515Speter if ( arccmp( arcp , prevp -> arc_childlist ) != LESSTHAN ) { 3884515Speter break; 3894515Speter } 3904515Speter } 3914515Speter arcp -> arc_childlist = prevp -> arc_childlist; 3924515Speter prevp -> arc_childlist = arcp; 3934515Speter } 3944515Speter /* 3954515Speter * reattach sorted children to parent 3964515Speter */ 3974515Speter parentp -> children = sorted.arc_childlist; 3984515Speter } 3994515Speter 4004515Speter sortparents( childp ) 4014515Speter nltype *childp; 4024515Speter { 4034515Speter arctype *arcp; 4044515Speter arctype *detachedp; 4054515Speter arctype sorted; 4064515Speter arctype *prevp; 4074515Speter 4084515Speter /* 4094515Speter * unlink parents from child, 4104515Speter * then insertion sort back on to sorted's parents. 4114515Speter * *arcp the arc you have detached and are inserting. 4124515Speter * *detachedp the rest of the arcs to be sorted. 4134515Speter * sorted arc list onto which you insertion sort. 4144515Speter * *prevp arc before the arc you are comparing. 4154515Speter */ 4164515Speter sorted.arc_parentlist = 0; 41711798Speter for ( (arcp = childp -> parents)&&(detachedp = arcp -> arc_parentlist); 4184515Speter arcp ; 41911798Speter (arcp = detachedp)&&(detachedp = detachedp -> arc_parentlist)) { 4204515Speter /* 4214515Speter * consider *arcp as disconnected 4224515Speter * insert it into sorted 4234515Speter */ 4244515Speter for ( prevp = &sorted ; 4254515Speter prevp -> arc_parentlist ; 4264515Speter prevp = prevp -> arc_parentlist ) { 4274515Speter if ( arccmp( arcp , prevp -> arc_parentlist ) != GREATERTHAN ) { 4284515Speter break; 4294515Speter } 4304515Speter } 4314515Speter arcp -> arc_parentlist = prevp -> arc_parentlist; 4324515Speter prevp -> arc_parentlist = arcp; 4334515Speter } 4344515Speter /* 4354515Speter * reattach sorted arcs to child 4364515Speter */ 4374515Speter childp -> parents = sorted.arc_parentlist; 4384515Speter } 4394515Speter 4404515Speter /* 4414753Speter * print a cycle header 4424753Speter */ 4434753Speter printcycle( cyclep ) 4444753Speter nltype *cyclep; 4454753Speter { 4464753Speter char kirkbuffer[ BUFSIZ ]; 4474753Speter 4484753Speter sprintf( kirkbuffer , "[%d]" , cyclep -> index ); 4494753Speter printf( "%-6.6s %5.1f %7.2f %11.2f %7d" , 4504753Speter kirkbuffer , 4517222Speter 100 * ( cyclep -> propself + cyclep -> propchild ) / printtime , 45210248Speter cyclep -> propself / hz , 45310248Speter cyclep -> propchild / hz , 4544753Speter cyclep -> ncall ); 4554753Speter if ( cyclep -> selfcalls != 0 ) { 4564753Speter printf( "+%-7d" , cyclep -> selfcalls ); 4574753Speter } else { 4584753Speter printf( " %7.7s" , "" ); 4594753Speter } 4604753Speter printf( " <cycle %d as a whole>\t[%d]\n" , 4614753Speter cyclep -> cycleno , cyclep -> index ); 4624753Speter } 4634753Speter 4644753Speter /* 4654753Speter * print the members of a cycle 4664753Speter */ 4674753Speter printmembers( cyclep ) 4684753Speter nltype *cyclep; 4694753Speter { 4704753Speter nltype *memberp; 4714753Speter 4724753Speter sortmembers( cyclep ); 4734753Speter for ( memberp = cyclep -> cnext ; memberp ; memberp = memberp -> cnext ) { 4744753Speter printf( "%6.6s %5.5s %7.2f %11.2f %7d" , 47510248Speter "" , "" , memberp -> propself / hz , memberp -> propchild / hz , 4764753Speter memberp -> ncall ); 4774753Speter if ( memberp -> selfcalls != 0 ) { 4784753Speter printf( "+%-7d" , memberp -> selfcalls ); 4794753Speter } else { 4804753Speter printf( " %7.7s" , "" ); 4814753Speter } 4824753Speter printf( " " ); 4834753Speter printname( memberp ); 4844753Speter printf( "\n" ); 4854753Speter } 4864753Speter } 4874753Speter 4884753Speter /* 4894753Speter * sort members of a cycle 4904753Speter */ 4914753Speter sortmembers( cyclep ) 4924753Speter nltype *cyclep; 4934753Speter { 4944753Speter nltype *todo; 4954753Speter nltype *doing; 4964753Speter nltype *prev; 4974753Speter 4984753Speter /* 4994753Speter * detach cycle members from cyclehead, 5004753Speter * and insertion sort them back on. 5014753Speter */ 5024753Speter todo = cyclep -> cnext; 5034753Speter cyclep -> cnext = 0; 50411798Speter for ( (doing = todo)&&(todo = doing -> cnext); 5054753Speter doing ; 50611798Speter (doing = todo )&&(todo = doing -> cnext )){ 5074753Speter for ( prev = cyclep ; prev -> cnext ; prev = prev -> cnext ) { 5084753Speter if ( membercmp( doing , prev -> cnext ) == GREATERTHAN ) { 5094753Speter break; 5104753Speter } 5114753Speter } 5124753Speter doing -> cnext = prev -> cnext; 5134753Speter prev -> cnext = doing; 5144753Speter } 5154753Speter } 5164753Speter 5174753Speter /* 5187222Speter * major sort is on propself + propchild, 5194753Speter * next is sort on ncalls + selfcalls. 5204753Speter */ 5214842Speter int 5224753Speter membercmp( this , that ) 5234753Speter nltype *this; 5244753Speter nltype *that; 5254753Speter { 5267222Speter double thistime = this -> propself + this -> propchild; 5277222Speter double thattime = that -> propself + that -> propchild; 5284753Speter long thiscalls = this -> ncall + this -> selfcalls; 5294753Speter long thatcalls = that -> ncall + that -> selfcalls; 5304753Speter 5314753Speter if ( thistime > thattime ) { 5324753Speter return GREATERTHAN; 5334753Speter } 5344753Speter if ( thistime < thattime ) { 5354753Speter return LESSTHAN; 5364753Speter } 5374753Speter if ( thiscalls > thatcalls ) { 5384753Speter return GREATERTHAN; 5394753Speter } 5404753Speter if ( thiscalls < thatcalls ) { 5414753Speter return LESSTHAN; 5424753Speter } 5434753Speter return EQUALTO; 5444753Speter } 5454753Speter /* 5464515Speter * compare two arcs to/from the same child/parent. 5474515Speter * - if one arc is a self arc, it's least. 5484515Speter * - if one arc is within a cycle, it's less than. 5494515Speter * - if both arcs are within a cycle, compare arc counts. 5504515Speter * - if neither arc is within a cycle, compare with 5517222Speter * arc_time + arc_childtime as major key 5524515Speter * arc count as minor key 5534515Speter */ 5544515Speter int 5554515Speter arccmp( thisp , thatp ) 5564515Speter arctype *thisp; 5574515Speter arctype *thatp; 5584515Speter { 5594515Speter nltype *thisparentp = thisp -> arc_parentp; 5604515Speter nltype *thischildp = thisp -> arc_childp; 5614515Speter nltype *thatparentp = thatp -> arc_parentp; 5624515Speter nltype *thatchildp = thatp -> arc_childp; 5634515Speter double thistime; 5644515Speter double thattime; 5654515Speter 5664515Speter # ifdef DEBUG 5674515Speter if ( debug & TIMEDEBUG ) { 5684515Speter printf( "[arccmp] " ); 5694515Speter printname( thisparentp ); 5704515Speter printf( " calls " ); 5714515Speter printname ( thischildp ); 5724515Speter printf( " %f + %f %d/%d\n" , 5734515Speter thisp -> arc_time , thisp -> arc_childtime , 5744515Speter thisp -> arc_count , thischildp -> ncall ); 5754515Speter printf( "[arccmp] " ); 5764515Speter printname( thatparentp ); 5774515Speter printf( " calls " ); 5784515Speter printname( thatchildp ); 5794515Speter printf( " %f + %f %d/%d\n" , 5804515Speter thatp -> arc_time , thatp -> arc_childtime , 5814515Speter thatp -> arc_count , thatchildp -> ncall ); 5824515Speter printf( "\n" ); 5834515Speter } 5844515Speter # endif DEBUG 5854515Speter if ( thisparentp == thischildp ) { 5864515Speter /* this is a self call */ 5874515Speter return LESSTHAN; 5884515Speter } 5894515Speter if ( thatparentp == thatchildp ) { 5904515Speter /* that is a self call */ 5914515Speter return GREATERTHAN; 5924515Speter } 5934515Speter if ( thisparentp -> cycleno != 0 && thischildp -> cycleno != 0 && 5944515Speter thisparentp -> cycleno == thischildp -> cycleno ) { 5954515Speter /* this is a call within a cycle */ 5964515Speter if ( thatparentp -> cycleno != 0 && thatchildp -> cycleno != 0 && 5974515Speter thatparentp -> cycleno == thatchildp -> cycleno ) { 5984515Speter /* that is a call within the cycle, too */ 5994515Speter if ( thisp -> arc_count < thatp -> arc_count ) { 6004515Speter return LESSTHAN; 6014515Speter } 6024515Speter if ( thisp -> arc_count > thatp -> arc_count ) { 6034515Speter return GREATERTHAN; 6044515Speter } 6054515Speter return EQUALTO; 6064515Speter } else { 6074515Speter /* that isn't a call within the cycle */ 6084515Speter return LESSTHAN; 6094515Speter } 6104515Speter } else { 6114515Speter /* this isn't a call within a cycle */ 6124515Speter if ( thatparentp -> cycleno != 0 && thatchildp -> cycleno != 0 && 6134515Speter thatparentp -> cycleno == thatchildp -> cycleno ) { 6144515Speter /* that is a call within a cycle */ 6154515Speter return GREATERTHAN; 6164515Speter } else { 6174515Speter /* neither is a call within a cycle */ 6184515Speter thistime = thisp -> arc_time + thisp -> arc_childtime; 6194515Speter thattime = thatp -> arc_time + thatp -> arc_childtime; 6204515Speter if ( thistime < thattime ) 6214515Speter return LESSTHAN; 6224515Speter if ( thistime > thattime ) 6234515Speter return GREATERTHAN; 6244515Speter if ( thisp -> arc_count < thatp -> arc_count ) 6254515Speter return LESSTHAN; 6264515Speter if ( thisp -> arc_count > thatp -> arc_count ) 6274515Speter return GREATERTHAN; 6284515Speter return EQUALTO; 6294515Speter } 6304515Speter } 6314515Speter } 6324854Speter 6334854Speter printblurb( blurbname ) 6344854Speter char *blurbname; 6354854Speter { 6364854Speter FILE *blurbfile; 6374854Speter int input; 6384854Speter 63910285Speter blurbfile = fopen( blurbname , "r" ); 6404854Speter if ( blurbfile == NULL ) { 64110285Speter perror( blurbname ); 6424854Speter return; 6434854Speter } 6444854Speter while ( ( input = getc( blurbfile ) ) != EOF ) { 6454854Speter putchar( input ); 6464854Speter } 6474854Speter fclose( blurbfile ); 6484854Speter } 64916853Smckusick 65016853Smckusick int 65116853Smckusick namecmp( npp1 , npp2 ) 65216853Smckusick nltype **npp1, **npp2; 65316853Smckusick { 65416853Smckusick return( strcmp( (*npp1) -> name , (*npp2) -> name ) ); 65516853Smckusick } 65616853Smckusick 65716853Smckusick printindex() 65816853Smckusick { 65916853Smckusick nltype **namesortnlp; 66016853Smckusick register nltype *nlp; 66116853Smckusick int index, nnames, todo, i, j; 66216853Smckusick char peterbuffer[ BUFSIZ ]; 66316853Smckusick 66416853Smckusick /* 66516853Smckusick * Now, sort regular function name alphbetically 66616853Smckusick * to create an index. 66716853Smckusick */ 66816853Smckusick namesortnlp = (nltype **) calloc( nname + ncycle , sizeof(nltype *) ); 66916853Smckusick if ( namesortnlp == (nltype **) 0 ) { 67016853Smckusick fprintf( stderr , "%s: ran out of memory for sorting\n" , whoami ); 67116853Smckusick } 67216853Smckusick for ( index = 0 , nnames = 0 ; index < nname ; index++ ) { 67316853Smckusick if ( zflag == 0 && nl[index].ncall == 0 && nl[index].time == 0 ) 67416853Smckusick continue; 67516853Smckusick namesortnlp[nnames++] = &nl[index]; 67616853Smckusick } 67716853Smckusick qsort( namesortnlp , nnames , sizeof(nltype *) , namecmp ); 67816853Smckusick for ( index = 1 , todo = nnames ; index <= ncycle ; index++ ) { 67916853Smckusick namesortnlp[todo++] = &cyclenl[index]; 68016853Smckusick } 68116853Smckusick printf( "\f\nIndex by function name\n\n" ); 68216853Smckusick index = ( todo + 2 ) / 3; 68316853Smckusick for ( i = 0; i < index ; i++ ) { 68416853Smckusick for ( j = i; j < todo ; j += index ) { 68516853Smckusick nlp = namesortnlp[ j ]; 68616853Smckusick if ( nlp -> printflag ) { 68716853Smckusick sprintf( peterbuffer , "[%d]" , nlp -> index ); 68816853Smckusick } else { 68916853Smckusick sprintf( peterbuffer , "(%d)" , nlp -> index ); 69016853Smckusick } 69116853Smckusick if ( j < nnames ) { 69216853Smckusick printf( "%6.6s %-19.19s" , peterbuffer , nlp -> name ); 69316853Smckusick } else { 69416853Smckusick printf( "%6.6s " , peterbuffer ); 69516853Smckusick sprintf( peterbuffer , "<cycle %d>" , nlp -> cycleno ); 69616853Smckusick printf( "%-19.19s" , peterbuffer ); 69716853Smckusick } 69816853Smckusick } 69916853Smckusick printf( "\n" ); 70016853Smckusick } 70116853Smckusick cfree( namesortnlp ); 70216853Smckusick } 703