1 /* $NetBSD: psrset.c,v 1.1 2008/06/22 13:53:59 ad Exp $ */
4 * Copyright (c) 2008 The NetBSD Foundation, Inc.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
29 #include <sys/cdefs.h>
31 __RCSID("$NetBSD: psrset.c,v 1.1 2008/06/22 13:53:59 ad Exp $");
34 #include <sys/types.h>
36 #include <sys/sched.h>
37 #include <sys/sysctl.h>
47 static void usage(void);
48 static int eatopt(char **);
49 static int cmd_a(char **, int);
50 static int cmd_b(char **, int);
51 static int cmd_c(char **, int);
52 static int cmd_d(char **, int);
53 static int cmd_e(char **, int);
54 static int cmd_i(char **, int);
55 static int cmd_p(char **, int);
56 static int cmd_r(char **, int);
57 static int cmd_u(char **, int);
58 static int cmd__(char **, int);
62 static cpuset_t
*cpuset
;
65 main(int argc
, char **argv
)
67 int (*cmd
)(char **, int);
70 ncpu
= sysconf(_SC_NPROCESSORS_CONF
);
71 cpuset
= cpuset_create();
73 err(EXIT_FAILURE
, "cpuset_create");
76 if (argc
== 1 || argv
[1][0] != '-') {
79 } else if (strncmp(argv
[1], "-a", 2) == 0) {
82 } else if (strncmp(argv
[1], "-b", 2) == 0) {
85 } else if (strncmp(argv
[1], "-c", 2) == 0) {
88 } else if (strncmp(argv
[1], "-d", 2) == 0) {
91 } else if (strncmp(argv
[1], "-e", 2) == 0) {
94 } else if (strncmp(argv
[1], "-i", 2) == 0) {
97 } else if (strncmp(argv
[1], "-p", 2) == 0) {
100 } else if (strncmp(argv
[1], "-r", 2) == 0) {
103 } else if (strncmp(argv
[1], "-u", 2) == 0) {
111 return (*cmd
)(argv
+ off
, argc
- off
);
118 if (argv
[1][2] != '\0') {
131 rv
= (int)strtol(p
, &q
, 10);
132 if (q
== p
|| *q
!= '\0')
141 fprintf(stderr
, "usage:\n"
142 "\tpsrset [setid ...]\n"
143 "\tpsrset -a setid cpuid ...\n"
144 "\tpsrset -b setid pid ...\n"
145 "\tpsrset -c [cpuid ...]\n"
146 "\tpsrset -d setid\n"
147 "\tpsrset -e setid command\n"
148 "\tpsrset -i [setid ...]\n"
150 "\tpsrset -r cpuid ...\n"
151 "\tpsrset -u pid ...\n");
157 makecpuset(char **argv
)
163 for (i
= 0; i
< ncpu
; i
++)
164 cpuset_set(i
, cpuset
);
168 for (; *argv
!= NULL
; argv
++) {
169 if (!isdigit((unsigned)**argv
))
171 i
= (int)strtol(*argv
, &p
, 10);
172 if ((*p
!= '\0' && *p
!= '-') || p
== *argv
)
175 if (!isdigit((unsigned)p
[1]))
177 j
= (int)strtol(p
+ 1, &q
, 10);
178 if (q
== p
|| *q
!= '\0')
184 errx(EXIT_FAILURE
, "value out of range");
187 cpuset_set(i
++, cpuset
);
192 * Assign processors to set.
195 cmd_a(char **argv
, int argc
)
201 psid
= getint(argv
[0]);
202 makecpuset(argv
+ 1);
203 for (i
= 0; i
< ncpu
; i
++) {
204 if (!cpuset_isset(i
, cpuset
))
206 if (pset_assign(psid
, i
, NULL
))
207 err(EXIT_FAILURE
, "pset_assign");
214 * Bind LWPs within processes to set.
217 cmd_b(char **argv
, int argc
)
222 psid
= getint(*argv
);
223 for (argv
++; *argv
!= NULL
; argv
++) {
224 if (pset_bind(psid
, P_PID
, (idtype_t
)getint(*argv
), NULL
))
225 err(EXIT_FAILURE
, "pset_bind");
235 cmd_c(char **argv
, int argc
)
239 if (pset_create(&psid
))
240 err(EXIT_FAILURE
, "pset_create");
241 printf("%d\n", (int)psid
);
244 for (i
= 0; i
< ncpu
; i
++) {
245 if (!cpuset_isset(i
, cpuset
))
247 if (pset_assign(psid
, i
, NULL
))
248 err(EXIT_FAILURE
, "pset_assign");
258 cmd_d(char **argv
, int argc
)
263 if (pset_destroy(getint(argv
[0])))
264 err(EXIT_FAILURE
, "pset_destroy");
270 * Execute command in set.
273 cmd_e(char **argv
, int argc
)
278 if (pset_bind(getint(argv
[0]), P_PID
, getpid(), NULL
))
279 err(EXIT_FAILURE
, "pset_bind");
280 (void)execvp(argv
[1], argv
+ 1);
285 * Print info about each set.
288 cmd_i(char **argv
, int argc
)
296 if (sysctlbyname("kern.pset.list", buf
, &len
, NULL
, 0) == -1)
297 err(EXIT_FAILURE
, "kern.pset.list");
300 while ((q
= strsep(&p
, ",")) != NULL
) {
301 i
= (int)strtol(q
, &q
, 10);
303 errx(EXIT_FAILURE
, "bad kern.pset.list");
304 printf("%s processor set %d: ",
305 (atoi(q
+ 1) == 1 ? "system" : "user"), i
);
306 for (j
= 0, k
= 0; j
< ncpu
; j
++) {
307 if (pset_assign(PS_QUERY
, j
, &psid
))
308 err(EXIT_FAILURE
, "pset_assign");
311 printf("processor(s)");
324 * Print set ID for each processor.
327 cmd_p(char **argv
, int argc
)
333 for (i
= 0; i
< ncpu
; i
++) {
334 if (!cpuset_isset(i
, cpuset
))
336 if (pset_assign(PS_QUERY
, i
, &psid
))
337 err(EXIT_FAILURE
, "ioctl");
338 printf("processor %d: ", i
);
340 printf("not assigned\n");
342 printf("%d\n", (int)psid
);
349 * Remove CPU from set and return to system.
352 cmd_r(char **argv
, int argc
)
358 for (i
= 0; i
< ncpu
; i
++) {
359 if (!cpuset_isset(i
, cpuset
))
361 if (pset_assign(PS_NONE
, i
, NULL
))
362 err(EXIT_FAILURE
, "ioctl");
369 * Unbind LWPs within process.
372 cmd_u(char **argv
, int argc
)
377 for (; *argv
!= NULL
; argv
++) {
378 if (pset_bind(PS_NONE
, P_PID
, (idtype_t
)getint(*argv
), NULL
))
379 err(EXIT_FAILURE
, "pset_bind");
390 cmd__(char **argv
, int argc
)