1/*-
  2 * SPDX-License-Identifier: BSD-3-Clause
  3 *
  4 * Copyright (c) 1982, 1986, 1992, 1993
  5 *	The Regents of the University of California.  All rights reserved.
  6 *
  7 * Redistribution and use in source and binary forms, with or without
  8 * modification, are permitted provided that the following conditions
  9 * are met:
 10 * 1. Redistributions of source code must retain the above copyright
 11 *    notice, this list of conditions and the following disclaimer.
 12 * 2. Redistributions in binary form must reproduce the above copyright
 13 *    notice, this list of conditions and the following disclaimer in the
 14 *    documentation and/or other materials provided with the distribution.
 15 * 3. Neither the name of the University nor the names of its contributors
 16 *    may be used to endorse or promote products derived from this software
 17 *    without specific prior written permission.
 18 *
 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 22 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 29 * SUCH DAMAGE.
 30 *
 31 *	@(#)gmon.h	8.2 (Berkeley) 1/4/94
 32 */
 33
 34#ifndef _SYS_GMON_H_
 35#define _SYS_GMON_H_
 36
 37#include <machine/profile.h>
 38
 39/*
 40 * Structure prepended to gmon.out profiling data file.
 41 */
 42struct gmonhdr {
 43	u_long	lpc;		/* base pc address of sample buffer */
 44	u_long	hpc;		/* max pc address of sampled buffer */
 45	int	ncnt;		/* size of sample buffer (plus this header) */
 46	int	version;	/* version number */
 47	int	profrate;	/* profiling clock rate */
 48	int	histcounter_type; /* size (in bits) and sign of HISTCOUNTER */
 49	int	spare[2];	/* reserved */
 50};
 51#define GMONVERSION	0x00051879
 52
 53/*
 54 * Type of histogram counters used in the kernel.
 55 */
 56#ifdef GPROF4
 57#define	HISTCOUNTER	int64_t
 58#else
 59#define	HISTCOUNTER	unsigned short
 60#endif
 61
 62/*
 63 * Fraction of text space to allocate for histogram counters.
 64 * We allocate counters at the same or higher density as function
 65 * addresses, so that each counter belongs to a unique function.
 66 * A lower density of counters would give less resolution but a
 67 * higher density would be wasted.
 68 */
 69#define	HISTFRACTION	(FUNCTION_ALIGNMENT / sizeof(HISTCOUNTER) == 0 \
 70			 ? 1 : FUNCTION_ALIGNMENT / sizeof(HISTCOUNTER))
 71
 72/*
 73 * Fraction of text space to allocate for from hash buckets.
 74 * The value of HASHFRACTION is based on the minimum number of bytes
 75 * of separation between two subroutine call points in the object code.
 76 * Given MIN_SUBR_SEPARATION bytes of separation the value of
 77 * HASHFRACTION is calculated as:
 78 *
 79 *	HASHFRACTION = MIN_SUBR_SEPARATION / (2 * sizeof(short) - 1);
 80 *
 81 * For example, on the VAX, the shortest two call sequence is:
 82 *
 83 *	calls	$0,(r0)
 84 *	calls	$0,(r0)
 85 *
 86 * which is separated by only three bytes, thus HASHFRACTION is
 87 * calculated as:
 88 *
 89 *	HASHFRACTION = 3 / (2 * 2 - 1) = 1
 90 *
 91 * Note that the division above rounds down, thus if MIN_SUBR_FRACTION
 92 * is less than three, this algorithm will not work!
 93 *
 94 * In practice, however, call instructions are rarely at a minimal
 95 * distance.  Hence, we will define HASHFRACTION to be 2 across all
 96 * architectures.  This saves a reasonable amount of space for
 97 * profiling data structures without (in practice) sacrificing
 98 * any granularity.
 99 */
