Annotation of OSKit-Mach/kern/pc_sample.c, revision 1.1.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.