diff options
author | bde <bde@FreeBSD.org> | 1995-12-29 15:30:05 +0000 |
---|---|---|
committer | bde <bde@FreeBSD.org> | 1995-12-29 15:30:05 +0000 |
commit | 586cc683d875b37dce82c825feb9ccc7d884b35e (patch) | |
tree | 9ce1e55534d3d930aead3ff55aeb7fcedbc086a4 /sys/amd64/include/profile.h | |
parent | ff6f507f6bbb3fda77fb14c7201db37bafea7a3f (diff) | |
download | FreeBSD-src-586cc683d875b37dce82c825feb9ccc7d884b35e.zip FreeBSD-src-586cc683d875b37dce82c825feb9ccc7d884b35e.tar.gz |
Implemented non-statistical kernel profiling. This is based on
looking at a high resolution clock for each of the following events:
function call, function return, interrupt entry, interrupt exit,
and interesting branches. The differences between the times of
these events are added at appropriate places in a ordinary histogram
(as if very fast statistical profiling sampled the pc at those
places) so that ordinary gprof can be used to analyze the times.
gmon.h:
Histogram counters need to be 4 bytes for microsecond resolutions.
They will need to be larger for the 586 clock.
The comments were vax-centric and wrong even on vaxes. Does anyone
disagree?
gprof4.c:
The standard gprof should support counters of all integral sizes
and the size of the counter should be in the gmon header. This
hack will do until then. (Use gprof4 -u to examine the results
of non-statistical profiling.)
config/*:
Non-statistical profiling is configured with `config -pp'.
`config -p' still gives ordinary profiling.
kgmon/*:
Non-statistical profiling is enabled with `kgmon -B'. `kgmon -b'
still enables ordinary profiling (and distables non-statistical
profiling) if non-statistical profiling is configured.
Diffstat (limited to 'sys/amd64/include/profile.h')
-rw-r--r-- | sys/amd64/include/profile.h | 54 |
1 files changed, 39 insertions, 15 deletions
diff --git a/sys/amd64/include/profile.h b/sys/amd64/include/profile.h index 9fe27ec..c55d629 100644 --- a/sys/amd64/include/profile.h +++ b/sys/amd64/include/profile.h @@ -31,35 +31,59 @@ * SUCH DAMAGE. * * @(#)profile.h 8.1 (Berkeley) 6/11/93 - * $Id: profile.h,v 1.3 1994/08/21 04:55:29 paul Exp $ + * $Id: profile.h,v 1.4 1994/09/15 16:27:14 paul Exp $ */ -#ifndef _I386_MACHINE_PROFILE_H_ -#define _I386_MACHINE_PROFILE_H_ +#ifndef _MACHINE_PROFILE_H_ +#define _MACHINE_PROFILE_H_ +#if 0 #define _MCOUNT_DECL static inline void _mcount #define MCOUNT \ extern void mcount() asm("mcount"); void mcount() { \ - int selfpc, frompcindex; \ + fptrint_t selfpc, frompc; \ /* \ - * find the return address for mcount, \ + * Find the return address for mcount, \ * and the return address for mcount's caller. \ * \ - * selfpc = pc pushed by mcount call \ + * selfpc = pc pushed by call to mcount \ */ \ asm("movl 4(%%ebp),%0" : "=r" (selfpc)); \ /* \ - * frompcindex = pc pushed by jsr into self. \ - * In GCC the caller's stack frame has already been built so we \ - * have to chase a6 to find caller's raddr. \ + * frompc = pc pushed by call to mcount's caller. \ + * The caller's stack frame has already been built, so %ebp is \ + * the caller's frame pointer. The caller's raddr is in the \ + * caller's frame following the caller's caller's frame pointer. \ */ \ - asm("movl (%%ebp),%0" : "=r" (frompcindex)); \ - frompcindex = ((int *)frompcindex)[1]; \ - _mcount(frompcindex, selfpc); \ + asm("movl (%%ebp),%0" : "=r" (frompc)); \ + frompc = ((fptrint_t *)frompc)[1]; \ + _mcount(frompc, selfpc); \ } +#else +#define _MCOUNT_DECL void mcount +#define MCOUNT +#endif -#define MCOUNT_ENTER save_eflags = read_eflags(); disable_intr() -#define MCOUNT_EXIT write_eflags(save_eflags) +#define MCOUNT_ENTER { save_eflags = read_eflags(); disable_intr(); } +#define MCOUNT_EXIT (write_eflags(save_eflags)) -#endif +#define CALIB_SCALE 1000 +#define KCOUNT(p,index) ((p)->kcount[(index) \ + / (HISTFRACTION * sizeof(*(p)->kcount))]) +#define PC_TO_I(p, pc) ((fptrint_t)(pc) - (fptrint_t)(p)->lowpc) + +/* An unsigned integral type that can hold function pointers. */ +typedef u_int fptrint_t; + +/* + * An unsigned integral type that can hold non-negative difference between + * function pointers. + */ +typedef int fptrdiff_t; + +u_int cputime __P((void)); +void mcount __P((fptrint_t frompc, fptrint_t selfpc)); +void mexitcount __P((fptrint_t selfpc)); + +#endif /* !MACHINE_PROFILE_H */ |