Beispiel #1
0
/*
 *	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 */
}
Beispiel #2
0
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);
}