|
|
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.