|
|
1.1 root 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 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.