diff options
Diffstat (limited to '')
-rw-r--r-- | src/shared/cpu-set-util.c | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/src/shared/cpu-set-util.c b/src/shared/cpu-set-util.c index d096576..1112de1 100644 --- a/src/shared/cpu-set-util.c +++ b/src/shared/cpu-set-util.c @@ -11,6 +11,7 @@ #include "errno-util.h" #include "extract-word.h" #include "fd-util.h" +#include "hexdecoct.h" #include "log.h" #include "macro.h" #include "memory-util.h" @@ -82,6 +83,63 @@ char *cpu_set_to_range_string(const CPUSet *set) { return TAKE_PTR(str) ?: strdup(""); } +char* cpu_set_to_mask_string(const CPUSet *a) { + _cleanup_free_ char *str = NULL; + size_t len = 0; + bool found_nonzero = false; + + assert(a); + + /* Return CPU set in hexadecimal bitmap mask, e.g. + * CPU 0 -> "1" + * CPU 1 -> "2" + * CPU 0,1 -> "3" + * CPU 0-3 -> "f" + * CPU 0-7 -> "ff" + * CPU 4-7 -> "f0" + * CPU 7 -> "80" + * None -> "0" + * + * When there are more than 32 CPUs, separate every 32 CPUs by comma, e.g. + * CPU 0-47 -> "ffff,ffffffff" + * CPU 0-63 -> "ffffffff,ffffffff" + * CPU 0-71 -> "ff,ffffffff,ffffffff" */ + + for (ssize_t i = a->allocated * 8; i >= 0; i -= 4) { + uint8_t m = 0; + + for (size_t j = 0; j < 4; j++) + if (CPU_ISSET_S(i + j, a->allocated, a->set)) + m |= 1U << j; + + if (!found_nonzero) + found_nonzero = m > 0; + + if (!found_nonzero && m == 0) + /* Skip leading zeros */ + continue; + + if (!GREEDY_REALLOC(str, len + 3)) + return NULL; + + str[len++] = hexchar(m); + if (i >= 4 && i % 32 == 0) + /* Separate by comma for each 32 CPUs. */ + str[len++] = ','; + str[len] = 0; + } + + return TAKE_PTR(str) ?: strdup("0"); +} + +CPUSet* cpu_set_free(CPUSet *c) { + if (!c) + return c; + + cpu_set_reset(c); + return mfree(c); +} + int cpu_set_realloc(CPUSet *cpu_set, unsigned ncpus) { size_t need; @@ -290,3 +348,22 @@ int cpu_set_from_dbus(const uint8_t *bits, size_t size, CPUSet *set) { *set = TAKE_STRUCT(s); return 0; } + +int cpu_mask_add_all(CPUSet *mask) { + long m; + int r; + + assert(mask); + + m = sysconf(_SC_NPROCESSORS_ONLN); + if (m < 0) + return -errno; + + for (unsigned i = 0; i < (unsigned) m; i++) { + r = cpu_set_add(mask, i); + if (r < 0) + return r; + } + + return 0; +} |