From f3a4db8368719fa31374c28ab35c2584add79bce Mon Sep 17 00:00:00 2001 From: Wasif Malik and Johannes Huning Date: Fri, 28 Nov 2014 17:50:10 +0100 Subject: os_mon: Implement cpu_sup:util/0,1 for FreeBSD Authors: Wasif Malik and Johannes Huning --- lib/os_mon/c_src/cpu_sup.c | 93 ++++++++++++++++++++++++++++++++++++--- lib/os_mon/src/cpu_sup.erl | 3 +- lib/os_mon/test/cpu_sup_SUITE.erl | 2 + 3 files changed, 90 insertions(+), 8 deletions(-) (limited to 'lib/os_mon') diff --git a/lib/os_mon/c_src/cpu_sup.c b/lib/os_mon/c_src/cpu_sup.c index 20bb9ce391..b81a5cd1ad 100644 --- a/lib/os_mon/c_src/cpu_sup.c +++ b/lib/os_mon/c_src/cpu_sup.c @@ -53,7 +53,6 @@ #endif #if defined(__linux__) -#include /* strlen */ #define PROCSTAT "/proc/stat" #define BUFFERSIZE (256) @@ -73,6 +72,13 @@ typedef struct { #endif +#if defined(__FreeBSD__) +#include +#include +#define CU_BSD_VALUES (6) +#endif + + #define FD_IN (0) #define FD_OUT (1) #define FD_ERR (2) @@ -157,12 +163,16 @@ static int processors_online() { } #endif +#if defined(__FreeBSD__) +void getsysctl(const char *, void *, size_t); +#endif + int main(int argc, char** argv) { char cmd; int rc; int sz; unsigned int *rv; -#if defined(__linux__) +#if defined(__linux__) || defined(__FreeBSD__) unsigned int no_of_cpus = 0; #endif @@ -175,7 +185,14 @@ int main(int argc, char** argv) { #if defined(__linux__) no_of_cpus = processors_online(); if ( (rv = (unsigned int*)malloc(sizeof(unsigned int)*(2 + 2*no_of_cpus*CU_VALUES))) == NULL) { - error("cpu_cup: malloc error"); + error("cpu_sup: malloc error"); + } +#endif + +#if defined(__FreeBSD__) + getsysctl("hw.ncpu", &no_of_cpus, sizeof(int)); + if ( (rv = (unsigned int*)malloc(sizeof(unsigned int)*(2 + 2*no_of_cpus*CU_BSD_VALUES))) == NULL) { + error("cpu_sup: malloc error"); } #endif @@ -204,14 +221,14 @@ int main(int argc, char** argv) { case AVG5: bsd_loadavg(1); break; case AVG15: bsd_loadavg(2); break; #endif -#if defined(__sun__) || defined(__linux__) +#if defined(__sun__) || defined(__linux__) || defined(__FreeBSD__) 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 */ + return 0; /* suppress warnings */ } /* ---------------------------- * @@ -519,6 +536,70 @@ static void util_measure(unsigned int **result_vec, int *result_sz) { } #endif +/* ---------------------------- * + * FreeBSD stat functions * + * ---------------------------- */ + +#if defined(__FreeBSD__) + +#define EXIT_WITH(msg) (rich_error(msg, __FILE__, __LINE__)) + +void rich_error(const char *reason, const char *file, const int line) { + const size_t buflen = 213; // left in error(char*) + char buf[buflen]; + snprintf(buf, buflen, "%s (%s:%i)", reason, file, line); + error(buf); +} + + +static void util_measure(unsigned int **result_vec, int *result_sz) { + int no_of_cpus; + getsysctl("hw.ncpu", &no_of_cpus, sizeof(int)); + + // Header constant CPUSTATES = #long values per cpu. + size_t size_cpu_times = sizeof(long) * CPUSTATES * no_of_cpus; + unsigned long *cpu_times = malloc(size_cpu_times); + if (!cpu_times) { + EXIT_WITH("badalloc"); + } + getsysctl("kern.cp_times", cpu_times, size_cpu_times); + + unsigned int *rv = NULL; + + rv = *result_vec; + rv[0] = no_of_cpus; + rv[1] = CU_BSD_VALUES; + ++rv; /* first value is number of cpus */ + ++rv; /* second value is number of entries */ + + int i; + for (i = 0; i < no_of_cpus; ++i) { + int offset = i * CPUSTATES; + rv[ 0] = CU_CPU_ID; rv[ 1] = i; + rv[ 2] = CU_USER; rv[ 3] = cpu_times[CP_USER + offset]; + rv[ 4] = CU_NICE_USER; rv[ 5] = cpu_times[CP_NICE + offset]; + rv[ 6] = CU_KERNEL; rv[ 7] = cpu_times[CP_SYS + offset]; + rv[ 8] = CU_IDLE; rv[ 9] = cpu_times[CP_IDLE + offset]; + rv[10] = CU_HARD_IRQ; rv[11] = cpu_times[CP_INTR + offset]; + rv += CU_BSD_VALUES*2; + } + + *result_sz = 2 + 2*CU_BSD_VALUES * no_of_cpus; +} + +void getsysctl(const char *name, void *ptr, size_t len) +{ + size_t gotlen = len; + if (sysctlbyname(name, ptr, &gotlen, NULL, 0) != 0) { + EXIT_WITH("sysctlbyname failed"); + } + if (gotlen != len) { + EXIT_WITH("sysctlbyname: unexpected length"); + } +} +#endif + + /* ---------------------------- * * Generic functions * * ---------------------------- */ @@ -581,5 +662,3 @@ static void error(char* err_msg) { ; exit(-1); } - - diff --git a/lib/os_mon/src/cpu_sup.erl b/lib/os_mon/src/cpu_sup.erl index 0c26956c57..3d837431d8 100644 --- a/lib/os_mon/src/cpu_sup.erl +++ b/lib/os_mon/src/cpu_sup.erl @@ -160,7 +160,8 @@ handle_call(?quit, _From, State) -> handle_call({?util, D, PC}, {Client, _Tag}, #state{os_type = {unix, Flavor}} = State) when Flavor == sunos; - Flavor == linux -> + Flavor == linux; + Flavor == freebsd -> case measurement_server_call(State#state.server, {?util, D, PC, Client}) of {error, Reason} -> { reply, diff --git a/lib/os_mon/test/cpu_sup_SUITE.erl b/lib/os_mon/test/cpu_sup_SUITE.erl index 9f58e043db..7da819379c 100644 --- a/lib/os_mon/test/cpu_sup_SUITE.erl +++ b/lib/os_mon/test/cpu_sup_SUITE.erl @@ -64,6 +64,8 @@ all() -> [load_api, util_api, util_values, port, unavailable]; {unix, linux} -> [load_api, util_api, util_values, port, unavailable]; + {unix, freebsd} -> + [load_api, util_api, util_values, port, unavailable]; {unix, _OSname} -> [load_api]; _OS -> [unavailable] end. -- cgit v1.2.3 From 3de8be10b12bcf8520cc1ec58ae4f8d123b7fe2f Mon Sep 17 00:00:00 2001 From: Wasif Malik and Johannes Huning Date: Fri, 28 Nov 2014 17:53:50 +0100 Subject: os_mon: Update docs for FreeBSD Authors: Wasif Malik and Johannes Huning --- lib/os_mon/doc/src/cpu_sup.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/os_mon') diff --git a/lib/os_mon/doc/src/cpu_sup.xml b/lib/os_mon/doc/src/cpu_sup.xml index 59da876208..4a8f5bffa0 100644 --- a/lib/os_mon/doc/src/cpu_sup.xml +++ b/lib/os_mon/doc/src/cpu_sup.xml @@ -34,7 +34,7 @@ and CPU utilization. It is part of the OS_Mon application, see os_mon(6). Available for Unix, although CPU utilization values (util/0,1) are only - available for Solaris and Linux.

