aboutsummaryrefslogtreecommitdiffstats
path: root/lib/os_mon/c_src/cpu_sup.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/os_mon/c_src/cpu_sup.c')
-rw-r--r--lib/os_mon/c_src/cpu_sup.c122
1 files changed, 113 insertions, 9 deletions
diff --git a/lib/os_mon/c_src/cpu_sup.c b/lib/os_mon/c_src/cpu_sup.c
index e9fd75a32c..20bb9ce391 100644
--- a/lib/os_mon/c_src/cpu_sup.c
+++ b/lib/os_mon/c_src/cpu_sup.c
@@ -31,13 +31,27 @@
#include <unistd.h>
#include <string.h>
+#if (defined(__APPLE__) && defined(__MACH__)) || defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <limits.h>
+#include <fcntl.h>
+#endif
+#if defined(__FreeBSD__) || defined(__DragonFly__)
+#include <kvm.h>
+#include <sys/user.h>
+#endif
+
#if defined(__sun__)
#include <kstat.h>
#endif
-#include <sys/sysinfo.h>
#include <errno.h>
+#if defined(__sun__) || defined(__linux__)
+#include <sys/sysinfo.h>
+#endif
+
#if defined(__linux__)
#include <string.h> /* strlen */
@@ -124,10 +138,15 @@ static void util_measure(unsigned int **result_vec, int *result_sz);
#if defined(__sun__)
static unsigned int misc_measure(char* name);
#endif
-static void send(unsigned int data);
+static void sendi(unsigned int data);
static void sendv(unsigned int data[], int ints);
static void error(char* err_msg);
+#if (defined(__APPLE__) && defined(__MACH__)) || defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
+static void bsd_count_procs(void);
+static void bsd_loadavg(int);
+#endif
+
#if defined(__sun__)
static kstat_ctl_t *kstat_ctl;
#endif
@@ -173,20 +192,104 @@ int main(int argc, char** argv) {
error("Erlang has closed");
switch(cmd) {
- case PING: send(4711); break;
+ case PING: sendi(4711); break;
#if defined(__sun__)
- case NPROCS: send(misc_measure("nproc")); break;
- case AVG1: send(misc_measure("avenrun_1min")); break;
- case AVG5: send(misc_measure("avenrun_5min")); break;
- case AVG15: send(misc_measure("avenrun_15min")); break;
+ case NPROCS: sendi(misc_measure("nproc")); break;
+ case AVG1: sendi(misc_measure("avenrun_1min")); break;
+ case AVG5: sendi(misc_measure("avenrun_5min")); break;
+ case AVG15: sendi(misc_measure("avenrun_15min")); break;
+#elif defined(__OpenBSD__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__FreeBSD__) || defined(__DragonFly__)
+ case NPROCS: bsd_count_procs(); break;
+ case AVG1: bsd_loadavg(0); break;
+ case AVG5: bsd_loadavg(1); break;
+ case AVG15: bsd_loadavg(2); break;
#endif
+#if defined(__sun__) || defined(__linux__)
case UTIL: util_measure(&rv,&sz); sendv(rv, sz); break;
+#endif
case QUIT: free((void*)rv); return 0;
default: error("Bad command"); break;
}
}
return 0; /* supress warnings */
}
+
+/* ---------------------------- *
+ * BSD stat functions *
+ * ---------------------------- */
+#if defined(__OpenBSD__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__FreeBSD__) || defined(__DragonFly__)
+
+static void bsd_loadavg(int idx) {
+ double avgs[3];
+ if (getloadavg(avgs, 3) < 0) {
+ error(strerror(errno));
+ return;
+ }
+ sendi((unsigned int)(avgs[idx] * 256));
+}
+
+#endif
+
+#if defined(__OpenBSD__)
+
+static void bsd_count_procs(void) {
+ int err, nproc;
+ size_t len = sizeof(nproc);
+ int mib[] = { CTL_KERN, KERN_NPROCS };
+
+ err = sysctl(mib, sizeof(mib) / sizeof(mib[0]), &nproc, &len, NULL, 0);
+ if (err) {
+ error(strerror(errno));
+ return;
+ }
+
+ sendi((unsigned int)nproc);
+}
+
+#elif defined(__FreeBSD__) || defined(__DragonFly__)
+
+static void bsd_count_procs(void) {
+ kvm_t *kd;
+ struct kinfo_proc *kp;
+ char err[_POSIX2_LINE_MAX];
+ int cnt = 0;
+
+ if ((kd = kvm_open(NULL, "/dev/null", NULL, O_RDONLY, err)) == NULL) {
+ error(err);
+ return;
+ }
+
+#if defined(KERN_PROC_PROC)
+ if ((kp = kvm_getprocs(kd, KERN_PROC_PROC, 0, &cnt)) == NULL) {
+#else
+ if ((kp = kvm_getprocs(kd, KERN_PROC_ALL, 0, &cnt)) == NULL) {
+#endif
+ error(strerror(errno));
+ return;
+ }
+
+ (void)kvm_close(kd);
+ sendi((unsigned int)cnt);
+}
+
+#elif (defined(__APPLE__) && defined(__MACH__))
+
+static void bsd_count_procs(void) {
+ int err;
+ size_t len = 0;
+ int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL };
+
+ err = sysctl(mib, sizeof(mib) / sizeof(mib[0]), NULL, &len, NULL, 0);
+ if (err) {
+ error(strerror(errno));
+ return;
+ }
+
+ sendi((unsigned int)(len / sizeof(struct kinfo_proc)));
+}
+
+#endif
+
/* ---------------------------- *
* Linux stat functions *
* ---------------------------- */
@@ -420,7 +523,7 @@ static void util_measure(unsigned int **result_vec, int *result_sz) {
* Generic functions *
* ---------------------------- */
-static void send(unsigned int data) { sendv(&data, 1); }
+static void sendi(unsigned int data) { sendv(&data, 1); }
static void sendv(unsigned int data[], int ints) {
static unsigned char *buf = NULL;
@@ -474,7 +577,8 @@ static void error(char* err_msg) {
buffer[i++] = '\n';
/* try to use one write only */
- if(write(FD_ERR, buffer, i));
+ if(write(FD_ERR, buffer, i))
+ ;
exit(-1);
}