2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_OSREFERENCE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the
10 * License may not be used to create, or enable the creation or
11 * redistribution of, unlawful or unlicensed copies of an Apple operating
12 * system, or to circumvent, violate, or enable the circumvention or
13 * violation of, any terms of an Apple operating system software license
16 * Please obtain a copy of the License at
17 * http://www.opensource.apple.com/apsl/ and read it before using this
20 * The Original Code and all software distributed under the License are
21 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
22 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
23 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
25 * Please see the License for the specific language governing rights and
26 * limitations under the License.
28 * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
34 * Define the internal interfaces between the profiling support that is
35 * common between the kernel, mach servers, and user space library.
38 #ifndef _PROFILE_INTERNAL_H
39 #define _PROFILE_INTERNAL_H
42 * Allow us not to require stdio.h in kernel/server space, but
43 * use it in user space.
46 #if !defined(MACH_KERNEL) && !defined(_KERNEL)
51 * Scaling factor for the profil system call.
54 #define SCALE_1_TO_1 0x10000L
58 * Forward reference to structures used.
65 struct profile_profil
;
74 typedef enum profile_type
{
81 * Whether to allocate memory in _profile_md_init.
84 typedef enum profile_alloc_mem
{
87 } profile_alloc_mem_t
;
90 * Allocation context block types.
93 typedef enum acontext_type
{
94 ACONTEXT_PROF
, /* 0: prof records */
95 ACONTEXT_GPROF
, /* 1: gprof arcs */
96 ACONTEXT_GFUNC
, /* 2: gprof function headers */
97 ACONTEXT_MISC
, /* 3: misc. allocations */
98 ACONTEXT_PROFIL
, /* 4: profil based allocations */
99 ACONTEXT_DCI
, /* 5: dci based allocations */
100 ACONTEXT_BASIC_BLOCK
, /* 6: basic block allocations */
101 ACONTEXT_CALLBACK
, /* 7: callback structures */
102 ACONTEXT_MAX
= 32 /* # allocation contexts */
105 #define ACONTEXT_FIRST ACONTEXT_PROF
107 #define ACONTEXT_NAMES { \
143 * Kgmon control codes
146 typedef enum kgmon_control
{
147 KGMON_UNUSED
, /* insure no 0 is ever used */
148 KGMON_GET_STATUS
, /* return whether or not profiling is active */
149 KGMON_GET_PROFILE_VARS
, /* return the _profile_vars structure */
150 KGMON_GET_PROFILE_STATS
, /* return the _profile_stats structure */
151 KGMON_GET_DEBUG
, /* return whether or not debugging is on */
153 KGMON_SET_PROFILE_ON
= 50, /* turn on profiling */
154 KGMON_SET_PROFILE_OFF
, /* turn off profiling */
155 KGMON_SET_PROFILE_RESET
, /* reset profiling tables */
156 KGMON_SET_DEBUG_ON
, /* turn on debugging */
157 KGMON_SET_DEBUG_OFF
/* turn off debugging */
160 #define KGMON_GET_MIN KGMON_GET_STATUS
161 #define KGMON_GET_MAX KGMON_GET_DEBUG
162 #define KGMON_SET_MIN KGMON_SET_PROFILE_ON
163 #define KGMON_SET_MAX KGMON_SET_DEBUG_OFF
165 #define ENCODE_KGMON(num, control, cpu_thread) \
166 ((num) = ((cpu_thread) << 8) | (control))
168 #define DECODE_KGMON(num, control, cpu_thread) \
170 control = (num) & 0xff; \
171 cpu_thread = (num) >> 8; \
174 #define LEGAL_KGMON(num) (((unsigned long)(num)) <= 0xffff)
177 * Pull in all of the machine dependent types now after defining the enums.
180 #include <profiling/machine/profile-md.h>
183 * general rounding functions.
186 #define ROUNDDOWN(x,y) (((x)/(y))*(y))
187 #define ROUNDUP(x,y) ((((x)+(y)-1)/(y))*(y))
190 * Linked list of pages allocated for a particular allocation context block.
194 void *first
; /* pointer to first byte available */
195 void *ptr
; /* pointer to next available byte */
196 struct page_list
*next
; /* next page allocated */
197 size_t bytes_free
; /* # bytes available */
198 size_t bytes_allocated
; /* # bytes allocates so far */
199 size_t num_allocations
; /* # of allocations */
203 * Allocation context block.
206 struct alloc_context
{
207 struct alloc_context
*next
; /* next allocation context block */
208 struct page_list
*plist
; /* head of page list */
209 prof_lock_t lock
; /* lock field available to asm */
214 * Callback structure that records information for one record in the
221 void *sec_ptr
; /* callback user data */
222 /* callback function */
223 size_t (*callback
)(struct profile_vars
*, struct callback
*);
224 long sec_val1
; /* section specific value */
225 long sec_val2
; /* section specific value */
226 size_t sec_recsize
; /* record size */
227 size_t sec_length
; /* total length */
228 char sec_name
[STR_MAX
]; /* section name */
232 * Basic profil information (except for the profil buffer).
235 struct profile_profil
{
236 prof_uptrint_t lowpc
; /* lowest address */
237 prof_uptrint_t highpc
; /* highest address */
238 size_t text_len
; /* highpc-lowpc */
239 size_t profil_len
; /* length of the profil buffer */
240 size_t counter_size
; /* size of indivual counters (HISTCOUNTER) */
241 unsigned long scale
; /* scaling factor (65536 / scale) */
242 unsigned long profil_unused
[8]; /* currently unused */
246 * Profiling internal variables. This structure is intended to be machine independent.
249 struct profile_vars
{
250 int major_version
; /* major version number */
251 int minor_version
; /* minor version number */
252 size_t vars_size
; /* size of profile_vars structure */
253 size_t plist_size
; /* size of page_list structure */
254 size_t acontext_size
; /* size of allocation context struct */
255 size_t callback_size
; /* size of callback structure */
256 profile_type_t type
; /* profile type */
257 const char *error_msg
; /* error message for perror */
258 const char *filename
; /* filename to write to */
259 char *str_ptr
; /* string table */
261 #if !defined(MACH_KERNEL) && !defined(_KERNEL)
262 FILE *stream
; /* stdio stream to write to */
263 FILE *diag_stream
; /* stdio stream to write diagnostics to */
264 /* function to write out some bytes */
265 size_t (*fwrite_func
)(const void *, size_t, size_t, FILE *);
267 void *stream
; /* pointer passed to fwrite_func */
268 void *diag_stream
; /* stdio stream to write diagnostics to */
269 /* function to write out some bytes */
270 size_t (*fwrite_func
)(const void *, size_t, size_t, void *);
273 size_t page_size
; /* machine pagesize */
274 size_t str_bytes
; /* # bytes in string table */
275 size_t str_total
; /* # bytes allocated total for string table */
276 long clock_ticks
; /* # clock ticks per second */
278 /* profil related variables */
279 struct profile_profil profil_info
; /* profil information */
280 HISTCOUNTER
*profil_buf
; /* profil buffer */
282 /* Profiling output selection */
283 void (*output_init
)(struct profile_vars
*); /* output init function */
284 void (*output
)(struct profile_vars
*); /* output function */
285 void *output_ptr
; /* output specific info */
287 /* allocation contexts */
288 struct alloc_context
*acontext
[(int)ACONTEXT_MAX
];
290 void (*bogus_func
)(void); /* Function to use if address out of bounds */
291 prof_uptrint_t vars_unused
[63]; /* future growth */
294 prof_flag_t init
; /* != 0 if initialized */
295 prof_flag_t active
; /* != 0 if profiling is active */
296 prof_flag_t do_profile
; /* != 0 if profiling is being done */
297 prof_flag_t use_dci
; /* != 0 if using DCI */
299 prof_flag_t use_profil
; /* != 0 if using profil */
300 prof_flag_t recursive_alloc
; /* != 0 if alloc taking place */
301 prof_flag_t output_uarea
; /* != 0 if output the uarea */
302 prof_flag_t output_stats
; /* != 0 if output the stats */
304 prof_flag_t output_clock
; /* != 0 if output the clock ticks */
305 prof_flag_t multiple_sections
; /* != 0 if output allows multiple sections */
306 prof_flag_t have_bb
; /* != 0 if we have basic block data */
307 prof_flag_t init_format
; /* != 0 if output format has been chosen */
309 prof_flag_t debug
; /* != 0 if debugging */
310 prof_flag_t check_funcs
; /* != 0 if check gprof arcs for being in range */
311 prof_flag_t flag_unused
[62]; /* space for more flags */
313 struct profile_stats stats
; /* profiling statistics */
314 struct profile_md md
; /* machine dependent info */
318 * Profiling static data.
321 extern struct profile_vars _profile_vars
;
324 * Functions called by the machine dependent routines, and provided by
325 * specific routines to the kernel, server, and user space library.
328 #if (__GNUC__ < 2) || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || defined(lint)
329 #define __attribute__(arg)
332 #if defined(_KERNEL) || defined(MACH_KERNEL)
333 #define _profile_printf printf
335 extern int _profile_printf(const char *, ...) __attribute__((format(printf
,1,2)));
338 extern void *_profile_alloc_pages (size_t);
339 extern void _profile_free_pages (void *, size_t);
340 extern void _profile_error(struct profile_vars
*);
343 * Functions provided by the machine dependent files.
346 extern void _profile_md_init(struct profile_vars
*, profile_type_t
, profile_alloc_mem_t
);
347 extern int _profile_md_start(void);
348 extern int _profile_md_stop(void);
349 extern void *_profile_alloc(struct profile_vars
*, size_t, acontext_type_t
);
350 extern size_t _gprof_write(struct profile_vars
*, struct callback
*);
351 extern size_t _prof_write(struct profile_vars
*, struct callback
*);
352 extern void _profile_update_stats(struct profile_vars
*);
353 extern void _profile_reset(struct profile_vars
*);
355 #if !defined(_KERNEL) && !defined(MACH_KERNEL)
356 extern void _profile_print_stats(FILE *, const struct profile_stats
*, const struct profile_profil
*);
357 extern void _profile_merge_stats(struct profile_stats
*, const struct profile_stats
*);
361 * Functions defined in profile-kgmon.c
364 extern long _profile_kgmon(int,
369 void (*)(kgmon_control_t
));
371 extern void kgmon_server_control(kgmon_control_t
);
374 #endif /* _KERNEL or MACH_KERNEL */
376 #endif /* _PROFILE_INTERNAL_H */