subr_evcount.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /* $OpenBSD: subr_evcount.c,v 1.12 2015/03/14 03:38:50 jsg 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. #include <sys/param.h>
  28. #include <sys/evcount.h>
  29. #include <sys/timeout.h>
  30. #include <sys/systm.h>
  31. #include <sys/sysctl.h>
  32. static TAILQ_HEAD(,evcount) evcount_list = TAILQ_HEAD_INITIALIZER(evcount_list);
  33. void
  34. evcount_attach(struct evcount *ec, const char *name, void *data)
  35. {
  36. static int nextid = 0;
  37. memset(ec, 0, sizeof(*ec));
  38. ec->ec_name = name;
  39. ec->ec_id = ++nextid;
  40. ec->ec_data = data;
  41. TAILQ_INSERT_TAIL(&evcount_list, ec, next);
  42. }
  43. void
  44. evcount_detach(struct evcount *ec)
  45. {
  46. TAILQ_REMOVE(&evcount_list, ec, next);
  47. }
  48. #ifndef SMALL_KERNEL
  49. int
  50. evcount_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
  51. void *newp, size_t newlen)
  52. {
  53. int error = 0, s, nintr, i;
  54. struct evcount *ec;
  55. u_int64_t count;
  56. if (newp != NULL)
  57. return (EPERM);
  58. if (name[0] != KERN_INTRCNT_NUM) {
  59. if (namelen != 2)
  60. return (ENOTDIR);
  61. if (name[1] < 0)
  62. return (EINVAL);
  63. i = name[1];
  64. } else
  65. i = -1;
  66. nintr = 0;
  67. TAILQ_FOREACH(ec, &evcount_list, next) {
  68. if (nintr++ == i)
  69. break;
  70. }
  71. switch (name[0]) {
  72. case KERN_INTRCNT_NUM:
  73. error = sysctl_rdint(oldp, oldlenp, NULL, nintr);
  74. break;
  75. case KERN_INTRCNT_CNT:
  76. if (ec == NULL)
  77. return (ENOENT);
  78. s = splhigh();
  79. count = ec->ec_count;
  80. splx(s);
  81. error = sysctl_rdquad(oldp, oldlenp, NULL, count);
  82. break;
  83. case KERN_INTRCNT_NAME:
  84. if (ec == NULL)
  85. return (ENOENT);
  86. error = sysctl_rdstring(oldp, oldlenp, NULL, ec->ec_name);
  87. break;
  88. case KERN_INTRCNT_VECTOR:
  89. if (ec == NULL || ec->ec_data == NULL)
  90. return (ENOENT);
  91. error = sysctl_rdint(oldp, oldlenp, NULL,
  92. *((int *)ec->ec_data));
  93. break;
  94. default:
  95. error = EOPNOTSUPP;
  96. break;
  97. }
  98. return (error);
  99. }
  100. #endif /* SMALL_KERNEL */