Hi, Giuseppe Scrivano wrote: > On BSDs, where SC_NPROCESSORS_ONLN is not available, the number of > online processors can be retrieved using `sysctl'. > > From 73c11226e320c1144887daeb15e3f549b0bb2ee5 Mon Sep 17 00:00:00 2001 > From: Giuseppe Scrivano <gscriv...@gnu.org> > Date: Sun, 18 Oct 2009 01:20:14 +0200 > Subject: [PATCH] nproc: use `sysctl' when it is available. > > * lib/nproc.c (num_processors): If `sysctl' is available, use it to > get the number of online processors. > --- > lib/nproc.c | 10 ++++++++++ > 1 files changed, 10 insertions(+), 0 deletions(-) > > diff --git a/lib/nproc.c b/lib/nproc.c > index 9a6e23a..f45feaf 100644 > --- a/lib/nproc.c > +++ b/lib/nproc.c > @@ -34,5 +34,15 @@ num_processors (void) > return nprocs; > #endif > > +#ifdef HW_NCPU > + int ret; > + int mib[2] = {CTL_HW, HW_NCPU}; > + long int nprocs; > + size_t len = sizeof (nprocs); > + ret = sysctl (mib, 2, &nprocs, &len, NULL, 0); > + if (ret == 0) > + return nprocs; > +#endif > + > return 1; > }
Thanks for the patch. It has a number of problems: - It is a nop, because HW_NCPU is defined in <sys/sysctl.h>, but this header file is not included. (Did you try "nm nproc.o"?) - The nprocs variable must be an 'int', not 'long int'. That's how it's documented in the sys/sysctl.h, and that's also what MacOS X 10.5 in 64-bit mode requires. - The function is documented to guarantee a positive return value. This is not ensured here. - On platforms which have both the sysconf approach and HW_NCPU, your patch introduces declarations after statements, which is does not work with ANSI C compilers. But these can all be fixed. I'm applying the patch below. 2009-10-18 Giuseppe Scrivano <gscriv...@gnu.org> Bruno Haible <br...@clisp.org> Implement nproc for NetBSD, OpenBSD. * lib/nproc.c: Include <sys/types.h>, <sys/param.h>, <sys/sysctl.h>. (ARRAY_SIZE): New macro. (num_processors): On BSD systems, try sysctl of HW_NCPU. * m4/nproc.m4: New file. * modules/nproc (Files): Add m4/nproc.m4. (configure.ac): Invoke gl_NPROC. Remove AC_LIBOBJ invocation. (Makefile.am): Instead, augment lib_SOURCES. --- lib/nproc.c.orig 2009-10-18 10:08:29.000000000 +0200 +++ lib/nproc.c 2009-10-18 10:07:34.000000000 +0200 @@ -23,15 +23,43 @@ #include <unistd.h> +#include <sys/types.h> + +#if HAVE_SYS_PARAM_H +# include <sys/param.h> +#endif + +#if HAVE_SYS_SYSCTL_H +# include <sys/sysctl.h> +#endif + +#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) + /* Return the total number of processors. The result is guaranteed to be at least 1. */ unsigned long int num_processors (void) { -#ifdef _SC_NPROCESSORS_ONLN - long int nprocs = sysconf (_SC_NPROCESSORS_ONLN); - if (0 < nprocs) - return nprocs; +#if defined _SC_NPROCESSORS_ONLN + { /* This works on glibc, MacOS X 10.5, FreeBSD, AIX, OSF/1, Solaris, Cygwin, + Haiku. */ + long int nprocs = sysconf (_SC_NPROCESSORS_ONLN); + if (0 < nprocs) + return nprocs; + } +#endif + +#if HAVE_SYSCTL && defined HW_NCPU + { /* This works on MacOS X, FreeBSD, NetBSD, OpenBSD. */ + int nprocs; + size_t len = sizeof (nprocs); + static int mib[2] = { CTL_HW, HW_NCPU }; + + if (sysctl (mib, ARRAY_SIZE (mib), &nprocs, &len, NULL, 0) == 0 + && len == sizeof (nprocs) + && 0 < nprocs) + return nprocs; + } #endif return 1; --- modules/nproc.orig 2009-10-18 10:08:29.000000000 +0200 +++ modules/nproc 2009-10-18 09:33:19.000000000 +0200 @@ -4,14 +4,16 @@ Files: lib/nproc.h lib/nproc.c +m4/nproc.m4 Depends-on: unistd configure.ac: -AC_LIBOBJ([nproc]) +gl_NPROC Makefile.am: +lib_SOURCES += nproc.c Include: "nproc.h" ================================= m4/nproc.m4 ================================= # nproc.m4 serial 1 dnl Copyright (C) 2009 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. AC_DEFUN([gl_NPROC], [ gl_PREREQ_NPROC ]) # Prerequisites of lib/nproc.c. AC_DEFUN([gl_PREREQ_NPROC], [ AC_CHECK_HEADERS([sys/param.h],,, [AC_INCLUDES_DEFAULT]) dnl <sys/sysctl.h> requires <sys/param.h> on OpenBSD 4.0. AC_CHECK_HEADERS([sys/sysctl.h],,, [AC_INCLUDES_DEFAULT #if HAVE_SYS_PARAM_H # include <sys/param.h> #endif ]) AC_CHECK_FUNCS([sysctl]) ])