root/kern/subr_evcount.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. TAILQ_HEAD
  2. evcount_attach
  3. evcount_detach
  4. evcount_sysctl

    1 /*      $OpenBSD: subr_evcount.c,v 1.8 2006/10/17 10:29:50 grange Exp $ */
    2 /*
    3  * Copyright (c) 2004 Artur Grabowski <art@openbsd.org>
    4  * Copyright (c) 2004 Aaron Campbell <aaron@openbsd.org>
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  *
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. The name of the author may not be used to endorse or promote products
   14  *    derived from this software without specific prior written permission.
   15  *
   16  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
   17  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
   18  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
   19  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   20  * EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
   22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
   23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
   25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   26  */
   27 
   28 #include <sys/param.h>
   29 #include <sys/evcount.h>
   30 #include <sys/timeout.h>
   31 #include <sys/kernel.h>
   32 #include <sys/systm.h>
   33 #include <sys/sysctl.h>
   34 
   35 static TAILQ_HEAD(,evcount) evcount_list;
   36 
   37 /*
   38  * Standard evcount parents.
   39  */
   40 struct evcount evcount_intr;
   41 
   42 void evcount_init(void);
   43 
   44 void
   45 evcount_init(void)
   46 {
   47         TAILQ_INIT(&evcount_list);
   48 
   49         evcount_attach(&evcount_intr, "intr", NULL, NULL);
   50 }
   51 
   52 
   53 void
   54 evcount_attach(struct evcount *ec, const char *name, void *data,
   55     struct evcount *parent)
   56 {
   57         static int nextid = 0;
   58 
   59         if (nextid == 0) {
   60                 nextid++;               /* start with 1 */
   61                 evcount_init();
   62         }
   63 
   64         memset(ec, 0, sizeof(*ec));
   65         ec->ec_name = name;
   66         ec->ec_parent = parent;
   67         ec->ec_id = nextid++;
   68         ec->ec_data = data;
   69         TAILQ_INSERT_TAIL(&evcount_list, ec, next);
   70 }
   71 
   72 void
   73 evcount_detach(struct evcount *ec)
   74 {
   75         TAILQ_REMOVE(&evcount_list, ec, next);
   76 }
   77 
   78 #ifndef SMALL_KERNEL
   79 
   80 int
   81 evcount_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
   82     void *newp, size_t newlen)
   83 {
   84         int error = 0, s, nintr, i;
   85         struct evcount *ec;
   86         u_int64_t count;
   87 
   88         if (newp != NULL)
   89                 return (EPERM);
   90 
   91         if (name[0] != KERN_INTRCNT_NUM) {
   92                 if (namelen != 2)
   93                         return (ENOTDIR);
   94                 if (name[1] < 0)
   95                         return (EINVAL);
   96                 i = name[1];
   97         } else
   98                 i = -1;
   99 
  100         nintr = 0;
  101         TAILQ_FOREACH(ec, &evcount_list, next) {
  102                 if (ec->ec_parent != &evcount_intr)
  103                         continue;
  104                 if (nintr++ == i)
  105                         break;
  106         }
  107 
  108         switch (name[0]) {
  109         case KERN_INTRCNT_NUM:
  110                 error = sysctl_rdint(oldp, oldlenp, NULL, nintr);
  111                 break;
  112         case KERN_INTRCNT_CNT:
  113                 if (ec == NULL)
  114                         return (ENOENT);
  115                 s = splhigh();
  116                 count = ec->ec_count;
  117                 splx(s);
  118                 error = sysctl_rdquad(oldp, oldlenp, NULL, count);
  119                 break;
  120         case KERN_INTRCNT_NAME:
  121                 if (ec == NULL)
  122                         return (ENOENT);
  123                 error = sysctl_rdstring(oldp, oldlenp, NULL, ec->ec_name);
  124                 break;
  125         case KERN_INTRCNT_VECTOR:
  126                 if (ec == NULL || ec->ec_data == NULL)
  127                         return (ENOENT);
  128                 error = sysctl_rdint(oldp, oldlenp, NULL,
  129                     *((int *)ec->ec_data));
  130                 break;
  131         default:
  132                 error = EOPNOTSUPP;
  133                 break;
  134         }
  135 
  136         return (error);
  137 }
  138 #endif  /* SMALL_KERNEL */

/* [<][>][^][v][top][bottom][index][help] */