Index: usr.bin/cpuset/cpuset.1 =================================================================== --- usr.bin/cpuset/cpuset.1 +++ usr.bin/cpuset/cpuset.1 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 3, 2018 +.Dd August 25, 2022 .Dt CPUSET 1 .Os .Sh NAME @@ -57,6 +57,10 @@ .Fl g .Op Fl cir .Op Fl d Ar domain | Fl j Ar jail | Fl p Ar pid | Fl t Ar tid | Fl s Ar setid | Fl x Ar irq +.Nm +.Fl g +.Fl -count +.Fl p Ar pid .Sh DESCRIPTION The .Nm @@ -172,6 +176,16 @@ .It Fl x Ar irq Specifies an irq as the target of the operation. .El +.Pp +The long options are as follows: +.Bl -tag -width ".Fl -count" +.It Fl -count +Count the number of hardware threads included in the set. Requires +.Fl g +and +.Fl p +flags. +.El .Sh EXIT STATUS .Ex -std .Sh EXAMPLES Index: usr.bin/cpuset/cpuset.c =================================================================== --- usr.bin/cpuset/cpuset.c +++ usr.bin/cpuset/cpuset.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -52,6 +53,9 @@ #include #include +/* + * Short opts. + */ static int Cflag; static int cflag; static int dflag; @@ -65,12 +69,24 @@ static int sflag; static int tflag; static int xflag; + +/* + * Long-only opts. + */ +static int count_flag; + static id_t id; static cpulevel_t level; static cpuwhich_t which; +#define OPT_THREADCOUNT (CHAR_MAX + 1) static void usage(void); +static struct option long_opts[] = { + { "count", no_argument, NULL, OPT_THREADCOUNT }, + { NULL, 0, NULL, 0 } +}; + struct numa_policy { const char *name; int policy; @@ -283,6 +299,18 @@ levelnames[level], setid); } +static void +printcount(void) +{ + cpuset_t mask; + CPU_ZERO(&mask); + + if (cpuset_getaffinity(CPU_LEVEL_ROOT, CPU_WHICH_PID, id, + sizeof(mask), &mask) != 0) + err(EXIT_FAILURE, "getaffinity"); + printf("%d\n", CPU_COUNT(&mask)); +} + int main(int argc, char *argv[]) { @@ -300,7 +328,8 @@ level = CPU_LEVEL_WHICH; which = CPU_WHICH_PID; id = pid = tid = setid = -1; - while ((ch = getopt(argc, argv, "Ccd:gij:l:n:p:rs:t:x:")) != -1) { + while ((ch = getopt_long(argc, argv, + "Ccd:gij:l:n:p:rs:t:x:", long_opts, NULL)) != -1) { switch (ch) { case 'C': Cflag = 1; @@ -359,12 +388,30 @@ which = CPU_WHICH_IRQ; id = atoi(optarg); break; + case OPT_THREADCOUNT: + count_flag = 1; + break; default: usage(); } } argc -= optind; argv += optind; + + /* + * count requires g and p flags and is incompatible with + * everything else for simplicity. + */ + if (count_flag) { + if (!gflag || !pflag) + usage(); + if (Cflag || cflag || dflag || iflag || jflag || lflag || + nflag || rflag || sflag || tflag || xflag) + usage(); + printcount(); + exit(EXIT_SUCCESS); + } + if (gflag) { if (argc || Cflag || lflag || nflag) usage(); @@ -471,5 +518,7 @@ fprintf(stderr, " cpuset -g [-cir]\n" " [-d domain | -j jailid | -p pid | -t tid | -s setid | -x irq]\n"); + fprintf(stderr, + " cpuset -g --count -p pid\n"); exit(1); }