Ignore:
Timestamp:
Dec 20, 2016, 4:07:32 PM (7 years ago)
Author:
Bruno Cornec
Message:

New 3?3 banch for incorporation of latest busybox 1.25. Changing minor version to handle potential incompatibilities.

Location:
branches/3.3
Files:
1 edited
1 copied

Legend:

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

    r3232 r3621  
    66 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    77 */
     8
     9//config:config TASKSET
     10//config:   bool "taskset"
     11//config:   default n  # doesn't build on some non-x86 targets (m68k)
     12//config:   help
     13//config:     Retrieve or set a processes's CPU affinity.
     14//config:     This requires sched_{g,s}etaffinity support in your libc.
     15//config:
     16//config:config FEATURE_TASKSET_FANCY
     17//config:   bool "Fancy output"
     18//config:   default y
     19//config:   depends on TASKSET
     20//config:   help
     21//config:     Add code for fancy output. This merely silences a compiler-warning
     22//config:     and adds about 135 Bytes. May be needed for machines with alot
     23//config:     of CPUs.
     24
     25//applet:IF_TASKSET(APPLET(taskset, BB_DIR_USR_BIN, BB_SUID_DROP))
     26//kbuild:lib-$(CONFIG_TASKSET) += taskset.o
    827
    928//usage:#define taskset_trivial_usage
     
    2342//usage:       "$ taskset -p 1\n"
    2443//usage:       "pid 1's current affinity mask: 3\n"
     44/*
     45 Not yet implemented:
     46 * -a/--all-tasks (affect all threads)
     47 * -c/--cpu-list  (specify CPUs via "1,3,5-7")
     48 */
    2549
    2650#include <sched.h>
     
    5276static unsigned long long from_cpuset(cpu_set_t *mask)
    5377{
    54     struct BUG_CPU_SETSIZE_is_too_small {
    55         char BUG_CPU_SETSIZE_is_too_small[
    56             CPU_SETSIZE < sizeof(int) ? -1 : 1];
    57     };
    58     char *p = (void*)mask;
    59 
    60     /* Take the least significant bits. Careful!
    61      * Consider both CPU_SETSIZE=4 and CPU_SETSIZE=1024 cases
     78    BUILD_BUG_ON(CPU_SETSIZE < 8*sizeof(int));
     79
     80    /* Take the least significant bits. Assume cpu_set_t is
     81     * implemented as an array of unsigned long or unsigned
     82     * int.
    6283     */
    63 #if BB_BIG_ENDIAN
    64     /* For big endian, it means LAST bits */
    65     if (CPU_SETSIZE < sizeof(long))
    66         p += CPU_SETSIZE - sizeof(int);
    67     else if (CPU_SETSIZE < sizeof(long long))
    68         p += CPU_SETSIZE - sizeof(long);
    69     else
    70         p += CPU_SETSIZE - sizeof(long long);
    71 #endif
    72     if (CPU_SETSIZE < sizeof(long))
    73         return *(unsigned*)p;
    74     if (CPU_SETSIZE < sizeof(long long))
    75         return *(unsigned long*)p;
    76     return *(unsigned long long*)p;
     84    if (CPU_SETSIZE < 8*sizeof(long))
     85        return *(unsigned*)mask;
     86    if (CPU_SETSIZE < 8*sizeof(long long))
     87        return *(unsigned long*)mask;
     88# if BB_BIG_ENDIAN
     89    if (sizeof(long long) > sizeof(long)) {
     90        /* We can put two long in the long long, but they have to
     91         * be swapped: the least significant word comes first in the
     92         * array */
     93        unsigned long *p = (void*)mask;
     94        return p[0] + ((unsigned long long)p[1] << (8*sizeof(long)));
     95    }
     96# endif
     97    return *(unsigned long long*)mask;
    7798}
    7899#endif
     
    129150    }
    130151
    131     { /* Affinity was specified, translate it into cpu_set_t */
     152    /* Affinity was specified, translate it into cpu_set_t */
     153    CPU_ZERO(&mask);
     154    if (!ENABLE_FEATURE_TASKSET_FANCY) {
    132155        unsigned i;
     156        unsigned long long m;
     157
    133158        /* Do not allow zero mask: */
    134         unsigned long long m = xstrtoull_range(aff, 0, 1, ULLONG_MAX);
    135         enum { CNT_BIT = CPU_SETSIZE < sizeof(m)*8 ? CPU_SETSIZE : sizeof(m)*8 };
    136 
    137         CPU_ZERO(&mask);
    138         for (i = 0; i < CNT_BIT; i++) {
    139             unsigned long long bit = (1ULL << i);
    140             if (bit & m)
     159        m = xstrtoull_range(aff, 0, 1, ULLONG_MAX);
     160        i = 0;
     161        do {
     162            if (m & 1)
    141163                CPU_SET(i, &mask);
     164            i++;
     165            m >>= 1;
     166        } while (m != 0);
     167    } else {
     168        unsigned i;
     169        char *last_byte;
     170        char *bin;
     171        uint8_t bit_in_byte;
     172
     173        /* Cheap way to get "long enough" buffer */
     174        bin = xstrdup(aff);
     175
     176        if (aff[0] != '0' || (aff[1]|0x20) != 'x') {
     177/* TODO: decimal/octal masks are still limited to 2^64 */
     178            unsigned long long m = xstrtoull_range(aff, 0, 1, ULLONG_MAX);
     179            bin += strlen(bin);
     180            last_byte = bin - 1;
     181            while (m) {
     182                *--bin = m & 0xff;
     183                m >>= 8;
     184            }
     185        } else {
     186            /* aff is "0x.....", we accept very long masks in this form */
     187            last_byte = hex2bin(bin, aff + 2, INT_MAX);
     188            if (!last_byte) {
     189 bad_aff:
     190                bb_error_msg_and_die("bad affinity '%s'", aff);
     191            }
     192            last_byte--; /* now points to the last byte */
     193        }
     194
     195        i = 0;
     196        bit_in_byte = 1;
     197        while (last_byte >= bin) {
     198            if (bit_in_byte & *last_byte) {
     199                if (i >= CPU_SETSIZE)
     200                    goto bad_aff;
     201                CPU_SET(i, &mask);
     202                //bb_error_msg("bit %d set", i);
     203            }
     204            i++;
     205            /* bit_in_byte is uint8_t! & 0xff is implied */
     206            bit_in_byte = (bit_in_byte << 1);
     207            if (!bit_in_byte) {
     208                bit_in_byte = 1;
     209                last_byte--;
     210            }
    142211        }
    143212    }
Note: See TracChangeset for help on using the changeset viewer.