/* * Assign samples to the procedures to which they belong. * * There are three cases as to where pcl and pch can be * with respect to the routine entry addresses svalue0 and svalue1 * as shown in the following diagram. overlap computes the * distance between the arrows, the fraction of the sample * that is to be credited to the routine which starts at svalue0. * * svalue0 svalue1 * | | * v v * * +-----------------------------------------------+ * | | * | ->| |<- ->| |<- ->| |<- | * | | | | | | * +---------+ +---------+ +---------+ * * ^ ^ ^ ^ ^ ^ * | | | | | | * pcl pch pcl pch pcl pch * * For the vax we assert that samples will never fall in the first * two bytes of any routine, since that is the entry mask, * thus we give call alignentries() to adjust the entry points if * the entry mask falls in one bucket but the code for the routine * doesn't start until the next bucket. In conjunction with the * alignment of routine addresses, this should allow us to have * only one sample for every four bytes of text space and never * have any overlap (the two end cases, above). */ void asgnsamples(void) { int j; UNIT ccnt; double time; unsigned long pcl, pch; unsigned long i; unsigned long overlap; unsigned long svalue0, svalue1; /* read samples and assign to namelist symbols */ scale = highpc - lowpc; scale /= nsamples; alignentries(); for (i = 0, j = 1; i < nsamples; i++) { ccnt = samples[i]; if (ccnt == 0) continue; pcl = lowpc + (unsigned long)(scale * i); pch = lowpc + (unsigned long)(scale * (i + 1)); time = ccnt; # ifdef DEBUG if ( debug & SAMPLEDEBUG ) { printf( "[asgnsamples] pcl 0x%lx pch 0x%lx ccnt %d\n" , pcl , pch , ccnt ); } # endif /* DEBUG */ totime += time; for (j = j - 1; j < nname; j++) { svalue0 = nl[j].svalue; svalue1 = nl[j+1].svalue; /* * if high end of tick is below entry address, * go for next tick. */ if (pch < svalue0) break; /* * if low end of tick into next routine, * go for next routine. */ if (pcl >= svalue1) continue; overlap = min(pch, svalue1) - max(pcl, svalue0); if (overlap > 0) { # ifdef DEBUG if (debug & SAMPLEDEBUG) { printf("[asgnsamples] (0x%lx->0x%lx-0x%lx) %s gets %f ticks %ld overlap\n", nl[j].value/sizeof(UNIT), svalue0, svalue1, nl[j].name, overlap * time / scale, overlap); } # endif /* DEBUG */ nl[j].time += overlap * time / scale; } } } # ifdef DEBUG if (debug & SAMPLEDEBUG) { printf("[asgnsamples] totime %f\n", totime); } # endif /* DEBUG */ }
int main( int argc, char **argv, char **envp) { uint32_t i; char **sp; nltype **timesortnlp; progname = argv[0]; --argc; argv++; debug = 0; bflag = TRUE; while(*argv != 0 && **argv == '-'){ (*argv)++; switch(**argv){ case 'a': aflag = TRUE; break; case 'b': bflag = FALSE; break; case 'c': printf("%s: -c not supported\n", progname); /* cflag = TRUE; */ break; case 'd': dflag = TRUE; (*argv)++; debug |= atoi(*argv); debug |= ANYDEBUG; #ifdef DEBUG printf("[main] debug = %u\n", debug); #else printf("%s: -d ignored\n", progname); #endif break; case 'E': ++argv; addlist(Elist, *argv); Eflag = TRUE; addlist(elist, *argv); eflag = TRUE; break; case 'e': addlist(elist, *++argv); eflag = TRUE; break; case 'F': ++argv; addlist(Flist, *argv); Fflag = TRUE; addlist(flist, *argv); fflag = TRUE; break; case 'f': addlist(flist, *++argv); fflag = TRUE; break; case 'S': Sflag = TRUE; break; case 's': sflag = TRUE; break; case 'x': xflag = TRUE; break; case 'z': zflag = TRUE; break; } argv++; } if(*argv != 0){ a_outname = *argv; argv++; } else{ a_outname = A_OUTNAME; } if(*argv != 0){ gmonname = *argv; argv++; } else{ gmonname = GMONNAME; } /* * Turn off default functions. */ for(sp = &defaultEs[0]; *sp; sp++){ Eflag = TRUE; addlist(Elist, *sp); eflag = TRUE; addlist(elist, *sp); } /* * Get information about a.out file. */ getnfile(); if(errors != 0) exit(1); /* * Get information about mon.out file(s). */ hz = 0; do{ getpfile(gmonname); if(*argv != 0){ gmonname = *argv; } }while(*argv++ != 0); /* * How many ticks per second? If we can't tell, report time in ticks. * If this was picked up from the mon.out files use that value. */ #ifndef __OPENSTEP__ if(hz == 0) #endif hz = hertz(); if(hz == 0){ hz = 1; fprintf(stderr, "time is in ticks, not seconds\n"); } /* * Dump out a gmon.sum file if requested. */ if(sflag){ dumpsum(GMONSUM); exit(0); } /* * Assign samples to procedures. */ alignentries(); for(i = 0; i < nsample_sets; i++) asgnsamples(sample_sets + i); /* * Assemble the dynamic profile. */ timesortnlp = doarcs(); /* * Print the dynamic profile. */ printgprof(timesortnlp); /* * Print the flat profile. */ printprof(); /* * Print the index. */ printindex(); /* * Dump out the order files if requested. */ if(Sflag) printscatter(); return(0); }