Annotation of Gnu-Mach/kern/pc_sample.c, revision 1.1.1.3

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: 
1.1.1.2   root       27: #include <kern/printf.h>
                     28: #include <string.h>
1.1       root       29: 
                     30: #include <mach/mach_types.h>   /* vm_address_t */
                     31: #include <mach/std_types.h>    /* pointer_t */
                     32: #include <mach/pc_sample.h>
1.1.1.2   root       33: #include <machine/trap.h>
                     34: #include <kern/kalloc.h>
1.1       root       35: #include <kern/host.h>
                     36: #include <kern/thread.h>
                     37: #include <kern/pc_sample.h>
1.1.1.2   root       38: #include <kern/mach_clock.h>
1.1       root       39: 
                     40: #if    MACH_PCSAMPLE
                     41: 
                     42: #define MAX_PC_SAMPLES 512
                     43: 
                     44: typedef sampled_pc_t sampled_pcs[MAX_PC_SAMPLES];
                     45: 
                     46: void take_pc_sample(
1.1.1.3 ! root       47:     const thread_t t,
        !            48:     sample_control_t *cp,
1.1       root       49:     sampled_pc_flavor_t flavor)
                     50: {
                     51:     vm_offset_t pc;
                     52:     struct sampled_pc *sample;
                     53:     
                     54:     pc = interrupted_pc(t);
                     55:     cp->seqno++;
                     56:     sample = &((sampled_pc_t *)cp->buffer)[cp->seqno % MAX_PC_SAMPLES];
1.1.1.2   root       57:     sample->id = (vm_offset_t)t;
1.1       root       58:     sample->pc = pc;
                     59:     sample->sampletype = flavor;
                     60: }
                     61: 
                     62: kern_return_t
                     63: thread_enable_pc_sampling(
                     64:     thread_t thread,
                     65:     int *tickp,
                     66:     sampled_pc_flavor_t flavors)
                     67: {
                     68:     vm_offset_t buf;
                     69: 
                     70:     if (thread == THREAD_NULL)  {
                     71:        return KERN_INVALID_ARGUMENT;
                     72:     }
                     73:     if (thread->pc_sample.buffer == 0)  {
                     74:        buf = (vm_offset_t) kalloc(sizeof (sampled_pcs));
                     75:        if (buf == 0) {
                     76:            printf("thread_enable_pc_sampling: kalloc failed\n");
                     77:            return KERN_INVALID_ARGUMENT;
                     78:        }
                     79:        thread->pc_sample.buffer = buf;
                     80:        thread->pc_sample.seqno = 0;
                     81:     }
                     82:     *tickp = tick;
                     83:     thread->pc_sample.sampletypes = flavors;
                     84:     return KERN_SUCCESS;
                     85: }
                     86: 
                     87: kern_return_t
                     88: task_enable_pc_sampling(
                     89:     task_t task,
                     90:     int *tickp,
                     91:     sampled_pc_flavor_t flavors)
                     92: {
                     93:     vm_offset_t buf;
                     94: 
                     95:     if (task == TASK_NULL)  {
                     96:        return KERN_INVALID_ARGUMENT;
                     97:     }
                     98:     if (task->pc_sample.buffer == 0)  {
                     99:        buf = (vm_offset_t) kalloc(sizeof (sampled_pcs));
                    100:        if (buf == 0) {
                    101:            printf("task_enable_pc_sampling: kalloc failed\n");
                    102:            return KERN_INVALID_ARGUMENT;
                    103:        }
                    104:        task->pc_sample.buffer = buf;
                    105:        task->pc_sample.seqno = 0;
                    106:     }
                    107:     *tickp = tick;
                    108:     task->pc_sample.sampletypes = flavors;
                    109:     return KERN_SUCCESS;
                    110: }
                    111: 
                    112: kern_return_t
                    113: thread_disable_pc_sampling(
                    114:     thread_t thread,
                    115:     int *samplecntp)
                    116: {
                    117:     vm_offset_t buf;
                    118: 
                    119:     if (thread == THREAD_NULL)  {
                    120:        return KERN_INVALID_ARGUMENT;
                    121:     }
                    122:     if ((buf = thread->pc_sample.buffer) != 0)
                    123:        kfree(buf, sizeof (sampled_pcs));
                    124:     thread->pc_sample.buffer = (vm_offset_t) 0;
                    125:     thread->pc_sample.seqno = 0;
                    126:     thread->pc_sample.sampletypes = 0; /* shut off sampling */
                    127:     
                    128:     return KERN_SUCCESS;
                    129: }
                    130: 
                    131: kern_return_t
                    132: task_disable_pc_sampling(
                    133:     task_t task,
                    134:     int *samplecntp)
                    135: {
                    136:     vm_offset_t buf;
                    137: 
                    138:     if (task == TASK_NULL)  {
                    139:        return KERN_INVALID_ARGUMENT;
                    140:     }
                    141:     if ((buf = task->pc_sample.buffer) != 0)
                    142:        kfree(buf, sizeof (sampled_pcs));
                    143:     task->pc_sample.buffer = (vm_offset_t) 0;
                    144:     task->pc_sample.seqno = 0;
                    145:     task->pc_sample.sampletypes = 0;   /* shut off sampling */
                    146: 
                    147:     return KERN_SUCCESS;
                    148: }
                    149: 
                    150: static kern_return_t
                    151: get_sampled_pcs(
                    152:        sample_control_t *cp,
                    153:        sampled_pc_seqno_t *seqnop,
                    154:        sampled_pc_array_t sampled_pcs_out,
                    155:        int *sampled_pcs_cntp)
                    156: {
                    157:     int nsamples;
                    158:     sampled_pc_seqno_t seqidx1, seqidx2;
                    159: 
                    160:     nsamples   = cp->seqno - *seqnop;
                    161:     seqidx1    = *seqnop % MAX_PC_SAMPLES;        /* index of *seqnop */
                    162:     seqidx2    = cp->seqno % MAX_PC_SAMPLES;  /* index of cp->seqno */
                    163: 
                    164:     if  (nsamples > MAX_PC_SAMPLES) {
                    165:        nsamples = MAX_PC_SAMPLES;
                    166:        seqidx1  = (seqidx2 + 1) % MAX_PC_SAMPLES;
                    167:     }
                    168: 
                    169:     if (nsamples > 0)  {
                    170:        /*
                    171:         * Carefully copy sampled_pcs into sampled_pcs_msgbuf IN ORDER.
                    172:         */
                    173:        if (seqidx1 < seqidx2) {
                    174:            /*
                    175:             * Simple case: no wraparound.
                    176:             * Copy from seqidx1 to seqidx2.
                    177:             */
1.1.1.2   root      178:            memcpy(sampled_pcs_out,
                    179:                   (sampled_pc_array_t)cp->buffer + seqidx1 + 1,
                    180:                   nsamples * sizeof(sampled_pc_t));
1.1       root      181:        } else {
                    182:            /* seqidx1 > seqidx2 -- Handle wraparound. */
                    183: 
1.1.1.2   root      184:            memcpy(sampled_pcs_out,
                    185:                   (sampled_pc_array_t)cp->buffer + seqidx1 + 1,
                    186:                   (MAX_PC_SAMPLES - seqidx1 - 1) * sizeof(sampled_pc_t));
                    187: 
                    188:            memcpy(sampled_pcs_out + (MAX_PC_SAMPLES - seqidx1 - 1),
                    189:                   (sampled_pc_array_t)cp->buffer,
                    190:                   (seqidx2 + 1) * sizeof(sampled_pc_t));
1.1       root      191:        }
1.1.1.3 ! root      192:     } else if (nsamples < 0) {
        !           193:        /* Bogus SEQNO supplied.  */
        !           194:        nsamples = 0;
1.1       root      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(
1.1.1.3 ! root      247:     const thread_t thread,
        !           248:     const int *tickp,
1.1       root      249:     sampled_pc_flavor_t flavors)
                    250: {
                    251:     return KERN_FAILURE;       /* not implemented */
                    252: }
                    253: 
                    254: kern_return_t
                    255: task_enable_pc_sampling(
1.1.1.3 ! root      256:     const task_t task,
        !           257:     const int *tickp,
1.1       root      258:     sampled_pc_flavor_t flavors)
                    259: {
                    260:     return KERN_FAILURE;       /* not implemented */
                    261: }
                    262: 
                    263: kern_return_t
                    264: thread_disable_pc_sampling(
1.1.1.3 ! root      265:     const thread_t thread,
        !           266:     const int *samplecntp)
1.1       root      267: {
                    268:     return KERN_FAILURE;       /* not implemented */
                    269: }
                    270: 
                    271: kern_return_t
                    272: task_disable_pc_sampling(
1.1.1.3 ! root      273:     const task_t task,
        !           274:     const int *samplecntp)
1.1       root      275: {
                    276:     return KERN_FAILURE;       /* not implemented */
                    277: }
                    278: 
                    279: kern_return_t
                    280: thread_get_sampled_pcs(
1.1.1.3 ! root      281:        const thread_t thread,
        !           282:        const sampled_pc_seqno_t *seqnop,
        !           283:        const sampled_pc_array_t sampled_pcs_out,
        !           284:        const int *sampled_pcs_cntp)
1.1       root      285: {
                    286:     return KERN_FAILURE;       /* not implemented */
                    287: }
                    288: 
                    289: kern_return_t
                    290: task_get_sampled_pcs(
1.1.1.3 ! root      291:        const task_t task,
        !           292:        const sampled_pc_seqno_t *seqnop,
        !           293:        const sampled_pc_array_t sampled_pcs_out,
        !           294:        const int *sampled_pcs_cntp)
1.1       root      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.