]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
shared/cpu-set-util: introduce cpu_set_to_range()
authorMichal Sekletar <msekleta@redhat.com>
Thu, 23 May 2019 12:27:18 +0000 (14:27 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 29 May 2019 15:02:21 +0000 (17:02 +0200)
src/shared/cpu-set-util.c
src/shared/cpu-set-util.h
src/test/test-cpu-set-util.c

index 4980e1964cedea24292ce4edbfafe06d68fdd77c..13a43dc6cca8314daaadc34a14ebe049687beed4 100644 (file)
@@ -34,6 +34,43 @@ char* cpu_set_to_string(const CPUSet *a) {
         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;
 
index f99a818c6019daa5028ad06ab820aab6f51ef75f..fd6a15f4468fa4becce701bfa8b4ec584e8a22bf 100644 (file)
@@ -21,7 +21,9 @@ static inline void cpu_set_reset(CPUSet *a) {
 int cpu_set_add_all(CPUSet *a, const CPUSet *b);
 
 char* cpu_set_to_string(const CPUSet *a);
+char *cpu_set_to_range_string(const CPUSet *a);
 int cpu_set_realloc(CPUSet *cpu_set, unsigned ncpus);
+
 int parse_cpu_set_full(
                 const char *rvalue,
                 CPUSet *cpu_set,
index ea443a1c3b25956714e3cc9c02dc297b1f0c8c93..d66d7d304d2fbe72bc2d3544d1201a05badc7f8c 100644 (file)
@@ -2,6 +2,7 @@
 
 #include "alloc-util.h"
 #include "cpu-set-util.h"
+#include "string-util.h"
 #include "macro.h"
 
 static void test_parse_cpu_set(void) {
@@ -11,6 +12,22 @@ 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);
@@ -22,6 +39,10 @@ static void test_parse_cpu_set(void) {
         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 */
@@ -32,9 +53,14 @@ static void test_parse_cpu_set(void) {
                 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 */
@@ -46,6 +72,10 @@ static void test_parse_cpu_set(void) {
         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 */
@@ -70,6 +100,10 @@ static void test_parse_cpu_set(void) {
         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 */
@@ -96,6 +130,10 @@ static void test_parse_cpu_set(void) {
         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) */
@@ -113,6 +151,10 @@ static void test_parse_cpu_set(void) {
         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 */
@@ -126,6 +168,10 @@ static void test_parse_cpu_set(void) {
         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 */
@@ -154,6 +200,10 @@ static void test_parse_cpu_set(void) {
         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);
 }