Code

Merge remote-tracking branch 'github/pr/387'
[collectd.git] / src / contextswitch.c
index 7787203dde178ad2b5859fd603bf7085b90ba663..344f76e76f0c29242ac20821d8efb25f83f12871 100644 (file)
@@ -1,6 +1,7 @@
 /**
  * collectd - src/contextswitch.c
  * Copyright (C) 2009  Patrik Weiskircher
+ * Copyright (C) 2010  Kimo Rosenbaum
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
  *
  * Authors:
  *   Patrik Weiskircher <weiskircher at inqnet.at>
+ *   Kimo Rosenbaum <http://github.com/kimor79>
  **/
 
 #include "collectd.h"
 #include "common.h"
 #include "plugin.h"
 
-#if !KERNEL_LINUX
+#ifdef HAVE_SYS_SYSCTL_H
+# include <sys/sysctl.h>
+#endif
+
+#if HAVE_SYSCTLBYNAME
+/* no global variables */
+/* #endif HAVE_SYSCTLBYNAME */
+
+#elif KERNEL_LINUX
+/* no global variables */
+/* #endif KERNEL_LINUX */
+
+#elif HAVE_PERFSTAT
+# include <sys/protosw.h>
+# include <libperfstat.h>
+/* #endif HAVE_PERFSTAT */
+
+#else
 # error "No applicable input method."
 #endif
 
-static void cs_submit (unsigned long context_switches)
+static void cs_submit (derive_t context_switches)
 {
        value_t values[1];
        value_list_t vl = VALUE_LIST_INIT;
@@ -45,11 +64,30 @@ static void cs_submit (unsigned long context_switches)
 
 static int cs_read (void)
 {
+#if HAVE_SYSCTLBYNAME
+       int value = 0;
+       size_t value_len = sizeof (value);
+       int status;
+
+       status = sysctlbyname ("vm.stats.sys.v_swtch",
+                       &value, &value_len,
+                       /* new pointer = */ NULL, /* new length = */ 0);
+       if (status != 0)
+       {
+               ERROR("contextswitch plugin: sysctlbyname "
+                               "(vm.stats.sys.v_swtch) failed");
+               return (-1);
+       }
+
+       cs_submit (value);
+/* #endif HAVE_SYSCTLBYNAME */
+
+#elif KERNEL_LINUX
        FILE *fh;
        char buffer[64];
        int numfields;
        char *fields[3];
-       unsigned long result = 0;
+       derive_t result = 0;
        int status = -2;
 
        fh = fopen ("/proc/stat", "r");
@@ -72,7 +110,7 @@ static int cs_read (void)
 
                errno = 0;
                endptr = NULL;
-               result = strtoul(fields[1], &endptr, 10);
+               result = (derive_t) strtoll (fields[1], &endptr, /* base = */ 10);
                if ((endptr == fields[1]) || (errno != 0)) {
                        ERROR ("contextswitch plugin: Cannot parse ctxt value: %s",
                                        fields[1]);
@@ -88,6 +126,24 @@ static int cs_read (void)
 
        if (status == -2)
                ERROR ("contextswitch plugin: Unable to find context switch value.");
+/* #endif  KERNEL_LINUX */
+
+#elif HAVE_PERFSTAT
+       int status = 0;
+       perfstat_cpu_total_t perfcputotal;
+
+       status = perfstat_cpu_total(NULL, &perfcputotal, sizeof(perfstat_cpu_total_t), 1);
+       if (status < 0)
+       {
+               char errbuf[1024];
+               ERROR ("contextswitch plugin: perfstat_cpu_total: %s",
+                       sstrerror (errno, errbuf, sizeof (errbuf)));
+               return (-1);
+       }
+
+       cs_submit(perfcputotal.pswitch);
+       status = 0;
+#endif /* defined(HAVE_PERFSTAT) */
 
        return status;
 }