Annotation of XNU/osfmk/profiling/profile-mk.c, revision 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.