Hi, I included what we have discussed into my patch. I renamed the new program to `nproc', now it accepts two options: --available and --installed. By default --available is used, if --available is not know then --installed is used.
I added another test to ensure nproc --available <= nproc --installed. Any comment? Cheers, Giuseppe >From 4665e1801f73eeba98cad9988c5d5829bad03a37 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano <gscriv...@gnu.org> Date: Sun, 25 Oct 2009 19:04:41 +0100 Subject: [PATCH] nproc: A new program to count the number of processors * AUTHORS: Add my name. * NEWS: Mention it. * bootstrap.conf (gnulib_modules): Add nproc and pthread. * doc/coreutils.texi (nproc invocation): Add nproc info. * src/Makefile.am (EXTRA_PROGRAMS): Add nproc. * src/nproc.c: New file. * tests/Makefile.am (TESTS): Add nproc/{avail, cpuinfo, positive}. * tests/nproc/avail: New file. * tests/nproc/cpuinfo: New file. * tests/nproc/positive: New file. --- AUTHORS | 1 + NEWS | 4 + bootstrap.conf | 2 + doc/coreutils.texi | 39 +++++++++++++ src/Makefile.am | 3 + src/nproc.c | 155 ++++++++++++++++++++++++++++++++++++++++++++++++++ tests/Makefile.am | 3 + tests/nproc/avail | 33 +++++++++++ tests/nproc/cpuinfo | 34 +++++++++++ tests/nproc/positive | 33 +++++++++++ 10 files changed, 307 insertions(+), 0 deletions(-) create mode 100644 src/nproc.c create mode 100644 tests/nproc/avail create mode 100755 tests/nproc/cpuinfo create mode 100755 tests/nproc/positive diff --git a/AUTHORS b/AUTHORS index 7095db0..3855622 100644 --- a/AUTHORS +++ b/AUTHORS @@ -51,6 +51,7 @@ mv: Mike Parker, David MacKenzie, Jim Meyering nice: David MacKenzie nl: Scott Bartram, David MacKenzie nohup: Jim Meyering +nproc: Giuseppe Scrivano od: Jim Meyering paste: David M. Ihnat, David MacKenzie pathchk: Paul Eggert, David MacKenzie, Jim Meyering diff --git a/NEWS b/NEWS index 1ed577f..4caa747 100644 --- a/NEWS +++ b/NEWS @@ -32,6 +32,10 @@ GNU coreutils NEWS -*- outline -*- with the invoked command failing with status 1. Likewise, nohup fails with status 125 instead of 127. +** New programs + + nproc: A new program to get the number of processors. + ** New features md5sum --check now also accepts openssl-style checksums. diff --git a/bootstrap.conf b/bootstrap.conf index 1857489..67e2672 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -157,6 +157,7 @@ gnulib_modules=" modechange mountlist mpsort + nproc obstack pathmax perl @@ -167,6 +168,7 @@ gnulib_modules=" priv-set progname propername + pthread putenv quote quotearg diff --git a/doc/coreutils.texi b/doc/coreutils.texi index c54ffb8..588150b 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi @@ -84,6 +84,7 @@ * nice: (coreutils)nice invocation. Modify niceness. * nl: (coreutils)nl invocation. Number lines and write files. * nohup: (coreutils)nohup invocation. Immunize to hangups. +* nproc: (coreutils)nproc invocation. Print the number of processors. * od: (coreutils)od invocation. Dump files in octal, etc. * paste: (coreutils)paste invocation. Merge lines of files. * pathchk: (coreutils)pathchk invocation. Check file name portability. @@ -409,6 +410,7 @@ System context * arch invocation:: Print machine hardware name * date invocation:: Print or set system date and time +* nproc invocation:: Print the number of processors * uname invocation:: Print system information * hostname invocation:: Print or set system name * hostid invocation:: Print numeric host identifier @@ -13221,6 +13223,7 @@ information. @menu * date invocation:: Print or set system date and time. * arch invocation:: Print machine hardware name. +* nproc invocation:: Print the number of processors. * uname invocation:: Print system information. * hostname invocation:: Print or set system name. * hostid invocation:: Print numeric host identifier. @@ -13880,6 +13883,42 @@ The program accepts the @ref{Common options} only. @exitstatus +...@node nproc invocation +...@section @command{nproc}: Print the number of processors + +...@pindex nproc +...@cindex Print the number of processors +...@cindex system information, printing + +...@command{nproc} prints the number of processors. It is not a hardware +inspection tool but a portable way to get how many processes +potentially can be executed in parallel. The result is guaranteed to +be a non-zero positive number. Synopsis: + +...@example +nproc [...@var{option}] +...@end example + +The program accepts the following options. Also see @ref{Common options}. + +...@table @samp + +...@item --available +...@opindex --available +Print the number of processors available to the current process. It +may be less than the number of installed processors. +If this information is not accessible, then nproc returs the number of +installed processors. By default --available is used. + +...@item --installed +...@opindex --installed +Print the number of installed processors. + +...@end table + +...@exitstatus + + @node uname invocation @section @command{uname}: Print system information diff --git a/src/Makefile.am b/src/Makefile.am index 67c29cc..a6dc5ff 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -86,6 +86,7 @@ EXTRA_PROGRAMS = \ mktemp \ mv \ nl \ + nproc \ nohup \ od \ paste \ @@ -189,6 +190,7 @@ chown_LDADD = $(LDADD) chroot_LDADD = $(LDADD) cksum_LDADD = $(LDADD) comm_LDADD = $(LDADD) +nproc_LDADD = $(LDADD) $(LIB_PTHREAD) cp_LDADD = $(LDADD) csplit_LDADD = $(LDADD) cut_LDADD = $(LDADD) @@ -480,6 +482,7 @@ rmdir_SOURCES = rmdir.c prog-fprintf.c uname_SOURCES = uname.c uname-uname.c arch_SOURCES = uname.c uname-arch.c +nproc_SOURCES = nproc.c md5sum_SOURCES = md5sum.c md5sum_CPPFLAGS = -DHASH_ALGO_MD5=1 $(AM_CPPFLAGS) diff --git a/src/nproc.c b/src/nproc.c new file mode 100644 index 0000000..2449fc9 --- /dev/null +++ b/src/nproc.c @@ -0,0 +1,155 @@ +/* nproc - print the number of processors. + Copyright (C) 2009 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +/* Written by Giuseppe Scrivano. */ + +#include <config.h> +#include <getopt.h> +#include <stdio.h> +#include <sys/types.h> + +#include "system.h" +#include "pthread.h" +#include "nproc.h" + +/* The official name of this program (e.g., no `g' prefix). */ +#define PROGRAM_NAME "nproc" + +#define AUTHORS proper_name ("Giuseppe Scrivano") + +enum +{ + AVAILABLE_OPTION = CHAR_MAX + 1, + INSTALLED_OPTION +}; + +static struct option const longopts[] = +{ + {"installed", no_argument, NULL, INSTALLED_OPTION}, + {"available", no_argument, NULL, AVAILABLE_OPTION}, + {GETOPT_HELP_OPTION_DECL}, + {GETOPT_VERSION_OPTION_DECL}, + {NULL, 0, NULL, 0} +}; + +void +usage (int status) +{ + if (status != EXIT_SUCCESS) + fprintf (stderr, _("Try `%s --help' for more information.\n"), + program_name); + else + { + printf (_("Usage: %s [OPTION]...\n"), program_name); + fputs (_("\ +Print the number of online cpu cores.\n\ +\n\ +"), stdout); + fputs (_("\ + --available report the number of processors available to the\n \ + current process.\n \ + --installed return the number of installed processors\n\ +"), stdout); + + fputs (HELP_OPTION_DESCRIPTION, stdout); + fputs (VERSION_OPTION_DESCRIPTION, stdout); + emit_ancillary_info (); + } + exit (status); +} + +/* Compute the number of available processors. Return 0 on error. */ + +static u_long +nproc_available () +{ + u_long nproc = 0; + +#ifdef CPU_SETSIZE + size_t j; + cpu_set_t cpuset; + CPU_ZERO (&cpuset); + + if (pthread_getaffinity_np (pthread_self (), sizeof (cpu_set_t), &cpuset)) + return 0; + + for (j = 0; j < CPU_SETSIZE; j++) + if (CPU_ISSET (j, &cpuset)) + nproc++; +#endif + + return nproc; +} + +/* Compute the number of processors. If AVAILABLE returns the number + of processors available to the current process, otherwise the number + of installed processors. In case the number of available processors + can't be computed rollback to the installed processors. The result is + guaranteed to be at least 1. */ + +static u_long +nproc (bool available) +{ + if (available) + { + u_long available_proc = nproc_available (); + if (available_proc) + return available_proc; + } + + return num_processors (); +} + +int +main (int argc, char **argv) +{ + bool available = true; + initialize_main (&argc, &argv); + set_program_name (argv[0]); + setlocale (LC_ALL, ""); + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); + + atexit (close_stdout); + + while (1) + { + int c = getopt_long (argc, argv, "", longopts, NULL); + if (c == -1) + break; + switch (c) + { + case_GETOPT_HELP_CHAR; + + case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); + + case AVAILABLE_OPTION: + available = true; + break; + + case INSTALLED_OPTION: + available = false; + break; + + default: + usage (EXIT_FAILURE); + } + } + + printf ("%u\n", nproc (available)); + + exit (EXIT_SUCCESS); +} diff --git a/tests/Makefile.am b/tests/Makefile.am index 03fe6f1..dd2beee 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -458,6 +458,9 @@ TESTS = \ touch/read-only \ touch/relative \ touch/trailing-slash \ + nproc/avail \ + nproc/cpuinfo \ + nproc/positive \ $(root_tests) pr_data = \ diff --git a/tests/nproc/avail b/tests/nproc/avail new file mode 100644 index 0000000..2543e5b --- /dev/null +++ b/tests/nproc/avail @@ -0,0 +1,33 @@ +#!/bin/sh +# Ensure that nproc --installed is greater or equal to nproc --available. + +# Copyright (C) 2009 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +if test "$VERBOSE" = yes; then + set -x + nproc --version +fi + +. $srcdir/test-lib.sh + +fail=0 + +available=$(nproc --available) +installed=$(nproc --installed) + +test $installed -ge $available || fail=1 + +Exit $fail diff --git a/tests/nproc/cpuinfo b/tests/nproc/cpuinfo new file mode 100755 index 0000000..3a3abe6 --- /dev/null +++ b/tests/nproc/cpuinfo @@ -0,0 +1,34 @@ +#!/bin/sh +# Check that the number of cores reported by nproc is equal to the number +# of cores listed in /proc/cpuinfo, when it is available + +# Copyright (C) 2009 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +if test "$VERBOSE" = yes; then + set -x + nproc --version +fi + +. $srcdir/test-lib.sh + +test -r /proc/cpuinfo || skip_test_ + +fail=0 +cores=$(nproc) + +test $(grep '^proc' /proc/cpuinfo | wc -l) -eq $cores || fail=1 + +Exit $fail diff --git a/tests/nproc/positive b/tests/nproc/positive new file mode 100755 index 0000000..acdba78 --- /dev/null +++ b/tests/nproc/positive @@ -0,0 +1,33 @@ +#!/bin/sh +# Ensure that nproc returns a non-zero positive number + +# Copyright (C) 2009 Free Software Foundation, Inc. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +if test "$VERBOSE" = yes; then + set -x + nproc --version +fi + +. $srcdir/test-lib.sh + +fail=0 + +for opt in --available --installed; do + cores=$(nproc $opt) + test $cores -gt 0 || fail=1 +done + +Exit $fail -- 1.6.5