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