Annotation of XNU/osfmk/profiling/i386/profile-md.h, revision 1.1.1.1

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:  * HISTORY
                     27:  * 
                     28:  * Revision 1.1.1.1  1998/09/22 21:05:49  wsanchez
                     29:  * Import of Mac OS X kernel (~semeria)
                     30:  *
                     31:  * Revision 1.1.1.1  1998/03/07 02:26:08  wsanchez
                     32:  * Import of OSF Mach kernel (~mburg)
                     33:  *
                     34:  * Revision 1.1.5.2  1996/07/31  09:57:36  paire
                     35:  *     Added some more constraints to __asm__ functions for compilation
                     36:  *     under gcc2.7.1 for PROF_CNT_[L]{ADD|SUB} macros
                     37:  *     [96/06/14            paire]
                     38:  *
                     39:  * Revision 1.1.5.1  1995/01/06  19:53:52  devrcs
                     40:  *     mk6 CR668 - 1.3b26 merge
                     41:  *     new file for mk6
                     42:  *     [1994/10/12  22:25:27  dwm]
                     43:  * 
                     44:  * Revision 1.1.2.2  1994/05/16  19:19:26  meissner
                     45:  *     Add {,L}PROF_CNT_{SUB,LSUB,OVERFLOW} macros for gprof command.
                     46:  *     [1994/05/10  10:36:06  meissner]
                     47:  * 
                     48:  *     Correct 64-bit integer asms to specify result values as inputs, and use =g instead of =m.
                     49:  *     Cast the integer argument to PROF_CNT_ADD to unsigned long, so a short register is widened.
                     50:  *     Add more support for writing the gprof command.
                     51:  *     PROF_CNT_{EQ,NE} should not use ^=, it just uses ^.
                     52:  *     Round PROF_CNT_DIGITS up to 24 bytes so it is word aligned.
                     53:  *     _profile_cnt_to_decimal now takes the low/high values as separate arguments.
                     54:  *     Delete _profile_cnt_to_hex.
                     55:  *     [1994/04/28  21:45:07  meissner]
                     56:  * 
                     57:  *     Add more 64 bit arithmetic macros to support writing gprof.
                     58:  *     [1994/04/20  15:47:05  meissner]
                     59:  * 
                     60:  * Revision 1.1.2.1  1994/04/08  17:51:56  meissner
                     61:  *     Correct spelling on LPROF_CNT_TO_LDOUBLE macro.
                     62:  *     [1994/04/08  16:18:06  meissner]
                     63:  * 
                     64:  *     Make LHISTCOUNTER be 64 bits.
                     65:  *     Define LPROF_CNT_INC to increment LHISTCOUNTER.
                     66:  *     [1994/04/08  12:40:32  meissner]
                     67:  * 
                     68:  *     Make most stats 64 bits, except for things like memory allocation.
                     69:  *     [1994/04/02  14:58:34  meissner]
                     70:  * 
                     71:  *     Add overflow support for {gprof,prof,old,dummy}_mcount counters.
                     72:  *     [1994/03/17  20:13:37  meissner]
                     73:  * 
                     74:  *     Add gprof/prof overflow support
                     75:  *     [1994/03/17  14:56:56  meissner]
                     76:  * 
                     77:  *     Define LHISTCOUNTER.
                     78:  *     [1994/02/28  12:05:16  meissner]
                     79:  * 
                     80:  *     Set HISTFRACTION to 4, so new lprofil call takes the same space.
                     81:  *     [1994/02/24  16:15:34  meissner]
                     82:  * 
                     83:  *     Add too_low/too_high to profile_stats.
                     84:  *     [1994/02/16  22:38:23  meissner]
                     85:  * 
                     86:  *     Make prof_cnt_t unsigned long.
                     87:  *     [1994/02/11  16:52:09  meissner]
                     88:  * 
                     89:  *     Remember function unique ptr in gfuncs structure to reset profiling.
                     90:  *     Add support for range checking gprof arc {from,self}pc addresses.
                     91:  *     Add counter for # times acontext was locked.
                     92:  *     Expand copyright.
                     93:  *     [1994/02/07  12:41:08  meissner]
                     94:  * 
                     95:  *     Keep track of the number of times the kernel overflows the HISTCOUNTER counter.
                     96:  *     [1994/02/03  20:13:31  meissner]
                     97:  * 
                     98:  *     Add stats for {user,kernel,idle} mode in the kernel.
                     99:  *     [1994/02/03  15:17:36  meissner]
                    100:  * 
                    101:  *     No change.
                    102:  *     [1994/02/03  00:58:59  meissner]
                    103:  * 
                    104:  *     Combine _profile_{vars,stats,md}; Allow more than one _profile_vars.
                    105:  *     [1994/02/01  12:04:04  meissner]
                    106:  * 
                    107:  *     Split # records to # gprof and # prof records.
                    108:  *     Add my_cpu/max_cpu fields.
                    109:  *     [1994/01/28  23:33:30  meissner]
                    110:  * 
                    111:  *     Eliminate hash_{size,mask} from gfuncs structure.
                    112:  *     [1994/01/26  20:23:41  meissner]
                    113:  * 
                    114:  *     Add structure size fields to _profile_{vars,stats,md}.
                    115:  *     Add major/minor version number to _profile_md.
                    116:  *     Move allocation context block pointer to main structure.
                    117:  *     Delete shift count for allocation contexts.
                    118:  *     [1994/01/25  01:46:08  meissner]
                    119:  * 
                    120:  *     Add HASHFRACTION
                    121:  *     [1994/01/22  01:14:02  meissner]
                    122:  * 
                    123:  *     Split profile-md.h into profile-internal.h and profile-md.
                    124:  *     [1994/01/20  20:57:18  meissner]
                    125:  * 
                    126:  *     Fixup copyright.
                    127:  *     [1994/01/18  23:08:14  meissner]
                    128:  * 
                    129:  *     Make flags byte-sized.
                    130:  *     Add have_bb flag.
                    131:  *     Add init_format flag.
                    132:  *     [1994/01/18  21:57:18  meissner]
                    133:  * 
                    134:  *     CR 10198 - Initial version.
                    135:  *     [1994/01/18  19:44:59  meissner]
                    136:  * 
                    137:  * $EndLog$
                    138:  */
                    139: 
                    140: #ifndef _PROFILE_MD_H
                    141: #define _PROFILE_MD_H
                    142: 
                    143: /*
                    144:  * Define the interfaces between the assembly language profiling support
                    145:  * that is common between the kernel, mach servers, and user space library.
                    146:  */
                    147: 
                    148: /*
                    149:  * Integer types used.
                    150:  */
                    151: 
                    152: typedef        long            prof_ptrint_t;  /* hold either pointer or signed int */
                    153: typedef        unsigned long   prof_uptrint_t; /* hold either pointer or unsigned int */
                    154: typedef        long            prof_lock_t;    /* lock word type */
                    155: typedef unsigned char  prof_flag_t;    /* type for boolean flags */
                    156: 
                    157: /*
                    158:  * Double precision counter.
                    159:  */
                    160: 
                    161: typedef struct prof_cnt_t {
                    162:        prof_uptrint_t  low;            /* low 32 bits of counter */
                    163:        prof_uptrint_t  high;           /* high 32 bits of counter */
                    164: } prof_cnt_t;
                    165: 
                    166: #if defined(__GNUC__) && !defined(lint)
                    167: #define PROF_CNT_INC(cnt)                                      \
                    168:        __asm__("addl $1,%0; adcl $0,%1"                        \
                    169:                : "=g" ((cnt).low), "=g" ((cnt).high)           \
                    170:                : "0" ((cnt).low), "1" ((cnt).high))
                    171: 
                    172: #define PROF_CNT_ADD(cnt,val)                                  \
                    173:        __asm__("addl %2,%0; adcl $0,%1"                        \
                    174:                : "=g,r" ((cnt).low), "=g,r" ((cnt).high)       \
                    175:                : "r,g" ((unsigned long)(val)),                 \
                    176:                "0,0" ((cnt).low), "1,1" ((cnt).high))
                    177: 
                    178: #define PROF_CNT_LADD(cnt,val)                                 \
                    179:        __asm__("addl %2,%0; adcl %3,%1"                        \
                    180:                : "=g,r" ((cnt).low), "=g,r" ((cnt).high)       \
                    181:                : "r,g" ((val).low), "r,g" ((val).high),        \
                    182:                "0,0" ((cnt).low), "1,1" ((cnt).high))
                    183: 
                    184: #define PROF_CNT_SUB(cnt,val)                                  \
                    185:        __asm__("subl %2,%0; sbbl $0,%1"                        \
                    186:                : "=g,r" ((cnt).low), "=g,r" ((cnt).high)       \
                    187:                : "r,g" ((unsigned long)(val)),                 \
                    188:                "0,0" ((cnt).low), "1,1" ((cnt).high))
                    189: 
                    190: #define PROF_CNT_LSUB(cnt,val)                                 \
                    191:        __asm__("subl %2,%0; sbbl %3,%1"                        \
                    192:                : "=g,r" ((cnt).low), "=g,r" ((cnt).high)       \
                    193:                : "r,g" ((val).low), "r,g" ((val).high),        \
                    194:                "0,0" ((cnt).low), "1,1" ((cnt).high))
                    195: 
                    196: #else
                    197: #define PROF_CNT_INC(cnt)      ((++((cnt).low) == 0) ? ++((cnt).high) : 0)
                    198: #define PROF_CNT_ADD(cnt,val)  (((((cnt).low + (val)) < (val)) ? ((cnt).high++) : 0), ((cnt).low += (val)))
                    199: #define PROF_CNT_LADD(cnt,val) (PROF_CNT_ADD(cnt,(val).low), (cnt).high += (val).high)
                    200: #define PROF_CNT_SUB(cnt,val)  (((((cnt).low - (val)) > (cnt).low) ? ((cnt).high--) : 0), ((cnt).low -= (val)))
                    201: #define PROF_CNT_LSUB(cnt,val) (PROF_CNT_SUB(cnt,(val).low), (cnt).high -= (val).high)
                    202: #endif
                    203: 
                    204: #define PROF_ULONG_TO_CNT(cnt,val)     (((cnt).high = 0), ((cnt).low = val))
                    205: #define        PROF_CNT_OVERFLOW(cnt,high,low) (((high) = (cnt).high), ((low) = (cnt).low))
                    206: #define PROF_CNT_TO_ULONG(cnt)         (((cnt).high == 0) ? (cnt).low : 0xffffffffu)
                    207: #define PROF_CNT_TO_LDOUBLE(cnt)       ((((long double)(cnt).high) * 4294967296.0L) + (long double)(cnt).low)
                    208: #define PROF_CNT_TO_DECIMAL(buf,cnt)   _profile_cnt_to_decimal(buf, (cnt).low, (cnt).high)
                    209: #define PROF_CNT_EQ_0(cnt)             (((cnt).high | (cnt).low) == 0)
                    210: #define PROF_CNT_NE_0(cnt)             (((cnt).high | (cnt).low) != 0)
                    211: #define PROF_CNT_EQ(cnt1,cnt2)         ((((cnt1).high ^ (cnt2).high) | ((cnt1).low ^ (cnt2).low)) == 0)
                    212: #define PROF_CNT_NE(cnt1,cnt2)         ((((cnt1).high ^ (cnt2).high) | ((cnt1).low ^ (cnt2).low)) != 0)
                    213: #define PROF_CNT_GT(cnt1,cnt2)         (((cnt1).high > (cnt2).high) || ((cnt1).low > (cnt2).low))
                    214: #define PROF_CNT_LT(cnt1,cnt2)         (((cnt1).high < (cnt2).high) || ((cnt1).low < (cnt2).low))
                    215: 
                    216: /* max # digits + null to hold prof_cnt_t values (round up to multiple of 4) */
                    217: #define PROF_CNT_DIGITS                        24
                    218: 
                    219: /*
                    220:  * Types of the profil counter.
                    221:  */
                    222: 
                    223: typedef unsigned short HISTCOUNTER;            /* profil */
                    224: typedef prof_cnt_t     LHISTCOUNTER;           /* lprofil */
                    225: 
                    226: #define LPROF_ULONG_TO_CNT(cnt,val)    PROF_ULONG_TO_CNT(cnt,val)
                    227: #define LPROF_CNT_INC(lp)              PROF_CNT_INC(lp)
                    228: #define LPROF_CNT_ADD(lp,val)          PROF_CNT_ADD(lp,val)
                    229: #define LPROF_CNT_LADD(lp,val)         PROF_CNT_LADD(lp,val)
                    230: #define LPROF_CNT_SUB(lp,val)          PROF_CNT_SUB(lp,val)
                    231: #define LPROF_CNT_LSUB(lp,val)         PROF_CNT_LSUB(lp,val)
                    232: #define        LPROF_CNT_OVERFLOW(lp,high,low) PROF_CNT_OVERFLOW(lp,high,low)
                    233: #define LPROF_CNT_TO_ULONG(lp)         PROF_CNT_TO_ULONG(lp)
                    234: #define LPROF_CNT_TO_LDOUBLE(lp)       PROF_CNT_TO_LDOUBLE(lp)
                    235: #define LPROF_CNT_TO_DECIMAL(buf,cnt)  PROF_CNT_TO_DECIMAL(buf,cnt)
                    236: #define LPROF_CNT_EQ_0(cnt)            PROF_CNT_EQ_0(cnt)
                    237: #define LPROF_CNT_NE_0(cnt)            PROF_CNT_NE_0(cnt)
                    238: #define LPROF_CNT_EQ(cnt1,cnt2)                PROF_CNT_EQ(cnt1,cnt2)
                    239: #define LPROF_CNT_NE(cnt1,cnt2)                PROF_CNT_NE(cnt1,cnt2)
                    240: #define LPROF_CNT_GT(cnt1,cnt2)                PROF_CNT_GT(cnt1,cnt2)
                    241: #define LPROF_CNT_LT(cnt1,cnt2)                PROF_CNT_LT(cnt1,cnt2)
                    242: #define LPROF_CNT_DIGITS               PROF_CNT_DIGITS
                    243: 
                    244: /*
                    245:  *  fraction of text space to allocate for histogram counters
                    246:  */
                    247: 
                    248: #define HISTFRACTION    4
                    249: 
                    250: /*
                    251:  * Fraction of text space to allocate for from hash buckets.
                    252:  */
                    253: 
                    254: #define HASHFRACTION   HISTFRACTION
                    255: 
                    256: /*
                    257:  * Prof call count, external format.
                    258:  */
                    259: 
                    260: struct prof_ext {
                    261:        prof_uptrint_t  cvalue;         /* caller address */
                    262:        prof_uptrint_t  cncall;         /* # of calls */
                    263: };
                    264: 
                    265: /*
                    266:  * Prof call count, internal format.
                    267:  */
                    268: 
                    269: struct prof_int {
                    270:        struct prof_ext prof;           /* external prof struct */
                    271:        prof_uptrint_t  overflow;       /* # times prof counter overflowed */
                    272: };
                    273: 
                    274: /*
                    275:  * Gprof arc, external format.
                    276:  */
                    277: 
                    278: struct gprof_arc {
                    279:        prof_uptrint_t   frompc;        /* caller's caller */
                    280:        prof_uptrint_t   selfpc;        /* caller's address */
                    281:        prof_uptrint_t   count;         /* # times arc traversed */
                    282: };
                    283: 
                    284: /*
                    285:  * Gprof arc, internal format.
                    286:  */
                    287: 
                    288: struct hasharc {
                    289:        struct hasharc  *next;          /* next gprof record */
                    290:        struct gprof_arc arc;           /* gprof record */
                    291:        prof_uptrint_t   overflow;      /* # times counter overflowed */
                    292: };
                    293: 
                    294: /*
                    295:  * Linked list of all function profile blocks.
                    296:  */
                    297: 
                    298: #define MAX_CACHE      3               /* # cache table entries */
                    299: 
                    300: struct gfuncs {
                    301:        struct hasharc **hash_ptr;              /* gprof hash table */
                    302:        struct hasharc **unique_ptr;            /* function unique pointer */
                    303:        struct prof_int prof;                   /* -p stats for elf */
                    304:        struct hasharc *cache_ptr[MAX_CACHE];   /* cache element pointers */
                    305: };
                    306: 
                    307: /*
                    308:  * Profile information which might be written out in ELF {,g}mon.out files.
                    309:  */
                    310: 
                    311: #define MAX_BUCKETS 9                  /* max bucket chain to print out */
                    312: 
                    313: struct profile_stats {                 /* Debugging counters */
                    314:        prof_uptrint_t major_version;   /* major version number */
                    315:        prof_uptrint_t minor_version;   /* minor version number */
                    316:        prof_uptrint_t stats_size;      /* size of profile_vars structure */
                    317:        prof_uptrint_t profil_buckets;  /* # profil buckets */
                    318:        prof_uptrint_t my_cpu;          /* identify current cpu/thread */
                    319:        prof_uptrint_t max_cpu;         /* identify max cpu/thread */
                    320:        prof_uptrint_t prof_records;    /* # of functions profiled */
                    321:        prof_uptrint_t gprof_records;   /* # of gprof arcs */
                    322:        prof_uptrint_t hash_buckets;    /* # gprof hash buckets */
                    323:        prof_uptrint_t bogus_count;     /* # of bogus functions found in gprof */
                    324: 
                    325:        prof_cnt_t cnt;                 /* # of calls to _{,g}prof_mcount */
                    326:        prof_cnt_t dummy;               /* # of calls to _dummy_mcount */
                    327:        prof_cnt_t old_mcount;          /* # of calls to old mcount */
                    328:        prof_cnt_t hash_search;         /* # hash buckets searched */
                    329:        prof_cnt_t hash_num;            /* # times hash table searched */
                    330:        prof_cnt_t user_ticks;          /* # ticks in user space */
                    331:        prof_cnt_t kernel_ticks;        /* # ticks in kernel space */
                    332:        prof_cnt_t idle_ticks;          /* # ticks in idle mode */
                    333:        prof_cnt_t overflow_ticks;      /* # ticks where HISTCOUNTER overflowed */
                    334:        prof_cnt_t acontext_locked;     /* # times an acontext was locked */
                    335:        prof_cnt_t too_low;             /* # times a histogram tick was too low */
                    336:        prof_cnt_t too_high;            /* # times a histogram tick was too high */
                    337:        prof_cnt_t prof_overflow;       /* # times a prof count field overflowed */
                    338:        prof_cnt_t gprof_overflow;      /* # times a gprof count field overflowed */
                    339: 
                    340:                                        /* allocation statistics */
                    341:        prof_uptrint_t num_alloc  [(int)ACONTEXT_MAX];  /* # allocations */
                    342:        prof_uptrint_t bytes_alloc[(int)ACONTEXT_MAX];  /* bytes allocated */
                    343:        prof_uptrint_t num_context[(int)ACONTEXT_MAX];  /* # contexts */
                    344:        prof_uptrint_t wasted     [(int)ACONTEXT_MAX];  /* wasted bytes */
                    345:        prof_uptrint_t overhead   [(int)ACONTEXT_MAX];  /* overhead bytes */
                    346: 
                    347:        prof_uptrint_t buckets[MAX_BUCKETS+1]; /* # hash indexes that have n buckets */
                    348:        prof_cnt_t     cache_hits[MAX_CACHE];  /* # times nth cache entry matched */
                    349: 
                    350:        prof_cnt_t stats_unused[64];    /* reserved for future use */
                    351: };
                    352: 
                    353: #define PROFILE_MAJOR_VERSION 1
                    354: #define PROFILE_MINOR_VERSION 1
                    355: 
                    356: /*
                    357:  * Machine dependent fields.
                    358:  */
                    359: 
                    360: struct profile_md {
                    361:        int major_version;              /* major version number */
                    362:        int minor_version;              /* minor version number */
                    363:        size_t md_size;                 /* size of profile_md structure */
                    364:        struct hasharc **hash_ptr;      /* gprof hash table */
                    365:        size_t hash_size;               /* size of hash table */
                    366:        prof_uptrint_t num_cache;       /* # of cache entries */
                    367:        void (*save_mcount_ptr)(void);  /* save for _mcount_ptr */
                    368:        void (**mcount_ptr_ptr)(void);  /* pointer to _mcount_ptr */
                    369:        struct hasharc *dummy_ptr;      /* pointer to dummy gprof record */
                    370:        void *(*alloc_pages)(size_t);   /* pointer to _profile_alloc_pages */
                    371:        char num_buffer[PROF_CNT_DIGITS]; /* convert 64 bit ints to string */
                    372:        long md_unused[58];             /* add unused fields */
                    373: };
                    374: 
                    375: /*
                    376:  * Record information about each function call.  Specify
                    377:  * caller, caller's caller, and a unique label for use by
                    378:  * the profiling routines.
                    379:  */
                    380: extern void _prof_mcount(void);
                    381: extern void _gprof_mcount(void);
                    382: extern void _dummy_mcount(void);
                    383: extern void (*_mcount_ptr)(void);
                    384: 
                    385: /*
                    386:  * Function in profile-md.c to convert prof_cnt_t to string format (decimal & hex).
                    387:  */
                    388: extern char *_profile_cnt_to_decimal(char *, prof_uptrint_t, prof_uptrint_t);
                    389: 
                    390: #endif /* _PROFILE_MD_H */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.