in src/sys_info.cc [28:97]
std::set<unsigned int> SysInfo::str_to_cpu_set(const char * s) {
std::set<unsigned int> ret;
if (!s) return ret;
// pointer into the string
const char * ptr = const_cast<char*>(s);
// fields for denoting a range of cpus
unsigned int curr, next;
char * endptr;
// we'll loop as long as there are fields left denoting active cpus (comma separated)
while (1) {
// stop if we reach an invalid field
if (*ptr < '0' || *ptr > '9') break;
// get an integer
curr = strtoul(ptr, &endptr, 10);
// check for strtoul error
if (curr == std::numeric_limits<unsigned int>::max()) {
fprintf(stderr, "Invalid cpu set \"%s\"", s);
exit(1);
}
// advance past this number
ptr = endptr;
// if there's a dash, it means this field specifies a range of cpus
if (*ptr == '-') {
// get the next number after the '-' and advance past it
++ptr;
// stop if we reach an invalid field
if (*ptr < '0' || *ptr > '9') break;
next = strtoul(ptr, &endptr, 10);
// check for strtoul error
if (next == std::numeric_limits<unsigned int>::max()) {
fprintf(stderr, "Invalid cpu set \"%s\"", s);
exit(1);
}
// advance past this number
ptr = endptr;
// otherwise, only one cpu in this field
} else {
next = curr;
}
// insert the range of cpu numbers [curr,next] into the set
for (int i = curr; i <= next; ++i) {
ret.insert(i);
}
// we're done if there are no more number fields (which are ',' separated)
if (*ptr != ',') break;
// otherwise increment the pointer past the comma to the next field
++ptr;
}
return ret;
}