FreeBSD/usr.bin/gprof/gprof.c
/*
 *	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).
 */
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





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).
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 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)
{
    register int	j;
    double		ccnt;
    double		thetime;
    unsigned long	pcl, pch;
    register int	i;
    unsigned long	overlap;
    unsigned long	svalue0, svalue1;
    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));
	thetime = ccnt;
#	ifdef DEBUG
	    if ( debug & SAMPLEDEBUG ) {
		printf( "[asgnsamples] pcl 0x%lx pch 0x%lx ccnt %.0f\n" ,
			pcl , pch , ccnt );
	    }
#	endif 
	totime += thetime;
	for (j = j - 1; j < nname; j++) {
	    svalue0 = nl[j].svalue;
	    svalue1 = nl[j+1].svalue;
	    if (pch < svalue0)
		    break;
	    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 %lu overlap\n",
				nl[j].value / HISTORICAL_SCALE_2,
				svalue0, svalue1, nl[j].name,
				overlap * thetime / scale, overlap);
		    }
#		endif 
		nl[j].time += overlap * thetime / scale;
	    }
	}
    }
#   ifdef DEBUG
	if (debug & SAMPLEDEBUG) {
	    printf("[asgnsamples] totime %f\n", totime);
	}
#   endif 
}
void asgnsamples ( void ) { register int j ; double ccnt ; double thetime ; unsigned long pcl , pch ; register int i ; unsigned long overlap ; unsigned long svalue0 , svalue1 ; 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 ) ) ; thetime = ccnt ; #	ifdef DEBUG if ( debug & SAMPLEDEBUG ) { printf ( " \n " , pcl , pch , ccnt ) ; } #	endif totime += thetime ; for ( j = j - 1 ; j < nname ; j ++ ) { svalue0 = nl [ j ] . svalue ; svalue1 = nl [ j + 1 ] . svalue ; if ( pch < svalue0 ) break ; if ( pcl >= svalue1 ) continue ; overlap = min ( pch , svalue1 ) - max ( pcl , svalue0 ) ; if ( overlap > 0 ) { #		ifdef DEBUG if ( debug & SAMPLEDEBUG ) { printf ( " \n " , nl [ j ] . value / HISTORICAL_SCALE_2 , svalue0 , svalue1 , nl [ j ] . name , overlap * thetime / scale , overlap ) ; } #		endif nl [ j ] . time += overlap * thetime / scale ; } } } #   ifdef DEBUG if ( debug & SAMPLEDEBUG ) { printf ( " \n " , totime ) ; } #   endif }
Assign samples to the procedures to which they belong.
Assign samples to the procedures to which they belong .
/* read samples and assign to namelist symbols */ /* DEBUG */ /*
		 *	if high end of tick is below entry address,
		 *	go for next tick.
		 */ /*
		 *	if low end of tick into next routine,
		 *	go for next routine.
		 */ /* DEBUG */ /* DEBUG */