11541Srgrimes/*-
21541Srgrimes * Copyright (c) 1982, 1986, 1992, 1993
31541Srgrimes *	The Regents of the University of California.  All rights reserved.
41541Srgrimes *
51541Srgrimes * Redistribution and use in source and binary forms, with or without
61541Srgrimes * modification, are permitted provided that the following conditions
71541Srgrimes * are met:
81541Srgrimes * 1. Redistributions of source code must retain the above copyright
91541Srgrimes *    notice, this list of conditions and the following disclaimer.
101541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111541Srgrimes *    notice, this list of conditions and the following disclaimer in the
121541Srgrimes *    documentation and/or other materials provided with the distribution.
131541Srgrimes * 4. Neither the name of the University nor the names of its contributors
141541Srgrimes *    may be used to endorse or promote products derived from this software
151541Srgrimes *    without specific prior written permission.
161541Srgrimes *
171541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
181541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
191541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
201541Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
211541Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
221541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
231541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
241541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
251541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
261541Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
271541Srgrimes * SUCH DAMAGE.
281541Srgrimes *
291541Srgrimes *	@(#)gmon.h	8.2 (Berkeley) 1/4/94
3050477Speter * $FreeBSD$
311541Srgrimes */
321541Srgrimes
331541Srgrimes#ifndef _SYS_GMON_H_
341541Srgrimes#define _SYS_GMON_H_
351541Srgrimes
361541Srgrimes#include <machine/profile.h>
371541Srgrimes
381541Srgrimes/*
391541Srgrimes * Structure prepended to gmon.out profiling data file.
401541Srgrimes */
411541Srgrimesstruct gmonhdr {
421541Srgrimes	u_long	lpc;		/* base pc address of sample buffer */
431541Srgrimes	u_long	hpc;		/* max pc address of sampled buffer */
441541Srgrimes	int	ncnt;		/* size of sample buffer (plus this header) */
451541Srgrimes	int	version;	/* version number */
461541Srgrimes	int	profrate;	/* profiling clock rate */
4791009Sbde	int	histcounter_type; /* size (in bits) and sign of HISTCOUNTER */
4891009Sbde	int	spare[2];	/* reserved */
491541Srgrimes};
501541Srgrimes#define GMONVERSION	0x00051879
511541Srgrimes
521541Srgrimes/*
5313107Sbde * Type of histogram counters used in the kernel.
541541Srgrimes */
5513107Sbde#ifdef GPROF4
5627379Sbde#define	HISTCOUNTER	int64_t
5713107Sbde#else
581541Srgrimes#define	HISTCOUNTER	unsigned short
5913107Sbde#endif
601541Srgrimes
611541Srgrimes/*
6213107Sbde * Fraction of text space to allocate for histogram counters.
6313107Sbde * We allocate counters at the same or higher density as function
6413107Sbde * addresses, so that each counter belongs to a unique function.
6513107Sbde * A lower density of counters would give less resolution but a
6613107Sbde * higher density would be wasted.
671541Srgrimes */
6813107Sbde#define	HISTFRACTION	(FUNCTION_ALIGNMENT / sizeof(HISTCOUNTER) == 0 \
6913107Sbde			 ? 1 : FUNCTION_ALIGNMENT / sizeof(HISTCOUNTER))
701541Srgrimes
711541Srgrimes/*
721541Srgrimes * Fraction of text space to allocate for from hash buckets.
731541Srgrimes * The value of HASHFRACTION is based on the minimum number of bytes
741541Srgrimes * of separation between two subroutine call points in the object code.
751541Srgrimes * Given MIN_SUBR_SEPARATION bytes of separation the value of
761541Srgrimes * HASHFRACTION is calculated as:
771541Srgrimes *
781541Srgrimes *	HASHFRACTION = MIN_SUBR_SEPARATION / (2 * sizeof(short) - 1);
791541Srgrimes *
801541Srgrimes * For example, on the VAX, the shortest two call sequence is:
811541Srgrimes *
821541Srgrimes *	calls	$0,(r0)
831541Srgrimes *	calls	$0,(r0)
841541Srgrimes *
858876Srgrimes * which is separated by only three bytes, thus HASHFRACTION is
861541Srgrimes * calculated as:
871541Srgrimes *
881541Srgrimes *	HASHFRACTION = 3 / (2 * 2 - 1) = 1
891541Srgrimes *
901541Srgrimes * Note that the division above rounds down, thus if MIN_SUBR_FRACTION
911541Srgrimes * is less than three, this algorithm will not work!
921541Srgrimes *
938876Srgrimes * In practice, however, call instructions are rarely at a minimal
941541Srgrimes * distance.  Hence, we will define HASHFRACTION to be 2 across all
958876Srgrimes * architectures.  This saves a reasonable amount of space for
961541Srgrimes * profiling data structures without (in practice) sacrificing
971541Srgrimes * any granularity.
981541Srgrimes */
9913107Sbde/*
10013107Sbde * XXX I think the above analysis completely misses the point.  I think
10113107Sbde * the point is that addresses in different functions must hash to
10213107Sbde * different values.  Since the hash is essentially division by
10313107Sbde * sizeof(unsigned short), the correct formula is:
10413107Sbde *
10513107Sbde * 	HASHFRACTION = MIN_FUNCTION_ALIGNMENT / sizeof(unsigned short)
10613107Sbde *
10713107Sbde * Note that he unsigned short here has nothing to do with the one for
10813107Sbde * HISTFRACTION.
10913107Sbde *
11013107Sbde * Hash collisions from a two call sequence don't matter.  They get
11113107Sbde * handled like collisions for calls to different addresses from the
11213107Sbde * same address through a function pointer.
11313107Sbde */
11413107Sbde#define	HASHFRACTION	(FUNCTION_ALIGNMENT / sizeof(unsigned short) == 0 \
11513107Sbde			 ? 1 : FUNCTION_ALIGNMENT / sizeof(unsigned short))
1161541Srgrimes
1171541Srgrimes/*
1181541Srgrimes * percent of text space to allocate for tostructs with a minimum.
1191541Srgrimes */
1201541Srgrimes#define ARCDENSITY	2
1211541Srgrimes#define MINARCS		50
1221541Srgrimes
1236010Sbde/*
1246010Sbde * Limit on the number of arcs to so that arc numbers can be stored in
1256010Sbde * `*froms' and stored and incremented without overflow in links.
1266010Sbde */
1276010Sbde#define MAXARCS		(((u_long)1 << (8 * sizeof(u_short))) - 2)
1286010Sbde
1291541Srgrimesstruct tostruct {
1301541Srgrimes	u_long	selfpc;
1311541Srgrimes	long	count;
1321541Srgrimes	u_short	link;
1331541Srgrimes	u_short pad;
1341541Srgrimes};
1351541Srgrimes
1361541Srgrimes/*
1378876Srgrimes * a raw arc, with pointers to the calling site and
1381541Srgrimes * the called site and a count.
1391541Srgrimes */
1401541Srgrimesstruct rawarc {
1411541Srgrimes	u_long	raw_frompc;
1421541Srgrimes	u_long	raw_selfpc;
1431541Srgrimes	long	raw_count;
1441541Srgrimes};
1451541Srgrimes
1461541Srgrimes/*
1471541Srgrimes * general rounding functions.
1481541Srgrimes */
1498504Sdg#define ROUNDDOWN(x,y)	rounddown(x,y)
1508504Sdg#define ROUNDUP(x,y)	roundup(x,y)
1511541Srgrimes
1521541Srgrimes/*
1531541Srgrimes * The profiling data structures are housed in this structure.
1541541Srgrimes */
1551541Srgrimesstruct gmonparam {
1561541Srgrimes	int		state;
15713107Sbde	HISTCOUNTER	*kcount;
1581541Srgrimes	u_long		kcountsize;
1591541Srgrimes	u_short		*froms;
1601541Srgrimes	u_long		fromssize;
1611541Srgrimes	struct tostruct	*tos;
1621541Srgrimes	u_long		tossize;
1631541Srgrimes	long		tolimit;
16437629Sbde	uintfptr_t	lowpc;
16537629Sbde	uintfptr_t	highpc;
1661541Srgrimes	u_long		textsize;
1671541Srgrimes	u_long		hashfraction;
16819000Sbde	int		profrate;	/* XXX wrong type to match gmonhdr */
16913107Sbde	HISTCOUNTER	*cputime_count;
17019000Sbde	int		cputime_overhead;
17113107Sbde	HISTCOUNTER	*mcount_count;
17219000Sbde	int		mcount_overhead;
17319000Sbde	int		mcount_post_overhead;
17419000Sbde	int		mcount_pre_overhead;
17513107Sbde	HISTCOUNTER	*mexitcount_count;
17619000Sbde	int		mexitcount_overhead;
17719000Sbde	int		mexitcount_post_overhead;
17819000Sbde	int		mexitcount_pre_overhead;
17991009Sbde	int		histcounter_type;
1801541Srgrimes};
1811541Srgrimesextern struct gmonparam _gmonparam;
1821541Srgrimes
1831541Srgrimes/*
1841541Srgrimes * Possible states of profiling.
1851541Srgrimes */
1861541Srgrimes#define	GMON_PROF_ON	0
1871541Srgrimes#define	GMON_PROF_BUSY	1
1881541Srgrimes#define	GMON_PROF_ERROR	2
1891541Srgrimes#define	GMON_PROF_OFF	3
19013107Sbde#define	GMON_PROF_HIRES	4
1911541Srgrimes
1921541Srgrimes/*
1931541Srgrimes * Sysctl definitions for extracting profiling information from the kernel.
1941541Srgrimes */
1951541Srgrimes#define	GPROF_STATE	0	/* int: profiling enabling variable */
1961541Srgrimes#define	GPROF_COUNT	1	/* struct: profile tick count buffer */
1971541Srgrimes#define	GPROF_FROMS	2	/* struct: from location hash bucket */
1981541Srgrimes#define	GPROF_TOS	3	/* struct: destination/count structure */
1991541Srgrimes#define	GPROF_GMONPARAM	4	/* struct: profiling parameters (see above) */
20010407Sbde
201129444Sbde#ifdef _KERNEL
202129444Sbde
203129444Sbde#define	KCOUNT(p,index) \
204129444Sbde	((p)->kcount[(index) / (HISTFRACTION * sizeof(HISTCOUNTER))])
205129444Sbde#define	PC_TO_I(p, pc)	((uintfptr_t)(pc) - (uintfptr_t)(p)->lowpc)
206129444Sbde
207157268Sjhb#ifdef GUPROF
208157268Sjhb
209157268Sjhb#define	CALIB_SCALE	1000
210157268Sjhb
211129444Sbdeextern int	cputime_bias;
212129444Sbde
213129444Sbdeint	cputime(void);
214129444Sbdevoid	nullfunc_loop_profiled(void);
215129444Sbdevoid	nullfunc_profiled(void);
216129444Sbdevoid	startguprof(struct gmonparam *p);
217129444Sbdevoid	stopguprof(struct gmonparam *p);
218129444Sbde
219129444Sbde#else /* !GUPROF */
220129444Sbde
221129444Sbde#define	startguprof(p)
222129444Sbde#define	stopguprof(p)
223129444Sbde
224129444Sbde#endif /* GUPROF */
225129444Sbde
226129444Sbdevoid	empty_loop(void);
227129444Sbdevoid	kmupetext(uintfptr_t nhighpc);
228129444Sbdevoid	mexitcount(uintfptr_t selfpc);
229129444Sbdevoid	nullfunc(void);
230129444Sbdevoid	nullfunc_loop(void);
231129444Sbde
232130484Sbms#else /* !_KERNEL */
233130484Sbms
234130484Sbms#include <sys/cdefs.h>
235130484Sbms
236130484Sbms__BEGIN_DECLS
237130484Sbmsvoid	moncontrol(int);
238130484Sbmsvoid	monstartup(u_long, u_long);
239130484Sbms__END_DECLS
240130484Sbms
241129444Sbde#endif /* _KERNEL */
242129444Sbde
2431541Srgrimes#endif /* !_SYS_GMON_H_ */
244