return TAKE_PTR(str) ?: strdup("");
}
+char *cpu_set_to_range_string(const CPUSet *set) {
+ unsigned range_start = 0, range_end;
+ _cleanup_free_ char *str = NULL;
+ size_t allocated = 0, len = 0;
+ bool in_range = false;
+ int r;
+
+ for (unsigned i = 0; i < set->allocated * 8; i++)
+ if (CPU_ISSET_S(i, set->allocated, set->set)) {
+ if (in_range)
+ range_end++;
+ else {
+ range_start = range_end = i;
+ in_range = true;
+ }
+ } else if (in_range) {
+ in_range = false;
+
+ if (!GREEDY_REALLOC(str, allocated, len + 2 + 2 * DECIMAL_STR_MAX(unsigned)))
+ return NULL;
+
+ r = sprintf(str + len, len > 0 ? " %d-%d" : "%d-%d", range_start, range_end);
+ assert_se(r > 0);
+ len += r;
+ }
+
+ if (in_range) {
+ if (!GREEDY_REALLOC(str, allocated, len + 2 + 2 * DECIMAL_STR_MAX(int)))
+ return NULL;
+
+ r = sprintf(str + len, len > 0 ? " %d-%d" : "%d-%d", range_start, range_end);
+ assert_se(r > 0);
+ }
+
+ return TAKE_PTR(str) ?: strdup("");
+}
+
int cpu_set_realloc(CPUSet *cpu_set, unsigned ncpus) {
size_t need;
#include "alloc-util.h"
#include "cpu-set-util.h"
+#include "string-util.h"
#include "macro.h"
static void test_parse_cpu_set(void) {
log_info("/* %s */", __func__);
+ /* Single value */
+ assert_se(parse_cpu_set_full("0", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
+ assert_se(c.set);
+ assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
+ assert_se(CPU_ISSET_S(0, c.allocated, c.set));
+ assert_se(CPU_COUNT_S(c.allocated, c.set) == 1);
+
+ assert_se(str = cpu_set_to_string(&c));
+ log_info("cpu_set_to_string: %s", str);
+ str = mfree(str);
+ assert_se(str = cpu_set_to_range_string(&c));
+ log_info("cpu_set_to_range_string: %s", str);
+ assert_se(streq(str, "0-0"));
+ str = mfree(str);
+ cpu_set_reset(&c);
+
/* Simple range (from CPUAffinity example) */
assert_se(parse_cpu_set_full("1 2", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
assert_se(c.set);
assert_se(str = cpu_set_to_string(&c));
log_info("cpu_set_to_string: %s", str);
str = mfree(str);
+ assert_se(str = cpu_set_to_range_string(&c));
+ log_info("cpu_set_to_range_string: %s", str);
+ assert_se(streq(str, "1-2"));
+ str = mfree(str);
cpu_set_reset(&c);
/* A more interesting range */
assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
for (cpu = 8; cpu < 12; cpu++)
assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
+
assert_se(str = cpu_set_to_string(&c));
log_info("cpu_set_to_string: %s", str);
str = mfree(str);
+ assert_se(str = cpu_set_to_range_string(&c));
+ log_info("cpu_set_to_range_string: %s", str);
+ assert_se(streq(str, "0-3 8-11"));
+ str = mfree(str);
cpu_set_reset(&c);
/* Quoted strings */
assert_se(str = cpu_set_to_string(&c));
log_info("cpu_set_to_string: %s", str);
str = mfree(str);
+ assert_se(str = cpu_set_to_range_string(&c));
+ log_info("cpu_set_to_range_string: %s", str);
+ assert_se(streq(str, "8-11"));
+ str = mfree(str);
cpu_set_reset(&c);
/* Use commas as separators */
assert_se(str = cpu_set_to_string(&c));
log_info("cpu_set_to_string: %s", str);
str = mfree(str);
+ assert_se(str = cpu_set_to_range_string(&c));
+ log_info("cpu_set_to_range_string: %s", str);
+ assert_se(streq(str, "0-7"));
+ str = mfree(str);
cpu_set_reset(&c);
/* Ranges */
assert_se(str = cpu_set_to_string(&c));
log_info("cpu_set_to_string: %s", str);
str = mfree(str);
+ assert_se(str = cpu_set_to_range_string(&c));
+ log_info("cpu_set_to_range_string: %s", str);
+ assert_se(streq(str, "0-3 8-11"));
+ str = mfree(str);
cpu_set_reset(&c);
/* Negative range (returns empty cpu_set) */
assert_se(str = cpu_set_to_string(&c));
log_info("cpu_set_to_string: %s", str);
str = mfree(str);
+ assert_se(str = cpu_set_to_range_string(&c));
+ log_info("cpu_set_to_range_string: %s", str);
+ assert_se(streq(str, "0-11"));
+ str = mfree(str);
cpu_set_reset(&c);
/* Mix ranges and individual CPUs */
assert_se(str = cpu_set_to_string(&c));
log_info("cpu_set_to_string: %s", str);
str = mfree(str);
+ assert_se(str = cpu_set_to_range_string(&c));
+ log_info("cpu_set_to_range_string: %s", str);
+ assert_se(streq(str, "0-1 4-11"));
+ str = mfree(str);
cpu_set_reset(&c);
/* Garbage */
assert_se(str = cpu_set_to_string(&c));
log_info("cpu_set_to_string: %s", str);
str = mfree(str);
+ assert_se(str = cpu_set_to_range_string(&c));
+ log_info("cpu_set_to_range_string: %s", str);
+ assert_se(streq(str, "8000-8191"));
+ str = mfree(str);
cpu_set_reset(&c);
}