The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/pc_sample.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* 
    2  * Mach Operating System
    3  * Copyright (c) 1991,1990,1989 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  Software.Distribution@CS.CMU.EDU
   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  * HISTORY
   28  * $Log:        pc_sample.c,v $
   29  * Revision 2.4  93/08/03  12:31:18  mrt
   30  *      [93/08/02  16:50:13  bershad]
   31  * 
   32  *      Flavor support for PC sampling.
   33  *      [93/07/30  10:23:02  bershad]
   34  * 
   35  * Revision 2.3  93/01/27  09:39:48  danner
   36  *      take_pc_sample() is void, get_sampled_pcs is static return_t
   37  *      [93/01/25            jfriedl]
   38  * 
   39  * Revision 2.2  93/01/24  13:19:46  danner
   40  *      Lots of changes.
   41  *      [93/01/12            rvb]
   42  *      Created.
   43  *      [92/05/10            cmaeda]
   44  * 
   45  */
   46 
   47 
   48 
   49 #include <mach_pcsample.h>
   50 
   51 #if     MACH_PCSAMPLE > 0
   52 
   53 
   54 #include <mach/mach_types.h>    /* vm_address_t */
   55 #include <mach/std_types.h>     /* pointer_t */
   56 #include <mach/pc_sample.h>
   57 #include <kern/host.h>
   58 #include <kern/thread.h>
   59 
   60 #define MAX_PC_SAMPLES 512
   61 
   62 typedef sampled_pc_t sampled_pcs[MAX_PC_SAMPLES];
   63 
   64 int pc_sampling_enabled = 0;
   65 decl_simple_lock_data(, pc_sampling_lock)       /* lock for enabling */
   66 
   67 void take_pc_sample(t, cp, flavor)
   68     register thread_t t;
   69     register sample_control_t *cp;
   70     sampled_pc_flavor_t flavor;
   71 {
   72     unsigned pc;
   73     struct sampled_pc *sample;
   74     
   75     pc = interrupted_pc(t);
   76     cp->seqno++;
   77     sample = &((sampled_pc_t *)cp->buffer)[cp->seqno % MAX_PC_SAMPLES];
   78     sample->id = (unsigned int)t;
   79     sample->pc = pc;
   80     sample->sampletype = flavor;
   81 }
   82 
   83 kern_return_t
   84 thread_enable_pc_sampling(thread, tickp, flavors)
   85     thread_t thread;
   86     int *tickp;
   87     sampled_pc_flavor_t flavors;
   88 {
   89     vm_offset_t buf;
   90     extern int tick;
   91 
   92     if (thread == THREAD_NULL)  {
   93         return KERN_INVALID_ARGUMENT;
   94     }
   95     if (!thread->pc_sample.buffer)  {
   96         if (!(int) (buf = (vm_offset_t) kalloc(sizeof (sampled_pcs)))) {
   97             printf("thread_enable_pc_sampling: kalloc failed\n");
   98             return KERN_INVALID_ARGUMENT;
   99         }
  100         thread->pc_sample.buffer = buf;
  101         thread->pc_sample.seqno = 0;
  102     }
  103     *tickp = tick;
  104     thread->pc_sample.sampletypes = flavors;
  105     return KERN_SUCCESS;
  106 }
  107 
  108 kern_return_t
  109 task_enable_pc_sampling(task, tickp, flavors)
  110     task_t task;
  111     int *tickp;
  112     sampled_pc_flavor_t flavors;
  113 {
  114     vm_offset_t buf;
  115     extern int tick;
  116 
  117     if (task == TASK_NULL)  {
  118         return KERN_INVALID_ARGUMENT;
  119     }
  120     if (!task->pc_sample.buffer)  {
  121         if (!(int) (buf = (vm_offset_t) kalloc(sizeof (sampled_pcs)))) {
  122             printf("task_enable_pc_sampling: kalloc failed\n");
  123             return KERN_INVALID_ARGUMENT;
  124         }
  125         task->pc_sample.buffer = buf;
  126         task->pc_sample.seqno = 0;
  127     }
  128     *tickp = tick;
  129     task->pc_sample.sampletypes = flavors;
  130     return KERN_SUCCESS;
  131 }
  132 
  133 kern_return_t
  134 thread_disable_pc_sampling(thread, samplecntp)
  135     thread_t thread;
  136     int *samplecntp;
  137 {
  138     vm_offset_t buf;
  139 
  140     if (thread == THREAD_NULL)  {
  141         return KERN_INVALID_ARGUMENT;
  142     }
  143     if (buf = thread->pc_sample.buffer)
  144         kfree(buf, sizeof (sampled_pcs));
  145     thread->pc_sample.buffer = (vm_offset_t) 0;
  146     thread->pc_sample.seqno = 0;
  147     
  148     return KERN_SUCCESS;
  149 }
  150 
  151 kern_return_t
  152 task_disable_pc_sampling(task, samplecntp)
  153     task_t task;
  154     int *samplecntp;
  155 {
  156     vm_offset_t buf;
  157 
  158     if (task == TASK_NULL)  {
  159         return KERN_INVALID_ARGUMENT;
  160     }
  161     if (buf = task->pc_sample.buffer)
  162         kfree(buf, sizeof (sampled_pcs));
  163     task->pc_sample.buffer = (vm_offset_t) 0;
  164     task->pc_sample.seqno = 0;
  165 
  166     return KERN_SUCCESS;
  167 }
  168 
  169 static kern_return_t
  170 get_sampled_pcs(cp, seqnop, sampled_pcs_out, sampled_pcs_cntp)
  171         sample_control_t *cp;
  172         sampled_pc_seqno_t *seqnop;
  173         sampled_pc_array_t sampled_pcs_out;
  174         int *sampled_pcs_cntp;
  175 {
  176     int nsamples;
  177     sampled_pc_seqno_t seqidx1, seqidx2;
  178 
  179     nsamples    = cp->seqno - *seqnop;
  180     seqidx1     = *seqnop % MAX_PC_SAMPLES;        /* index of *seqnop */
  181     seqidx2     = cp->seqno % MAX_PC_SAMPLES;  /* index of cp->seqno */
  182 
  183     if  (nsamples > MAX_PC_SAMPLES) {
  184         nsamples = MAX_PC_SAMPLES;
  185         seqidx1  = (seqidx2 + 1) % MAX_PC_SAMPLES;
  186     }
  187 
  188     if (nsamples > 0)  {
  189         /*
  190          * Carefully copy sampled_pcs into sampled_pcs_msgbuf IN ORDER.
  191          */
  192         if (seqidx1 < seqidx2) {
  193             /*
  194              * Simple case: no wraparound.
  195              * Copy from seqidx1 to seqidx2.
  196              */
  197             bcopy((sampled_pc_array_t)cp->buffer + seqidx1 + 1,
  198                   sampled_pcs_out,
  199                   nsamples * sizeof(sampled_pc_t));
  200         } else {
  201             /* seqidx1 > seqidx2 -- Handle wraparound. */
  202 
  203             bcopy((sampled_pc_array_t)cp->buffer + seqidx1 + 1,
  204                   sampled_pcs_out,
  205                   (MAX_PC_SAMPLES - seqidx1 - 1) * sizeof(sampled_pc_t));
  206 
  207             bcopy((sampled_pc_array_t)cp->buffer,
  208                   sampled_pcs_out + (MAX_PC_SAMPLES - seqidx1 - 1),
  209                   (seqidx2 + 1) * sizeof(sampled_pc_t));
  210         }
  211     } else {
  212         /*  could either be zero because of overflow, or because
  213          *  we are being lied to.  In either case, return nothing.
  214          *  If overflow, only once in a blue moon. If being lied to,
  215          *  then we have no obligation to return anything useful anyway.
  216          */
  217         ;
  218     }
  219         
  220     *sampled_pcs_cntp = nsamples;
  221     *seqnop = cp->seqno;
  222     return KERN_SUCCESS;
  223 }
  224 
  225 kern_return_t
  226 thread_get_sampled_pcs(thread, seqnop, sampled_pcs_out, sampled_pcs_cntp)
  227         thread_t thread;
  228         sampled_pc_seqno_t *seqnop;
  229         sampled_pc_array_t sampled_pcs_out;
  230         int *sampled_pcs_cntp;
  231 {
  232     if (thread == THREAD_NULL)
  233         return KERN_INVALID_ARGUMENT;
  234 
  235     if ((int)thread->pc_sample.buffer == 0)
  236         return KERN_FAILURE;
  237 
  238     return get_sampled_pcs(&thread->pc_sample, seqnop, sampled_pcs_out, sampled_pcs_cntp);
  239 }
  240 
  241 kern_return_t
  242 task_get_sampled_pcs(task, seqnop, sampled_pcs_out, sampled_pcs_cntp)
  243         task_t task;
  244         sampled_pc_seqno_t *seqnop;
  245         sampled_pc_array_t sampled_pcs_out;
  246         int *sampled_pcs_cntp;
  247 {
  248     int nsamples;
  249     sampled_pc_seqno_t seqidx1, seqidx2;
  250 
  251     if (task == TASK_NULL)
  252         return KERN_INVALID_ARGUMENT;
  253 
  254     if ((int)task->pc_sample.buffer == 0)
  255         return KERN_FAILURE;
  256 
  257     return get_sampled_pcs(&task->pc_sample, seqnop, sampled_pcs_out, sampled_pcs_cntp);
  258     
  259 }
  260 
  261 
  262 #endif /* MACH_PCSAMPLE > 0 */
  263 

Cache object: 12c0aae8671352378d0f2f30d8bb1f93


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.