100/*
101 * XXX I think the above analysis completely misses the point.  I think
102 * the point is that addresses in different functions must hash to
103 * different values.  Since the hash is essentially division by
104 * sizeof(unsigned short), the correct formula is:
105 *
106 * 	HASHFRACTION = MIN_FUNCTION_ALIGNMENT / sizeof(unsigned short)
107 *
108 * Note that he unsigned short here has nothing to do with the one for
109 * HISTFRACTION.
110 *
111 * Hash collisions from a two call sequence don't matter.  They get
112 * handled like collisions for calls to different addresses from the
113 * same address through a function pointer.
114 */
115#define	HASHFRACTION	(FUNCTION_ALIGNMENT / sizeof(unsigned short) == 0 \
116			 ? 1 : FUNCTION_ALIGNMENT / sizeof(unsigned short))
117
118/*
119 * percent of text space to allocate for tostructs with a minimum.
120 */
121#define ARCDENSITY	2
122#define MINARCS		50
123
124/*
125 * Limit on the number of arcs to so that arc numbers can be stored in
126 * `*froms' and stored and incremented without overflow in links.
127 */
128#define MAXARCS		(((u_long)1 << (8 * sizeof(u_short))) - 2)
129
130struct tostruct {
131	u_long	selfpc;
132	long	count;
133	u_short	link;
134	u_short pad;
135};
136
137/*
138 * a raw arc, with pointers to the calling site and
139 * the called site and a count.
140 */
141struct rawarc {
142	u_long	raw_frompc;
143	u_long	raw_selfpc;
144	long	raw_count;
145};
146
147/*
148 * general rounding functions.
149 */
150#define ROUNDDOWN(x,y)	rounddown(x,y)
151#define ROUNDUP(x,y)	roundup(x,y)
152
153/*
154 * The profiling data structures are housed in this structure.
155 */
156struct gmonparam {
157	int		state;
158	HISTCOUNTER	*kcount;
159	u_long		kcountsize;
160	u_short		*froms;
161	u_long		fromssize;
162	struct tostruct	*tos;
163	u_long		tossize;
164	long		tolimit;
165	uintfptr_t	lowpc;
166	uintfptr_t	highpc;
167	u_long		textsize;
168	u_long		hashfraction;
169	int		profrate;	/* XXX wrong type to match gmonhdr */
170	HISTCOUNTER	*cputime_count;
171	int		cputime_overhead;
172	HISTCOUNTER	*mcount_count;
173	int		mcount_overhead;
174	int		mcount_post_overhead;
175	int		mcount_pre_overhead;
176	HISTCOUNTER	*mexitcount_count;
177	int		mexitcount_overhead;
178	int		mexitcount_post_overhead;
179	int		mexitcount_pre_overhead;
180	int		histcounter_type;
181};
182extern struct gmonparam _gmonparam;
183
184/*
185 * Possible states of profiling.
186 */
187#define	GMON_PROF_ON	0
188#define	GMON_PROF_BUSY	1
189#define	GMON_PROF_ERROR	2
190#define	GMON_PROF_OFF	3
191#define	GMON_PROF_HIRES	4
192
193/*
194 * Sysctl definitions for extracting profiling information from the kernel.
195 */
196#define	GPROF_STATE	0	/* int: profiling enabling variable */
197#define	GPROF_COUNT	1	/* struct: profile tick count buffer */
198#define	GPROF_FROMS	2	/* struct: from location hash bucket */
199#define	GPROF_TOS	3	/* struct: destination/count structure */
200#define	GPROF_GMONPARAM	4	/* struct: profiling parameters (see above) */
201
202#ifdef _KERNEL
203
204#define	KCOUNT(p,index) \
205	((p)->kcount[(index) / (HISTFRACTION * sizeof(HISTCOUNTER))])
206#define	PC_TO_I(p, pc)	((uintfptr_t)(pc) - (uintfptr_t)(p)->lowpc)
207
208#ifdef GUPROF
209
210#define	CALIB_SCALE	1000
211
212extern int	cputime_bias;
213
214int	cputime(void);
215void	nullfunc_loop_profiled(void);
216void	nullfunc_profiled(void);
217void	startguprof(struct gmonparam *p);
218void	stopguprof(struct gmonparam *p);
219
220#else /* !GUPROF */
221
222#define	startguprof(p)
223#define	stopguprof(p)
224
225#endif /* GUPROF */
226
227void	empty_loop(void);
228void	kmupetext(uintfptr_t nhighpc);
229void	mexitcount(uintfptr_t selfpc);
230void	nullfunc(void);
231void	nullfunc_loop(void);
232
233#else /* !_KERNEL */
234
235#include <sys/cdefs.h>
236
237__BEGIN_DECLS
238void	moncontrol(int);
239void	monstartup(u_long, u_long);
240__END_DECLS
241
242#endif /* _KERNEL */
243
244#endif /* !_SYS_GMON_H_ */