Ignore:
Timestamp:
Feb 25, 2011, 9:26:54 PM (13 years ago)
Author:
Bruno Cornec
Message:
  • Update mindi-busybox to 1.18.3 to avoid problems with the tar command which is now failing on recent versions with busybox 1.7.3
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2.2.9/mindi-busybox/miscutils/taskset.c

    r1765 r2725  
    22/*
    33 * taskset - retrieve or set a processes' CPU affinity
    4  * Copyright (c) 2006 Bernhard Fischer
     4 * Copyright (c) 2006 Bernhard Reutner-Fischer
    55 *
    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.
    77 */
    88
    99#include <sched.h>
    10 #include <getopt.h> /* optind */
    1110#include "libbb.h"
    1211
    1312#if ENABLE_FEATURE_TASKSET_FANCY
    1413#define TASKSET_PRINTF_MASK "%s"
    15 #define from_cpuset(x) __from_cpuset(&x)
    1614/* craft a string from the mask */
    17 static char *__from_cpuset(cpu_set_t *mask)
     15static char *from_cpuset(cpu_set_t *mask)
    1816{
    1917    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 */
    2120
    2221    for (i = CPU_SETSIZE - 4; i >= 0; i -= 4) {
    23         char val = 0;
     22        int val = 0;
    2423        int off;
    2524        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;
    2927        if (!ret && val)
    3028            ret = str;
    31         *str++ = (val-'0'<=9) ? (val+48) : (val+87);
     29        *str++ = bb_hexdigits_upcase[val] | 0x20;
    3230    }
    3331    return ret;
    3432}
    3533#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"
     35static 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}
    4061#endif
    4162
    42 #define OPT_p 1
    4363
    44 int taskset_main(int argc, char** argv);
    45 int taskset_main(int argc, char** argv)
     64int taskset_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
     65int taskset_main(int argc UNUSED_PARAM, char **argv)
    4666{
    47     cpu_set_t mask, new_mask;
     67    cpu_set_t mask;
    4868    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 */
    5273
    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:..." */
    5478
    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 */
    5988        }
    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    }
    6796
    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);
    73125        }
    74126    }
    75127
    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);
    85131
    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);
    96136}
    97 #undef OPT_p
    98 #undef TASKSET_PRINTF_MASK
    99 #undef from_cpuset
Note: See TracChangeset for help on using the changeset viewer.