]> git.saurik.com Git - apple/xnu.git/blame - osfmk/profiling/profile-internal.h
xnu-792.12.6.tar.gz
[apple/xnu.git] / osfmk / profiling / profile-internal.h
CommitLineData
1c79356b
A
1/*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
8ad349bb 4 * @APPLE_LICENSE_OSREFERENCE_HEADER_START@
1c79356b 5 *
8ad349bb
A
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
14 * agreement.
15 *
16 * Please obtain a copy of the License at
17 * http://www.opensource.apple.com/apsl/ and read it before using this
18 * file.
19 *
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.
27 *
28 * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
1c79356b
A
29 */
30/*
31 * @OSF_COPYRIGHT@
32 */
33/*
34 * Define the internal interfaces between the profiling support that is
35 * common between the kernel, mach servers, and user space library.
36 */
37
38#ifndef _PROFILE_INTERNAL_H
39#define _PROFILE_INTERNAL_H
40
41/*
42 * Allow us not to require stdio.h in kernel/server space, but
43 * use it in user space.
44 */
45
46#if !defined(MACH_KERNEL) && !defined(_KERNEL)
47#include <stdio.h>
48#endif
49
50/*
51 * Scaling factor for the profil system call.
52 */
53
54#define SCALE_1_TO_1 0x10000L
55
56
57/*
58 * Forward reference to structures used.
59 */
60
61struct profile_vars;
62struct profile_stats;
63struct profile_md;
64struct profile_dci;
65struct profile_profil;
66struct callback;
67struct gprof_arc;
68struct prof_ext;
69
70/*
71 * Profiling type
72 */
73
74typedef enum profile_type {
75 PROFILE_NONE,
76 PROFILE_GPROF,
77 PROFILE_PROF
78} profile_type_t;
79
80/*
81 * Whether to allocate memory in _profile_md_init.
82 */
83
84typedef enum profile_alloc_mem {
85 PROFILE_ALLOC_MEM_NO,
86 PROFILE_ALLOC_MEM_YES
87} profile_alloc_mem_t;
88
89/*
90 * Allocation context block types.
91 */
92
93typedef 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 */
103} acontext_type_t;
104
105#define ACONTEXT_FIRST ACONTEXT_PROF
106
107#define ACONTEXT_NAMES { \
108 "prof", \
109 "gprof", \
110 "gfunc", \
111 "misc", \
112 "profil", \
113 "dci", \
114 "bb", \
115 "callback", \
116 "#8", \
117 "#9", \
118 "#10", \
119 "#11", \
120 "#12", \
121 "#13", \
122 "#14", \
123 "#15", \
124 "#16", \
125 "#17", \
126 "#18", \
127 "#19", \
128 "#20", \
129 "#21", \
130 "#22", \
131 "#23", \
132 "#24", \
133 "#25", \
134 "#26", \
135 "#27", \
136 "#28", \
137 "#29", \
138 "#30", \
139 "#31", \
140 }
141
142/*
143 * Kgmon control codes
144 */
145
146typedef 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 */
152
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 */
158} kgmon_control_t;
159
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
164
165#define ENCODE_KGMON(num, control, cpu_thread) \
166 ((num) = ((cpu_thread) << 8) | (control))
167
168#define DECODE_KGMON(num, control, cpu_thread) \
169do { \
170 control = (num) & 0xff; \
171 cpu_thread = (num) >> 8; \
172} while (0)
173
174#define LEGAL_KGMON(num) (((unsigned long)(num)) <= 0xffff)
175
176/*
177 * Pull in all of the machine dependent types now after defining the enums.
178 */
179
180#include <profiling/machine/profile-md.h>
181
182/*
183 * general rounding functions.
184 */
185
186#define ROUNDDOWN(x,y) (((x)/(y))*(y))
187#define ROUNDUP(x,y) ((((x)+(y)-1)/(y))*(y))
188
189/*
190 * Linked list of pages allocated for a particular allocation context block.
191 */
192
193struct page_list {
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 */
200};
201
202/*
203 * Allocation context block.
204 */
205
206struct 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 */
210};
211
212
213/*
214 * Callback structure that records information for one record in the
215 * profiling output.
216 */
217
218#define STR_MAX 32
219
220struct callback {
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 */
229};
230
231/*
232 * Basic profil information (except for the profil buffer).
233 */
234
235struct 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 */
243};
244
245/*
246 * Profiling internal variables. This structure is intended to be machine independent.
247 */
248
249struct 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 */
260
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 *);
266#else
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 *);
271#endif
272
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 */
277
278 /* profil related variables */
279 struct profile_profil profil_info; /* profil information */
280 HISTCOUNTER *profil_buf; /* profil buffer */
281
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 */
286
287 /* allocation contexts */
288 struct alloc_context *acontext[(int)ACONTEXT_MAX];
289
290 void (*bogus_func)(void); /* Function to use if address out of bounds */
291 prof_uptrint_t vars_unused[63]; /* future growth */
292
293 /* Various flags */
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 */
298
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 */
303
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 */
308
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 */
312
313 struct profile_stats stats; /* profiling statistics */
314 struct profile_md md; /* machine dependent info */
315};
316
317/*
318 * Profiling static data.
319 */
320
321extern struct profile_vars _profile_vars;
322
323/*
324 * Functions called by the machine dependent routines, and provided by
325 * specific routines to the kernel, server, and user space library.
326 */
327
328#if (__GNUC__ < 2) || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || defined(lint)
329#define __attribute__(arg)
330#endif
331
332#if defined(_KERNEL) || defined(MACH_KERNEL)
333#define _profile_printf printf
334#else
335extern int _profile_printf(const char *, ...) __attribute__((format(printf,1,2)));
336#endif
337
338extern void *_profile_alloc_pages (size_t);
339extern void _profile_free_pages (void *, size_t);
340extern void _profile_error(struct profile_vars *);
341
342/*
343 * Functions provided by the machine dependent files.
344 */
345
346extern void _profile_md_init(struct profile_vars *, profile_type_t, profile_alloc_mem_t);
347extern int _profile_md_start(void);
348extern int _profile_md_stop(void);
349extern void *_profile_alloc(struct profile_vars *, size_t, acontext_type_t);
350extern size_t _gprof_write(struct profile_vars *, struct callback *);
351extern size_t _prof_write(struct profile_vars *, struct callback *);
352extern void _profile_update_stats(struct profile_vars *);
353extern void _profile_reset(struct profile_vars *);
354
355#if !defined(_KERNEL) && !defined(MACH_KERNEL)
356extern void _profile_print_stats(FILE *, const struct profile_stats *, const struct profile_profil *);
357extern void _profile_merge_stats(struct profile_stats *, const struct profile_stats *);
358#else
359
360/*
361 * Functions defined in profile-kgmon.c
362 */
363
364extern long _profile_kgmon(int,
365 size_t,
366 long,
367 int,
368 void **,
369 void (*)(kgmon_control_t));
370#ifdef _KERNEL
371extern void kgmon_server_control(kgmon_control_t);
372
373#endif /* _KERNEL */
374#endif /* _KERNEL or MACH_KERNEL */
375
376#endif /* _PROFILE_INTERNAL_H */