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 59struct profile_vars; 60struct profile_stats; 61struct profile_md; 62struct profile_dci; 63struct profile_profil; 64struct callback; 65struct gprof_arc; 66struct prof_ext; 67 68/* 69 * Profiling type 70 */ 71 72typedef 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 82typedef 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 91typedef 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 144typedef 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) \ 167do { \ 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 191struct 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 204struct 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 218struct 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 233struct 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 247struct 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 319extern 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 333extern int _profile_printf(const char *, ...) __attribute__((format(printf,1,2))); 334#endif 335 336extern void *_profile_alloc_pages (size_t); 337extern void _profile_free_pages (void *, size_t); 338extern void _profile_error(struct profile_vars *); 339 340/* 341 * Functions provided by the machine dependent files. 342 */ 343 344extern void _profile_md_init(struct profile_vars *, profile_type_t, profile_alloc_mem_t); 345extern int _profile_md_start(void); 346extern int _profile_md_stop(void); 347extern void *_profile_alloc(struct profile_vars *, size_t, acontext_type_t); 348extern size_t _gprof_write(struct profile_vars *, struct callback *); 349extern size_t _prof_write(struct profile_vars *, struct callback *); 350extern void _profile_update_stats(struct profile_vars *); 351extern void _profile_reset(struct profile_vars *); 352 353#if !defined(_KERNEL) && !defined(MACH_KERNEL) 354extern void _profile_print_stats(FILE *, const struct profile_stats *, const struct profile_profil *); 355extern void _profile_merge_stats(struct profile_stats *, const struct profile_stats *); 356#else 357 358/* 359 * Functions defined in profile-kgmon.c 360 */ 361 362extern long _profile_kgmon(int, 363 size_t, 364 long, 365 int, 366 void **, 367 void (*)(kgmon_control_t)); 368#ifdef _KERNEL 369extern void kgmon_server_control(kgmon_control_t); 370 371#endif /* _KERNEL */ 372#endif /* _KERNEL or MACH_KERNEL */ 373 374#endif /* _PROFILE_INTERNAL_H */ 375