* Copyright (c) 1983 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
static char sccsid
[] = "@(#)printgprof.c 5.1 (Berkeley) %G%";
* Sort the symbol table in by time
sortednlp
= (nltype
**) calloc( nname
, sizeof(nltype
*) );
if ( sortednlp
== (nltype
**) 0 ) {
fprintf( stderr
, "[printprof] ran out of memory for time sorting\n" );
for ( index
= 0 ; index
< nname
; index
+= 1 ) {
sortednlp
[ index
] = &nl
[ index
];
qsort( sortednlp
, nname
, sizeof(nltype
*) , timecmp
);
for ( index
= 0 ; index
< nname
; index
+= 1 ) {
timediff
= (*npp2
) -> time
- (*npp1
) -> time
;
calldiff
= (*npp2
) -> ncall
- (*npp1
) -> ncall
;
return( strcmp( (*npp1
) -> name
, (*npp2
) -> name
) );
* header for flatprofline
printblurb( FLAT_BLURB
);
printf( "\ngranularity: each sample hit covers %d byte(s)" ,
(long) scale
* sizeof(UNIT
) );
printf( " for %.2f%% of %.2f seconds\n\n" ,
100.0/totime
, totime
/ hz
);
printf( " no time accumulated\n\n" );
* this doesn't hurt sinc eall the numerators will be zero.
printf( "%5.5s %10.10s %8.8s %8.8s %8.8s %8.8s %-8.8s\n" ,
"% " , "cumulative" , "self " , "" , "self " , "total " , "" );
printf( "%5.5s %10.10s %8.8s %8.8s %8.8s %8.8s %-8.8s\n" ,
"time" , "seconds " , "seconds" , "calls" ,
"ms/call" , "ms/call" , "name" );
if ( zflag
== 0 && np
-> ncall
== 0 && np
-> time
== 0 ) {
printf( "%5.1f %10.2f %8.2f" ,
100 * np
-> time
/ totime
, actime
/ hz
, np
-> time
/ hz
);
if ( np
-> ncall
!= 0 ) {
printf( " %8d %8.2f %8.2f " , np
-> ncall
,
1000 * np
-> time
/ hz
/ np
-> ncall
,
1000 * ( np
-> time
+ np
-> childtime
) / hz
/ np
-> ncall
);
printf( " %8.8s %8.8s %8.8s " , "" , "" , "" );
printblurb( CALLG_BLURB
);
printf( "\ngranularity: each sample hit covers %d byte(s)" ,
(long) scale
* sizeof(UNIT
) );
printf( " for %.2f%% of %.2f seconds\n\n" ,
100.0/printtime
, printtime
/ hz
);
printf( " no time propagated\n\n" );
* this doesn't hurt, since all the numerators will be 0.0
printf( "%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s %-8.8s\n" ,
"" , "" , "" , "" , "called" , "total" , "parents" , "" );
printf( "%-6.6s %5.5s %7.7s %11.11s %7.7s+%-7.7s %-8.8s\t%5.5s\n" ,
"index" , "%time" , "self" , "descendents" ,
"called" , "self" , "name" , "index" );
printf( "%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s %-8.8s\n" ,
"" , "" , "" , "" , "called" , "total" , "children" , "" );
char kirkbuffer
[ BUFSIZ
];
sprintf( kirkbuffer
, "[%d]" , np
-> index
);
printf( "%-6.6s %5.1f %7.2f %11.2f" ,
100 * ( np
-> propself
+ np
-> propchild
) / printtime
,
if ( ( np
-> ncall
+ np
-> selfcalls
) != 0 ) {
printf( " %7d" , np
-> ncall
);
if ( np
-> selfcalls
!= 0 ) {
printf( "+%-7d " , np
-> selfcalls
);
printf( " %7.7s " , "" );
printf( " %7.7s %7.7s " , "" , "" );
* Print out the structured profiling list
for ( index
= 0 ; index
< nname
+ ncycle
; index
++ ) {
parentp
= timesortnlp
[ index
];
parentp
-> selfcalls
== 0 &&
parentp
-> propself
== 0 &&
parentp
-> propchild
== 0 ) {
if ( ! parentp
-> printflag
) {
if ( parentp
-> name
== 0 && parentp
-> cycleno
!= 0 ) {
printchildren( parentp
);
printf( "-----------------------------------------------\n" );
* sort by decreasing propagated time
* if times are equal, but one is a cycle header,
* say that's first (e.g. less, i.e. -1).
* if one's name doesn't have an underscore and the other does,
* all else being equal, sort by names.
register nltype
*np1
= *npp1
;
register nltype
*np2
= *npp2
;
diff
= ( np1
-> propself
+ np1
-> propchild
)
- ( np2
-> propself
+ np2
-> propchild
);
if ( np1
-> name
== 0 && np1
-> cycleno
!= 0 )
if ( np2
-> name
== 0 && np2
-> cycleno
!= 0 )
if ( *(np1
-> name
) != '_' && *(np2
-> name
) == '_' )
if ( *(np1
-> name
) == '_' && *(np2
-> name
) != '_' )
if ( np1
-> ncall
> np2
-> ncall
)
if ( np1
-> ncall
< np2
-> ncall
)
return strcmp( np1
-> name
, np2
-> name
);
if ( childp
-> cyclehead
!= 0 ) {
cycleheadp
= childp
-> cyclehead
;
if ( childp
-> parents
== 0 ) {
printf( "%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s <spontaneous>\n" ,
"" , "" , "" , "" , "" , "" );
for ( arcp
= childp
-> parents
; arcp
; arcp
= arcp
-> arc_parentlist
) {
parentp
= arcp
-> arc_parentp
;
if ( childp
== parentp
||
( childp
->cycleno
!= 0 && parentp
->cycleno
== childp
->cycleno
) ) {
* selfcall or call among siblings
printf( "%6.6s %5.5s %7.7s %11.11s %7d %7.7s " ,
arcp
-> arc_count
, "" );
* regular parent of child
printf( "%6.6s %5.5s %7.2f %11.2f %7d/%-7d " ,
arcp
-> arc_time
/ hz
, arcp
-> arc_childtime
/ hz
,
arcp
-> arc_count
, cycleheadp
-> ncall
);
arcp
= parentp
-> children
;
for ( arcp
= parentp
-> children
; arcp
; arcp
= arcp
-> arc_childlist
) {
childp
= arcp
-> arc_childp
;
if ( childp
== parentp
||
( childp
->cycleno
!= 0 && childp
->cycleno
== parentp
->cycleno
) ) {
* self call or call to sibling
printf( "%6.6s %5.5s %7.7s %11.11s %7d %7.7s " ,
"" , "" , "" , "" , arcp
-> arc_count
, "" );
* regular child of parent
printf( "%6.6s %5.5s %7.2f %11.2f %7d/%-7d " ,
arcp
-> arc_time
/ hz
, arcp
-> arc_childtime
/ hz
,
arcp
-> arc_count
, childp
-> cyclehead
-> ncall
);
if ( selfp
-> name
!= 0 ) {
printf( "%s" , selfp
-> name
);
if ( debug
& DFNDEBUG
) {
printf( "{%d} " , selfp
-> toporder
);
if ( debug
& PROPDEBUG
) {
printf( "%5.2f%% " , selfp
-> propfraction
);
if ( selfp
-> cycleno
!= 0 ) {
printf( " <cycle %d>" , selfp
-> cycleno
);
if ( selfp
-> index
!= 0 ) {
if ( selfp
-> printflag
) {
printf( " [%d]" , selfp
-> index
);
printf( " (%d)" , selfp
-> index
);
* unlink children from parent,
* then insertion sort back on to sorted's children.
* *arcp the arc you have detached and are inserting.
* *detachedp the rest of the arcs to be sorted.
* sorted arc list onto which you insertion sort.
* *prevp arc before the arc you are comparing.
sorted
.arc_childlist
= 0;
for ( (arcp
= parentp
-> children
)&&(detachedp
= arcp
-> arc_childlist
);
(arcp
= detachedp
)&&(detachedp
= detachedp
-> arc_childlist
)) {
* consider *arcp as disconnected
prevp
= prevp
-> arc_childlist
) {
if ( arccmp( arcp
, prevp
-> arc_childlist
) != LESSTHAN
) {
arcp
-> arc_childlist
= prevp
-> arc_childlist
;
prevp
-> arc_childlist
= arcp
;
* reattach sorted children to parent
parentp
-> children
= sorted
.arc_childlist
;
* unlink parents from child,
* then insertion sort back on to sorted's parents.
* *arcp the arc you have detached and are inserting.
* *detachedp the rest of the arcs to be sorted.
* sorted arc list onto which you insertion sort.
* *prevp arc before the arc you are comparing.
sorted
.arc_parentlist
= 0;
for ( (arcp
= childp
-> parents
)&&(detachedp
= arcp
-> arc_parentlist
);
(arcp
= detachedp
)&&(detachedp
= detachedp
-> arc_parentlist
)) {
* consider *arcp as disconnected
prevp
-> arc_parentlist
;
prevp
= prevp
-> arc_parentlist
) {
if ( arccmp( arcp
, prevp
-> arc_parentlist
) != GREATERTHAN
) {
arcp
-> arc_parentlist
= prevp
-> arc_parentlist
;
prevp
-> arc_parentlist
= arcp
;
* reattach sorted arcs to child
childp
-> parents
= sorted
.arc_parentlist
;
char kirkbuffer
[ BUFSIZ
];
sprintf( kirkbuffer
, "[%d]" , cyclep
-> index
);
printf( "%-6.6s %5.1f %7.2f %11.2f %7d" ,
100 * ( cyclep
-> propself
+ cyclep
-> propchild
) / printtime
,
cyclep
-> propself
/ hz
,
cyclep
-> propchild
/ hz
,
if ( cyclep
-> selfcalls
!= 0 ) {
printf( "+%-7d" , cyclep
-> selfcalls
);
printf( " <cycle %d as a whole>\t[%d]\n" ,
cyclep
-> cycleno
, cyclep
-> index
);
* print the members of a cycle
for ( memberp
= cyclep
-> cnext
; memberp
; memberp
= memberp
-> cnext
) {
printf( "%6.6s %5.5s %7.2f %11.2f %7d" ,
"" , "" , memberp
-> propself
/ hz
, memberp
-> propchild
/ hz
,
if ( memberp
-> selfcalls
!= 0 ) {
printf( "+%-7d" , memberp
-> selfcalls
);
* sort members of a cycle
* detach cycle members from cyclehead,
* and insertion sort them back on.
for ( (doing
= todo
)&&(todo
= doing
-> cnext
);
(doing
= todo
)&&(todo
= doing
-> cnext
)){
for ( prev
= cyclep
; prev
-> cnext
; prev
= prev
-> cnext
) {
if ( membercmp( doing
, prev
-> cnext
) == GREATERTHAN
) {
doing
-> cnext
= prev
-> cnext
;
* major sort is on propself + propchild,
* next is sort on ncalls + selfcalls.
double thistime
= this -> propself
+ this -> propchild
;
double thattime
= that
-> propself
+ that
-> propchild
;
long thiscalls
= this -> ncall
+ this -> selfcalls
;
long thatcalls
= that
-> ncall
+ that
-> selfcalls
;
if ( thistime
> thattime
) {
if ( thistime
< thattime
) {
if ( thiscalls
> thatcalls
) {
if ( thiscalls
< thatcalls
) {
* compare two arcs to/from the same child/parent.
* - if one arc is a self arc, it's least.
* - if one arc is within a cycle, it's less than.
* - if both arcs are within a cycle, compare arc counts.
* - if neither arc is within a cycle, compare with
* arc_time + arc_childtime as major key
nltype
*thisparentp
= thisp
-> arc_parentp
;
nltype
*thischildp
= thisp
-> arc_childp
;
nltype
*thatparentp
= thatp
-> arc_parentp
;
nltype
*thatchildp
= thatp
-> arc_childp
;
if ( debug
& TIMEDEBUG
) {
printname( thisparentp
);
printname ( thischildp
);
printf( " %f + %f %d/%d\n" ,
thisp
-> arc_time
, thisp
-> arc_childtime
,
thisp
-> arc_count
, thischildp
-> ncall
);
printname( thatparentp
);
printf( " %f + %f %d/%d\n" ,
thatp
-> arc_time
, thatp
-> arc_childtime
,
thatp
-> arc_count
, thatchildp
-> ncall
);
if ( thisparentp
== thischildp
) {
/* this is a self call */
if ( thatparentp
== thatchildp
) {
/* that is a self call */
if ( thisparentp
-> cycleno
!= 0 && thischildp
-> cycleno
!= 0 &&
thisparentp
-> cycleno
== thischildp
-> cycleno
) {
/* this is a call within a cycle */
if ( thatparentp
-> cycleno
!= 0 && thatchildp
-> cycleno
!= 0 &&
thatparentp
-> cycleno
== thatchildp
-> cycleno
) {
/* that is a call within the cycle, too */
if ( thisp
-> arc_count
< thatp
-> arc_count
) {
if ( thisp
-> arc_count
> thatp
-> arc_count
) {
/* that isn't a call within the cycle */
/* this isn't a call within a cycle */
if ( thatparentp
-> cycleno
!= 0 && thatchildp
-> cycleno
!= 0 &&
thatparentp
-> cycleno
== thatchildp
-> cycleno
) {
/* that is a call within a cycle */
/* neither is a call within a cycle */
thistime
= thisp
-> arc_time
+ thisp
-> arc_childtime
;
thattime
= thatp
-> arc_time
+ thatp
-> arc_childtime
;
if ( thistime
< thattime
)
if ( thistime
> thattime
)
if ( thisp
-> arc_count
< thatp
-> arc_count
)
if ( thisp
-> arc_count
> thatp
-> arc_count
)
blurbfile
= fopen( blurbname
, "r" );
if ( blurbfile
== NULL
) {
while ( ( input
= getc( blurbfile
) ) != EOF
) {
return( strcmp( (*npp1
) -> name
, (*npp2
) -> name
) );
int index
, nnames
, todo
, i
, j
;
char peterbuffer
[ BUFSIZ
];
* Now, sort regular function name alphbetically
namesortnlp
= (nltype
**) calloc( nname
+ ncycle
, sizeof(nltype
*) );
if ( namesortnlp
== (nltype
**) 0 ) {
fprintf( stderr
, "%s: ran out of memory for sorting\n" , whoami
);
for ( index
= 0 , nnames
= 0 ; index
< nname
; index
++ ) {
if ( zflag
== 0 && nl
[index
].ncall
== 0 && nl
[index
].time
== 0 )
namesortnlp
[nnames
++] = &nl
[index
];
qsort( namesortnlp
, nnames
, sizeof(nltype
*) , namecmp
);
for ( index
= 1 , todo
= nnames
; index
<= ncycle
; index
++ ) {
namesortnlp
[todo
++] = &cyclenl
[index
];
printf( "\f\nIndex by function name\n\n" );
index
= ( todo
+ 2 ) / 3;
for ( i
= 0; i
< index
; i
++ ) {
for ( j
= i
; j
< todo
; j
+= index
) {
if ( nlp
-> printflag
) {
sprintf( peterbuffer
, "[%d]" , nlp
-> index
);
sprintf( peterbuffer
, "(%d)" , nlp
-> index
);
printf( "%6.6s %-19.19s" , peterbuffer
, nlp
-> name
);
printf( "%6.6s " , peterbuffer
);
sprintf( peterbuffer
, "<cycle %d>" , nlp
-> cycleno
);
printf( "%-19.19s" , peterbuffer
);