[Xenomai-git] Philippe Gerum : boilerplate/setup: accept CPU ranges in --cpu-affinity
Module: xenomai-3 Branch: stable-3.0.x Commit: 53974367e350fbe1de289a796424ba7b2d176431 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=53974367e350fbe1de289a796424ba7b2d176431 Author: Philippe GerumDate: Thu May 25 10:33:40 2017 +0200 boilerplate/setup: accept CPU ranges in --cpu-affinity e.g. --cpu-affinity=0-2 selects CPU0, CPU1 and CPU2. --cpu-affinity=3-4,7 selects CPU3, CPU4 and CPU7. --cpu-affinity=1- selects a range from CPU1 to the last CPU configured. NOTE: if a selected CPU is configured but not online, the setup may fail with -EINVAL. --- lib/boilerplate/setup.c | 69 ++- 1 file changed, 56 insertions(+), 13 deletions(-) diff --git a/lib/boilerplate/setup.c b/lib/boilerplate/setup.c index e534e66..eb9b7e1 100644 --- a/lib/boilerplate/setup.c +++ b/lib/boilerplate/setup.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -150,20 +151,56 @@ static inline void dump_configuration(void) printf("AUTOMATIC_BOOTSTRAP=%d\n", xenomai_auto_bootstrap); } +static inline int resolve_cpuid(const char *s) +{ + return isdigit(*s) ? atoi(s) : -1; +} + static int collect_cpu_affinity(const char *cpu_list) { - char *s = strdup(cpu_list), *p, *n; - int ret, cpu; - - n = s; - while ((p = strtok(n, ",")) != NULL) { - cpu = atoi(p); - if (cpu >= CPU_SETSIZE) { - free(s); - early_warning("invalid CPU number '%d'", cpu); - return -EINVAL; + char *s, *n, *range, *range_p = NULL, *id, *id_r; + int start, end, cpu, nr_cpus, ret; + + /* +* We don't know which CPUs are online yet, but we may know +* which CPU identifier range is valid. Ask for the number of +* processors configured to find out. +*/ + nr_cpus = (int)sysconf(_SC_NPROCESSORS_CONF); + if (nr_cpus < 0) { + ret = -errno; + warning("sysconf(_SC_NPROCESSORS_CONF) failed [%s]", symerror(ret)); + return ret; + } + + s = n = strdup(cpu_list); + while ((range = strtok_r(n, ",", _p)) != NULL) { + if (*range == '\0') + continue; + end = -1; + if (range[strlen(range)-1] == '-') + end = nr_cpus - 1; + id = strtok_r(range, "-", _r); + if (id) { + start = resolve_cpuid(id); + if (*range == '-') { + end = start; + start = 0; + } + id = strtok_r(NULL, "-", _r); + if (id) + end = resolve_cpuid(id); + else if (end < 0) + end = start; + if (start < 0 || start >= nr_cpus || + end < 0 || end >= nr_cpus) + goto fail; + } else { + start = 0; + end = nr_cpus - 1; } - CPU_SET(cpu, &__base_setup_data.cpu_affinity); + for (cpu = start; cpu <= end; cpu++) + CPU_SET(cpu, &__base_setup_data.cpu_affinity); n = NULL; } @@ -182,11 +219,17 @@ static int collect_cpu_affinity(const char *cpu_list) ret = sched_setaffinity(0, sizeof(__base_setup_data.cpu_affinity), &__base_setup_data.cpu_affinity); if (ret) { - early_warning("invalid CPU in affinity list '%s'", cpu_list); - return -errno; + ret = -errno; + early_warning("invalid CPU in '%s'", cpu_list); + return ret; } return 0; +fail: + warning("invalid CPU number/range in '%s'", cpu_list); + free(s); + + return -EINVAL; } static inline char **prep_args(int argc, char *const argv[], int *largcp) ___ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Philippe Gerum : boilerplate/setup: accept CPU ranges in --cpu-affinity
Module: xenomai-3 Branch: next Commit: 3397f94bdd7d38edbccf9e96789db04cc81800a7 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=3397f94bdd7d38edbccf9e96789db04cc81800a7 Author: Philippe GerumDate: Thu May 25 10:33:40 2017 +0200 boilerplate/setup: accept CPU ranges in --cpu-affinity e.g. --cpu-affinity=0-2 selects CPU0, CPU1 and CPU2. --cpu-affinity=3-4,7 selects CPU3, CPU4 and CPU7. --cpu-affinity=1- selects a range from CPU1 to the last CPU configured. NOTE: if a selected CPU is configured but not online, the setup may fail with -EINVAL. --- lib/boilerplate/setup.c | 69 ++- 1 file changed, 56 insertions(+), 13 deletions(-) diff --git a/lib/boilerplate/setup.c b/lib/boilerplate/setup.c index e534e66..eb9b7e1 100644 --- a/lib/boilerplate/setup.c +++ b/lib/boilerplate/setup.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -150,20 +151,56 @@ static inline void dump_configuration(void) printf("AUTOMATIC_BOOTSTRAP=%d\n", xenomai_auto_bootstrap); } +static inline int resolve_cpuid(const char *s) +{ + return isdigit(*s) ? atoi(s) : -1; +} + static int collect_cpu_affinity(const char *cpu_list) { - char *s = strdup(cpu_list), *p, *n; - int ret, cpu; - - n = s; - while ((p = strtok(n, ",")) != NULL) { - cpu = atoi(p); - if (cpu >= CPU_SETSIZE) { - free(s); - early_warning("invalid CPU number '%d'", cpu); - return -EINVAL; + char *s, *n, *range, *range_p = NULL, *id, *id_r; + int start, end, cpu, nr_cpus, ret; + + /* +* We don't know which CPUs are online yet, but we may know +* which CPU identifier range is valid. Ask for the number of +* processors configured to find out. +*/ + nr_cpus = (int)sysconf(_SC_NPROCESSORS_CONF); + if (nr_cpus < 0) { + ret = -errno; + warning("sysconf(_SC_NPROCESSORS_CONF) failed [%s]", symerror(ret)); + return ret; + } + + s = n = strdup(cpu_list); + while ((range = strtok_r(n, ",", _p)) != NULL) { + if (*range == '\0') + continue; + end = -1; + if (range[strlen(range)-1] == '-') + end = nr_cpus - 1; + id = strtok_r(range, "-", _r); + if (id) { + start = resolve_cpuid(id); + if (*range == '-') { + end = start; + start = 0; + } + id = strtok_r(NULL, "-", _r); + if (id) + end = resolve_cpuid(id); + else if (end < 0) + end = start; + if (start < 0 || start >= nr_cpus || + end < 0 || end >= nr_cpus) + goto fail; + } else { + start = 0; + end = nr_cpus - 1; } - CPU_SET(cpu, &__base_setup_data.cpu_affinity); + for (cpu = start; cpu <= end; cpu++) + CPU_SET(cpu, &__base_setup_data.cpu_affinity); n = NULL; } @@ -182,11 +219,17 @@ static int collect_cpu_affinity(const char *cpu_list) ret = sched_setaffinity(0, sizeof(__base_setup_data.cpu_affinity), &__base_setup_data.cpu_affinity); if (ret) { - early_warning("invalid CPU in affinity list '%s'", cpu_list); - return -errno; + ret = -errno; + early_warning("invalid CPU in '%s'", cpu_list); + return ret; } return 0; +fail: + warning("invalid CPU number/range in '%s'", cpu_list); + free(s); + + return -EINVAL; } static inline char **prep_args(int argc, char *const argv[], int *largcp) ___ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git
[Xenomai-git] Philippe Gerum : boilerplate/setup: accept CPU ranges in --cpu-affinity
Module: xenomai-3 Branch: next Commit: 6e233c1066944debf11ebc4e42ddadec6c201c3c URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=6e233c1066944debf11ebc4e42ddadec6c201c3c Author: Philippe GerumDate: Thu May 25 10:33:40 2017 +0200 boilerplate/setup: accept CPU ranges in --cpu-affinity e.g. --cpu-affinity=0-2 selects CPU0, CPU1 and CPU2. --cpu-affinity=3-4,7 selects CPU3, CPU4 and CPU7. --cpu-affinity=1- selects a range from CPU1 to the last CPU configured. NOTE: if a selected CPU is configured but not online, the setup may fail with -EINVAL. --- lib/boilerplate/setup.c | 69 ++- 1 file changed, 56 insertions(+), 13 deletions(-) diff --git a/lib/boilerplate/setup.c b/lib/boilerplate/setup.c index e534e66..eb9b7e1 100644 --- a/lib/boilerplate/setup.c +++ b/lib/boilerplate/setup.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -150,20 +151,56 @@ static inline void dump_configuration(void) printf("AUTOMATIC_BOOTSTRAP=%d\n", xenomai_auto_bootstrap); } +static inline int resolve_cpuid(const char *s) +{ + return isdigit(*s) ? atoi(s) : -1; +} + static int collect_cpu_affinity(const char *cpu_list) { - char *s = strdup(cpu_list), *p, *n; - int ret, cpu; - - n = s; - while ((p = strtok(n, ",")) != NULL) { - cpu = atoi(p); - if (cpu >= CPU_SETSIZE) { - free(s); - early_warning("invalid CPU number '%d'", cpu); - return -EINVAL; + char *s, *n, *range, *range_p = NULL, *id, *id_r; + int start, end, cpu, nr_cpus, ret; + + /* +* We don't know which CPUs are online yet, but we may know +* which CPU identifier range is valid. Ask for the number of +* processors configured to find out. +*/ + nr_cpus = (int)sysconf(_SC_NPROCESSORS_CONF); + if (nr_cpus < 0) { + ret = -errno; + warning("sysconf(_SC_NPROCESSORS_CONF) failed [%s]", symerror(ret)); + return ret; + } + + s = n = strdup(cpu_list); + while ((range = strtok_r(n, ",", _p)) != NULL) { + if (*range == '\0') + continue; + end = -1; + if (range[strlen(range)-1] == '-') + end = nr_cpus - 1; + id = strtok_r(range, "-", _r); + if (id) { + start = resolve_cpuid(id); + if (*range == '-') { + end = start; + start = 0; + } + id = strtok_r(NULL, "-", _r); + if (id) + end = resolve_cpuid(id); + else if (end < 0) + end = start; + if (start < 0 || start >= nr_cpus || + end < 0 || end >= nr_cpus) + goto fail; + } else { + start = 0; + end = nr_cpus - 1; } - CPU_SET(cpu, &__base_setup_data.cpu_affinity); + for (cpu = start; cpu <= end; cpu++) + CPU_SET(cpu, &__base_setup_data.cpu_affinity); n = NULL; } @@ -182,11 +219,17 @@ static int collect_cpu_affinity(const char *cpu_list) ret = sched_setaffinity(0, sizeof(__base_setup_data.cpu_affinity), &__base_setup_data.cpu_affinity); if (ret) { - early_warning("invalid CPU in affinity list '%s'", cpu_list); - return -errno; + ret = -errno; + early_warning("invalid CPU in '%s'", cpu_list); + return ret; } return 0; +fail: + warning("invalid CPU number/range in '%s'", cpu_list); + free(s); + + return -EINVAL; } static inline char **prep_args(int argc, char *const argv[], int *largcp) ___ Xenomai-git mailing list Xenomai-git@xenomai.org https://xenomai.org/mailman/listinfo/xenomai-git