summaryrefslogtreecommitdiffstats
path: root/sys/i386/include/profile.h
diff options
context:
space:
mode:
authorbde <bde@FreeBSD.org>1995-12-29 15:30:05 +0000
committerbde <bde@FreeBSD.org>1995-12-29 15:30:05 +0000
commit586cc683d875b37dce82c825feb9ccc7d884b35e (patch)
tree9ce1e55534d3d930aead3ff55aeb7fcedbc086a4 /sys/i386/include/profile.h
parentff6f507f6bbb3fda77fb14c7201db37bafea7a3f (diff)
downloadFreeBSD-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/i386/include/profile.h')
-rw-r--r--sys/i386/include/profile.h54
1 files changed, 39 insertions, 15 deletions
diff --git a/sys/i386/include/profile.h b/sys/i386/include/profile.h
index 9fe27ec..c55d629 100644
--- a/sys/i386/include/profile.h
+++ b/sys/i386/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 */
OpenPOWER on IntegriCloud