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