]> git.saurik.com Git - apple/xnu.git/blame_incremental - osfmk/profiling/profile-internal.h
xnu-517.11.1.tar.gz
[apple/xnu.git] / osfmk / profiling / profile-internal.h
... / ...
CommitLineData
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
53struct profile_vars;
54struct profile_stats;
55struct profile_md;
56struct profile_dci;
57struct profile_profil;
58struct callback;
59struct gprof_arc;
60struct prof_ext;
61
62/*
63 * Profiling type
64 */
65
66typedef 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
76typedef 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
85typedef 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
138typedef 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) \
161do { \
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
185struct 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
198struct 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
212struct 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
227struct 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
241struct 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
313extern 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
327extern int _profile_printf(const char *, ...) __attribute__((format(printf,1,2)));
328#endif
329
330extern void *_profile_alloc_pages (size_t);
331extern void _profile_free_pages (void *, size_t);
332extern void _profile_error(struct profile_vars *);
333
334/*
335 * Functions provided by the machine dependent files.
336 */
337
338extern void _profile_md_init(struct profile_vars *, profile_type_t, profile_alloc_mem_t);
339extern int _profile_md_start(void);
340extern int _profile_md_stop(void);
341extern void *_profile_alloc(struct profile_vars *, size_t, acontext_type_t);
342extern size_t _gprof_write(struct profile_vars *, struct callback *);
343extern size_t _prof_write(struct profile_vars *, struct callback *);
344extern void _profile_update_stats(struct profile_vars *);
345extern void _profile_reset(struct profile_vars *);
346
347#if !defined(_KERNEL) && !defined(MACH_KERNEL)
348extern void _profile_print_stats(FILE *, const struct profile_stats *, const struct profile_profil *);
349extern void _profile_merge_stats(struct profile_stats *, const struct profile_stats *);
350#else
351
352/*
353 * Functions defined in profile-kgmon.c
354 */
355
356extern long _profile_kgmon(int,
357 size_t,
358 long,
359 int,
360 void **,
361 void (*)(kgmon_control_t));
362#ifdef _KERNEL
363extern void kgmon_server_control(kgmon_control_t);
364
365#endif /* _KERNEL */
366#endif /* _KERNEL or MACH_KERNEL */
367
368#endif /* _PROFILE_INTERNAL_H */