]> git.ipfire.org Git - thirdparty/collectd.git/commitdiff
Implement irq plugin for NetBSD
authorEdgar Fuß <ef@math.uni-bonn.de>
Wed, 8 Jul 2020 17:19:02 +0000 (19:19 +0200)
committerGitHub <noreply@github.com>
Wed, 8 Jul 2020 17:19:02 +0000 (19:19 +0200)
Implement the irq plugin for NetBSD.
Written by Håvard Eidnes <he@NetBSD.org>

src/irq.c

index 915635606cd8addf345665269b012449f7ccabcd..83fa0dd4e8e0e05fa31ebeff2f485523078afca2 100644 (file)
--- a/src/irq.c
+++ b/src/irq.c
 #include "utils/common/common.h"
 #include "utils/ignorelist/ignorelist.h"
 
-#if !KERNEL_LINUX
+#if !KERNEL_LINUX && !KERNEL_NETBSD
 #error "No applicable input method."
 #endif
 
+#if KERNEL_NETBSD
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#include <sys/evcnt.h>
+#include <malloc.h>
+#endif /* KERNEL_NETBSD */
+
 /*
  * (Module-)Global variables
  */
@@ -75,6 +83,7 @@ static void irq_submit(const char *irq_name, derive_t value) {
   plugin_dispatch_values(&vl);
 } /* void irq_submit */
 
+#if KERNEL_LINUX
 static int irq_read(void) {
   FILE *fh;
   char buffer[1024];
@@ -165,6 +174,64 @@ static int irq_read(void) {
 
   return 0;
 } /* int irq_read */
+#endif /* KERNEL_LINUX */
+
+#if KERNEL_NETBSD
+static int
+irq_read (void)
+{
+  const int mib[4] = {
+    CTL_KERN,
+    KERN_EVCNT,
+    EVCNT_TYPE_INTR,
+    KERN_EVCNT_COUNT_NONZERO
+  };
+  size_t buflen = 0;
+  void *buf = NULL;
+  const struct evcnt_sysctl *evs, *last_evs;
+
+  for (;;) {
+    size_t newlen;
+    int error;
+
+    newlen = buflen;
+    if (buflen)
+      buf = malloc(buflen);
+    error = sysctl(mib, __arraycount(mib),
+                   buf, &newlen, NULL, 0);
+    if (error) {
+      ERROR("irq plugin: failed to get event count");
+      return -1;
+    }
+    if (newlen <= buflen) {
+      buflen = newlen;
+      break;
+    }
+    if (buf)
+            free(buf);
+    buflen = newlen;
+  }
+  evs = buf;
+  last_evs = (void*)((char *)buf + buflen);
+  buflen /= sizeof(uint64_t);
+  while(evs < last_evs
+    && buflen > sizeof(*evs) / sizeof(uint64_t)
+    && buflen >= evs->ev_len)
+  {
+    char irqname[80];
+
+    snprintf(irqname, 80, "%s-%s", evs->ev_strings,
+      evs->ev_strings + evs->ev_grouplen + 1);
+
+    irq_submit(irqname, evs->ev_count);
+
+    buflen -= evs->ev_len;
+    evs =(const void*)((const uint64_t *)evs + evs->ev_len);
+  }
+  free(buf);
+  return 0;
+}
+#endif /* KERNEL_NETBSD */
 
 void module_register(void) {
   plugin_register_config("irq", irq_config, config_keys, config_keys_num);