busybox/util-linux/taskset.c
Denys Vlasenko 22542eca18 getopt32: remove opt_complementary
function                                             old     new   delta
vgetopt32                                           1318    1392     +74
runsvdir_main                                        703     713     +10
bb_make_directory                                    423     425      +2
collect_cpu                                          546     545      -1
opt_chars                                              3       -      -3
opt_complementary                                      4       -      -4
tftpd_main                                           567     562      -5
ntp_init                                             476     471      -5
zcip_main                                           1266    1256     -10
xxd_main                                             428     418     -10
whois_main                                           140     130     -10
who_main                                             463     453     -10
which_main                                           212     202     -10
wget_main                                           2535    2525     -10
watchdog_main                                        291     281     -10
watch_main                                           222     212     -10
vlock_main                                           399     389     -10
uuencode_main                                        332     322     -10
uudecode_main                                        316     306     -10
unlink_main                                           45      35     -10
udhcpd_main                                         1482    1472     -10
udhcpc_main                                         2762    2752     -10
tune2fs_main                                         290     280     -10
tunctl_main                                          366     356     -10
truncate_main                                        218     208     -10
tr_main                                              518     508     -10
time_main                                           1134    1124     -10
tftp_main                                            286     276     -10
telnetd_main                                        1873    1863     -10
tcpudpsvd_main                                      1785    1775     -10
taskset_main                                         521     511     -10
tar_main                                            1009     999     -10
tail_main                                           1644    1634     -10
syslogd_main                                        1967    1957     -10
switch_root_main                                     368     358     -10
svlogd_main                                         1454    1444     -10
sv                                                  1296    1286     -10
stat_main                                            104      94     -10
start_stop_daemon_main                              1028    1018     -10
split_main                                           542     532     -10
sort_main                                            796     786     -10
slattach_main                                        624     614     -10
shuf_main                                            504     494     -10
setsid_main                                           96      86     -10
setserial_main                                      1132    1122     -10
setfont_main                                         388     378     -10
setconsole_main                                       78      68     -10
sendmail_main                                       1209    1199     -10
sed_main                                             677     667     -10
script_main                                         1077    1067     -10
run_parts_main                                       325     315     -10
rtcwake_main                                         454     444     -10
rm_main                                              175     165     -10
reformime_main                                       119     109     -10
readlink_main                                        123     113     -10
rdate_main                                           246     236     -10
pwdx_main                                            189     179     -10
pstree_main                                          317     307     -10
pscan_main                                           663     653     -10
popmaildir_main                                      818     808     -10
pmap_main                                             80      70     -10
nc_main                                             1042    1032     -10
mv_main                                              558     548     -10
mountpoint_main                                      477     467     -10
mount_main                                          1264    1254     -10
modprobe_main                                        768     758     -10
modinfo_main                                         333     323     -10
mktemp_main                                          200     190     -10
mkswap_main                                          324     314     -10
mkfs_vfat_main                                      1489    1479     -10
microcom_main                                        715     705     -10
md5_sha1_sum_main                                    521     511     -10
man_main                                             867     857     -10
makedevs_main                                       1052    1042     -10
ls_main                                              563     553     -10
losetup_main                                         432     422     -10
loadfont_main                                         89      79     -10
ln_main                                              524     514     -10
link_main                                             75      65     -10
ipcalc_main                                          544     534     -10
iostat_main                                         2397    2387     -10
install_main                                         768     758     -10
id_main                                              480     470     -10
i2cset_main                                         1239    1229     -10
i2cget_main                                          380     370     -10
i2cdump_main                                        1482    1472     -10
i2cdetect_main                                       682     672     -10
hwclock_main                                         406     396     -10
httpd_main                                           741     731     -10
grep_main                                            837     827     -10
getty_main                                          1559    1549     -10
fuser_main                                           297     287     -10
ftpgetput_main                                       345     335     -10
ftpd_main                                           2232    2222     -10
fstrim_main                                          251     241     -10
fsfreeze_main                                         77      67     -10
fsck_minix_main                                     2921    2911     -10
flock_main                                           314     304     -10
flashcp_main                                         740     730     -10
flash_eraseall_main                                  833     823     -10
fdformat_main                                        532     522     -10
expand_main                                          680     670     -10
eject_main                                           335     325     -10
dumpleases_main                                      630     620     -10
du_main                                              314     304     -10
dos2unix_main                                        441     431     -10
diff_main                                           1350    1340     -10
df_main                                             1064    1054     -10
date_main                                           1095    1085     -10
cut_main                                             961     951     -10
cryptpw_main                                         228     218     -10
crontab_main                                         575     565     -10
crond_main                                          1149    1139     -10
cp_main                                              370     360     -10
common_traceroute_main                              3834    3824     -10
common_ping_main                                    1767    1757     -10
comm_main                                            239     229     -10
cmp_main                                             655     645     -10
chrt_main                                            379     369     -10
chpst_main                                           704     694     -10
chpasswd_main                                        308     298     -10
chown_main                                           171     161     -10
chmod_main                                           158     148     -10
cat_main                                             428     418     -10
bzip2_main                                           120     110     -10
blkdiscard_main                                      264     254     -10
base64_main                                          221     211     -10
arping_main                                         1665    1655     -10
ar_main                                              556     546     -10
adjtimex_main                                        406     396     -10
adduser_main                                         882     872     -10
addgroup_main                                        411     401     -10
acpid_main                                          1198    1188     -10
optstring                                             11       -     -11
opt_string                                            18       -     -18
OPT_STR                                               25       -     -25
ubi_tools_main                                      1288    1258     -30
ls_options                                            31       -     -31
------------------------------------------------------------------------------
(add/remove: 0/6 grow/shrink: 3/129 up/down: 86/-1383)      Total: -1297 bytes
   text	   data	    bss	    dec	    hex	filename
 915428	    485	   6876	 922789	  e14a5	busybox_old
 914629	    485	   6872	 921986	  e1182	busybox_unstripped

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2017-08-08 21:55:02 +02:00

