From nobody Wed Feb 8 19:47:37 2023 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4PBrBK5gYJz3p8VW; Wed, 8 Feb 2023 19:47:37 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4PBrBK58fcz3FwB; Wed, 8 Feb 2023 19:47:37 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1675885657; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=o3t0LClgJjWL633VTtrviMwZV+7upryEkpK/PvtPBkw=; b=EGcJYd8mMIhhJYcx7gyLPulp6RcuQMe/gkFCM0cQwQs+jLHGqqe+ay/Y/kfmrBcBznskbB iyCzj0B16iHuIA/OYBEwYbvROzvvLaDIfA4rIYZbO+Q4mefElkk/eIVjoL55VYinRzIjAJ LV81rIbr1BQTDvKNKvz22wki8RAG8Qdq3vtjdq4sQHob6dG/lz2RUUCBTVgama/eBy/uEY +1xtcnekMinnTq2AbrsAyZdNR25wlXRoMjULB0vPlnEO7c+ehmZSSvnjk0I+ikc48IqJCZ lBiu9ANmy7k9XREl0/0AI8eZtF88iZcqz9DFdMX9heFJF+uwctmZ0mTWwEAzDw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1675885657; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=o3t0LClgJjWL633VTtrviMwZV+7upryEkpK/PvtPBkw=; b=UZON7c7OFRhnsHc/vVNtu/QrPcLijkC92G3NUj/4GQzCGRhP8v+XYxjgjjlFfodGXglTm7 dpbXuyD9xC5dNg99kQV9zKOm137GIfg6PjZasavrQZQj0vO20CyUHJR3YLJPlgydcZyxjB GFrjpgxvHcUjC6dgPyfPX8DGZoQnNE4IfdRwSz65MgYHl9fUFy90zwY6+7qCsHFdvb6a7y WCNotb9GgV60Dn+bwdA2bS96K6TBQRljRf4gBZHqL9P/+y2DqBg4NFLXJYXY1l2LV/pHCv QjiQtEANimgB+mg+qxF4eMq645lmi/QQfCxAJ4kMlSeTwskQ9nyOVIR4I4qjtA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1675885657; a=rsa-sha256; cv=none; b=HT6MxfrmP2sbTBXa6m7rt0sSzHUnoZlqLf7p7AV4U2efeux0+bJt5FmUw5iRoig0cCu+44 RogJAt5Zr30VAAUnRVBBqR+IK/OPVTqElxbTbFgJlYcf/+lmnvVxhGyFs7vap3jA3g+lE+ 46BxaiFyoJh6noe/DZdMJE+U9tgjlQa6fag1Xas/c0h4U3tkJULdSjL+D1te1SpPHoWADI 2riZmi428d4P+ZP8dD5shcrE8FqRXu9rGEI8e6mnJlQDN32Ouc7dG9h9gbPB2jaXv236Q3 S+mfb+5cMYctyltqG/4nlPOqst6b2KAN2M2oTeUlgRxvTJNjk5UiYpwa5fw7Wg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4PBrBK4BhXz18S1; Wed, 8 Feb 2023 19:47:37 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 318JlblP052827; Wed, 8 Feb 2023 19:47:37 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 318Jlbt6052826; Wed, 8 Feb 2023 19:47:37 GMT (envelope-from git) Date: Wed, 8 Feb 2023 19:47:37 GMT Message-Id: <202302081947.318Jlbt6052826@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Mateusz Guzik Subject: git: 48bfd3597654 - main - Add nproc(1) List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: mjg X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 48bfd3597654490cdc43bf0f591a539d3a28b590 Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by mjg: URL: https://cgit.FreeBSD.org/src/commit/?id=48bfd3597654490cdc43bf0f591a539d3a28b590 commit 48bfd3597654490cdc43bf0f591a539d3a28b590 Author: Mateusz Guzik AuthorDate: 2023-02-04 23:33:48 +0000 Commit: Mateusz Guzik CommitDate: 2023-02-08 19:47:33 +0000 Add nproc(1) This program prints the number of CPU threads it can run on, while respecting cpusets (or not, depending on switches). It aims to be compatible with nproc as found in GNU coreutils. Reviewed by: des Reviewed by: pstef Differential Revision: https://reviews.freebsd.org/D38386 --- bin/Makefile | 1 + bin/nproc/Makefile | 4 ++ bin/nproc/nproc.1 | 54 ++++++++++++++++++++ bin/nproc/nproc.c | 132 ++++++++++++++++++++++++++++++++++++++++++++++++ usr.bin/cpuset/cpuset.1 | 1 + 5 files changed, 192 insertions(+) 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 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 +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 .Sh SEE ALSO +.Xr nproc 1 , .Xr cpuset 2 , .Xr rctl 8 .Sh HISTORY