diff options
author | Alex Wilson <alex@cooperi.net> | 2014-10-31 17:25:24 +1000 |
---|---|---|
committer | Alex Wilson <alex@cooperi.net> | 2014-12-29 11:06:55 +1000 |
commit | 9a065ead487d1d655b8a73e84ee68e2c51ee21b0 (patch) | |
tree | c0363f341e102f3d7db4e5eebefe973b7d5e06f6 /lib/os_mon/c_src | |
parent | e2a09281ec8d60cd47f86caa59d41d3cd945d8bc (diff) | |
download | otp-9a065ead487d1d655b8a73e84ee68e2c51ee21b0.tar.gz otp-9a065ead487d1d655b8a73e84ee68e2c51ee21b0.tar.bz2 otp-9a065ead487d1d655b8a73e84ee68e2c51ee21b0.zip |
os_mon: cpu_sup should use native sysctl/libkvm calls on BSD
This avoids forking off with os:cmd every time we just want to
collect the load averages. riak does this every second, which
results in a lot of unnecessary load.
Diffstat (limited to 'lib/os_mon/c_src')
-rw-r--r-- | lib/os_mon/c_src/cpu_sup.c | 108 |
1 files changed, 106 insertions, 2 deletions
diff --git a/lib/os_mon/c_src/cpu_sup.c b/lib/os_mon/c_src/cpu_sup.c index e9fd75a32c..4198cc73f3 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 */ @@ -128,6 +142,11 @@ static void send(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 @@ -179,14 +198,98 @@ int main(int argc, char** argv) { case AVG1: send(misc_measure("avenrun_1min")); break; case AVG5: send(misc_measure("avenrun_5min")); break; case AVG15: send(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; + } + send((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; + } + + send((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); + send((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; + } + + send((unsigned int)(len / sizeof(struct kinfo_proc))); +} + +#endif + /* ---------------------------- * * Linux stat functions * * ---------------------------- */ @@ -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); } |