Annotation of XNU/osfmk/profiling/profile-mk.c, 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:  * Microkernel interface to common profiling.
                     27:  */
                     28: 
                     29: #include <profiling/profile-mk.h>
                     30: #include <string.h>
                     31: #include <kern/cpu_number.h>
                     32: #include <kern/processor.h>
                     33: #include <kern/spl.h>
                     34: #include <kern/misc_protos.h>
                     35: #include <vm/vm_kern.h>
                     36: #include <mach/vm_param.h>
                     37: 
                     38: #include <device/ds_routines.h>
                     39: #include <device/io_req.h>
                     40: #include <device/buf.h>
                     41: 
                     42: extern char etext[], pstart[];
                     43: 
                     44: #if NCPUS > 1
                     45: struct profile_vars *_profile_vars_cpus[NCPUS] = { &_profile_vars };
                     46: struct profile_vars _profile_vars_aux[NCPUS-1];
                     47: #endif
                     48: 
                     49: void *
                     50: _profile_alloc_pages (size_t size)
                     51: {
                     52:        vm_offset_t addr;
                     53: 
                     54:        /*
                     55:         * For the MK, we can't support allocating pages at runtime, because we
                     56:         * might be at interrupt level, so abort if we didn't size the table
                     57:         * properly.
                     58:         */
                     59: 
                     60:        if (PROFILE_VARS(0)->active) {
                     61:                panic("Call to _profile_alloc_pages while profiling is running.");
                     62:        }
                     63: 
                     64:        if (kmem_alloc(kernel_map, &addr, size)) {
                     65:                panic("Could not allocate memory for profiling");
                     66:        }
                     67: 
                     68:        memset((void *)addr, '\0', size);
                     69:        if (PROFILE_VARS(0)->debug) {
                     70:                printf("Allocated %d bytes for profiling, address 0x%x\n", (int)size, (int)addr);
                     71:        }
                     72: 
                     73:        return((caddr_t)addr);
                     74: }
                     75: 
                     76: void
                     77: _profile_free_pages(void *addr, size_t size)
                     78: {
                     79:        if (PROFILE_VARS(0)->debug) {
                     80:                printf("Freed %d bytes for profiling, address 0x%x\n", (int)size, (int)addr);
                     81:        }
                     82: 
                     83:        kmem_free(kernel_map, (vm_offset_t)addr, size);
                     84:        return;
                     85: }
                     86: 
                     87: void _profile_error(struct profile_vars *pv)
                     88: {
                     89:        panic("Fatal error in profiling");
                     90: }
                     91: 
                     92: void
                     93: kmstartup(void)
                     94: {
                     95:        prof_uptrint_t textsize;
                     96:        prof_uptrint_t monsize;
                     97:        prof_uptrint_t lowpc;
                     98:        prof_uptrint_t highpc;
                     99:        int i;
                    100:        struct profile_vars *pv;
                    101: 
                    102:        /*
                    103:         * round lowpc and highpc to multiples of the density we're using
                    104:         * so the rest of the scaling (here and in gprof) stays in ints.
                    105:         */
                    106: 
                    107:        lowpc = ROUNDDOWN((prof_uptrint_t)&pstart[0], HISTFRACTION*sizeof(LHISTCOUNTER));
                    108:        highpc = ROUNDUP((prof_uptrint_t)&etext[0], HISTFRACTION*sizeof(LHISTCOUNTER));
                    109:        textsize = highpc - lowpc;
                    110:        monsize = (textsize / HISTFRACTION) * sizeof(LHISTCOUNTER);
                    111: 
                    112:        for (i = 0; i < NCPUS; i++) {
                    113:                pv = PROFILE_VARS(i);
                    114: 
                    115: #if NCPUS > 1
                    116:                if (!pv) {
                    117:                        _profile_vars_cpus[i] = pv = &_profile_vars_aux[i-i];
                    118:                }
                    119: #endif
                    120: 
                    121: #ifdef DEBUG_PROFILE
                    122:                pv->debug = 1;
                    123: #endif
                    124:                pv->page_size = PAGE_SIZE;
                    125:                _profile_md_init(pv, PROFILE_GPROF, PROFILE_ALLOC_MEM_YES);
                    126: 
                    127:                /* Profil related variables */
                    128:                pv->profil_buf = _profile_alloc (pv, monsize, ACONTEXT_PROFIL);
                    129:                pv->profil_info.highpc = highpc;
                    130:                pv->profil_info.lowpc = lowpc;
                    131:                pv->profil_info.text_len = textsize;
                    132:                pv->profil_info.profil_len = monsize;
                    133:                pv->profil_info.counter_size = sizeof(LHISTCOUNTER);
                    134:                pv->profil_info.scale = 0x10000 / HISTFRACTION;
                    135:                pv->stats.profil_buckets = monsize / sizeof(LHISTCOUNTER);
                    136: 
                    137:                /* Other gprof variables */
                    138:                pv->stats.my_cpu = i;
                    139:                pv->stats.max_cpu = NCPUS;
                    140:                pv->init = 1;
                    141:                pv->active = 1;
                    142:                pv->use_dci = 0;
                    143:                pv->use_profil = 1;
                    144:                pv->check_funcs = 1;            /* for now */
                    145: 
                    146:                if (pv->debug) {
                    147:                        printf("Profiling kernel, s_textsize=%ld, monsize=%ld [0x%lx..0x%lx], cpu = %d\n",
                    148:                               (long)textsize,
                    149:                               (long)monsize,
                    150:                               (long)lowpc,
                    151:                               (long)highpc,
                    152:                               i);
                    153:                }
                    154:        }
                    155: 
                    156:        _profile_md_start();
                    157: }
                    158: 
                    159: /* driver component */
                    160: 
                    161: int
                    162: gprofprobe(caddr_t port, void *ctlr)
                    163: {
                    164:        return(1);
                    165: }
                    166: 
                    167: void
                    168: gprofattach(void)
                    169: {
                    170:        kmstartup();
                    171:        return;
                    172: }
                    173: 
                    174: /* struct bus_device *gprofinfo[NGPROF]; */
                    175: struct bus_device *gprofinfo[1];
                    176: 
                    177: struct bus_driver      gprof_driver = {
                    178:        gprofprobe, 0, gprofattach, 0, 0, "gprof", gprofinfo, "gprofc", 0, 0};
                    179: 
                    180: 
                    181: io_return_t
                    182: gprofopen(dev_t dev,
                    183:          int flags,
                    184:          io_req_t ior)
                    185: {
                    186:        ior->io_error = D_SUCCESS;
                    187:        return(0);
                    188: }
                    189: 
                    190: void
                    191: gprofclose(dev_t dev)
                    192: {
                    193:        return;
                    194: }
                    195: 
                    196: void
                    197: gprofstrategy(io_req_t ior)
                    198: {
                    199:        void *sys_ptr = (void *)0;
                    200: 
                    201:        long count = _profile_kgmon(!(ior->io_op & IO_READ),
                    202:                                    ior->io_count,
                    203:                                    ior->io_recnum,
                    204:                                    NCPUS,
                    205:                                    &sys_ptr,
                    206:                                    (void (*)(kgmon_control_t))0);
                    207: 
                    208:        if (count < 0) {
                    209:                ior->io_error = D_INVALID_RECNUM;
                    210: 
                    211:        } else {
                    212:                if (count > 0 && sys_ptr != (void *)0) {
                    213:                        if (ior->io_op & IO_READ) {
                    214:                                memcpy((void *)ior->io_data, sys_ptr, count);
                    215:                        } else {
                    216:                                memcpy(sys_ptr, (void *)ior->io_data, count);
                    217:                        }
                    218:                }
                    219: 
                    220:                ior->io_error = D_SUCCESS;
                    221:                ior->io_residual = ior->io_count - count;
                    222:        }
                    223: 
                    224:        iodone(ior);
                    225: }
                    226: 
                    227: io_return_t
                    228: gprofread(dev_t dev,
                    229:          io_req_t ior)
                    230: {
                    231:        return(block_io(gprofstrategy, minphys, ior));
                    232: }
                    233: 
                    234: io_return_t
                    235: gprofwrite(dev_t dev,
                    236:           io_req_t ior)
                    237: {
                    238:        return (block_io(gprofstrategy, minphys, ior));
                    239: }

unix.superglobalmegacorp.com

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