Annotation of OSKit-Mach/kern/pc_sample.c, revision 1.1

1.1     ! root        1: /* 
        !             2:  * Mach Operating System
        !             3:  * Copyright (c) 1993,1992 Carnegie Mellon University
        !             4:  * All Rights Reserved.
        !             5:  * 
        !             6:  * Permission to use, copy, modify and distribute this software and its
        !             7:  * documentation is hereby granted, provided that both the copyright
        !             8:  * notice and this permission notice appear in all copies of the
        !             9:  * software, derivative works or modified versions, and any portions
        !            10:  * thereof, and that both notices appear in supporting documentation.
        !            11:  * 
        !            12:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
        !            13:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
        !            14:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
        !            15:  * 
        !            16:  * Carnegie Mellon requests users of this software to return to
        !            17:  * 
        !            18:  *  Software Distribution Coordinator  or  [email protected]
        !            19:  *  School of Computer Science
        !            20:  *  Carnegie Mellon University
        !            21:  *  Pittsburgh PA 15213-3890
        !            22:  * 
        !            23:  * any improvements or extensions that they make and grant Carnegie Mellon
        !            24:  * the rights to redistribute these changes.
        !            25:  */
        !            26: 
        !            27: 
        !            28: 
        !            29: #include <mach_pcsample.h>
        !            30: 
        !            31: #include <mach/mach_types.h>   /* vm_address_t */
        !            32: #include <mach/std_types.h>    /* pointer_t */
        !            33: #include <mach/pc_sample.h>
        !            34: #include <kern/host.h>
        !            35: #include <kern/thread.h>
        !            36: #include <kern/pc_sample.h>
        !            37: 
        !            38: #if    MACH_PCSAMPLE
        !            39: 
        !            40: #define MAX_PC_SAMPLES 512
        !            41: 
        !            42: typedef sampled_pc_t sampled_pcs[MAX_PC_SAMPLES];
        !            43: 
        !            44: int pc_sampling_enabled = 0;
        !            45: decl_simple_lock_data(, pc_sampling_lock)      /* lock for enabling */
        !            46: 
        !            47: void take_pc_sample(
        !            48:     register thread_t t,
        !            49:     register sample_control_t *cp,
        !            50:     sampled_pc_flavor_t flavor)
        !            51: {
        !            52:     vm_offset_t pc;
        !            53:     struct sampled_pc *sample;
        !            54:     
        !            55:     pc = interrupted_pc(t);
        !            56:     cp->seqno++;
        !            57:     sample = &((sampled_pc_t *)cp->buffer)[cp->seqno % MAX_PC_SAMPLES];
        !            58:     sample->id = (natural_t)t;
        !            59:     sample->pc = pc;
        !            60:     sample->sampletype = flavor;
        !            61: }
        !            62: 
        !            63: kern_return_t
        !            64: thread_enable_pc_sampling(
        !            65:     thread_t thread,
        !            66:     int *tickp,
        !            67:     sampled_pc_flavor_t flavors)
        !            68: {
        !            69:     vm_offset_t buf;
        !            70:     extern int tick;
        !            71: 
        !            72:     if (thread == THREAD_NULL)  {
        !            73:        return KERN_INVALID_ARGUMENT;
        !            74:     }
        !            75:     if (thread->pc_sample.buffer == 0)  {
        !            76:        buf = (vm_offset_t) kalloc(sizeof (sampled_pcs));
        !            77:        if (buf == 0) {
        !            78:            printf("thread_enable_pc_sampling: kalloc failed\n");
        !            79:            return KERN_INVALID_ARGUMENT;
        !            80:        }
        !            81:        thread->pc_sample.buffer = buf;
        !            82:        thread->pc_sample.seqno = 0;
        !            83:     }
        !            84:     *tickp = tick;
        !            85:     thread->pc_sample.sampletypes = flavors;
        !            86:     return KERN_SUCCESS;
        !            87: }
        !            88: 
        !            89: kern_return_t
        !            90: task_enable_pc_sampling(
        !            91:     task_t task,
        !            92:     int *tickp,
        !            93:     sampled_pc_flavor_t flavors)
        !            94: {
        !            95:     vm_offset_t buf;
        !            96:     extern int tick;
        !            97: 
        !            98:     if (task == TASK_NULL)  {
        !            99:        return KERN_INVALID_ARGUMENT;
        !           100:     }
        !           101:     if (task->pc_sample.buffer == 0)  {
        !           102:        buf = (vm_offset_t) kalloc(sizeof (sampled_pcs));
        !           103:        if (buf == 0) {
        !           104:            printf("task_enable_pc_sampling: kalloc failed\n");
        !           105:            return KERN_INVALID_ARGUMENT;
        !           106:        }
        !           107:        task->pc_sample.buffer = buf;
        !           108:        task->pc_sample.seqno = 0;
        !           109:     }
        !           110:     *tickp = tick;
        !           111:     task->pc_sample.sampletypes = flavors;
        !           112:     return KERN_SUCCESS;
        !           113: }
        !           114: 
        !           115: kern_return_t
        !           116: thread_disable_pc_sampling(
        !           117:     thread_t thread,
        !           118:     int *samplecntp)
        !           119: {
        !           120:     vm_offset_t buf;
        !           121: 
        !           122:     if (thread == THREAD_NULL)  {
        !           123:        return KERN_INVALID_ARGUMENT;
        !           124:     }
        !           125:     if ((buf = thread->pc_sample.buffer) != 0)
        !           126:        kfree(buf, sizeof (sampled_pcs));
        !           127:     thread->pc_sample.buffer = (vm_offset_t) 0;
        !           128:     thread->pc_sample.seqno = 0;
        !           129:     thread->pc_sample.sampletypes = 0; /* shut off sampling */
        !           130:     
        !           131:     return KERN_SUCCESS;
        !           132: }
        !           133: 
        !           134: kern_return_t
        !           135: task_disable_pc_sampling(
        !           136:     task_t task,
        !           137:     int *samplecntp)
        !           138: {
        !           139:     vm_offset_t buf;
        !           140: 
        !           141:     if (task == TASK_NULL)  {
        !           142:        return KERN_INVALID_ARGUMENT;
        !           143:     }
        !           144:     if ((buf = task->pc_sample.buffer) != 0)
        !           145:        kfree(buf, sizeof (sampled_pcs));
        !           146:     task->pc_sample.buffer = (vm_offset_t) 0;
        !           147:     task->pc_sample.seqno = 0;
        !           148:     task->pc_sample.sampletypes = 0;   /* shut off sampling */
        !           149: 
        !           150:     return KERN_SUCCESS;
        !           151: }
        !           152: 
        !           153: static kern_return_t
        !           154: get_sampled_pcs(
        !           155:        sample_control_t *cp,
        !           156:        sampled_pc_seqno_t *seqnop,
        !           157:        sampled_pc_array_t sampled_pcs_out,
        !           158:        int *sampled_pcs_cntp)
        !           159: {
        !           160:     int nsamples;
        !           161:     sampled_pc_seqno_t seqidx1, seqidx2;
        !           162: 
        !           163:     nsamples   = cp->seqno - *seqnop;
        !           164:     seqidx1    = *seqnop % MAX_PC_SAMPLES;        /* index of *seqnop */
        !           165:     seqidx2    = cp->seqno % MAX_PC_SAMPLES;  /* index of cp->seqno */
        !           166: 
        !           167:     if  (nsamples > MAX_PC_SAMPLES) {
        !           168:        nsamples = MAX_PC_SAMPLES;
        !           169:        seqidx1  = (seqidx2 + 1) % MAX_PC_SAMPLES;
        !           170:     }
        !           171: 
        !           172:     if (nsamples > 0)  {
        !           173:        /*
        !           174:         * Carefully copy sampled_pcs into sampled_pcs_msgbuf IN ORDER.
        !           175:         */
        !           176:        if (seqidx1 < seqidx2) {
        !           177:            /*
        !           178:             * Simple case: no wraparound.
        !           179:             * Copy from seqidx1 to seqidx2.
        !           180:             */
        !           181:            bcopy((sampled_pc_array_t)cp->buffer + seqidx1 + 1,
        !           182:                  sampled_pcs_out,
        !           183:                  nsamples * sizeof(sampled_pc_t));
        !           184:        } else {
        !           185:            /* seqidx1 > seqidx2 -- Handle wraparound. */
        !           186: 
        !           187:            bcopy((sampled_pc_array_t)cp->buffer + seqidx1 + 1,
        !           188:                  sampled_pcs_out,
        !           189:                  (MAX_PC_SAMPLES - seqidx1 - 1) * sizeof(sampled_pc_t));
        !           190: 
        !           191:            bcopy((sampled_pc_array_t)cp->buffer,
        !           192:                  sampled_pcs_out + (MAX_PC_SAMPLES - seqidx1 - 1),
        !           193:                  (seqidx2 + 1) * sizeof(sampled_pc_t));
        !           194:        }
        !           195:     } else {
        !           196:        /*  could either be zero because of overflow, or because
        !           197:         *  we are being lied to.  In either case, return nothing.
        !           198:         *  If overflow, only once in a blue moon. If being lied to,
        !           199:         *  then we have no obligation to return anything useful anyway.
        !           200:         */
        !           201:        ;
        !           202:     }
        !           203:        
        !           204:     *sampled_pcs_cntp = nsamples;
        !           205:     *seqnop = cp->seqno;
        !           206:     return KERN_SUCCESS;
        !           207: }
        !           208: 
        !           209: kern_return_t
        !           210: thread_get_sampled_pcs(
        !           211:        thread_t thread,
        !           212:        sampled_pc_seqno_t *seqnop,
        !           213:        sampled_pc_array_t sampled_pcs_out,
        !           214:        int *sampled_pcs_cntp)
        !           215: {
        !           216:     if (thread == THREAD_NULL)
        !           217:        return KERN_INVALID_ARGUMENT;
        !           218: 
        !           219:     if (thread->pc_sample.buffer == 0)
        !           220:         return KERN_FAILURE;
        !           221: 
        !           222:     return get_sampled_pcs(&thread->pc_sample, seqnop, sampled_pcs_out,
        !           223:                           sampled_pcs_cntp);
        !           224: }
        !           225: 
        !           226: kern_return_t
        !           227: task_get_sampled_pcs(
        !           228:        task_t task,
        !           229:        sampled_pc_seqno_t *seqnop,
        !           230:        sampled_pc_array_t sampled_pcs_out,
        !           231:        int *sampled_pcs_cntp)
        !           232: {
        !           233:     if (task == TASK_NULL)
        !           234:        return KERN_INVALID_ARGUMENT;
        !           235: 
        !           236:     if (task->pc_sample.buffer == 0)
        !           237:         return KERN_FAILURE;
        !           238: 
        !           239:     return get_sampled_pcs(&task->pc_sample, seqnop, sampled_pcs_out,
        !           240:                           sampled_pcs_cntp);
        !           241: }
        !           242: 
        !           243: #else  /* MACH_PCSAMPLE */
        !           244: 
        !           245: kern_return_t
        !           246: thread_enable_pc_sampling(
        !           247:     thread_t thread,
        !           248:     int *tickp,
        !           249:     sampled_pc_flavor_t flavors)
        !           250: {
        !           251:     return KERN_FAILURE;       /* not implemented */
        !           252: }
        !           253: 
        !           254: kern_return_t
        !           255: task_enable_pc_sampling(
        !           256:     task_t task,
        !           257:     int *tickp,
        !           258:     sampled_pc_flavor_t flavors)
        !           259: {
        !           260:     return KERN_FAILURE;       /* not implemented */
        !           261: }
        !           262: 
        !           263: kern_return_t
        !           264: thread_disable_pc_sampling(
        !           265:     thread_t thread,
        !           266:     int *samplecntp)
        !           267: {
        !           268:     return KERN_FAILURE;       /* not implemented */
        !           269: }
        !           270: 
        !           271: kern_return_t
        !           272: task_disable_pc_sampling(
        !           273:     task_t task,
        !           274:     int *samplecntp)
        !           275: {
        !           276:     return KERN_FAILURE;       /* not implemented */
        !           277: }
        !           278: 
        !           279: kern_return_t
        !           280: thread_get_sampled_pcs(
        !           281:        thread_t thread,
        !           282:        sampled_pc_seqno_t *seqnop,
        !           283:        sampled_pc_array_t sampled_pcs_out,
        !           284:        int *sampled_pcs_cntp)
        !           285: {
        !           286:     return KERN_FAILURE;       /* not implemented */
        !           287: }
        !           288: 
        !           289: kern_return_t
        !           290: task_get_sampled_pcs(
        !           291:        task_t task,
        !           292:        sampled_pc_seqno_t *seqnop,
        !           293:        sampled_pc_array_t sampled_pcs_out,
        !           294:        int *sampled_pcs_cntp)
        !           295: {
        !           296:     return KERN_FAILURE;       /* not implemented */
        !           297: }
        !           298: 
        !           299: #endif /* MACH_PCSAMPLE */

unix.superglobalmegacorp.com

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