taskset: use libc based cpu_set_t
The glibc already supports dynamically allocated CPU sets. We don't have to maintains our private non-compatible implementation. Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
parent
125b6a9191
commit
ff5a6d2067
|
@ -1,23 +1,18 @@
|
||||||
#ifndef UTIL_LINUX_CPUSET_H
|
#ifndef UTIL_LINUX_CPUSET_H
|
||||||
#define UTIL_LINUX_CPUSET_H
|
#define UTIL_LINUX_CPUSET_H
|
||||||
|
|
||||||
struct bitmask {
|
#include <sched.h>
|
||||||
unsigned int size;
|
|
||||||
unsigned long *maskp;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#define howmany(x,y) (((x)+((y)-1))/(y))
|
#define cpuset_nbits(setsize) (8 * (setsize))
|
||||||
#define bitsperlong (8 * sizeof(unsigned long))
|
|
||||||
#define longsperbits(n) howmany(n, bitsperlong)
|
|
||||||
#define bytesperbits(x) ((x+7)/8)
|
|
||||||
|
|
||||||
extern unsigned int bitmask_nbytes(struct bitmask *bmp);
|
extern cpu_set_t *cpuset_alloc(int ncpus, size_t *setsize, size_t *nbits);
|
||||||
extern struct bitmask *bitmask_alloc(unsigned int n);
|
extern void cpuset_free(cpu_set_t *set);
|
||||||
|
|
||||||
extern char *cpuset_to_cstr(struct bitmask *mask, char *str);
|
extern char *cpulist_create(char *str, size_t len, cpu_set_t *set, size_t setsize);
|
||||||
extern char *cpuset_to_str(struct bitmask *mask, char *str);
|
extern int cpulist_parse(const char *str, cpu_set_t *set, size_t setsize);
|
||||||
extern int str_to_cpuset(struct bitmask *mask, const char* str);
|
|
||||||
extern int cstr_to_cpuset(struct bitmask *mask, const char* str);
|
extern char *cpumask_create(char *str, size_t len, cpu_set_t *set, size_t setsize);
|
||||||
|
extern int cpumask_parse(const char *str, cpu_set_t *set, size_t setsize);
|
||||||
|
|
||||||
#endif /* UTIL_LINUX_CPUSET_H */
|
#endif /* UTIL_LINUX_CPUSET_H */
|
||||||
|
|
215
lib/cpuset.c
215
lib/cpuset.c
|
@ -1,3 +1,15 @@
|
||||||
|
/*
|
||||||
|
* Terminology:
|
||||||
|
*
|
||||||
|
* cpuset - (libc) cpu_set_t data structure represents set of CPUs
|
||||||
|
* cpumask - string with hex mask (e.g. "0x00000001")
|
||||||
|
* cpulist - string with CPU ranges (e.g. "0-3,5,7,8")
|
||||||
|
*
|
||||||
|
* Based on code from taskset.c and Linux kernel.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Karel Zak <kzak@redhat.com>
|
||||||
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -6,7 +18,6 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <sys/syscall.h>
|
|
||||||
|
|
||||||
#include "cpuset.h"
|
#include "cpuset.h"
|
||||||
|
|
||||||
|
@ -20,73 +31,6 @@ static inline int val_to_char(int v)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* The following bitmask declarations, bitmask_*() routines, and associated
|
|
||||||
* _setbit() and _getbit() routines are:
|
|
||||||
* Copyright (c) 2004 Silicon Graphics, Inc. (SGI) All rights reserved.
|
|
||||||
* SGI publishes it under the terms of the GNU General Public License, v2,
|
|
||||||
* as published by the Free Software Foundation.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static unsigned int _getbit(const struct bitmask *bmp, unsigned int n)
|
|
||||||
{
|
|
||||||
if (n < bmp->size)
|
|
||||||
return (bmp->maskp[n/bitsperlong] >> (n % bitsperlong)) & 1;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _setbit(struct bitmask *bmp, unsigned int n, unsigned int v)
|
|
||||||
{
|
|
||||||
if (n < bmp->size) {
|
|
||||||
if (v)
|
|
||||||
bmp->maskp[n/bitsperlong] |= 1UL << (n % bitsperlong);
|
|
||||||
else
|
|
||||||
bmp->maskp[n/bitsperlong] &= ~(1UL << (n % bitsperlong));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int bitmask_isbitset(const struct bitmask *bmp, unsigned int i)
|
|
||||||
{
|
|
||||||
return _getbit(bmp, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct bitmask *bitmask_clearall(struct bitmask *bmp)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
for (i = 0; i < bmp->size; i++)
|
|
||||||
_setbit(bmp, i, 0);
|
|
||||||
return bmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct bitmask *bitmask_setbit(struct bitmask *bmp, unsigned int i)
|
|
||||||
{
|
|
||||||
_setbit(bmp, i, 1);
|
|
||||||
return bmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int bitmask_nbytes(struct bitmask *bmp)
|
|
||||||
{
|
|
||||||
return longsperbits(bmp->size) * sizeof(unsigned long);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct bitmask *bitmask_alloc(unsigned int n)
|
|
||||||
{
|
|
||||||
struct bitmask *bmp;
|
|
||||||
|
|
||||||
bmp = malloc(sizeof(*bmp));
|
|
||||||
if (!bmp)
|
|
||||||
return 0;
|
|
||||||
bmp->size = n;
|
|
||||||
bmp->maskp = calloc(longsperbits(n), sizeof(unsigned long));
|
|
||||||
if (!bmp->maskp) {
|
|
||||||
free(bmp);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return bmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int char_to_val(int c)
|
static inline int char_to_val(int c)
|
||||||
{
|
{
|
||||||
int cl;
|
int cl;
|
||||||
|
@ -109,102 +53,148 @@ static const char *nexttoken(const char *q, int sep)
|
||||||
return q;
|
return q;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *cpuset_to_cstr(struct bitmask *mask, char *str)
|
/*
|
||||||
|
* Allocates a new set for ncpus and returns size in bytes and size in bits
|
||||||
|
*/
|
||||||
|
cpu_set_t *cpuset_alloc(int ncpus, size_t *setsize, size_t *nbits)
|
||||||
|
{
|
||||||
|
cpu_set_t *set = CPU_ALLOC(ncpus);
|
||||||
|
|
||||||
|
if (!set)
|
||||||
|
return NULL;
|
||||||
|
if (setsize)
|
||||||
|
*setsize = CPU_ALLOC_SIZE(ncpus);
|
||||||
|
if (nbits)
|
||||||
|
*nbits = cpuset_nbits(CPU_ALLOC_SIZE(ncpus));
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cpuset_free(cpu_set_t *set)
|
||||||
|
{
|
||||||
|
CPU_FREE(set);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns human readable representation of the cpuset. The output format is
|
||||||
|
* a list of CPUs with ranges (for example, "0,1,3-9").
|
||||||
|
*/
|
||||||
|
char *cpulist_create(char *str, size_t len,
|
||||||
|
cpu_set_t *set, size_t setsize)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char *ptr = str;
|
char *ptr = str;
|
||||||
int entry_made = 0;
|
int entry_made = 0;
|
||||||
|
size_t max = cpuset_nbits(setsize);
|
||||||
|
|
||||||
for (i = 0; i < mask->size; i++) {
|
for (i = 0; i < max; i++) {
|
||||||
if (bitmask_isbitset(mask, i)) {
|
if (CPU_ISSET_S(i, setsize, set)) {
|
||||||
int j;
|
int j, rlen;
|
||||||
int run = 0;
|
int run = 0;
|
||||||
entry_made = 1;
|
entry_made = 1;
|
||||||
for (j = i + 1; j < mask->size; j++) {
|
for (j = i + 1; j < max; j++) {
|
||||||
if (bitmask_isbitset(mask, j))
|
if (CPU_ISSET_S(j, setsize, set))
|
||||||
run++;
|
run++;
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!run)
|
if (!run)
|
||||||
sprintf(ptr, "%d,", i);
|
rlen = snprintf(ptr, len, "%d,", i);
|
||||||
else if (run == 1) {
|
else if (run == 1) {
|
||||||
sprintf(ptr, "%d,%d,", i, i + 1);
|
rlen = snprintf(ptr, len, "%d,%d,", i, i + 1);
|
||||||
i++;
|
i++;
|
||||||
} else {
|
} else {
|
||||||
sprintf(ptr, "%d-%d,", i, i + run);
|
rlen = snprintf(ptr, len, "%d-%d,", i, i + run);
|
||||||
i += run;
|
i += run;
|
||||||
}
|
}
|
||||||
while (*ptr != 0)
|
if (rlen < 0 || rlen + 1 > len)
|
||||||
ptr++;
|
return NULL;
|
||||||
|
ptr += rlen;
|
||||||
|
len -= rlen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ptr -= entry_made;
|
ptr -= entry_made;
|
||||||
*ptr = 0;
|
*ptr = '\0';
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *cpuset_to_str(struct bitmask *mask, char *str)
|
/*
|
||||||
|
* Returns string with CPU mask.
|
||||||
|
*/
|
||||||
|
char *cpumask_create(char *str, size_t len,
|
||||||
|
cpu_set_t *set, size_t setsize)
|
||||||
{
|
{
|
||||||
int base;
|
|
||||||
char *ptr = str;
|
char *ptr = str;
|
||||||
char *ret = 0;
|
char *ret = NULL;
|
||||||
|
int cpu;
|
||||||
|
|
||||||
for (base = mask->size - 4; base >= 0; base -= 4) {
|
for (cpu = cpuset_nbits(setsize) - 4; cpu >= 0; cpu -= 4) {
|
||||||
char val = 0;
|
char val = 0;
|
||||||
if (bitmask_isbitset(mask, base))
|
|
||||||
|
if (len == (ptr - str))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (CPU_ISSET_S(cpu, setsize, set))
|
||||||
val |= 1;
|
val |= 1;
|
||||||
if (bitmask_isbitset(mask, base + 1))
|
if (CPU_ISSET_S(cpu + 1, setsize, set))
|
||||||
val |= 2;
|
val |= 2;
|
||||||
if (bitmask_isbitset(mask, base + 2))
|
if (CPU_ISSET_S(cpu + 2, setsize, set))
|
||||||
val |= 4;
|
val |= 4;
|
||||||
if (bitmask_isbitset(mask, base + 3))
|
if (CPU_ISSET_S(cpu + 3, setsize, set))
|
||||||
val |= 8;
|
val |= 8;
|
||||||
|
|
||||||
if (!ret && val)
|
if (!ret && val)
|
||||||
ret = ptr;
|
ret = ptr;
|
||||||
*ptr++ = val_to_char(val);
|
*ptr++ = val_to_char(val);
|
||||||
}
|
}
|
||||||
*ptr = 0;
|
*ptr = '\0';
|
||||||
return ret ? ret : ptr - 1;
|
return ret ? ret : ptr - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int str_to_cpuset(struct bitmask *mask, const char* str)
|
/*
|
||||||
|
* Parses string with list of CPU ranges.
|
||||||
|
*/
|
||||||
|
int cpumask_parse(const char *str, cpu_set_t *set, size_t setsize)
|
||||||
{
|
{
|
||||||
int len = strlen(str);
|
int len = strlen(str);
|
||||||
const char *ptr = str + len - 1;
|
const char *ptr = str + len - 1;
|
||||||
int base = 0;
|
int cpu = 0;
|
||||||
|
|
||||||
/* skip 0x, it's all hex anyway */
|
/* skip 0x, it's all hex anyway */
|
||||||
if (len > 1 && !memcmp(str, "0x", 2L))
|
if (len > 1 && !memcmp(str, "0x", 2L))
|
||||||
str += 2;
|
str += 2;
|
||||||
|
|
||||||
bitmask_clearall(mask);
|
CPU_ZERO_S(setsize, set);
|
||||||
|
|
||||||
while (ptr >= str) {
|
while (ptr >= str) {
|
||||||
char val = char_to_val(*ptr);
|
char val = char_to_val(*ptr);
|
||||||
if (val == (char) -1)
|
if (val == (char) -1)
|
||||||
return -1;
|
return -1;
|
||||||
if (val & 1)
|
if (val & 1)
|
||||||
bitmask_setbit(mask, base);
|
CPU_SET_S(cpu, setsize, set);
|
||||||
if (val & 2)
|
if (val & 2)
|
||||||
bitmask_setbit(mask, base + 1);
|
CPU_SET_S(cpu + 1, setsize, set);
|
||||||
if (val & 4)
|
if (val & 4)
|
||||||
bitmask_setbit(mask, base + 2);
|
CPU_SET_S(cpu + 2, setsize, set);
|
||||||
if (val & 8)
|
if (val & 8)
|
||||||
bitmask_setbit(mask, base + 3);
|
CPU_SET_S(cpu + 3, setsize, set);
|
||||||
len--;
|
len--;
|
||||||
ptr--;
|
ptr--;
|
||||||
base += 4;
|
cpu += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cstr_to_cpuset(struct bitmask *mask, const char* str)
|
/*
|
||||||
|
* Parses string with CPUs mask.
|
||||||
|
*/
|
||||||
|
int cpulist_parse(const char *str, cpu_set_t *set, size_t setsize)
|
||||||
{
|
{
|
||||||
const char *p, *q;
|
const char *p, *q;
|
||||||
q = str;
|
q = str;
|
||||||
bitmask_clearall(mask);
|
|
||||||
|
CPU_ZERO_S(setsize, set);
|
||||||
|
|
||||||
while (p = q, q = nexttoken(q, ','), p) {
|
while (p = q, q = nexttoken(q, ','), p) {
|
||||||
unsigned int a; /* beginning of range */
|
unsigned int a; /* beginning of range */
|
||||||
|
@ -232,7 +222,7 @@ int cstr_to_cpuset(struct bitmask *mask, const char* str)
|
||||||
if (!(a <= b))
|
if (!(a <= b))
|
||||||
return 1;
|
return 1;
|
||||||
while (a <= b) {
|
while (a <= b) {
|
||||||
bitmask_setbit(mask, a);
|
CPU_SET_S(a, setsize, set);
|
||||||
a += s;
|
a += s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -247,7 +237,8 @@ int cstr_to_cpuset(struct bitmask *mask, const char* str)
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
struct bitmask *set;
|
cpu_set_t *set;
|
||||||
|
size_t setsize, buflen, nbits;
|
||||||
char *buf, *mask = NULL, *range = NULL;
|
char *buf, *mask = NULL, *range = NULL;
|
||||||
int ncpus = 2048, rc, c;
|
int ncpus = 2048, rc, c;
|
||||||
|
|
||||||
|
@ -277,28 +268,34 @@ int main(int argc, char *argv[])
|
||||||
if (!mask && !range)
|
if (!mask && !range)
|
||||||
goto usage_err;
|
goto usage_err;
|
||||||
|
|
||||||
set = bitmask_alloc(ncpus);
|
set = cpuset_alloc(ncpus, &setsize, &nbits);
|
||||||
if (!set)
|
if (!set)
|
||||||
err(EXIT_FAILURE, "failed to allocate cpu set");
|
err(EXIT_FAILURE, "failed to allocate cpu set");
|
||||||
|
|
||||||
buf = malloc(7 * ncpus);
|
/*
|
||||||
|
fprintf(stderr, "ncpus: %d, cpuset bits: %zd, cpuset bytes: %zd\n",
|
||||||
|
ncpus, nbits, setsize);
|
||||||
|
*/
|
||||||
|
|
||||||
|
buflen = 7 * nbits;
|
||||||
|
buf = malloc(buflen);
|
||||||
if (!buf)
|
if (!buf)
|
||||||
err(EXIT_FAILURE, "failed to allocate cpu set buffer");
|
err(EXIT_FAILURE, "failed to allocate cpu set buffer");
|
||||||
|
|
||||||
if (mask)
|
if (mask)
|
||||||
rc = str_to_cpuset(set, mask);
|
rc = cpumask_parse(mask, set, setsize);
|
||||||
else
|
else
|
||||||
rc = cstr_to_cpuset(set, range);
|
rc = cpulist_parse(range, set, setsize);
|
||||||
|
|
||||||
if (rc)
|
if (rc)
|
||||||
errx(EXIT_FAILURE, "failed to parse string: %s", mask ? : range);
|
errx(EXIT_FAILURE, "failed to parse string: %s", mask ? : range);
|
||||||
|
|
||||||
printf("%-15s = %15s ", mask ? : range, cpuset_to_str(set, buf));
|
printf("%-15s = %15s ", mask ? : range,
|
||||||
printf("[%s]\n", cpuset_to_cstr(set, buf));
|
cpumask_create(buf, buflen, set, setsize));
|
||||||
|
printf("[%s]\n", cpulist_create(buf, buflen, set, setsize));
|
||||||
|
|
||||||
free(buf);
|
free(buf);
|
||||||
free(set->maskp);
|
cpuset_free(set);
|
||||||
free(set);
|
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
|
||||||
|
|
|
@ -72,19 +72,31 @@ max_number_of_cpus(void)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
int cpus = 2048;
|
int cpus = 2048;
|
||||||
|
size_t setsize;
|
||||||
|
cpu_set_t *set = cpuset_alloc(cpus, &setsize, NULL);
|
||||||
|
|
||||||
|
if (!set)
|
||||||
|
goto err;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
unsigned long buffer[longsperbits(cpus)];
|
CPU_ZERO_S(setsize, set);
|
||||||
memset(buffer, 0, sizeof(buffer));
|
|
||||||
/* the library version does not return size of cpumask_t */
|
/* the library version does not return size of cpumask_t */
|
||||||
n = syscall(SYS_sched_getaffinity, 0, bytesperbits(cpus),
|
n = syscall(SYS_sched_getaffinity, 0, setsize, set);
|
||||||
&buffer);
|
|
||||||
if (n < 0 && errno == EINVAL && cpus < 1024*1024) {
|
if (n < 0 && errno == EINVAL && cpus < 1024*1024) {
|
||||||
|
cpuset_free(set);
|
||||||
cpus *= 2;
|
cpus *= 2;
|
||||||
|
set = cpuset_alloc(cpus, &setsize, NULL);
|
||||||
|
if (!set)
|
||||||
|
goto err;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
cpuset_free(set);
|
||||||
return n*8;
|
return n*8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err:
|
||||||
fprintf (stderr, "cannot determine NR_CPUS; aborting");
|
fprintf (stderr, "cannot determine NR_CPUS; aborting");
|
||||||
exit(1);
|
exit(1);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -92,14 +104,13 @@ max_number_of_cpus(void)
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
struct bitmask *new_mask, *cur_mask;
|
cpu_set_t *new_set, *cur_set;
|
||||||
pid_t pid = 0;
|
pid_t pid = 0;
|
||||||
int opt, err;
|
int opt, err;
|
||||||
char *mstr;
|
char *buf;
|
||||||
char *cstr;
|
|
||||||
int c_opt = 0;
|
int c_opt = 0;
|
||||||
unsigned int cpus_configured;
|
unsigned int ncpus;
|
||||||
int new_mask_byte_size, cur_mask_byte_size;
|
size_t new_setsize, cur_setsize, cur_nbits, buflen;
|
||||||
|
|
||||||
struct option longopts[] = {
|
struct option longopts[] = {
|
||||||
{ "pid", 0, NULL, 'p' },
|
{ "pid", 0, NULL, 'p' },
|
||||||
|
@ -136,37 +147,34 @@ int main(int argc, char *argv[])
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
cpus_configured = max_number_of_cpus();
|
ncpus = max_number_of_cpus();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* cur_mask is always used for the sched_getaffinity call
|
* cur_mask is always used for the sched_getaffinity call
|
||||||
* On the sched_getaffinity the kernel demands a user mask of
|
* On the sched_getaffinity the kernel demands a user mask of
|
||||||
* at least the size of its own cpumask_t.
|
* at least the size of its own cpumask_t.
|
||||||
*/
|
*/
|
||||||
cur_mask = bitmask_alloc(cpus_configured);
|
cur_set = cpuset_alloc(ncpus, &cur_setsize, &cur_nbits);
|
||||||
if (!cur_mask) {
|
if (!cur_set) {
|
||||||
fprintf (stderr, "bitmask_alloc failed\n");
|
fprintf (stderr, "cpuset_alloc failed\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
cur_mask_byte_size = bitmask_nbytes(cur_mask);
|
buflen = 7 * cur_nbits;
|
||||||
mstr = malloc(1 + cur_mask->size / 4);
|
buf = malloc(buflen);
|
||||||
cstr = malloc(7 * cur_mask->size);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* new_mask is always used for the sched_setaffinity call
|
* new_mask is always used for the sched_setaffinity call
|
||||||
* On the sched_setaffinity the kernel will zero-fill its
|
* On the sched_setaffinity the kernel will zero-fill its
|
||||||
* cpumask_t if the user's mask is shorter.
|
* cpumask_t if the user's mask is shorter.
|
||||||
*/
|
*/
|
||||||
new_mask = bitmask_alloc(cpus_configured);
|
new_set = cpuset_alloc(ncpus, &new_setsize, NULL);
|
||||||
if (!new_mask) {
|
if (!new_set) {
|
||||||
fprintf (stderr, "bitmask_alloc failed\n");
|
fprintf (stderr, "cpuset_alloc failed\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
new_mask_byte_size = bitmask_nbytes(new_mask);
|
|
||||||
|
|
||||||
if (pid) {
|
if (pid) {
|
||||||
if (sched_getaffinity(pid, cur_mask_byte_size,
|
if (sched_getaffinity(pid, cur_setsize, cur_set) < 0) {
|
||||||
(cpu_set_t *)cur_mask->maskp) < 0) {
|
|
||||||
perror("sched_getaffinity");
|
perror("sched_getaffinity");
|
||||||
fprintf(stderr, "failed to get pid %d's affinity\n",
|
fprintf(stderr, "failed to get pid %d's affinity\n",
|
||||||
pid);
|
pid);
|
||||||
|
@ -174,19 +182,19 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
if (c_opt)
|
if (c_opt)
|
||||||
printf("pid %d's current affinity list: %s\n", pid,
|
printf("pid %d's current affinity list: %s\n", pid,
|
||||||
cpuset_to_cstr(cur_mask, cstr));
|
cpulist_create(buf, buflen, cur_set, cur_setsize));
|
||||||
else
|
else
|
||||||
printf("pid %d's current affinity mask: %s\n", pid,
|
printf("pid %d's current affinity mask: %s\n", pid,
|
||||||
cpuset_to_str(cur_mask, mstr));
|
cpumask_create(buf, buflen, cur_set, cur_setsize));
|
||||||
|
|
||||||
if (argc - optind == 1)
|
if (argc - optind == 1)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c_opt)
|
if (c_opt)
|
||||||
err = cstr_to_cpuset(new_mask, argv[optind]);
|
err = cpulist_parse(argv[optind], new_set, new_setsize);
|
||||||
else
|
else
|
||||||
err = str_to_cpuset(new_mask, argv[optind]);
|
err = cpumask_parse(argv[optind], new_set, new_setsize);
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
if (c_opt)
|
if (c_opt)
|
||||||
|
@ -198,15 +206,13 @@ int main(int argc, char *argv[])
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sched_setaffinity(pid, new_mask_byte_size,
|
if (sched_setaffinity(pid, new_setsize, new_set) < 0) {
|
||||||
(cpu_set_t *) new_mask->maskp) < 0) {
|
|
||||||
perror("sched_setaffinity");
|
perror("sched_setaffinity");
|
||||||
fprintf(stderr, "failed to set pid %d's affinity.\n", pid);
|
fprintf(stderr, "failed to set pid %d's affinity.\n", pid);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sched_getaffinity(pid, cur_mask_byte_size,
|
if (sched_getaffinity(pid, cur_setsize, cur_set) < 0) {
|
||||||
(cpu_set_t *)cur_mask->maskp) < 0) {
|
|
||||||
perror("sched_getaffinity");
|
perror("sched_getaffinity");
|
||||||
fprintf(stderr, "failed to get pid %d's affinity.\n", pid);
|
fprintf(stderr, "failed to get pid %d's affinity.\n", pid);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -215,11 +221,17 @@ int main(int argc, char *argv[])
|
||||||
if (pid) {
|
if (pid) {
|
||||||
if (c_opt)
|
if (c_opt)
|
||||||
printf("pid %d's new affinity list: %s\n", pid,
|
printf("pid %d's new affinity list: %s\n", pid,
|
||||||
cpuset_to_cstr(cur_mask, cstr));
|
cpulist_create(buf, buflen, cur_set, cur_setsize));
|
||||||
else
|
else
|
||||||
printf("pid %d's new affinity mask: %s\n", pid,
|
printf("pid %d's new affinity mask: %s\n", pid,
|
||||||
cpuset_to_str(cur_mask, mstr));
|
cpumask_create(buf, buflen, cur_set, cur_setsize));
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
free(buf);
|
||||||
|
cpuset_free(cur_set);
|
||||||
|
cpuset_free(new_set);
|
||||||
|
|
||||||
|
if (!pid) {
|
||||||
argv += optind + 1;
|
argv += optind + 1;
|
||||||
execvp(argv[0], argv);
|
execvp(argv[0], argv);
|
||||||
perror("execvp");
|
perror("execvp");
|
||||||
|
|
Loading…
Reference in New Issue