]> git.saurik.com Git - apple/xnu.git/blob - osfmk/profiling/profile-internal.h
xnu-344.21.74.tar.gz
[apple/xnu.git] / osfmk / profiling / profile-internal.h
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25 /*
26 * @OSF_COPYRIGHT@
27 */
28 /*
29 * Define the internal interfaces between the profiling support that is
30 * common between the kernel, mach servers, and user space library.
31 */
32
33 #ifndef _PROFILE_INTERNAL_H
34 #define _PROFILE_INTERNAL_H
35
36 /*
37 * Allow us not to require stdio.h in kernel/server space, but
38 * use it in user space.
39 */
40
41 #if !defined(MACH_KERNEL) && !defined(_KERNEL)
42 #include <stdio.h>
43 #endif
44
45 /*
46 * Scaling factor for the profil system call.
47 */
48
49 #define SCALE_1_TO_1 0x10000L
50
51
52 /*
53 * Forward reference to structures used.
54 */
55
56 struct profile_vars;
57 struct profile_stats;
58 struct profile_md;
59 struct profile_dci;
60 struct profile_profil;
61 struct callback;
62 struct gprof_arc;
63 struct prof_ext;
64
65 /*
66 * Profiling type
67 */
68
69 typedef enum profile_type {
70 PROFILE_NONE,
71 PROFILE_GPROF,
72 PROFILE_PROF
73 } profile_type_t;
74
75 /*
76 * Whether to allocate memory in _profile_md_init.
77 */
78
79 typedef enum profile_alloc_mem {
80 PROFILE_ALLOC_MEM_NO,
81 PROFILE_ALLOC_MEM_YES
82 } profile_alloc_mem_t;
83
84 /*
85 * Allocation context block types.
86 */
87
88 typedef enum acontext_type {
89 ACONTEXT_PROF, /* 0: prof records */
90 ACONTEXT_GPROF, /* 1: gprof arcs */
91 ACONTEXT_GFUNC, /* 2: gprof function headers */
92 ACONTEXT_MISC, /* 3: misc. allocations */
93 ACONTEXT_PROFIL, /* 4: profil based allocations */
94 ACONTEXT_DCI, /* 5: dci based allocations */
95 ACONTEXT_BASIC_BLOCK, /* 6: basic block allocations */
96 ACONTEXT_CALLBACK, /* 7: callback structures */
97 ACONTEXT_MAX = 32 /* # allocation contexts */
98 } acontext_type_t;
99
100 #define ACONTEXT_FIRST ACONTEXT_PROF
101
102 #define ACONTEXT_NAMES { \
103 "prof", \
104 "gprof", \
105 "gfunc", \
106 "misc", \
107 "profil", \
108 "dci", \
109 "bb", \
110 "callback", \
111 "#8", \
112 "#9", \
113 "#10", \
114 "#11", \
115 "#12", \
116 "#13", \
117 "#14", \
118 "#15", \
119 "#16", \
120 "#17", \
121 "#18", \
122 "#19", \
123 "#20", \
124 "#21", \
125 "#22", \
126 "#23", \
127 "#24", \
128 "#25", \
129 "#26", \
130 "#27", \
131 "#28", \
132 "#29", \
133 "#30", \
134 "#31", \
135 }
136
137 /*
138 * Kgmon control codes
139 */
140
141 typedef enum kgmon_control {
142 KGMON_UNUSED, /* insure no 0 is ever used */
143 KGMON_GET_STATUS, /* return whether or not profiling is active */
144 KGMON_GET_PROFILE_VARS, /* return the _profile_vars structure */
145 KGMON_GET_PROFILE_STATS, /* return the _profile_stats structure */
146 KGMON_GET_DEBUG, /* return whether or not debugging is on */
147
148 KGMON_SET_PROFILE_ON = 50, /* turn on profiling */
149 KGMON_SET_PROFILE_OFF, /* turn off profiling */
150 KGMON_SET_PROFILE_RESET, /* reset profiling tables */
151 KGMON_SET_DEBUG_ON, /* turn on debugging */
152 KGMON_SET_DEBUG_OFF /* turn off debugging */
153 } kgmon_control_t;
154
155 #define KGMON_GET_MIN KGMON_GET_STATUS
156 #define KGMON_GET_MAX KGMON_GET_DEBUG
157 #define KGMON_SET_MIN KGMON_SET_PROFILE_ON
158 #define KGMON_SET_MAX KGMON_SET_DEBUG_OFF
159
160 #define ENCODE_KGMON(num, control, cpu_thread) \
161 ((num) = ((cpu_thread) << 8) | (control))
162
163 #define DECODE_KGMON(num, control, cpu_thread) \
164 do { \
165 control = (num) & 0xff; \
166 cpu_thread = (num) >> 8; \
167 } while (0)
168
169 #define LEGAL_KGMON(num) (((unsigned long)(num)) <= 0xffff)
170
171 /*
172 * Pull in all of the machine dependent types now after defining the enums.
173 */
174
175 #include <profiling/machine/profile-md.h>
176
177 /*
178 * general rounding functions.
179 */
180
181 #define ROUNDDOWN(x,y) (((x)/(y))*(y))
182 #define ROUNDUP(x,y) ((((x)+(y)-1)/(y))*(y))
183
184 /*
185 * Linked list of pages allocated for a particular allocation context block.
186 */
187
188 struct page_list {
189 void *first; /* pointer to first byte available */
190 void *ptr; /* pointer to next available byte */
191 struct page_list *next; /* next page allocated */
192 size_t bytes_free; /* # bytes available */
193 size_t bytes_allocated; /* # bytes allocates so far */
194 size_t num_allocations; /* # of allocations */
195 };
196
197 /*
198 * Allocation context block.
199 */
200
201 struct alloc_context {
202 struct alloc_context *next; /* next allocation context block */
203 struct page_list *plist; /* head of page list */
204 prof_lock_t lock; /* lock field available to asm */
205 };
206
207
208 /*
209 * Callback structure that records information for one record in the
210 * profiling output.
211 */
212
213 #define STR_MAX 32
214
215 struct callback {
216 void *sec_ptr; /* callback user data */
217 /* callback function */
218 size_t (*callback)(struct profile_vars *, struct callback *);
219 long sec_val1; /* section specific value */
220 long sec_val2; /* section specific value */
221 size_t sec_recsize; /* record size */
222 size_t sec_length; /* total length */
223 char sec_name[STR_MAX]; /* section name */
224 };
225
226 /*
227 * Basic profil information (except for the profil buffer).
228 */
229
230 struct profile_profil {
231 prof_uptrint_t lowpc; /* lowest address */
232 prof_uptrint_t highpc; /* highest address */
233 size_t text_len; /* highpc-lowpc */
234 size_t profil_len; /* length of the profil buffer */
235 size_t counter_size; /* size of indivual counters (HISTCOUNTER) */
236 unsigned long scale; /* scaling factor (65536 / scale) */
237 unsigned long profil_unused[8]; /* currently unused */
238 };
239
240 /*
241 * Profiling internal variables. This structure is intended to be machine independent.
242 */
243
244 struct profile_vars {
245 int major_version; /* major version number */
246 int minor_version; /* minor version number */
247 size_t vars_size; /* size of profile_vars structure */
248 size_t plist_size; /* size of page_list structure */
249 size_t acontext_size; /* size of allocation context struct */
250 size_t callback_size; /* size of callback structure */
251 profile_type_t type; /* profile type */
252 const char *error_msg; /* error message for perror */
253 const char *filename; /* filename to write to */
254 char *str_ptr; /* string table */
255
256 #if !defined(MACH_KERNEL) && !defined(_KERNEL)
257 FILE *stream; /* stdio stream to write to */
258 FILE *diag_stream; /* stdio stream to write diagnostics to */
259 /* function to write out some bytes */
260 size_t (*fwrite_func)(const void *, size_t, size_t, FILE *);
261 #else
262 void *stream; /* pointer passed to fwrite_func */
263 void *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, void *);
266 #endif
267
268 size_t page_size; /* machine pagesize */
269 size_t str_bytes; /* # bytes in string table */
270 size_t str_total; /* # bytes allocated total for string table */
271 long clock_ticks; /* # clock ticks per second */
272
273 /* profil related variables */
274 struct profile_profil profil_info; /* profil information */
275 HISTCOUNTER *profil_buf; /* profil buffer */
276
277 /* Profiling output selection */
278 void (*output_init)(struct profile_vars *); /* output init function */
279 void (*output)(struct profile_vars *); /* output function */
280 void *output_ptr; /* output specific info */
281
282 /* allocation contexts */
283 struct alloc_context *acontext[(int)ACONTEXT_MAX];
284
285 void (*bogus_func)(void); /* Function to use if address out of bounds */
286 prof_uptrint_t vars_unused[63]; /* future growth */
287
288 /* Various flags */
289 prof_flag_t init; /* != 0 if initialized */
290 prof_flag_t active; /* != 0 if profiling is active */
291 prof_flag_t do_profile; /* != 0 if profiling is being done */
292 prof_flag_t use_dci; /* != 0 if using DCI */
293
294 prof_flag_t use_profil; /* != 0 if using profil */
295 prof_flag_t recursive_alloc; /* != 0 if alloc taking place */
296 prof_flag_t output_uarea; /* != 0 if output the uarea */
297 prof_flag_t output_stats; /* != 0 if output the stats */
298
299 prof_flag_t output_clock; /* != 0 if output the clock ticks */
300 prof_flag_t multiple_sections; /* != 0 if output allows multiple sections */
301 prof_flag_t have_bb; /* != 0 if we have basic block data */
302 prof_flag_t init_format; /* != 0 if output format has been chosen */
303
304 prof_flag_t debug; /* != 0 if debugging */
305 prof_flag_t check_funcs; /* != 0 if check gprof arcs for being in range */
306 prof_flag_t flag_unused[62]; /* space for more flags */
307
308 struct profile_stats stats; /* profiling statistics */
309 struct profile_md md; /* machine dependent info */
310 };
311
312 /*
313 * Profiling static data.
314 */
315
316 extern struct profile_vars _profile_vars;
317
318 /*
319 * Functions called by the machine dependent routines, and provided by
320 * specific routines to the kernel, server, and user space library.
321 */
322
323 #if (__GNUC__ < 2) || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || defined(lint)
324 #define __attribute__(arg)
325 #endif
326
327 #if defined(_KERNEL) || defined(MACH_KERNEL)
328 #define _profile_printf printf
329 #else
330 extern int _profile_printf(const char *, ...) __attribute__((format(printf,1,2)));
331 #endif
332
333 extern void *_profile_alloc_pages (size_t);
334 extern void _profile_free_pages (void *, size_t);
335 extern void _profile_error(struct profile_vars *);
336
337 /*
338 * Functions provided by the machine dependent files.
339 */
340
341 extern void _profile_md_init(struct profile_vars *, profile_type_t, profile_alloc_mem_t);
342 extern int _profile_md_start(void);
343 extern int _profile_md_stop(void);
344 extern void *_profile_alloc(struct profile_vars *, size_t, acontext_type_t);
345 extern size_t _gprof_write(struct profile_vars *, struct callback *);
346 extern size_t _prof_write(struct profile_vars *, struct callback *);
347 extern void _profile_update_stats(struct profile_vars *);
348 extern void _profile_reset(struct profile_vars *);
349
350 #if !defined(_KERNEL) && !defined(MACH_KERNEL)
351 extern void _profile_print_stats(FILE *, const struct profile_stats *, const struct profile_profil *);
352 extern void _profile_merge_stats(struct profile_stats *, const struct profile_stats *);
353 #else
354
355 /*
356 * Functions defined in profile-kgmon.c
357 */
358
359 extern long _profile_kgmon(int,
360 size_t,
361 long,
362 int,
363 void **,
364 void (*)(kgmon_control_t));
365 #ifdef _KERNEL
366 extern void kgmon_server_control(kgmon_control_t);
367
368 #endif /* _KERNEL */
369 #endif /* _KERNEL or MACH_KERNEL */
370
371 #endif /* _PROFILE_INTERNAL_H */