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/port/devkprof.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 #include        "u.h"
    2 #include        "../port/lib.h"
    3 #include        "mem.h"
    4 #include        "dat.h"
    5 #include        "fns.h"
    6 #include        "../port/error.h"
    7 
    8 
    9 #define LRES    3               /* log of PC resolution */
   10 #define SZ      4               /* sizeof of count cell; well known as 4 */
   11 
   12 struct
   13 {
   14         int     minpc;
   15         int     maxpc;
   16         int     nbuf;
   17         int     time;
   18         ulong   *buf;
   19 }kprof;
   20 
   21 enum{
   22         Kprofdirqid,
   23         Kprofdataqid,
   24         Kprofctlqid,
   25 };
   26 Dirtab kproftab[]={
   27         ".",    {Kprofdirqid, 0, QTDIR},                0,      DMDIR|0550,
   28         "kpdata",       {Kprofdataqid},         0,      0600,
   29         "kpctl",        {Kprofctlqid},          0,      0600,
   30 };
   31 
   32 static void
   33 _kproftimer(ulong pc)
   34 {
   35         extern void spldone(void);
   36 
   37         if(kprof.time == 0)
   38                 return;
   39         /*
   40          *  if the pc is coming out of spllo or splx,
   41          *  use the pc saved when we went splhi.
   42          */
   43         if(pc>=(ulong)spllo && pc<=(ulong)spldone)
   44                 pc = m->splpc;
   45 
   46         kprof.buf[0] += TK2MS(1);
   47         if(kprof.minpc<=pc && pc<kprof.maxpc){
   48                 pc -= kprof.minpc;
   49                 pc >>= LRES;
   50                 kprof.buf[pc] += TK2MS(1);
   51         }else
   52                 kprof.buf[1] += TK2MS(1);
   53 }
   54 
   55 static void
   56 kprofinit(void)
   57 {
   58         if(SZ != sizeof kprof.buf[0])
   59                 panic("kprof size");
   60         kproftimer = _kproftimer;
   61 }
   62 
   63 static Chan*
   64 kprofattach(char *spec)
   65 {
   66         ulong n;
   67 
   68         /* allocate when first used */
   69         kprof.minpc = KTZERO;
   70         kprof.maxpc = (ulong)etext;
   71         kprof.nbuf = (kprof.maxpc-kprof.minpc) >> LRES;
   72         n = kprof.nbuf*SZ;
   73         if(kprof.buf == 0) {
   74                 kprof.buf = xalloc(n);
   75                 if(kprof.buf == 0)
   76                         error(Enomem);
   77         }
   78         kproftab[1].length = n;
   79         return devattach('K', spec);
   80 }
   81 
   82 static Walkqid*
   83 kprofwalk(Chan *c, Chan *nc, char **name, int nname)
   84 {
   85         return devwalk(c, nc, name, nname, kproftab, nelem(kproftab), devgen);
   86 }
   87 
   88 static int
   89 kprofstat(Chan *c, uchar *db, int n)
   90 {
   91         return devstat(c, db, n, kproftab, nelem(kproftab), devgen);
   92 }
   93 
   94 static Chan*
   95 kprofopen(Chan *c, int omode)
   96 {
   97         if(c->qid.type == QTDIR){
   98                 if(omode != OREAD)
   99                         error(Eperm);
  100         }
  101         c->mode = openmode(omode);
  102         c->flag |= COPEN;
  103         c->offset = 0;
  104         return c;
  105 }
  106 
  107 static void
  108 kprofclose(Chan*)
  109 {
  110 }
  111 
  112 static long
  113 kprofread(Chan *c, void *va, long n, vlong off)
  114 {
  115         ulong end;
  116         ulong w, *bp;
  117         uchar *a, *ea;
  118         ulong offset = off;
  119 
  120         switch((int)c->qid.path){
  121         case Kprofdirqid:
  122                 return devdirread(c, va, n, kproftab, nelem(kproftab), devgen);
  123 
  124         case Kprofdataqid:
  125                 end = kprof.nbuf*SZ;
  126                 if(offset & (SZ-1))
  127                         error(Ebadarg);
  128                 if(offset >= end){
  129                         n = 0;
  130                         break;
  131                 }
  132                 if(offset+n > end)
  133                         n = end-offset;
  134                 n &= ~(SZ-1);
  135                 a = va;
  136                 ea = a + n;
  137                 bp = kprof.buf + offset/SZ;
  138                 while(a < ea){
  139                         w = *bp++;
  140                         *a++ = w>>24;
  141                         *a++ = w>>16;
  142                         *a++ = w>>8;
  143                         *a++ = w>>0;
  144                 }
  145                 break;
  146 
  147         default:
  148                 n = 0;
  149                 break;
  150         }
  151         return n;
  152 }
  153 
  154 static long
  155 kprofwrite(Chan *c, void *a, long n, vlong)
  156 {
  157         switch((int)(c->qid.path)){
  158         case Kprofctlqid:
  159                 if(strncmp(a, "startclr", 8) == 0){
  160                         memset((char *)kprof.buf, 0, kprof.nbuf*SZ);
  161                         kprof.time = 1;
  162                 }else if(strncmp(a, "start", 5) == 0)
  163                         kprof.time = 1;
  164                 else if(strncmp(a, "stop", 4) == 0)
  165                         kprof.time = 0;
  166                 break;
  167         default:
  168                 error(Ebadusefd);
  169         }
  170         return n;
  171 }
  172 
  173 Dev kprofdevtab = {
  174         'K',
  175         "kprof",
  176 
  177         devreset,
  178         kprofinit,
  179         devshutdown,
  180         kprofattach,
  181         kprofwalk,
  182         kprofstat,
  183         kprofopen,
  184         devcreate,
  185         kprofclose,
  186         kprofread,
  187         devbread,
  188         kprofwrite,
  189         devbwrite,
  190         devremove,
  191         devwstat,
  192 };

Cache object: 49a5b66657e22b3199dabca6dfa45543


[ 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.