Hi,

I was bothered long enough by the

"OS_MON (cpu_sup), util/1 unavailable for this OS"

message when testing erlang builds on OpenBSD and decided to have a shot at an implementation.

I tried to keep it structurally very similar to the already available FreeBSD implementation (which looks to me like it's leaking memory, though), and filled the gaps with what I understood from OpenBSD's top(1) implementation.

Tests pass, and interactive use of cpu_sup:util/0 and cpu_sup:util/1 produces reasonable results here, both with and without SMP enabled.

It would be great if some of you could have a look if what I came up with makes sense.

cheers,
Volker
Index: Makefile
===================================================================
RCS file: /cvs/ports/lang/erlang/25/Makefile,v
retrieving revision 1.15
diff -u -p -r1.15 Makefile
--- Makefile	8 Mar 2023 07:54:04 -0000	1.15
+++ Makefile	27 Mar 2023 20:36:55 -0000
@@ -10,6 +10,7 @@ PKGNAME=	erlang-$V
 PKGNAME-main=	erlang-$V
 PKGNAME-wx=	erlang-wx-$V
 EPOCH=		0
+REVISION=	0
 
 VERSION_SPEC=	>=25v0,<26v0
 PKGSPEC-main=	erlang-${VERSION_SPEC}
Index: patches/patch-lib_os_mon_c_src_cpu_sup_c
===================================================================
RCS file: patches/patch-lib_os_mon_c_src_cpu_sup_c
diff -N patches/patch-lib_os_mon_c_src_cpu_sup_c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ patches/patch-lib_os_mon_c_src_cpu_sup_c	27 Mar 2023 20:36:55 -0000
@@ -0,0 +1,131 @@
+Index: lib/os_mon/c_src/cpu_sup.c
+--- lib/os_mon/c_src/cpu_sup.c.orig
++++ lib/os_mon/c_src/cpu_sup.c
+@@ -87,6 +87,11 @@ typedef struct {
+ #define CU_BSD_VALUES (6)
+ #endif
+ 
++#if defined(__OpenBSD__)
++#include <sys/types.h>
++#include <sys/sched.h>
++#define CU_OPENBSD_VALUES (6)
++#endif
+ 
+ #define FD_IN		(0)
+ #define FD_OUT		(1)
+@@ -178,12 +183,17 @@ static int processors_online() {
+ void getsysctl(const char *, void *, size_t);
+ #endif
+ 
++#if defined(__OpenBSD__)
++static int getncpu(void);
++static int getncpuonline(void);
++#endif
++
+ int main(int argc, char** argv) {
+   char cmd;
+   int rc;
+   int sz;
+   unsigned int *rv;
+-#if defined(__linux__) || (defined(__APPLE__) && defined(__MACH__)) ||defined(__FreeBSD__)
++#if defined(__linux__) || (defined(__APPLE__) && defined(__MACH__)) ||defined(__FreeBSD__) ||defined(__OpenBSD__)
+   unsigned int no_of_cpus = 0;
+ #endif
+ 
+@@ -207,6 +217,15 @@ int main(int argc, char** argv) {
+     }
+ #endif
+ 
++#if defined(__OpenBSD__)
++    no_of_cpus = getncpu();
++    if ( no_of_cpus == -1 )
++      error("cpu_sup: sysctl error");
++     
++    if ( (rv = (unsigned int*)malloc(sizeof(unsigned int)*(2 + 2*no_of_cpus*CU_OPENBSD_VALUES))) == NULL)
++      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) {
+@@ -244,7 +263,7 @@ int main(int argc, char** argv) {
+     case AVG5:		bsd_loadavg(1);					break;
+     case AVG15:		bsd_loadavg(2);					break;
+ #endif
+-#if defined(__sun__) || defined(__linux__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__FreeBSD__)
++#if defined(__sun__) || defined(__linux__) || (defined(__APPLE__) && defined(__MACH__)) || defined(__FreeBSD__) || defined(__OpenBSD__)
+     case UTIL:		util_measure(&rv,&sz); sendv(rv, sz);		break;
+ #endif
+     case QUIT:		free((void*)rv); return 0;
+@@ -709,6 +728,71 @@ static void util_measure(unsigned int **result_vec, in
+     }
+ 
+     *result_sz = 2 + 2*CU_BSD_VALUES * no_of_cpus;
++}
++#endif
++
++/* ---------------------------- *
++ *     OpenBSD stat functions 	*
++ * ---------------------------- */
++
++#if defined(__OpenBSD__)
++static int getncpu(void) {
++    const int mib[] = { CTL_HW, HW_NCPU };
++    int numcpu;
++    size_t size = sizeof(numcpu);
++   
++    if (sysctl(mib, sizeof(mib)/sizeof(mib[0]), &numcpu, &size, NULL, 0) == -1)
++        error("cpu_sup: sysctl error");
++
++    return(numcpu);
++}
++
++static int getncpuonline(void) {
++    const int mib[] = { CTL_HW, HW_NCPUONLINE };
++    int numcpu;
++    size_t size = sizeof(numcpu);
++   
++    if (sysctl(mib, sizeof(mib)/sizeof(mib[0]), &numcpu, &size, NULL, 0) == -1)
++        error("cpu_sup: sysctl error");
++
++    return(numcpu);
++}
++
++static void util_measure(unsigned int **result_vec, int *result_sz) {
++    static int mib[] = { CTL_KERN, KERN_CPTIME2, 0 };
++    size_t size_cpu_times;
++    int64_t *cpu_times;
++    unsigned int *rv = NULL;
++    int i;
++    int ncpuonline = getncpuonline();
++
++    size_cpu_times = sizeof(int64_t) * CPUSTATES;
++    cpu_times = malloc(size_cpu_times);
++    if (!cpu_times) 
++        error("cpu_sup: malloc error");
++
++    rv = *result_vec;
++    rv[0] = ncpuonline;
++    rv[1] = CU_OPENBSD_VALUES;
++    ++rv; /* first value is number of cpus */
++    ++rv; /* second value is number of entries */
++
++    for (i = 0; i < ncpuonline; ++i) {
++        mib[2] = i;
++        if (sysctl(mib, sizeof(mib)/sizeof(mib[0]), cpu_times, &size_cpu_times, NULL, 0) == -1)
++            error("cpu_sup: sysctl error");
++    
++      	rv[ 0] = CU_CPU_ID;    rv[ 1] = i;
++      	rv[ 2] = CU_USER;      rv[ 3] = (unsigned int)cpu_times[CP_USER];
++      	rv[ 4] = CU_NICE_USER; rv[ 5] = (unsigned int)cpu_times[CP_NICE];
++      	rv[ 6] = CU_KERNEL;    rv[ 7] = (unsigned int)cpu_times[CP_SYS];
++      	rv[ 8] = CU_IDLE;      rv[ 9] = (unsigned int)cpu_times[CP_IDLE];
++      	rv[10] = CU_HARD_IRQ;  rv[11] = (unsigned int)cpu_times[CP_INTR];
++      	rv += CU_OPENBSD_VALUES*2;
++    }
++    free((void*) cpu_times);
++
++    *result_sz = 2 + 2*CU_OPENBSD_VALUES * ncpuonline;
+ }
+ #endif
+ 
Index: patches/patch-lib_os_mon_src_cpu_sup_erl
===================================================================
RCS file: patches/patch-lib_os_mon_src_cpu_sup_erl
diff -N patches/patch-lib_os_mon_src_cpu_sup_erl
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ patches/patch-lib_os_mon_src_cpu_sup_erl	27 Mar 2023 20:36:55 -0000
@@ -0,0 +1,11 @@
+Index: lib/os_mon/src/cpu_sup.erl
+--- lib/os_mon/src/cpu_sup.erl.orig
++++ lib/os_mon/src/cpu_sup.erl
+@@ -163,6 +163,7 @@ handle_call({?util, D, PC}, {Client, _Tag},
+ 	when Flavor == sunos;
+ 	     Flavor == linux;
+ 	     Flavor == freebsd;
++	     Flavor == openbsd;
+ 	     Flavor == darwin ->
+     case measurement_server_call(State#state.server, {?util, D, PC, Client}) of
+ 	{error, Reason} -> 
Index: patches/patch-lib_os_mon_test_cpu_sup_SUITE_erl
===================================================================
RCS file: patches/patch-lib_os_mon_test_cpu_sup_SUITE_erl
diff -N patches/patch-lib_os_mon_test_cpu_sup_SUITE_erl
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ patches/patch-lib_os_mon_test_cpu_sup_SUITE_erl	27 Mar 2023 20:36:55 -0000
@@ -0,0 +1,12 @@
+Index: lib/os_mon/test/cpu_sup_SUITE.erl
+--- lib/os_mon/test/cpu_sup_SUITE.erl.orig
++++ lib/os_mon/test/cpu_sup_SUITE.erl
+@@ -61,6 +61,8 @@ all() -> 
+             [load_api, util_api, util_values, port, unavailable];
+         {unix, linux} ->
+             [load_api, util_api, util_values, port, unavailable];
++        {unix, openbsd} ->
++            [load_api, util_api, util_values, port, unavailable];
+         {unix, freebsd} ->
+             [load_api, util_api, util_values, port, unavailable];
+         {unix, darwin} ->

Reply via email to