+ available for Solaris, Linux and FreeBSD.

The load values are proportional to how long time a runnable Unix process has to spend in the run queue before it is scheduled. Accordingly, higher values mean more system load. The returned -- cgit v1.2.3 From 5dc2cc80ee62c8c7da2775b56e9ed5e1f30eb940 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?= Date: Tue, 2 Jun 2015 11:11:43 +0200 Subject: os_mon: Comply with C89 standard --- lib/os_mon/c_src/cpu_sup.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'lib/os_mon') diff --git a/lib/os_mon/c_src/cpu_sup.c b/lib/os_mon/c_src/cpu_sup.c index b81a5cd1ad..9e217db105 100644 --- a/lib/os_mon/c_src/cpu_sup.c +++ b/lib/os_mon/c_src/cpu_sup.c @@ -543,36 +543,37 @@ static void util_measure(unsigned int **result_vec, int *result_sz) { #if defined(__FreeBSD__) #define EXIT_WITH(msg) (rich_error(msg, __FILE__, __LINE__)) +#define RICH_BUFLEN (213) /* left in error(char*) */ void rich_error(const char *reason, const char *file, const int line) { - const size_t buflen = 213; // left in error(char*) - char buf[buflen]; - snprintf(buf, buflen, "%s (%s:%i)", reason, file, line); + char buf[RICH_BUFLEN]; + snprintf(buf, RICH_BUFLEN, "%s (%s:%i)", reason, file, line); error(buf); } - +#undef RICH_BUFLEN static void util_measure(unsigned int **result_vec, int *result_sz) { int no_of_cpus; - getsysctl("hw.ncpu", &no_of_cpus, sizeof(int)); + size_t size_cpu_times; + unsigned long *cpu_times; + unsigned int *rv = NULL; + int i; - // Header constant CPUSTATES = #long values per cpu. - size_t size_cpu_times = sizeof(long) * CPUSTATES * no_of_cpus; - unsigned long *cpu_times = malloc(size_cpu_times); + getsysctl("hw.ncpu", &no_of_cpus, sizeof(int)); + /* Header constant CPUSTATES = #long values per cpu. */ + size_cpu_times = sizeof(long) * CPUSTATES * no_of_cpus; + cpu_times = malloc(size_cpu_times); if (!cpu_times) { EXIT_WITH("badalloc"); } getsysctl("kern.cp_times", cpu_times, size_cpu_times); - unsigned int *rv = NULL; - rv = *result_vec; rv[0] = no_of_cpus; rv[1] = CU_BSD_VALUES; ++rv; /* first value is number of cpus */ ++rv; /* second value is number of entries */ - int i; for (i = 0; i < no_of_cpus; ++i) { int offset = i * CPUSTATES; rv[ 0] = CU_CPU_ID; rv[ 1] = i; -- cgit v1.2.3