Changeset 2725 in MondoRescue for branches/2.2.9/mindi-busybox/miscutils/taskset.c
- Timestamp:
- Feb 25, 2011, 9:26:54 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2.2.9/mindi-busybox/miscutils/taskset.c
r1765 r2725 2 2 /* 3 3 * taskset - retrieve or set a processes' CPU affinity 4 * Copyright (c) 2006 Bernhard Fischer4 * Copyright (c) 2006 Bernhard Reutner-Fischer 5 5 * 6 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.6 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 7 7 */ 8 8 9 9 #include <sched.h> 10 #include <getopt.h> /* optind */11 10 #include "libbb.h" 12 11 13 12 #if ENABLE_FEATURE_TASKSET_FANCY 14 13 #define TASKSET_PRINTF_MASK "%s" 15 #define from_cpuset(x) __from_cpuset(&x)16 14 /* craft a string from the mask */ 17 static char * __from_cpuset(cpu_set_t *mask)15 static char *from_cpuset(cpu_set_t *mask) 18 16 { 19 17 int i; 20 char *ret = 0, *str = xzalloc(9); 18 char *ret = NULL; 19 char *str = xzalloc((CPU_SETSIZE / 4) + 1); /* we will leak it */ 21 20 22 21 for (i = CPU_SETSIZE - 4; i >= 0; i -= 4) { 23 charval = 0;22 int val = 0; 24 23 int off; 25 24 for (off = 0; off <= 3; ++off) 26 if (CPU_ISSET(i+off, mask)) 27 val |= 1<<off; 28 25 if (CPU_ISSET(i + off, mask)) 26 val |= 1 << off; 29 27 if (!ret && val) 30 28 ret = str; 31 *str++ = (val-'0'<=9) ? (val+48) : (val+87);29 *str++ = bb_hexdigits_upcase[val] | 0x20; 32 30 } 33 31 return ret; 34 32 } 35 33 #else 36 #define TASKSET_PRINTF_MASK "%x" 37 /* (void*) cast is for battling gcc: */ 38 /* "dereferencing type-punned pointer will break strict-aliasing rules" */ 39 #define from_cpuset(mask) (*(unsigned*)(void*)&(mask)) 34 #define TASKSET_PRINTF_MASK "%llx" 35 static unsigned long long from_cpuset(cpu_set_t *mask) 36 { 37 struct BUG_CPU_SETSIZE_is_too_small { 38 char BUG_CPU_SETSIZE_is_too_small[ 39 CPU_SETSIZE < sizeof(int) ? -1 : 1]; 40 }; 41 char *p = (void*)mask; 42 43 /* Take the least significant bits. Careful! 44 * Consider both CPU_SETSIZE=4 and CPU_SETSIZE=1024 cases 45 */ 46 #if BB_BIG_ENDIAN 47 /* For big endian, it means LAST bits */ 48 if (CPU_SETSIZE < sizeof(long)) 49 p += CPU_SETSIZE - sizeof(int); 50 else if (CPU_SETSIZE < sizeof(long long)) 51 p += CPU_SETSIZE - sizeof(long); 52 else 53 p += CPU_SETSIZE - sizeof(long long); 54 #endif 55 if (CPU_SETSIZE < sizeof(long)) 56 return *(unsigned*)p; 57 if (CPU_SETSIZE < sizeof(long long)) 58 return *(unsigned long*)p; 59 return *(unsigned long long*)p; 60 } 40 61 #endif 41 62 42 #define OPT_p 143 63 44 int taskset_main(int argc, char ** argv);45 int taskset_main(int argc , char**argv)64 int taskset_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 65 int taskset_main(int argc UNUSED_PARAM, char **argv) 46 66 { 47 cpu_set_t mask , new_mask;67 cpu_set_t mask; 48 68 pid_t pid = 0; 49 unsigned opt; 50 const char *state = "current\0new"; 51 char *p_opt = NULL, *aff = NULL; 69 unsigned opt_p; 70 const char *current_new; 71 char *pid_str; 72 char *aff = aff; /* for compiler */ 52 73 53 opt = getopt32(argv, "+p:", &p_opt); 74 /* NB: we mimic util-linux's taskset: -p does not take 75 * an argument, i.e., "-pN" is NOT valid, only "-p N"! 76 * Indeed, util-linux-2.13-pre7 uses: 77 * getopt_long(argc, argv, "+pchV", ...), not "...p:..." */ 54 78 55 if (opt & OPT_p) { 56 if (argc == optind+1) { /* -p <aff> <pid> */ 57 aff = p_opt; 58 p_opt = argv[optind]; 79 opt_complementary = "-1"; /* at least 1 arg */ 80 opt_p = getopt32(argv, "+p"); 81 argv += optind; 82 83 if (opt_p) { 84 pid_str = *argv++; 85 if (*argv) { /* "-p <aff> <pid> ...rest.is.ignored..." */ 86 aff = pid_str; 87 pid_str = *argv; /* NB: *argv != NULL in this case */ 59 88 } 60 argv += optind; /* me -p <arg>*/61 pid = xatoul_range(p _opt, 1, ULONG_MAX); /* -p <pid> */62 } else 63 aff = * ++argv; /* <aff> <cmd...> */64 if (aff) {65 unsigned i = 0;66 unsigned long l = xstrtol_range(aff, 0, 1, LONG_MAX);89 /* else it was just "-p <pid>", and *argv == NULL */ 90 pid = xatoul_range(pid_str, 1, ((unsigned)(pid_t)ULONG_MAX) >> 1); 91 } else { 92 aff = *argv++; /* <aff> <cmd...> */ 93 if (!*argv) 94 bb_show_usage(); 95 } 67 96 68 CPU_ZERO(&new_mask); 69 while (i < CPU_SETSIZE && l >= (1<<i)) { 70 if ((1<<i) & l) 71 CPU_SET(i, &new_mask); 72 ++i; 97 current_new = "current\0new"; 98 if (opt_p) { 99 print_aff: 100 if (sched_getaffinity(pid, sizeof(mask), &mask) < 0) 101 bb_perror_msg_and_die("can't %cet pid %d's affinity", 'g', pid); 102 printf("pid %d's %s affinity mask: "TASKSET_PRINTF_MASK"\n", 103 pid, current_new, from_cpuset(&mask)); 104 if (!*argv) { 105 /* Either it was just "-p <pid>", 106 * or it was "-p <aff> <pid>" and we came here 107 * for the second time (see goto below) */ 108 return EXIT_SUCCESS; 109 } 110 *argv = NULL; 111 current_new += 8; /* "new" */ 112 } 113 114 { /* Affinity was specified, translate it into cpu_set_t */ 115 unsigned i; 116 /* Do not allow zero mask: */ 117 unsigned long long m = xstrtoull_range(aff, 0, 1, ULLONG_MAX); 118 enum { CNT_BIT = CPU_SETSIZE < sizeof(m)*8 ? CPU_SETSIZE : sizeof(m)*8 }; 119 120 CPU_ZERO(&mask); 121 for (i = 0; i < CNT_BIT; i++) { 122 unsigned long long bit = (1ULL << i); 123 if (bit & m) 124 CPU_SET(i, &mask); 73 125 } 74 126 } 75 127 76 if (opt & OPT_p) { 77 print_aff: 78 if (sched_getaffinity(pid, sizeof(mask), &mask) < 0) 79 bb_perror_msg_and_die("failed to %cet pid %d's affinity", 'g', pid); 80 printf("pid %d's %s affinity mask: "TASKSET_PRINTF_MASK"\n", 81 pid, state, from_cpuset(mask)); 82 if (!*argv) /* no new affinity given or we did print already, done. */ 83 return EXIT_SUCCESS; 84 } 128 /* Set pid's or our own (pid==0) affinity */ 129 if (sched_setaffinity(pid, sizeof(mask), &mask)) 130 bb_perror_msg_and_die("can't %cet pid %d's affinity", 's', pid); 85 131 86 if (sched_setaffinity(pid, sizeof(new_mask), &new_mask)) 87 bb_perror_msg_and_die("failed to %cet pid %d's affinity", 's', pid); 88 if (opt & OPT_p) { 89 state += 8; 90 ++argv; 91 goto print_aff; 92 } 93 ++argv; 94 BB_EXECVP(*argv, argv); 95 bb_perror_msg_and_die("%s", *argv); 132 if (!argv[0]) /* "-p <aff> <pid> [...ignored...]" */ 133 goto print_aff; /* print new affinity and exit */ 134 135 BB_EXECVP_or_die(argv); 96 136 } 97 #undef OPT_p98 #undef TASKSET_PRINTF_MASK99 #undef from_cpuset
Note:
See TracChangeset
for help on using the changeset viewer.