1*4515Speter #ifndef lint 2*4515Speter static char *sccsid = "@(#)printgprof.c 1.1 (Berkeley) 10/15/81"; 3*4515Speter #endif lint 4*4515Speter 5*4515Speter #include "dprof.h" 6*4515Speter 7*4515Speter printdprof() 8*4515Speter { 9*4515Speter nltype **timesortnlp; 10*4515Speter int index; 11*4515Speter nltype *parentp; 12*4515Speter nltype *childp; 13*4515Speter 14*4515Speter /* 15*4515Speter * Now, sort by time + childtime. 16*4515Speter * include the cycle headers hiding out past nl[nname]. 17*4515Speter */ 18*4515Speter timesortnlp = (nltype **) calloc( nname+1+cyclemax , sizeof(nltype *) ); 19*4515Speter if ( timesortnlp == (nltype **) 0 ) { 20*4515Speter fprintf( stderr , "[doarcs] ran out of memory for sorting\n" ); 21*4515Speter } 22*4515Speter for ( index = 0 ; index < nname+1+cyclemax ; index++ ) { 23*4515Speter timesortnlp[index] = &nl[index]; 24*4515Speter } 25*4515Speter qsort( timesortnlp , nname+1+cyclemax , sizeof(nltype *) , totalcmp ); 26*4515Speter for ( index = 0 ; index < nname+1+cyclemax ; index++ ) { 27*4515Speter timesortnlp[ index ] -> index = index + 1; 28*4515Speter } 29*4515Speter /* 30*4515Speter * Now, print out the structured profiling list 31*4515Speter */ 32*4515Speter actime = 0.0; 33*4515Speter printf( "\f" ); 34*4515Speter putprofheader(); 35*4515Speter for ( index = 0 ; index < nname + 1 + cyclemax ; index ++ ) { 36*4515Speter parentp = timesortnlp[ index ]; 37*4515Speter if ( zflg == 0 && 38*4515Speter parentp -> ncall == 0 && 39*4515Speter parentp -> selfcalls == 0 && 40*4515Speter parentp -> time == 0 && 41*4515Speter parentp -> childtime == 0 ) { 42*4515Speter continue; 43*4515Speter } 44*4515Speter if ( parentp -> name == 0 && parentp -> cycleno != 0 ) { 45*4515Speter /* 46*4515Speter * cycle header 47*4515Speter */ 48*4515Speter putprofline( parentp , 0 ); 49*4515Speter for ( childp = parentp->cnext ; childp ; childp = childp->cnext ) { 50*4515Speter putprofline( childp , 0 ); 51*4515Speter } 52*4515Speter } else { 53*4515Speter printparents( parentp ); 54*4515Speter putprofline( parentp , 1 ); 55*4515Speter printchildren( parentp ); 56*4515Speter } 57*4515Speter printf( "\n" ); 58*4515Speter } 59*4515Speter actime = 0.0; 60*4515Speter } 61*4515Speter 62*4515Speter printparents( childp ) 63*4515Speter nltype *childp; 64*4515Speter { 65*4515Speter nltype *parentp; 66*4515Speter arctype *arcp; 67*4515Speter nltype *cycleheadp; 68*4515Speter 69*4515Speter if ( childp -> cyclehead != 0 ) { 70*4515Speter cycleheadp = childp -> cyclehead; 71*4515Speter } else { 72*4515Speter cycleheadp = childp; 73*4515Speter } 74*4515Speter if ( childp -> parents == 0 ) { 75*4515Speter printf( "\t%5.5s %7.7s %7.7s %7.7s %7.7s %7.7s <spontaneous>\n" , 76*4515Speter "" , "" , "" , "" , "" , "" ); 77*4515Speter return; 78*4515Speter } 79*4515Speter sortparents( childp ); 80*4515Speter for ( arcp = childp -> parents ; arcp ; arcp = arcp -> arc_parentlist ) { 81*4515Speter parentp = arcp -> arc_parentp; 82*4515Speter if ( childp == parentp || 83*4515Speter ( childp->cycleno != 0 && parentp->cycleno == childp->cycleno ) ) { 84*4515Speter /* 85*4515Speter * selfcall or call amoung siblings 86*4515Speter */ 87*4515Speter printf( "\t%5.5s %7.7s %7.7s %7.7s %7d %7.7s " , 88*4515Speter "" , "" , "" , "" , 89*4515Speter arcp -> arc_count , "" ); 90*4515Speter printname( parentp ); 91*4515Speter printf( "\n" ); 92*4515Speter } else { 93*4515Speter /* 94*4515Speter * regular parent of child 95*4515Speter */ 96*4515Speter printf( "\t%5.5s %7.7s %7.1f %7.1f %7d/%-7d " , "" , "" , 97*4515Speter arcp -> arc_time / HZ , arcp -> arc_childtime / HZ , 98*4515Speter arcp -> arc_count , cycleheadp -> ncall ); 99*4515Speter printname( parentp ); 100*4515Speter printf( "\n" ); 101*4515Speter } 102*4515Speter } 103*4515Speter } 104*4515Speter 105*4515Speter printchildren( parentp ) 106*4515Speter nltype *parentp; 107*4515Speter { 108*4515Speter nltype *childp; 109*4515Speter arctype *arcp; 110*4515Speter 111*4515Speter sortchildren( parentp ); 112*4515Speter arcp = parentp -> children; 113*4515Speter for ( arcp = parentp -> children ; arcp ; arcp = arcp -> arc_childlist ) { 114*4515Speter childp = arcp -> arc_childp; 115*4515Speter if ( childp == parentp || 116*4515Speter ( childp->cycleno != 0 && childp->cycleno == parentp->cycleno ) ) { 117*4515Speter /* 118*4515Speter * self call or call to sibling 119*4515Speter */ 120*4515Speter printf( "\t%5.5s %7.7s %7.7s %7.7s %7d %7.7s " , 121*4515Speter "" , "" , "" , "" , 122*4515Speter arcp -> arc_count , "" ); 123*4515Speter printname( childp ); 124*4515Speter printf( "\n" ); 125*4515Speter } else { 126*4515Speter /* 127*4515Speter * regular child of parent 128*4515Speter */ 129*4515Speter printf( "\t%5.5s %7.7s %7.1f %7.1f %7d/%-7d " , "" , "" , 130*4515Speter arcp -> arc_time / HZ , arcp -> arc_childtime / HZ , 131*4515Speter arcp -> arc_count , childp -> cyclehead -> ncall ); 132*4515Speter printname( childp ); 133*4515Speter printf( "\n" ); 134*4515Speter } 135*4515Speter } 136*4515Speter } 137*4515Speter 138*4515Speter printname( selfp ) 139*4515Speter nltype *selfp; 140*4515Speter { 141*4515Speter 142*4515Speter if ( selfp -> name != 0 ) { 143*4515Speter printf( "%s\t" , selfp -> name ); 144*4515Speter if ( selfp -> index != 0 ) { 145*4515Speter printf( "[%d] " , selfp -> index ); 146*4515Speter } 147*4515Speter # ifdef DEBUG 148*4515Speter if ( debug & DFNDEBUG ) { 149*4515Speter printf( "{%d} " , selfp -> toporder ); 150*4515Speter } 151*4515Speter # endif DEBUG 152*4515Speter } 153*4515Speter if ( selfp -> cycleno != 0 ) { 154*4515Speter printf( "<cycle %d>" , selfp -> cycleno ); 155*4515Speter } 156*4515Speter } 157*4515Speter 158*4515Speter sortchildren( parentp ) 159*4515Speter nltype *parentp; 160*4515Speter { 161*4515Speter arctype *arcp; 162*4515Speter arctype *detachedp; 163*4515Speter arctype sorted; 164*4515Speter arctype *prevp; 165*4515Speter 166*4515Speter /* 167*4515Speter * unlink children from parent, 168*4515Speter * then insertion sort back on to sorted's children. 169*4515Speter * *arcp the arc you have detached and are inserting. 170*4515Speter * *detachedp the rest of the arcs to be sorted. 171*4515Speter * sorted arc list onto which you insertion sort. 172*4515Speter * *prevp arc before the arc you are comparing. 173*4515Speter */ 174*4515Speter sorted.arc_childlist = 0; 175*4515Speter for ( arcp = parentp -> children , detachedp = arcp -> arc_childlist ; 176*4515Speter arcp ; 177*4515Speter arcp = detachedp , detachedp = detachedp -> arc_childlist ) { 178*4515Speter /* 179*4515Speter * consider *arcp as disconnected 180*4515Speter * insert it into sorted 181*4515Speter */ 182*4515Speter for ( prevp = &sorted ; 183*4515Speter prevp -> arc_childlist ; 184*4515Speter prevp = prevp -> arc_childlist ) { 185*4515Speter if ( arccmp( arcp , prevp -> arc_childlist ) != LESSTHAN ) { 186*4515Speter break; 187*4515Speter } 188*4515Speter } 189*4515Speter arcp -> arc_childlist = prevp -> arc_childlist; 190*4515Speter prevp -> arc_childlist = arcp; 191*4515Speter } 192*4515Speter /* 193*4515Speter * reattach sorted children to parent 194*4515Speter */ 195*4515Speter parentp -> children = sorted.arc_childlist; 196*4515Speter } 197*4515Speter 198*4515Speter sortparents( childp ) 199*4515Speter nltype *childp; 200*4515Speter { 201*4515Speter arctype *arcp; 202*4515Speter arctype *detachedp; 203*4515Speter arctype sorted; 204*4515Speter arctype *prevp; 205*4515Speter 206*4515Speter /* 207*4515Speter * unlink parents from child, 208*4515Speter * then insertion sort back on to sorted's parents. 209*4515Speter * *arcp the arc you have detached and are inserting. 210*4515Speter * *detachedp the rest of the arcs to be sorted. 211*4515Speter * sorted arc list onto which you insertion sort. 212*4515Speter * *prevp arc before the arc you are comparing. 213*4515Speter */ 214*4515Speter sorted.arc_parentlist = 0; 215*4515Speter for ( arcp = childp -> parents , detachedp = arcp -> arc_parentlist ; 216*4515Speter arcp ; 217*4515Speter arcp = detachedp , detachedp = detachedp -> arc_parentlist ) { 218*4515Speter /* 219*4515Speter * consider *arcp as disconnected 220*4515Speter * insert it into sorted 221*4515Speter */ 222*4515Speter for ( prevp = &sorted ; 223*4515Speter prevp -> arc_parentlist ; 224*4515Speter prevp = prevp -> arc_parentlist ) { 225*4515Speter if ( arccmp( arcp , prevp -> arc_parentlist ) != GREATERTHAN ) { 226*4515Speter break; 227*4515Speter } 228*4515Speter } 229*4515Speter arcp -> arc_parentlist = prevp -> arc_parentlist; 230*4515Speter prevp -> arc_parentlist = arcp; 231*4515Speter } 232*4515Speter /* 233*4515Speter * reattach sorted arcs to child 234*4515Speter */ 235*4515Speter childp -> parents = sorted.arc_parentlist; 236*4515Speter } 237*4515Speter 238*4515Speter /* 239*4515Speter * compare two arcs to/from the same child/parent. 240*4515Speter * - if one arc is a self arc, it's least. 241*4515Speter * - if one arc is within a cycle, it's less than. 242*4515Speter * - if both arcs are within a cycle, compare arc counts. 243*4515Speter * - if neither arc is within a cycle, compare with 244*4515Speter * time + childtime as major key 245*4515Speter * arc count as minor key 246*4515Speter */ 247*4515Speter int 248*4515Speter arccmp( thisp , thatp ) 249*4515Speter arctype *thisp; 250*4515Speter arctype *thatp; 251*4515Speter { 252*4515Speter nltype *thisparentp = thisp -> arc_parentp; 253*4515Speter nltype *thischildp = thisp -> arc_childp; 254*4515Speter nltype *thatparentp = thatp -> arc_parentp; 255*4515Speter nltype *thatchildp = thatp -> arc_childp; 256*4515Speter double thistime; 257*4515Speter double thattime; 258*4515Speter 259*4515Speter # ifdef DEBUG 260*4515Speter if ( debug & TIMEDEBUG ) { 261*4515Speter printf( "[arccmp] " ); 262*4515Speter printname( thisparentp ); 263*4515Speter printf( " calls " ); 264*4515Speter printname ( thischildp ); 265*4515Speter printf( " %f + %f %d/%d\n" , 266*4515Speter thisp -> arc_time , thisp -> arc_childtime , 267*4515Speter thisp -> arc_count , thischildp -> ncall ); 268*4515Speter printf( "[arccmp] " ); 269*4515Speter printname( thatparentp ); 270*4515Speter printf( " calls " ); 271*4515Speter printname( thatchildp ); 272*4515Speter printf( " %f + %f %d/%d\n" , 273*4515Speter thatp -> arc_time , thatp -> arc_childtime , 274*4515Speter thatp -> arc_count , thatchildp -> ncall ); 275*4515Speter printf( "\n" ); 276*4515Speter } 277*4515Speter # endif DEBUG 278*4515Speter if ( thisparentp == thischildp ) { 279*4515Speter /* this is a self call */ 280*4515Speter return LESSTHAN; 281*4515Speter } 282*4515Speter if ( thatparentp == thatchildp ) { 283*4515Speter /* that is a self call */ 284*4515Speter return GREATERTHAN; 285*4515Speter } 286*4515Speter if ( thisparentp -> cycleno != 0 && thischildp -> cycleno != 0 && 287*4515Speter thisparentp -> cycleno == thischildp -> cycleno ) { 288*4515Speter /* this is a call within a cycle */ 289*4515Speter if ( thatparentp -> cycleno != 0 && thatchildp -> cycleno != 0 && 290*4515Speter thatparentp -> cycleno == thatchildp -> cycleno ) { 291*4515Speter /* that is a call within the cycle, too */ 292*4515Speter if ( thisp -> arc_count < thatp -> arc_count ) { 293*4515Speter return LESSTHAN; 294*4515Speter } 295*4515Speter if ( thisp -> arc_count > thatp -> arc_count ) { 296*4515Speter return GREATERTHAN; 297*4515Speter } 298*4515Speter return EQUALTO; 299*4515Speter } else { 300*4515Speter /* that isn't a call within the cycle */ 301*4515Speter return LESSTHAN; 302*4515Speter } 303*4515Speter } else { 304*4515Speter /* this isn't a call within a cycle */ 305*4515Speter if ( thatparentp -> cycleno != 0 && thatchildp -> cycleno != 0 && 306*4515Speter thatparentp -> cycleno == thatchildp -> cycleno ) { 307*4515Speter /* that is a call within a cycle */ 308*4515Speter return GREATERTHAN; 309*4515Speter } else { 310*4515Speter /* neither is a call within a cycle */ 311*4515Speter thistime = thisp -> arc_time + thisp -> arc_childtime; 312*4515Speter thattime = thatp -> arc_time + thatp -> arc_childtime; 313*4515Speter if ( thistime < thattime ) 314*4515Speter return LESSTHAN; 315*4515Speter if ( thistime > thattime ) 316*4515Speter return GREATERTHAN; 317*4515Speter if ( thisp -> arc_count < thatp -> arc_count ) 318*4515Speter return LESSTHAN; 319*4515Speter if ( thisp -> arc_count > thatp -> arc_count ) 320*4515Speter return GREATERTHAN; 321*4515Speter return EQUALTO; 322*4515Speter } 323*4515Speter } 324*4515Speter } 325