Changeset View
Standalone View
lib/libutil/cpuset.c
- This file was added.
Property | Old Value | New Value |
---|---|---|
svn:eol-style | null | native \ No newline at end of property |
svn:keywords | null | FreeBSD=%H \ No newline at end of property |
svn:mime-type | null | text/plain \ No newline at end of property |
/* | |||||
* Copyright (c) 2007, 2008 Jeffrey Roberson <jeff@freebsd.org> | |||||
* All rights reserved. | |||||
* | |||||
* Copyright (c) 2008 Nokia Corporation | |||||
* All rights reserved. | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | |||||
* modification, are permitted provided that the following conditions | |||||
* are met: | |||||
* 1. Redistributions of source code must retain the above copyright | |||||
* notice, this list of conditions and the following disclaimer. | |||||
* 2. Redistributions in binary form must reproduce the above copyright | |||||
* notice, this list of conditions and the following disclaimer in the | |||||
* documentation and/or other materials provided with the distribution. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
* SUCH DAMAGE. | |||||
*/ | |||||
#include <sys/types.h> | |||||
#include <sys/cpuset.h> | |||||
#include <stdlib.h> | |||||
#include <string.h> | |||||
#include <libutil.h> | |||||
#include <ctype.h> | |||||
int | |||||
cpuset_parselist(const char *list, cpuset_t *mask) | |||||
{ | |||||
jilles: should use `const char *list` (which also needs adding some `const` below) | |||||
enum { NONE, NUM, DASH } state; | |||||
int lastnum; | |||||
int curnum; | |||||
const char *l; | |||||
Not Done Inline ActionsPerhaps use an unsigned type to avoid undefined behaviour on overflow (see below). jilles: Perhaps use an unsigned type to avoid undefined behaviour on overflow (see below). | |||||
Not Done Inline ActionsThis is will be fixed in a another commit bapt: This is will be fixed in a another commit | |||||
if (strcasecmp(list, "all") == 0) { | |||||
if (cpuset_getaffinity(CPU_LEVEL_ROOT, CPU_WHICH_PID, -1, | |||||
sizeof(*mask), mask) != 0) | |||||
return (CPUSET_PARSE_GETAFFINITY); | |||||
return (CPUSET_PARSE_OK); | |||||
} | |||||
jeffUnsubmitted Not Done Inline ActionsThis behavior should really be split off separately from the list handling. I would like to be able to use the list handling code for domains, which also won't be cpumask_t. Instead I would pass in the bitset type and size that cpumask is derived from. So eliminating cpu specific code from this function will make it more useful and generic in general. Other code man choose to derive bit manipulation functions from the bitset macros in the future and this would be compatible. jeff: This behavior should really be split off separately from the list handling. I would like to be… | |||||
jillesUnsubmitted Not Done Inline ActionsI think the cpuset_parselist() API is useful as is; the more general ranges-of-numbers code can be extracted out in another commit. jilles: I think the `cpuset_parselist()` API is useful as is; the more general ranges-of-numbers code… | |||||
state = NONE; | |||||
curnum = lastnum = 0; | |||||
for (l = list; *l != '\0';) { | |||||
if (isdigit(*l)) { | |||||
curnum = atoi(l); | |||||
Not Done Inline ActionsIt is annoying but the way to pass a char to isdigit and similar macros is to cast it to unsigned char first. jilles: It is annoying but the way to pass a `char` to `isdigit` and similar macros is to cast it to… | |||||
Not Done Inline Actionsin another commit bapt: in another commit | |||||
if (curnum > CPU_SETSIZE) | |||||
return (CPUSET_PARSE_INVALID_CPU); | |||||
while (isdigit(*l)) | |||||
l++; | |||||
switch (state) { | |||||
Not Done Inline Actionsatoi causes undefined behaviour on overflow; consider strtoul or an open-coded loop. jilles: `atoi` causes undefined behaviour on overflow; consider `strtoul` or an open-coded loop. | |||||
Not Done Inline Actionsin a separated commit bapt: in a separated commit | |||||
case NONE: | |||||
lastnum = curnum; | |||||
state = NUM; | |||||
break; | |||||
case DASH: | |||||
for (; lastnum <= curnum; lastnum++) | |||||
CPU_SET(lastnum, mask); | |||||
state = NONE; | |||||
break; | |||||
case NUM: | |||||
default: | |||||
goto parserr; | |||||
} | |||||
continue; | |||||
} | |||||
switch (*l) { | |||||
case ',': | |||||
switch (state) { | |||||
case NONE: | |||||
break; | |||||
case NUM: | |||||
CPU_SET(curnum, mask); | |||||
state = NONE; | |||||
break; | |||||
case DASH: | |||||
goto parserr; | |||||
break; | |||||
} | |||||
break; | |||||
case '-': | |||||
if (state != NUM) | |||||
goto parserr; | |||||
state = DASH; | |||||
break; | |||||
default: | |||||
goto parserr; | |||||
} | |||||
l++; | |||||
} | |||||
switch (state) { | |||||
case NONE: | |||||
break; | |||||
case NUM: | |||||
CPU_SET(curnum, mask); | |||||
break; | |||||
case DASH: | |||||
goto parserr; | |||||
} | |||||
return (CPUSET_PARSE_OK); | |||||
parserr: | |||||
return (CPUSET_PARSE_ERROR); | |||||
} |
should use const char *list (which also needs adding some const below)