14515Speter #ifndef lint 2*7129Speter static char *sccsid = "@(#)printgprof.c 1.8 (Berkeley) 06/08/82"; 34515Speter #endif lint 44515Speter 54562Speter #include "gprof.h" 64515Speter 74753Speter printprof() 84753Speter { 94753Speter register nltype *np; 104753Speter nltype **sortednlp; 114753Speter int index; 124753Speter 134854Speter printf( "\ngranularity: each sample hit covers %d byte(s)" , (long) scale ); 144854Speter printf( " for %.2f%% of %.2f seconds\n\n" , 100.0/totime , totime / HZ ); 154753Speter actime = 0.0; 164753Speter flatprofheader(); 174753Speter /* 184753Speter * Sort the symbol table in by time 194753Speter */ 204753Speter sortednlp = (nltype **) calloc( nname , sizeof(nltype *) ); 214753Speter if ( sortednlp == (nltype **) 0 ) { 224753Speter fprintf( stderr , "[printprof] ran out of memory for time sorting\n" ); 234753Speter } 244753Speter for ( index = 0 ; index < nname ; index += 1 ) { 254753Speter sortednlp[ index ] = &nl[ index ]; 264753Speter } 274753Speter qsort( sortednlp , nname , sizeof(nltype *) , timecmp ); 284753Speter for ( index = 0 ; index < nname ; index += 1 ) { 294753Speter np = sortednlp[ index ]; 304753Speter flatprofline( np ); 314753Speter } 324753Speter actime = 0.0; 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 ) { 614854Speter printblurb( "flat.blurb" ); 624854Speter } 634753Speter printf( "%5.5s %7.7s %7.7s %7.7s %-8.8s\n" , 644753Speter "%time" , "cumsecs" , "seconds" , "calls" , "name" ); 654753Speter } 664753Speter 674753Speter flatprofline( np ) 684753Speter register nltype *np; 694753Speter { 704753Speter 714854Speter if ( zflag == 0 && np -> ncall == 0 && np -> time == 0 ) { 724753Speter return; 734753Speter } 744753Speter actime += np -> time; 754753Speter printf( "%5.1f %7.2f %7.2f" , 764753Speter 100 * np -> time / totime , actime / HZ , np -> time / HZ ); 774753Speter if ( np -> ncall != 0 ) { 784753Speter printf( " %7d" , np -> ncall ); 794753Speter } else { 804753Speter printf( " %7.7s" , "" ); 814753Speter } 824753Speter printf( " %s\n" , np -> name ); 834753Speter } 844753Speter 854753Speter gprofheader() 864753Speter { 874854Speter 884854Speter if ( bflag ) { 894854Speter printblurb( "callg.blurb" ); 904854Speter } 914753Speter printf( "%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s %-8.8s\n" , 924753Speter "" , "" , "" , "" , "called" , "total" , "parents" , "" ); 934753Speter printf( "%-6.6s %5.5s %7.7s %11.11s %7.7s+%-7.7s %-8.8s\t%5.5s\n" , 944753Speter "index" , "%time" , "self" , "descendents" , 954753Speter "called" , "self" , "name" , "index" ); 964753Speter printf( "%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s %-8.8s\n" , 974753Speter "" , "" , "" , "" , "called" , "total" , "children" , "" ); 984753Speter printf( "\n" ); 994753Speter } 1004753Speter 1014753Speter gprofline( np ) 1024753Speter register nltype *np; 1034753Speter { 1044753Speter char kirkbuffer[ BUFSIZ ]; 1054753Speter 1064753Speter sprintf( kirkbuffer , "[%d]" , np -> index ); 1074753Speter printf( "%-6.6s %5.1f %7.2f %11.2f" , 1084753Speter kirkbuffer , 1094753Speter 100 * ( np -> time + np -> childtime ) / totime , 1104753Speter np -> time / HZ , 1114753Speter np -> childtime / HZ ); 1124753Speter if ( ( np -> ncall + np -> selfcalls ) != 0 ) { 1134753Speter printf( " %7d" , np -> ncall ); 1144753Speter if ( np -> selfcalls != 0 ) { 1154753Speter printf( "+%-7d " , np -> selfcalls ); 1164753Speter } else { 1174753Speter printf( " %7.7s " , "" ); 1184753Speter } 1194753Speter } else { 1204753Speter printf( " %7.7s %7.7s " , "" , "" ); 1214753Speter } 1224753Speter printname( np ); 1234753Speter printf( "\n" ); 1244753Speter } 1254753Speter 1264562Speter printgprof() 1274515Speter { 1284515Speter nltype **timesortnlp; 1294515Speter int index; 1304515Speter nltype *parentp; 1314515Speter 1324515Speter /* 1334515Speter * Now, sort by time + childtime. 134*7129Speter * sorting both the regular function names 135*7129Speter * and cycle headers. 1364515Speter */ 137*7129Speter timesortnlp = (nltype **) calloc( nname + ncycle , sizeof(nltype *) ); 1384515Speter if ( timesortnlp == (nltype **) 0 ) { 139*7129Speter fprintf( stderr , "%s: ran out of memory for sorting\n" , whoami ); 1404515Speter } 1414753Speter for ( index = 0 ; index < nname ; index++ ) { 1424515Speter timesortnlp[index] = &nl[index]; 1434515Speter } 144*7129Speter for ( index = 1 ; index <= ncycle ; index++ ) { 145*7129Speter timesortnlp[nname+index-1] = &cyclenl[index]; 1464753Speter } 147*7129Speter qsort( timesortnlp , nname + ncycle , sizeof(nltype *) , totalcmp ); 148*7129Speter for ( index = 0 ; index < nname + ncycle ; index++ ) { 1494515Speter timesortnlp[ index ] -> index = index + 1; 1504515Speter } 1514515Speter /* 1524515Speter * Now, print out the structured profiling list 1534515Speter */ 1544753Speter printf( "\f\n" ); 1554753Speter gprofheader(); 156*7129Speter for ( index = 0 ; index < nname + ncycle ; index ++ ) { 1574515Speter parentp = timesortnlp[ index ]; 1584854Speter if ( zflag == 0 && 1594515Speter parentp -> ncall == 0 && 1604515Speter parentp -> selfcalls == 0 && 1614515Speter parentp -> time == 0 && 1624515Speter parentp -> childtime == 0 ) { 1634515Speter continue; 1644515Speter } 1654515Speter if ( parentp -> name == 0 && parentp -> cycleno != 0 ) { 1664515Speter /* 1674515Speter * cycle header 1684515Speter */ 1694753Speter printcycle( parentp ); 1704753Speter printmembers( parentp ); 1714515Speter } else { 1724515Speter printparents( parentp ); 1734753Speter gprofline( parentp ); 1744515Speter printchildren( parentp ); 1754515Speter } 1764515Speter printf( "\n" ); 1774753Speter printf( "-----------------------------------------------\n" ); 1784753Speter printf( "\n" ); 1794515Speter } 1804515Speter } 1814515Speter 1824856Speter /* 1834856Speter * sort by decreasing total time (time+childtime) 1844856Speter * if times are equal, but one is a cycle header, 1854856Speter * say that's first (e.g. less, i.e. -1). 1864856Speter * if one's name doesn't have an underscore and the other does, 1874856Speter * say the one is first. 1884856Speter * all else being equal, sort by names. 1894856Speter */ 1904856Speter int 1914856Speter totalcmp( npp1 , npp2 ) 1924856Speter nltype **npp1; 1934856Speter nltype **npp2; 1944856Speter { 1954856Speter register nltype *np1 = *npp1; 1964856Speter register nltype *np2 = *npp2; 1974856Speter double diff; 1984856Speter 1994856Speter diff = ( np1 -> time + np1 -> childtime ) 2004856Speter - ( np2 -> time + np2 -> childtime ); 2014856Speter if ( diff < 0.0 ) 2024856Speter return 1; 2034856Speter if ( diff > 0.0 ) 2044856Speter return -1; 2054856Speter if ( np1 -> name == 0 && np1 -> cycleno != 0 ) 2064856Speter return -1; 2074856Speter if ( np2 -> name == 0 && np2 -> cycleno != 0 ) 2084856Speter return 1; 2094856Speter if ( np1 -> name == 0 ) 2104856Speter return -1; 2114856Speter if ( np2 -> name == 0 ) 2124856Speter return 1; 2134856Speter if ( *(np1 -> name) != '_' && *(np2 -> name) == '_' ) 2144856Speter return -1; 2154856Speter if ( *(np1 -> name) == '_' && *(np2 -> name) != '_' ) 2164856Speter return 1; 2174856Speter return strcmp( np1 -> name , np2 -> name ); 2184856Speter } 2194856Speter 2204515Speter printparents( childp ) 2214515Speter nltype *childp; 2224515Speter { 2234515Speter nltype *parentp; 2244515Speter arctype *arcp; 2254515Speter nltype *cycleheadp; 2264515Speter 2274515Speter if ( childp -> cyclehead != 0 ) { 2284515Speter cycleheadp = childp -> cyclehead; 2294515Speter } else { 2304515Speter cycleheadp = childp; 2314515Speter } 2324515Speter if ( childp -> parents == 0 ) { 2334753Speter printf( "%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s <spontaneous>\n" , 2344515Speter "" , "" , "" , "" , "" , "" ); 2354515Speter return; 2364515Speter } 2374515Speter sortparents( childp ); 2384515Speter for ( arcp = childp -> parents ; arcp ; arcp = arcp -> arc_parentlist ) { 2394515Speter parentp = arcp -> arc_parentp; 2404515Speter if ( childp == parentp || 2414515Speter ( childp->cycleno != 0 && parentp->cycleno == childp->cycleno ) ) { 2424515Speter /* 2434753Speter * selfcall or call among siblings 2444515Speter */ 2454753Speter printf( "%6.6s %5.5s %7.7s %11.11s %7d %7.7s " , 2464515Speter "" , "" , "" , "" , 2474515Speter arcp -> arc_count , "" ); 2484515Speter printname( parentp ); 2494515Speter printf( "\n" ); 2504515Speter } else { 2514515Speter /* 2524515Speter * regular parent of child 2534515Speter */ 2544753Speter printf( "%6.6s %5.5s %7.2f %11.2f %7d/%-7d " , 2554753Speter "" , "" , 2564515Speter arcp -> arc_time / HZ , arcp -> arc_childtime / HZ , 2574515Speter arcp -> arc_count , cycleheadp -> ncall ); 2584515Speter printname( parentp ); 2594515Speter printf( "\n" ); 2604515Speter } 2614515Speter } 2624515Speter } 2634515Speter 2644515Speter printchildren( parentp ) 2654515Speter nltype *parentp; 2664515Speter { 2674515Speter nltype *childp; 2684515Speter arctype *arcp; 2694515Speter 2704515Speter sortchildren( parentp ); 2714515Speter arcp = parentp -> children; 2724515Speter for ( arcp = parentp -> children ; arcp ; arcp = arcp -> arc_childlist ) { 2734515Speter childp = arcp -> arc_childp; 2744515Speter if ( childp == parentp || 2754515Speter ( childp->cycleno != 0 && childp->cycleno == parentp->cycleno ) ) { 2764515Speter /* 2774515Speter * self call or call to sibling 2784515Speter */ 2794753Speter printf( "%6.6s %5.5s %7.7s %11.11s %7d %7.7s " , 2804753Speter "" , "" , "" , "" , arcp -> arc_count , "" ); 2814515Speter printname( childp ); 2824515Speter printf( "\n" ); 2834515Speter } else { 2844515Speter /* 2854515Speter * regular child of parent 2864515Speter */ 2874753Speter printf( "%6.6s %5.5s %7.2f %11.2f %7d/%-7d " , 2884753Speter "" , "" , 2894515Speter arcp -> arc_time / HZ , arcp -> arc_childtime / HZ , 2904515Speter arcp -> arc_count , childp -> cyclehead -> ncall ); 2914515Speter printname( childp ); 2924515Speter printf( "\n" ); 2934515Speter } 2944515Speter } 2954515Speter } 2964515Speter 2974515Speter printname( selfp ) 2984515Speter nltype *selfp; 2994515Speter { 3004515Speter 3014515Speter if ( selfp -> name != 0 ) { 3024753Speter printf( "%s" , selfp -> name ); 3034515Speter # ifdef DEBUG 3044515Speter if ( debug & DFNDEBUG ) { 3054515Speter printf( "{%d} " , selfp -> toporder ); 3064515Speter } 3074515Speter # endif DEBUG 3084515Speter } 3094842Speter if ( selfp -> cycleno != 0 ) { 3104842Speter printf( "\t<cycle %d>" , selfp -> cycleno ); 3114842Speter } 3124753Speter if ( selfp -> index != 0 ) { 3134842Speter printf( " [%d]" , selfp -> index ); 3144753Speter } 3154515Speter } 3164515Speter 3174515Speter sortchildren( parentp ) 3184515Speter nltype *parentp; 3194515Speter { 3204515Speter arctype *arcp; 3214515Speter arctype *detachedp; 3224515Speter arctype sorted; 3234515Speter arctype *prevp; 3244515Speter 3254515Speter /* 3264515Speter * unlink children from parent, 3274515Speter * then insertion sort back on to sorted's children. 3284515Speter * *arcp the arc you have detached and are inserting. 3294515Speter * *detachedp the rest of the arcs to be sorted. 3304515Speter * sorted arc list onto which you insertion sort. 3314515Speter * *prevp arc before the arc you are comparing. 3324515Speter */ 3334515Speter sorted.arc_childlist = 0; 3344515Speter for ( arcp = parentp -> children , detachedp = arcp -> arc_childlist ; 3354515Speter arcp ; 3364515Speter arcp = detachedp , detachedp = detachedp -> arc_childlist ) { 3374515Speter /* 3384515Speter * consider *arcp as disconnected 3394515Speter * insert it into sorted 3404515Speter */ 3414515Speter for ( prevp = &sorted ; 3424515Speter prevp -> arc_childlist ; 3434515Speter prevp = prevp -> arc_childlist ) { 3444515Speter if ( arccmp( arcp , prevp -> arc_childlist ) != LESSTHAN ) { 3454515Speter break; 3464515Speter } 3474515Speter } 3484515Speter arcp -> arc_childlist = prevp -> arc_childlist; 3494515Speter prevp -> arc_childlist = arcp; 3504515Speter } 3514515Speter /* 3524515Speter * reattach sorted children to parent 3534515Speter */ 3544515Speter parentp -> children = sorted.arc_childlist; 3554515Speter } 3564515Speter 3574515Speter sortparents( childp ) 3584515Speter nltype *childp; 3594515Speter { 3604515Speter arctype *arcp; 3614515Speter arctype *detachedp; 3624515Speter arctype sorted; 3634515Speter arctype *prevp; 3644515Speter 3654515Speter /* 3664515Speter * unlink parents from child, 3674515Speter * then insertion sort back on to sorted's parents. 3684515Speter * *arcp the arc you have detached and are inserting. 3694515Speter * *detachedp the rest of the arcs to be sorted. 3704515Speter * sorted arc list onto which you insertion sort. 3714515Speter * *prevp arc before the arc you are comparing. 3724515Speter */ 3734515Speter sorted.arc_parentlist = 0; 3744515Speter for ( arcp = childp -> parents , detachedp = arcp -> arc_parentlist ; 3754515Speter arcp ; 3764515Speter arcp = detachedp , detachedp = detachedp -> arc_parentlist ) { 3774515Speter /* 3784515Speter * consider *arcp as disconnected 3794515Speter * insert it into sorted 3804515Speter */ 3814515Speter for ( prevp = &sorted ; 3824515Speter prevp -> arc_parentlist ; 3834515Speter prevp = prevp -> arc_parentlist ) { 3844515Speter if ( arccmp( arcp , prevp -> arc_parentlist ) != GREATERTHAN ) { 3854515Speter break; 3864515Speter } 3874515Speter } 3884515Speter arcp -> arc_parentlist = prevp -> arc_parentlist; 3894515Speter prevp -> arc_parentlist = arcp; 3904515Speter } 3914515Speter /* 3924515Speter * reattach sorted arcs to child 3934515Speter */ 3944515Speter childp -> parents = sorted.arc_parentlist; 3954515Speter } 3964515Speter 3974515Speter /* 3984753Speter * print a cycle header 3994753Speter */ 4004753Speter printcycle( cyclep ) 4014753Speter nltype *cyclep; 4024753Speter { 4034753Speter char kirkbuffer[ BUFSIZ ]; 4044753Speter 4054753Speter sprintf( kirkbuffer , "[%d]" , cyclep -> index ); 4064753Speter printf( "%-6.6s %5.1f %7.2f %11.2f %7d" , 4074753Speter kirkbuffer , 4084753Speter 100 * ( cyclep -> time + cyclep -> childtime ) / totime , 4094753Speter cyclep -> time / HZ , 4104753Speter cyclep -> childtime / HZ , 4114753Speter cyclep -> ncall ); 4124753Speter if ( cyclep -> selfcalls != 0 ) { 4134753Speter printf( "+%-7d" , cyclep -> selfcalls ); 4144753Speter } else { 4154753Speter printf( " %7.7s" , "" ); 4164753Speter } 4174753Speter printf( " <cycle %d as a whole>\t[%d]\n" , 4184753Speter cyclep -> cycleno , cyclep -> index ); 4194753Speter } 4204753Speter 4214753Speter /* 4224753Speter * print the members of a cycle 4234753Speter */ 4244753Speter printmembers( cyclep ) 4254753Speter nltype *cyclep; 4264753Speter { 4274753Speter nltype *memberp; 4284753Speter 4294753Speter sortmembers( cyclep ); 4304753Speter for ( memberp = cyclep -> cnext ; memberp ; memberp = memberp -> cnext ) { 4314753Speter printf( "%6.6s %5.5s %7.2f %11.2f %7d" , 4324753Speter "" , "" , memberp -> time / HZ , memberp -> childtime / HZ , 4334753Speter memberp -> ncall ); 4344753Speter if ( memberp -> selfcalls != 0 ) { 4354753Speter printf( "+%-7d" , memberp -> selfcalls ); 4364753Speter } else { 4374753Speter printf( " %7.7s" , "" ); 4384753Speter } 4394753Speter printf( " " ); 4404753Speter printname( memberp ); 4414753Speter printf( "\n" ); 4424753Speter } 4434753Speter } 4444753Speter 4454753Speter /* 4464753Speter * sort members of a cycle 4474753Speter */ 4484753Speter sortmembers( cyclep ) 4494753Speter nltype *cyclep; 4504753Speter { 4514753Speter nltype *todo; 4524753Speter nltype *doing; 4534753Speter nltype *prev; 4544753Speter 4554753Speter /* 4564753Speter * detach cycle members from cyclehead, 4574753Speter * and insertion sort them back on. 4584753Speter */ 4594753Speter todo = cyclep -> cnext; 4604753Speter cyclep -> cnext = 0; 4614753Speter for ( doing = todo , todo = doing -> cnext ; 4624753Speter doing ; 4634753Speter doing = todo , todo = doing -> cnext ) { 4644753Speter for ( prev = cyclep ; prev -> cnext ; prev = prev -> cnext ) { 4654753Speter if ( membercmp( doing , prev -> cnext ) == GREATERTHAN ) { 4664753Speter break; 4674753Speter } 4684753Speter } 4694753Speter doing -> cnext = prev -> cnext; 4704753Speter prev -> cnext = doing; 4714753Speter } 4724753Speter } 4734753Speter 4744753Speter /* 4754753Speter * major sort is on time + childtime, 4764753Speter * next is sort on ncalls + selfcalls. 4774753Speter */ 4784842Speter int 4794753Speter membercmp( this , that ) 4804753Speter nltype *this; 4814753Speter nltype *that; 4824753Speter { 4834753Speter double thistime = this -> time + this -> childtime; 4844753Speter double thattime = that -> time + that -> childtime; 4854753Speter long thiscalls = this -> ncall + this -> selfcalls; 4864753Speter long thatcalls = that -> ncall + that -> selfcalls; 4874753Speter 4884753Speter if ( thistime > thattime ) { 4894753Speter return GREATERTHAN; 4904753Speter } 4914753Speter if ( thistime < thattime ) { 4924753Speter return LESSTHAN; 4934753Speter } 4944753Speter if ( thiscalls > thatcalls ) { 4954753Speter return GREATERTHAN; 4964753Speter } 4974753Speter if ( thiscalls < thatcalls ) { 4984753Speter return LESSTHAN; 4994753Speter } 5004753Speter return EQUALTO; 5014753Speter } 5024753Speter /* 5034515Speter * compare two arcs to/from the same child/parent. 5044515Speter * - if one arc is a self arc, it's least. 5054515Speter * - if one arc is within a cycle, it's less than. 5064515Speter * - if both arcs are within a cycle, compare arc counts. 5074515Speter * - if neither arc is within a cycle, compare with 5084515Speter * time + childtime as major key 5094515Speter * arc count as minor key 5104515Speter */ 5114515Speter int 5124515Speter arccmp( thisp , thatp ) 5134515Speter arctype *thisp; 5144515Speter arctype *thatp; 5154515Speter { 5164515Speter nltype *thisparentp = thisp -> arc_parentp; 5174515Speter nltype *thischildp = thisp -> arc_childp; 5184515Speter nltype *thatparentp = thatp -> arc_parentp; 5194515Speter nltype *thatchildp = thatp -> arc_childp; 5204515Speter double thistime; 5214515Speter double thattime; 5224515Speter 5234515Speter # ifdef DEBUG 5244515Speter if ( debug & TIMEDEBUG ) { 5254515Speter printf( "[arccmp] " ); 5264515Speter printname( thisparentp ); 5274515Speter printf( " calls " ); 5284515Speter printname ( thischildp ); 5294515Speter printf( " %f + %f %d/%d\n" , 5304515Speter thisp -> arc_time , thisp -> arc_childtime , 5314515Speter thisp -> arc_count , thischildp -> ncall ); 5324515Speter printf( "[arccmp] " ); 5334515Speter printname( thatparentp ); 5344515Speter printf( " calls " ); 5354515Speter printname( thatchildp ); 5364515Speter printf( " %f + %f %d/%d\n" , 5374515Speter thatp -> arc_time , thatp -> arc_childtime , 5384515Speter thatp -> arc_count , thatchildp -> ncall ); 5394515Speter printf( "\n" ); 5404515Speter } 5414515Speter # endif DEBUG 5424515Speter if ( thisparentp == thischildp ) { 5434515Speter /* this is a self call */ 5444515Speter return LESSTHAN; 5454515Speter } 5464515Speter if ( thatparentp == thatchildp ) { 5474515Speter /* that is a self call */ 5484515Speter return GREATERTHAN; 5494515Speter } 5504515Speter if ( thisparentp -> cycleno != 0 && thischildp -> cycleno != 0 && 5514515Speter thisparentp -> cycleno == thischildp -> cycleno ) { 5524515Speter /* this is a call within a cycle */ 5534515Speter if ( thatparentp -> cycleno != 0 && thatchildp -> cycleno != 0 && 5544515Speter thatparentp -> cycleno == thatchildp -> cycleno ) { 5554515Speter /* that is a call within the cycle, too */ 5564515Speter if ( thisp -> arc_count < thatp -> arc_count ) { 5574515Speter return LESSTHAN; 5584515Speter } 5594515Speter if ( thisp -> arc_count > thatp -> arc_count ) { 5604515Speter return GREATERTHAN; 5614515Speter } 5624515Speter return EQUALTO; 5634515Speter } else { 5644515Speter /* that isn't a call within the cycle */ 5654515Speter return LESSTHAN; 5664515Speter } 5674515Speter } else { 5684515Speter /* this isn't a call within a cycle */ 5694515Speter if ( thatparentp -> cycleno != 0 && thatchildp -> cycleno != 0 && 5704515Speter thatparentp -> cycleno == thatchildp -> cycleno ) { 5714515Speter /* that is a call within a cycle */ 5724515Speter return GREATERTHAN; 5734515Speter } else { 5744515Speter /* neither is a call within a cycle */ 5754515Speter thistime = thisp -> arc_time + thisp -> arc_childtime; 5764515Speter thattime = thatp -> arc_time + thatp -> arc_childtime; 5774515Speter if ( thistime < thattime ) 5784515Speter return LESSTHAN; 5794515Speter if ( thistime > thattime ) 5804515Speter return GREATERTHAN; 5814515Speter if ( thisp -> arc_count < thatp -> arc_count ) 5824515Speter return LESSTHAN; 5834515Speter if ( thisp -> arc_count > thatp -> arc_count ) 5844515Speter return GREATERTHAN; 5854515Speter return EQUALTO; 5864515Speter } 5874515Speter } 5884515Speter } 5894854Speter 5904854Speter printblurb( blurbname ) 5914854Speter char *blurbname; 5924854Speter { 5934854Speter char pathname[ BUFSIZ ]; 5944854Speter FILE *blurbfile; 5954854Speter int input; 5964854Speter 5974854Speter sprintf( pathname , "%s%s" , BLURBLIB , blurbname ); 5984854Speter blurbfile = fopen( pathname , "r" ); 5994854Speter if ( blurbfile == NULL ) { 6004854Speter perror( pathname ); 6014854Speter return; 6024854Speter } 6034854Speter while ( ( input = getc( blurbfile ) ) != EOF ) { 6044854Speter putchar( input ); 6054854Speter } 6064854Speter fclose( blurbfile ); 6074854Speter } 608