221 lines
6.3 KiB
C

/* vi: set sw=4 ts=4: */
/*
* taskset - retrieve or set a processes' CPU affinity
* Copyright (c) 2006 Bernhard Reutner-Fischer
*
* Licensed under GPLv2 or later, see file LICENSE in this source tree.
*/
//config:config TASKSET
//config: bool "taskset (4.1 kb)"
//config: default y
//config: help
//config: Retrieve or set a processes's CPU affinity.
//config: This requires sched_{g,s}etaffinity support in your libc.
//config:
//config:config FEATURE_TASKSET_FANCY
//config: bool "Fancy output"
//config: default y
//config: depends on TASKSET
//config: help
//config: Needed for machines with more than 32-64 CPUs:
//config: affinity parameter 0xHHHHHHHHHHHHHHHHHHHH can be arbitrarily long
//config: in this case. Otherwise, it is limited to sizeof(long).
//applet:IF_TASKSET(APPLET_NOEXEC(taskset, taskset, BB_DIR_USR_BIN, BB_SUID_DROP, taskset))
//kbuild:lib-$(CONFIG_TASKSET) += taskset.o
//usage:#define taskset_trivial_usage
//usage: "[-p] [HEXMASK] PID | PROG ARGS"
//usage:#define taskset_full_usage "\n\n"
//usage: "Set or get CPU affinity\n"
//usage: "\n -p Operate on an existing PID"
//usage:
//usage:#define taskset_example_usage
//usage: "$ taskset 0x7 ./dgemm_test&\n"
//usage: "$ taskset -p 0x1 $!\n"
//usage: "pid 4790's current affinity mask: 7\n"
//usage: "pid 4790's new affinity mask: 1\n"
//usage: "$ taskset 0x7 /bin/sh -c './taskset -p 0x1 $$'\n"
//usage: "pid 6671's current affinity mask: 1\n"
//usage: "pid 6671's new affinity mask: 1\n"
//usage: "$ taskset -p 1\n"
//usage: "pid 1's current affinity mask: 3\n"
/*
* Not yet implemented:
* -a/--all-tasks (affect all threads)
* needs to get TIDs from /proc/PID/task/ and use _them_ as "pid" in sched_setaffinity(pid)
* -c/--cpu-list (specify CPUs via "1,3,5-7")
*/
#include <sched.h>
#include "libbb.h"
typedef unsigned long ul;
#define SZOF_UL (unsigned)(sizeof(ul))
#define BITS_UL (unsigned)(sizeof(ul)*8)
#define MASK_UL (unsigned)(sizeof(ul)*8 - 1)
#if ENABLE_FEATURE_TASKSET_FANCY
#define TASKSET_PRINTF_MASK "%s"
/* craft a string from the mask */
static char *from_mask(const ul *mask, unsigned sz_in_bytes)
{
char *str = xzalloc((sz_in_bytes+1) * 2); /* we will leak it */
char *p = str;
for (;;) {
ul v = *mask++;
if (SZOF_UL == 4)
p += sprintf(p, "%08lx", v);
if (SZOF_UL == 8)
p += sprintf(p, "%016lx", v);
if (SZOF_UL == 16)
p += sprintf(p, "%032lx", v); /* :) */
sz_in_bytes -= SZOF_UL;
if ((int)sz_in_bytes <= 0)
break;
}
while (str[0] == '0' && str[1])
str++;
return str;
}
#else
#define TASKSET_PRINTF_MASK "%lx"
static unsigned long long from_mask(ul *mask, unsigned sz_in_bytes UNUSED_PARAM)
{
return *mask;
}
#endif
static unsigned long *get_aff(int pid, unsigned *sz)
{
int r;
unsigned long *mask = NULL;
unsigned sz_in_bytes = *sz;
for (;;) {
mask = xrealloc(mask, sz_in_bytes);
r = sched_getaffinity(pid, sz_in_bytes, (void*)mask);
if (r == 0)
break;
sz_in_bytes *= 2;
if (errno == EINVAL && (int)sz_in_bytes > 0)
continue;
bb_perror_msg_and_die("can't %cet pid %d's affinity", 'g', pid);
}
//bb_error_msg("get mask[0]:%lx sz_in_bytes:%d", mask[0], sz_in_bytes);
*sz = sz_in_bytes;
return mask;
}
int taskset_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int taskset_main(int argc UNUSED_PARAM, char **argv)
{
ul *mask;
unsigned mask_size_in_bytes;
pid_t pid = 0;
unsigned opt_p;
const char *current_new;
char *aff;
/* NB: we mimic util-linux's taskset: -p does not take
* an argument, i.e., "-pN" is NOT valid, only "-p N"!
* Indeed, util-linux-2.13-pre7 uses:
* getopt_long(argc, argv, "+pchV", ...), not "...p:..." */
opt_p = getopt32(argv, "^+" "p" "\0" "-1" /* at least 1 arg */);
argv += optind;
aff = *argv++;
if (opt_p) {
char *pid_str = aff;
if (*argv) { /* "-p <aff> <pid> ...rest.is.ignored..." */
pid_str = *argv; /* NB: *argv != NULL in this case */
}
/* else it was just "-p <pid>", and *argv == NULL */
pid = xatoul_range(pid_str, 1, ((unsigned)(pid_t)ULONG_MAX) >> 1);
} else {
/* <aff> <cmd...> */
if (!*argv)
bb_show_usage();
}
mask_size_in_bytes = SZOF_UL;
current_new = "current";
print_aff:
mask = get_aff(pid, &mask_size_in_bytes);
if (opt_p) {
printf("pid %d's %s affinity mask: "TASKSET_PRINTF_MASK"\n",
pid, current_new, from_mask(mask, mask_size_in_bytes));
if (*argv == NULL) {
/* Either it was just "-p <pid>",
* or it was "-p <aff> <pid>" and we came here
* for the second time (see goto below) */
return EXIT_SUCCESS;
}
*argv = NULL;
current_new = "new";
}
memset(mask, 0, mask_size_in_bytes);
/* Affinity was specified, translate it into mask */
/* it is always in hex, skip "0x" if it exists */
if (aff[0] == '0' && (aff[1]|0x20) == 'x')
aff += 2;
if (!ENABLE_FEATURE_TASKSET_FANCY) {
mask[0] = xstrtoul(aff, 16);
} else {
unsigned i;
char *last_char;
i = 0; /* bit pos in mask[] */
/* aff is ASCII hex string, accept very long masks in this form.
* Process hex string AABBCCDD... to ulong mask[]
* from the rightmost nibble, which is least-significant.
* Bits not fitting into mask[] are ignored: (example: 1234
* in 12340000000000000000000000000000000000000ff)
*/
last_char = strchrnul(aff, '\0');
while (last_char > aff) {
char c;
ul val;
last_char--;
c = *last_char;
if (isdigit(c))
val = c - '0';
else if ((c|0x20) >= 'a' && (c|0x20) <= 'f')
val = (c|0x20) - ('a' - 10);
else
bb_error_msg_and_die("bad affinity '%s'", aff);
if (i < mask_size_in_bytes * 8) {
mask[i / BITS_UL] |= val << (i & MASK_UL);
//bb_error_msg("bit %d set", i);
}
/* else:
* We can error out here, but we don't.
* For one, kernel itself ignores bits in mask[]
* which do not map to any CPUs:
* if mask[] has one 32-bit long element,
* but you have only 8 CPUs, all bits beyond first 8
* are ignored, silently.
* No point in making bits past 31th to be errors.
*/
i += 4;
}
}
/* Set pid's or our own (pid==0) affinity */
if (sched_setaffinity(pid, mask_size_in_bytes, (void*)mask))
bb_perror_msg_and_die("can't %cet pid %d's affinity", 's', pid);
//bb_error_msg("set mask[0]:%lx", mask[0]);
if (!argv[0]) /* "-p <aff> <pid> [...ignored...]" */
goto print_aff; /* print new affinity and exit */
BB_EXECVP_or_die(argv);
}