aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bin/Makefile1
-rw-r--r--bin/nproc/Makefile4
-rw-r--r--bin/nproc/nproc.154
-rw-r--r--bin/nproc/nproc.c132
-rw-r--r--usr.bin/cpuset/cpuset.11
5 files changed, 192 insertions, 0 deletions
diff --git a/bin/Makefile b/bin/Makefile
index cdd96d0b84e8..83bf79dcb9f9 100644
--- a/bin/Makefile
+++ b/bin/Makefile
@@ -24,6 +24,7 @@ SUBDIR= cat \
ls \
mkdir \
mv \
+ nproc \
pax \
pkill \
ps \
diff --git a/bin/nproc/Makefile b/bin/nproc/Makefile
new file mode 100644
index 000000000000..2a57083b9d40
--- /dev/null
+++ b/bin/nproc/Makefile
@@ -0,0 +1,4 @@
+PACKAGE=runtime
+PROG= nproc
+
+.include <bsd.prog.mk>
diff --git a/bin/nproc/nproc.1 b/bin/nproc/nproc.1
new file mode 100644
index 000000000000..ae252fe0f50c
--- /dev/null
+++ b/bin/nproc/nproc.1
@@ -0,0 +1,54 @@
+.\"-
+.\" * Copyright (c) 2023 Piotr Paweł Stefaniak
+.\"
+.\" * SPDX-License-Identifier: BSD-2-Clause
+.\"
+.Dd February 5, 2023
+.Dt NPROC 1
+.Os
+.Sh NAME
+.Nm nproc
+.Nd print the number of processors
+.Sh SYNOPSIS
+.Nm
+.Op Fl -all
+.Op Fl -ignore Ns = Ns Ar count
+.Nm Fl -help
+.Nm Fl -version
+.Sh DESCRIPTION
+The
+.Nm
+utility is used to print the number of processors limited to the
+.Xr cpuset 2
+of the current process, unless the
+.Fl -all
+flag is specified.
+.Pp
+The available flags are:
+.Bl -tag -width Ds
+.It Fl -all
+Count all processors currently online.
+.It Fl -ignore Ns = Ns Ar count
+The result is decreased by
+.Ar count ,
+but never below 1.
+.It Fl -version
+Print the current program version and exit. Don't use this option.
+.It Fl -help
+Print usage information and exit.
+.El
+.Sh COMPATIBILITY
+This program is intended to be compatible with nproc as found in GNU coreutils.
+.Sh SEE ALSO
+.Xr cpuset 1
+.Sh HISTORY
+The
+.Nm
+utility first appeared in
+.Fx 14.0 .
+.Sh AUTHORS
+.An -nosplit
+.An Mateusz Guzik Aq Mt mjg@FreeBSD.org
+wrote the program and
+.An Piotr Paweł Stefaniak Aq Mt pstef@FreeBSD.org
+wrote this page.
diff --git a/bin/nproc/nproc.c b/bin/nproc/nproc.c
new file mode 100644
index 000000000000..9037c74dbfff
--- /dev/null
+++ b/bin/nproc/nproc.c
@@ -0,0 +1,132 @@
+/*-
+ * Copyright (c) 2023 Mateusz Guzik
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+/*
+ * This program is intended to be compatible with nproc as found in GNU
+ * coreutils.
+ *
+ * In order to maintain that, do not add any features here if they are not
+ * present in said program. If you are looking for anything more advanced you
+ * probably should patch cpuset(1) instead.
+ */
+
+#include <sys/param.h>
+#include <sys/cpuset.h>
+
+#include <err.h>
+#include <errno.h>
+#include <getopt.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sysexits.h>
+#include <unistd.h>
+
+#define OPT_ALL (CHAR_MAX + 1)
+#define OPT_IGNORE (CHAR_MAX + 2)
+#define OPT_VERSION (CHAR_MAX + 3)
+#define OPT_HELP (CHAR_MAX + 4)
+
+static struct option long_opts[] = {
+ { "all", no_argument, NULL, OPT_ALL },
+ { "ignore", required_argument, NULL, OPT_IGNORE },
+ { "version", no_argument, NULL, OPT_VERSION },
+ { "help", no_argument, NULL, OPT_HELP },
+ { NULL, 0, NULL, 0 }
+};
+
+static void
+help(void)
+{
+ fprintf(stderr,
+ "usage: nproc [--all] [--ignore=count]\n");
+ fprintf(stderr,
+ " nproc --help\n");
+ fprintf(stderr,
+ " nproc --version\n");
+}
+
+static void
+usage(void)
+{
+ help();
+ exit(EX_USAGE);
+}
+
+/*
+ * GNU variant ships with the --version switch.
+ *
+ * While we don't have anything to put there, print something which is
+ * whitespace-compatible with the original. Version number was taken
+ * from coreutils this code is in sync with.
+ */
+static void
+version(void)
+{
+ printf("nproc (neither_GNU nor_coreutils) 8.32\n");
+ exit(EXIT_SUCCESS);
+}
+
+int
+main(int argc, char *argv[])
+{
+ const char *errstr;
+ cpuset_t mask;
+ int ch, cpus, ignore;
+ bool all_flag;
+
+ ignore = 0;
+ all_flag = false;
+
+ while ((ch = getopt_long(argc, argv, "", long_opts, NULL)) != -1) {
+ switch (ch) {
+ case OPT_ALL:
+ all_flag = true;
+ break;
+ case OPT_IGNORE:
+ ignore = strtonum(optarg, 0, INT_MAX, &errstr);
+ if (errstr)
+ errx(1, "bad ignore count: %s", errstr);
+ break;
+ case OPT_VERSION:
+ version();
+ __builtin_unreachable();
+ case OPT_HELP:
+ help();
+ exit(EXIT_SUCCESS);
+ default:
+ usage();
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 0)
+ usage();
+
+ if (all_flag) {
+ cpus = sysconf(_SC_NPROCESSORS_ONLN);
+ if (cpus == -1)
+ err(1, "sysconf");
+ } else {
+ CPU_ZERO(&mask);
+ if (cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1,
+ sizeof(mask), &mask) != 0)
+ err(1, "cpuset_getaffinity");
+ cpus = CPU_COUNT(&mask);
+ }
+
+ if (ignore >= cpus)
+ cpus = 1;
+ else
+ cpus -= ignore;
+
+ printf("%u\n", cpus);
+
+ exit(EXIT_SUCCESS);
+}
diff --git a/usr.bin/cpuset/cpuset.1 b/usr.bin/cpuset/cpuset.1
index 1a8902e1c235..31a3e45134d7 100644
--- a/usr.bin/cpuset/cpuset.1
+++ b/usr.bin/cpuset/cpuset.1
@@ -231,6 +231,7 @@ Create a new cpuset that is restricted to CPUs 0 and 2 and move
into the new set:
.Dl cpuset -C -c -l 0,2 -p <pid>
.Sh SEE ALSO
+.Xr nproc 1 ,
.Xr cpuset 2 ,
.Xr rctl 8
.Sh HISTORY